Files

15 KiB
Raw Blame History

Context

复杂 Chat 当前由 ChatController -> ChatService.executeChatWithStrategy -> executeChatComplex 驱动。executeChatComplex 同时负责 Run 生命周期、外层 LOW_CONFID round、SequentialAgent 构造、Verifier 解析、Composer、Fallback、持久化和评估;VerifierInputHook 又解析 Executor 输出、读取当前 Run 工具摘要、执行 ExecutorGatekeeperService 并通过 VerifierContextHolder 回传隐式状态。这些职责形成无法精确表达失败恢复位置、条件边和审计路径的隐式状态机。

阶段 0 不改变运行时,只冻结后续五个独立 change 必须遵守的架构契约。当前 change 的运行时影响为 L1;冻结目标最终涉及状态机语义、数据库与 Trace API,属于 L4。

区域 当前职责 冻结后的职责
ChatController 调用 ChatService 请求/响应协议不变
ChatService Run 生命周期和细粒度隐式状态机 只维护 Run 生命周期并调用 Graph orchestrator
SequentialAgent 固定跨 Agent 顺序 不再用于复杂 Chat 编排
VerifierInputHook / VerifierContextHolder 隐式 Gatekeeper、输入构造和跨层回传 Gatekeeper/投影迁入显式 Node;旧隐式入口删除
ExecutorGatekeeperService 确定性 binding 校验 原规则复用,由显式 Gatekeeper Node 单次调用
DiagnosisRun / DiagnosisTraceService Run 与 self evaluation 聚合 增加 run-scoped orchestration trace

Goals / Non-Goals

Goals:

  • 冻结最小 Graph State 的字段、所有权和更新策略。
  • 冻结完整、有界且可终止的条件边与 retry 语义。
  • 冻结 verified-input、Fallback、Run 状态与审计安全边界。
  • 冻结旧测试替换范围和后续五个独立 change 的交付边界。
  • 提供可被后续 OpenSpec Commit gate 机械对照的设计基线。

Non-Goals:

  • 本 change 不实现或编译任何 Java/SQL/Prompt/配置变更。
  • 不修改当前主运行时 specs 来宣称 StateGraph 已上线。
  • 不运行 Maven E2E、日志或数据库验收。
  • 不引入 SupervisorAgent、持久 Checkpointer、HITL、并行执行或 AIOps 公共 Graph。
  • 不保留 Sequential/StateGraph 双轨开关。

Decisions

1. StateGraph 只拥有跨节点控制状态

StateGraph 负责顺序、条件边、重试、终止和降级;现有 ReactAgent 继续完成语义任务;Gatekeeper、verified-input builder、evidence retry prepare 和固定 Fallback 使用确定性 Java Node。

替代方案:

  • 继续在 ChatService 外层叠加 if/for:无法精确恢复失败节点和审计条件边,拒绝。
  • 使用 SupervisorAgent:固定诊断 Pipeline 不需要动态选择专科 Agent,拒绝。
  • 直接把父 State 交给 ReactAgent.asNode(...):存在 messages/outputKey/私有状态泄漏风险,首版拒绝。

2. 最小 Graph State

默认 Replace;只有有界 orchestration_events 使用 Append。

