12 KiB
帮道受约束业务 Agent TechSpec
状态:IMPLEMENTED_AND_PRODUCTION_ACTIVE_LIMITED_SCOPE。Grounded Agent 已在现役 /api/aihr/agent/** 文本入口落地;仓库默认 OFF,生产于 2026-08-04 受控启用 ACTIVE,仅接管符合范围和门禁的 KNOWLEDGE_QA、LIVE_MY_WORK,其余请求及不合格计划回退旧链路。
当前生产 JAR SHA-256:74d0cd2acc60ebf52f20eb8bee643f59395ba7cff3583076d671e57406f824ac;服务和公开预检已通过。认证态用户逐例验收、客户端状态 UI 全量验收和人工黄金集召回评测仍为 PENDING,因此不宣称生产召回率达标。
目标
将当前由关键词路由、RAG 回答和单数据工具组成的问师傅链路,迁移为受约束、可授权、可审计的业务 Agent。RAG 是工具之一;最终回答只能使用通过门禁的文档证据和实时事实。
不变量
- LLM 不得生成或覆盖
tenantId/userId/projectId/spaceId/appId/extPartyId/role等授权字段。 - 原问题中的数字、币种、日期、期限、比较符、否定和版本必须由确定性校验器保真。
DOCUMENT_EVIDENCE、VERIFIED_FACT和USER_ASSERTION永久分型,不能互相升级。- 历史回答只用于语言理解,不具有事实资格;跨轮事实只能通过重新鉴权的
factRef/citationId延续。 - 初次执行加一次有明确证据目标的补查;第三轮只允许澄清或结束。无新增证据目标立即停止。
- 零合格证据直接返回
NO_EVIDENCE,不调用答案生成模型。 - 模型私有思维过程不保存、不展示;只记录结构化 action、observation 和 reason code。
- 模型输出的
supportedNeedCodes/claimTypes仅是候选支持关系,不能授予“已证明”资格;正式场景无法确认正文支持时必须 fail-closed。 - 工具调用参数必须匹配服务端注册的 schema。日期范围只进入
MY_CURRENT_TASKS,不得进入KNOWLEDGE_SEARCH;授权与作用域参数始终由ExecutionContext注入。
核心契约
ResolvedContext:问题与上轮状态的关系、当前目标、候选实体、用户陈述、可信引用和缺口。SemanticQueryPlan:原问题、规范化问题、意图、领域、候选实体、证据需求和白名单动作。ExecutionContext:服务端从认证上下文解析的租户、主体、应用、项目、空间与角色;不进入模型输入。ToolCall:只包含工具代码和业务参数。ToolResult:工具状态、文档证据、实时事实、缺口、冲突和结构化观察。DocumentEvidence:引用 ID、来源权威/类型、版本、生效时间、适用范围、正文、候选supportedNeedCodes和候选claimTypes。VerifiedFact:事实引用、类型、值、来源系统、查询时点、TTL、范围和授权快照。DecisionResult:ANSWERED/PARTIAL/NEEDS_INPUT/NO_EVIDENCE/CONFLICT与领域结果。GroundedAnswer:摘要、确定性陈述、步骤、缺失信息和澄清问题;陈述和步骤逐项绑定引用。
Java 契约以 AihrAgentGroundingDto 为准。HTTP DTO 在兼容期保持 additive,旧客户端可继续读取 answer/citations/data。
模块边界
agent.context:上下文关系识别、结构化会话状态和引用失效。agent.planning:受约束语义规划及确定性实体校验。agent.tool:Spring Bean Tool Registry、参数 schema、授权策略和执行。agent.evidence:来源、授权、有效期、适用范围、证据槽位与冲突评估。agent.runtime:最多三轮的有限状态执行器。agent.answer:基于已验证输入的组装与 Claim/Reference 校验。knowledge:继续负责 MySQL/Qdrant 检索、治理过滤、候选追踪和原文件重新鉴权。
证据资格与结论校验
证据需求按槽位逐项判断,不能因为标题、领域相同或模型标签命中就让一份文档满足全部需求。文档槽位只有同时满足以下条件才算已覆盖:
- 来源权威、来源类型、版本、有效期和适用范围通过治理门禁。
supportedNeedCodes明确包含当前需求,且claimTypes包含该需求映射的结论类型。- 正文独立支持对应结论类型;模型分类结果与正文保守判定取交集。
- 最终逐 claim 校验正文蕴含、数字一致性和引用 ID 属于本轮通过门禁的证据。
额度片段只可支持 AMOUNT_RULE,不能自动支持 PROCESS_STEPS/MATERIALS/APPROVAL;操作手册步骤也不能自动证明额度或适用资格。制度/流程结论只能由合适 authority/kind 的 DocumentEvidence 支持,实时状态只能由未过期、重新鉴权的 VerifiedFact 支持。PARTIAL 只输出已覆盖槽位,缺失步骤不得由最终模型补齐。
有界执行与工具参数
MY_CURRENT_TASKS 只接受 dateRange/startDate/endDate/status,KNOWLEDGE_SEARCH 只接受 query/domain。Planner 对模型参数按工具 schema 收敛,Tool Registry 在执行前再次校验;tenant/user/project/space/app 等授权字段出现时整份模型计划失效。
运行时只允许初次执行和一次具有新增证据目标的定向补查;第三轮只允许澄清或结束。同工具同规范化参数通过 hash 去重,无新增证据目标立即停止。运行时设总工具调用数、候选数和耗时预算;超时映射为受控 TIMEOUT,迟到结果丢弃,不无限重试,也不把失败详情交给答案模型。
aihr_knowledge_conversation.context_json 继续保持旧版 List<Turn> 格式。结构化状态使用 additive
的 state_json/state_version 列;其中的 factRef 仅映射到服务端保存的工具代码、业务参数、
itemKey、时点、TTL、作用域、授权快照和审计引用,不保存工具事实正文。引用再次使用时必须按
当前 tenant/app/user/conversation/project/version 重新读取并调用已注册工具,不能接受客户端回传的事实内容。
迁移顺序
- 新契约和 Semantic Planner 以影子方式运行,不改变旧响应。
- 将
MY_CURRENT_TASKS与KNOWLEDGE_SEARCH接入 Tool Registry,分别返回事实和文档证据。 - 新 Evidence Evaluator 和 Grounded Composer 只接管新 Planner 能完整规划的请求,其他请求回退旧链路。
- 增加结构化 ConversationState、引用 TTL/重新鉴权和纠正失效。
- 黄金集达到门槛后,逐步退出旧 Planner 的关键词早退和 Orchestrator 文本边界分支。
兼容与回滚
- 不直接删除
AihrAgentPlanner、AihrKnowledgeConversationService或现有 RAG 回答。 - 新运行时仅在计划通过严格 schema 校验且所有动作已注册时接管,否则回退旧链路。
- 数据库变更使用 additive、幂等 MySQL 8 SQL;旧服务忽略新增列。
- 不接入自由 ReAct 或第三方 Agent 框架。
验收
首批 30 条纯内存契约黄金集覆盖金额口径、哪些 路由、CRM 能力幻觉、零证据、待办与流程、多轮第二项、月份纠正、跨项目、过期 factRef、来源冲突、工具失败/超时、模型失败回退、重复调用停止和对抗性槽位误标。该集合验证内部契约,不代表本地 MySQL/Qdrant/真实模型效果;没有 100-300 条人工黄金集前不宣称正式召回率达标。
HTTP 运行边界
aihr.agent.grounded-mode允许OFF/SHADOW/ACTIVE,仓库默认OFF。SHADOW复用现役认证主体、应用和项目输入,但在异步线程中重新解析并校验项目、空间与应用授权;ACTIVE只在文本请求符合严格计划、授权和证据门禁时接管用户可见结果。- 旧
AihrAgentOrchestrator先完整生成用户可见AgentResponse;旁路的计划、工具、DecisionResult 或失败均不得改写answer/status/citations/data/contextVersion。媒体和附件请求明确跳过。 - 在生产
ACTIVE下,合格文本请求由AihrAgentActiveService适配为兼容AgentResponse;不支持的意图、工具失败、授权失败或异常继续返回旧链路结果,不改变旧客户端 DTO。 - 专用有界队列满时立即
REJECTED,watchdog 超时后取消任务;原子终态保证超时与迟到完成只记录一次。旁路失败不得阻断主请求。 aihr_agent_shadow_run只保存 run ID、query SHA-256、授权范围哈希、结构化 intent/tool/status/reason、数量和耗时,不保存原始问题、答案、手机号、token、附件名、Citation/Fact 正文或工具响应正文。- 默认
grounded-shadow-timeout-ms=4000是保守的旁路保护预算,不是模型服务 SLA。2026-08-04 的本地真实模型诊断仅通过进程环境临时放宽到 45000ms;样本显示规划耗时可超过 4 秒,因此不能把 4 秒预算当作模型 SLA,也不能据此扩大生产 ACTIVE 范围。生产当前仅保留受控文本范围,仓库默认仍为OFF。
2026-08-04 本地实依赖验证
本地诊断曾以 SHADOW + 45000ms 运行,仓库默认值仍为 OFF + 4000ms。最近一组真实请求的 Semantic Planner 耗时约 1.4-4.1s、单次 shadow 总耗时约 3.1-7.3s;早期模型冷启动曾出现 18.4s 离群值。Qdrant 直接探测约 0.2s,当前主要延迟来自受约束模型规划、证据分类和旧知识查询审计,不应仅靠放宽 watchdog 掩盖。默认 4 秒预算不是模型服务 SLA,后续灰度仍需真实分位数和容量数据。
2026-08-04 生产发布后完成了 JAR、服务、schema 和公开接口核验;未完成认证态用户逐例问答验证。生产 ACTIVE 是有限范围的受控运行状态,不等于所有入口都已迁移,也不替代 100–300 条人工标注黄金集。
治理索引已完成本地幂等重建并通过当前事实核对:MySQL 有效 production、PUBLISHED、HUMAN_VERIFIED fragment 为 224,aihr_knowledge_governed_v1 为 green、224 points、1024 维 Cosine,模型为 BAAI/bge-m3;224 个 points 与 MySQL fragment 一一对应,payload 必填治理字段缺失为 0,全部属于 production/PUBLISHED/HUMAN_VERIFIED。这只证明索引和治理过滤可用,不证明检索召回率达标。
| 脱敏场景组 | SHADOW 观察 | 当前结论 |
|---|---|---|
500元的一笔采购如何报销、500元以下的零星采购怎么报销、五百块的小额自采怎么走账 |
均调用 KNOWLEDGE_SEARCH;分别保留报销/采购领域、金额原文和口径缺口,NO_EVIDENCE,未调用 Composer |
正式来源缺失时安全失败关闭;未把月累计额度推成单笔资格,也未引用访谈/案例 |
当前账号能查询哪些内容 |
CAPABILITY_QUERY → ANSWERED,1 个 VERIFIED_FACT |
只返回当前注册且授权的工具集合,不使用文档推断能力 |
| CRM 提及、催费话术 | CRM 场景走 CAPABILITY_QUERY 且 requestedSupported=false;催费话术走 KNOWLEDGE_SEARCH,当前资料不足时 NO_EVIDENCE |
文档提及 CRM 不会升级为系统已接入;粗粒度话术不会绕过规划或生成无依据流程 |
本月待办加流程、第二项需要什么材料 |
首问与追问均执行 MY_CURRENT_TASKS + KNOWLEDGE_SEARCH;事实与文档分型,材料槽位缺失时 PARTIAL,不补齐步骤 |
多工具和 REQUIRED_MATERIALS 已在真实 HTTP shadow 证明;旧响应仍保持兼容,不被旁路改写 |
| 月份纠正、过期/跨作用域引用 | 既有 stateful 回归覆盖纠正后旧 ref 失效、TTL 重查和授权拒绝;本阶段继续保持服务端重鉴权 | 会话状态仅保存受控引用元数据,不能由客户端回传正文冒充事实 |
| 零正式证据、来源冲突 | 零合格证据记录 ANSWER_GENERATION_SKIPPED;来源冲突进入 CONFLICT/NEEDS_INPUT 或 fail-closed |
门禁生效;仍需更多真实冲突资料验证 |
当前真实 HTTP 仍由旧 Orchestrator 返回用户可见状态,部分旧请求会显示 CLARIFY/NEEDS_INPUT;这不代表 shadow 未执行。审计行只记录 query hash、run ID、结构化差异、计数和阶段耗时,未发现原问题、答案、手机号、token、附件或工具正文。以上结果证明旁路隔离、工具分型、治理索引、失败关闭和隐私边界,不证明召回率达标,也不支持客户端接管;进入受控客户端灰度前仍需 100-300 条人工标注黄金集、真实延迟分位数、容量评估及来源冲突样本。