字段 所有者/用途 策略
diagnosis_context query、history、sessionId、runId Replace
planner_plan Planner 结构化计划 Replace
planner_status COMPLETED / INVALID_OUTPUT / RETRYABLE_FAILED / NON_RETRYABLE_FAILED Replace
planner_retry_count 当前 Planner 阶段技术重试次数 Replace
planner_mode NORMAL / EVIDENCE_GAP_ONLY Replace
executor_output 完整 executor_evidence_v2 Replace
executor_status COMPLETED / INVALID_OUTPUT / TOOL_BLOCKED / FAILED Replace
gatekeeper_result 原始确定性校验结果 Replace
gatekeeper_status PASS / LOW_CONFID / REJECT Replace
verified_executor_output 只保留通过 binding 的 claim 投影 Replace
verified_evidence 从通过 binding 的 matched_text 构造 Replace
verified_binding_count 当前可信 binding 数 Replace
verifier_verdict_ceiling PASS 或 LOW_CONFID Replace
verifier_output Verifier 结构化结果 Replace
verifier_status COMPLETED / INVALID_OUTPUT / RETRYABLE_FAILED / NON_RETRYABLE_FAILED Replace
verifier_retry_count 固定 verified input 技术重试次数 Replace
verifier_model_verdict 模型 PASS / LOW_CONFID / REJECT Replace
effective_verdict 应用 Gatekeeper ceiling 后的 verdict Replace
composer_output Composer 结构化输出 Replace
composer_status COMPLETED / INVALID_OUTPUT / RETRYABLE_FAILED / NON_RETRYABLE_FAILED Replace
composer_retry_count 固定安全输入技术重试次数 Replace
evidence_retry_count 诊断补证据轮次 Replace
retry_context evidence gaps、prior verified data、completed queries、约束 Replace
orchestration_events 每个 node attempt 的有界终态事件 Append
final_answer 最终安全用户表达 Replace
failure_reason 确定性失败 reason code Replace

不保存 Prompt、模型思考、完整工具原文、完整 Graph State 快照或其他 Run 数据。

3. 完整路由矩阵

From Outcome / Guard To 计数与约束
START always Planner Planner 阶段 retry count=0
Planner COMPLETED Executor 不增加 retry
Planner INVALID_OUTPUT / RETRYABLE_FAILED 且 count=0 Planner 同业务输入重试一次,count=1
Planner NON_RETRYABLE_FAILED 或技术重试耗尽 Fallback 不执行后续 Agent
Executor COMPLETED Gatekeeper 合法 no-evidence 也属于 COMPLETED
Executor INVALID_OUTPUT / TOOL_BLOCKED / FAILED Fallback Executor 永不重试
Gatekeeper PASS Verified Input Builder ceiling=PASS
Gatekeeper LOW_CONFID 且 verified binding > 0 Verified Input Builder ceiling=LOW_CONFID
Gatekeeper REJECT、未知状态或 LOW_CONFID 且 binding=0 Fallback 不执行 Verifier
Verified Input Builder completed Verifier 只投影通过 binding
Verifier INVALID_OUTPUT / RETRYABLE_FAILED 且 count=0 Verifier 相同 verified input 重试一次
Verifier NON_RETRYABLE_FAILED 或技术重试耗尽 Fallback 不输出 Executor claim
Verifier PASS / REJECT Composer 使用 effective verdict
Verifier LOW_CONFID,非 ceiling 导致,存在有效 gaps,evidence count=0 Prepare Evidence Retry evidence count 增加一次
Verifier LOW_CONFID 且任一补查条件不满足 Composer 不补查
Prepare Evidence Retry completed Planner mode=EVIDENCE_GAP_ONLY;新 Planner 阶段 retry count 重置
Composer COMPLETED END 返回 Composer 安全表达
Composer INVALID_OUTPUT / RETRYABLE_FAILED 且 count=0 Composer 相同 allowed material 重试一次
Composer NON_RETRYABLE_FAILED 或技术重试耗尽 Fallback 可使用 Verifier 已允许材料
Fallback deterministic answer produced END degraded=true
未处理异常/持久化失败/无法生成安全答案 failure outer failure handling Run=FAILED,best-effort 保存已有 events

Graph compile 必须设置 recursion limit 作为最终保险;业务循环仍由独立计数显式限制。

4. 四类计数互相独立

  • planner_retry_count:每次进入 Planner 阶段最多一次;evidence retry 重新进入时重置。
  • verifier_retry_count:同一 verified input 最多一次。
  • composer_retry_count:同一 allowed material 最多一次。
  • evidence_retry_count:整个 Run 最多一次。

技术重试不增加 evidence retry,也不得重新执行前序节点或工具。

5. Executor 状态按输出契约定义

合法 executor_evidence_v2(包括 no-evidence、空查询结果或工具限制说明)均为 COMPLETED。只有工具层明确禁止且没有合法结构时为 TOOL_BLOCKED;空/非法结构为 INVALID_OUTPUT;其他未形成合法结构的异常为 FAILED。只有 COMPLETED 进入 Gatekeeper,其余直接 Fallback 且不重试。

补证据轮只执行增量查询,但输出包含应保留 prior verified claims 的完整快照;Java 不做 claim 文本语义合并,完整快照重新经过 Gatekeeper。

6. Gatekeeper 与 Verifier 输入边界

Gatekeeper 保留原始结果并 fail-closed 标准化为 PASS / LOW_CONFID / REJECT;未知、缺失或无法识别结果映射为 REJECT。

PASS 与可继续 LOW_CONFID 都经过 Verified Input Builder。Builder 复用 checked_bindings,仅从通过项投影 claim_id、source_invocation_id、tool_name、raw_path、matched_text;不得传递完整 tool_trace_summary、失败 binding 或 Executor 自由文本。LOW_CONFID ceiling 不得被模型 PASS 提升。

7. 两类安全 Fallback

前置验证失败: Planner/Executor/Verifier 无法形成可信材料,或 Gatekeeper REJECT/零可信 binding。固定表达只包含校验状态、工具执行概况、诊断限制和人工查看 Trace 建议,不含任何 Executor claim。

Composer 后置降级: 已有 Verifier 允许材料,但 Composer 技术重试耗尽。确定性模板可以使用 allowed claims/missing info/recommended actions,仍不得读取 raw output。

成功生成安全答案时 Run=SUCCESS,并用 verdict 或 orchestrationTrace.degraded=true 表达质量;只有未处理异常、持久化失败或无法生成安全答案时为 FAILED,不新增 DEGRADED 状态。

8. Run-scoped 编排审计

每个 Node attempt 最多追加一个 {node,outcome,reason_code,attempt} 终态 event。按事件顺序压缩为 version、transitions、final_node、termination_reason、degraded、evidence_retry_count。

只持久化到当前 diagnosis_run.orchestration_trace;RunnableConfig.threadId=runId。Trace API 只在 run.orchestrationTrace 返回解析对象,不复制到顶层/session/raw 字段。它不替代 self evaluation、AgentStep、ToolInvocation 或 Graph checkpoint。

9. 测试替换边界

测试 处理
ChatServiceSequentialAgentTest 用 Graph 路由、Node 契约和 Chat 集成测试替换;删除固定顺序断言
VerifierInputHookTest 删除或改写为显式 Gatekeeper/Input Builder 契约测试
ExecutorGatekeeperServiceTest 保留并扩展 checked binding 与未知状态 fail-closed
ChatControllerTest 保留,证明 /api/chat 兼容
DiagnosisTraceServiceTest / Repository tests 保留并扩展 run-scoped orchestration trace
Eval/Composer 安全测试 保留,证明 allowed-material、no-evidence 和 REJECT 不退化

阶段 0 无运行时行为,不新增单元测试。阶段 1–4 按风险建立上述测试;阶段 5 统一执行 Maven E2E、日志和数据库验收。

10. 六个独立 OpenSpec change

阶段 Change 唯一交付边界
0 chat-diagnosis-stategraph-design-freeze 冻结本设计,不改运行时
1 chat-diagnosis-stategraph-routing-skeleton Graph State、拓扑、Fake Node 路由与 trace builder
2 chat-diagnosis-stategraph-real-nodes Agent Adapter、Gatekeeper、verified input、retry prepare、Fallback
3 chat-diagnosis-stategraph-chatservice-cutover ChatService 生产入口、DB migration、Run/Trace API
4 chat-diagnosis-stategraph-test-suite 新测试体系与旧测试替换
5 chat-diagnosis-stategraph-cleanup-docs 旧编排清理、最终回归、Maven E2E、日志/DB、文档

后续 change 必须先读取阶段 0 archive;若发现设计不准,必须在当阶段 OpenSpec 中显式记录和解决。

Interface Impact

Classification

  • 当前阶段 0 change:L1。只交付设计、术语和决策档案,不改变运行时。
  • 最终冻结目标:L4。状态机语义和 Run 终态判断变化,Trace API 与数据库契约扩展,旧内部调用路径将被删除。

Changed contracts and consumers

契约 目标变化 消费者
/api/chat 请求/响应结构保持不变,内部路径改由 Graph 驱动 ChatController、前端/demo 客户端
Agent 输出协议 executor_evidence_v2、Verifier、Composer 输出保持不变 Agent adapters、Eval
Verifier 输入 改为 verified_executor_output + verified_evidence,不再提供完整 tool trace Verifier adapter、Prompt binding
Run 状态 安全 Fallback 为 SUCCESS + degraded;只有无法安全响应的未处理失败为 FAILED Trace、Feedback、Eval、运维审计
Trace API 仅 run.orchestrationTrace 新增解析对象 Trace DTO/Service、demo 脚本、Trace UI
数据库 仅新增 nullable JSON diagnosis_run.orchestration_trace Flyway、DiagnosisRun repository
内部编排 删除复杂 Chat Sequential、外层 round、Gatekeeper-in-Hook/ThreadLocal 入口 ChatService、Hook、测试

Compatibility, migration, and rollback

  • 兼容消费者不需要修改 /api/chat 调用;Trace 消费者按加法字段处理。
  • 新 StateGraph Chat Run 必须写非空 orchestration trace;历史 Run 不回填、不增加兼容读取。
  • 数据库迁移先加 nullable 列,再切换代码;nullable 只服务于安全部署,不降低新 Run 应用契约。
  • 每阶段可 Git revert;阶段 3 后回滚代码时允许保留无害 nullable 列。
  • 不以 feature flag 或配置恢复长期双轨;若切换失败,回滚完整阶段提交。

Interface acceptance

  • Controller 契约测试证明 /api/chat 不变。
  • Node/集成测试证明 Verifier 输入与安全 Fallback 边界。
  • Repository/Trace 测试证明 run ownership 和唯一 API 投影。
  • 阶段 5 Maven E2E、logs/ 和数据库查询证明跨层最终行为。

Risks / Trade-offs

  • [阶段性 spec 与运行时差异] 阶段 0 只新增设计基线 capability,不修改运行时 specs。
  • [六个 change 漂移] 每个 Discover/Commit gate 强制引用阶段 0 archive。
  • [Graph API 漂移] 后续只使用本地 1.1.2.0 JAR 已验证签名,并由阶段 1 编译测试锁定。
  • [Gatekeeper 双执行] 阶段 2 迁移显式 Node,阶段 5 删除旧 Hook/ThreadLocal,不形成长期双轨。
  • [安全降级泄漏] Fallback 输入类型分离并用 Node/集成测试证明。
  • [Trace 无限增长或泄密] event 每 attempt 一条,受业务次数与 recursion limit 限制,字段白名单禁原文。

Migration Plan

  1. 阶段 0 archive 本设计基线并提交。
  2. 阶段 1 引入未接生产入口的 Graph 骨架和路由测试。
  3. 阶段 2 接入真实节点但不切换 ChatService。
  4. 阶段 3 切换 ChatService,增加 nullable JSON 列和 run Trace 投影。
  5. 阶段 4 用新测试体系覆盖路由和安全契约。
  6. 阶段 5 删除旧编排并执行最终 Maven E2E、logs/ 与数据库验收。

回滚按阶段 Git revert。阶段 3 后回滚运行时代码时允许保留 nullable 列;不通过配置重新启用长期双轨。历史 Run 不回填。

Open Questions

无。若后续发现本设计与锁定 API 或安全契约冲突,必须在当阶段 sm-flow 中分类并按门禁处理。