跳到正文

AI 全闭环架构 ​

一句话:把“人带 Agent 做一个需求”的全过程拆成状态机——编排管流程、问答代理挡交互、人工审批管责任。换来的是人只在少数决策点出现,代价是平台复杂度上升,而且答错一次比不答更贵。

为什么需要 ​

一个人用 CLI Agent 做需求时,人本身就是总线:上下文在会话里,切走就丢;每次“这个字段什么意思”都要人来答;两个需求并行,人要在两套上下文之间来回切换;出了问题,只能翻聊天记录。Agent 提效的那部分,被人肉协调吃掉了。根因是状态只活在进程和人的记忆里,所以要做三件事:外置状态让会话可恢复,交互分层让能查的不问人,权限收口让 Agent 不直连系统。它们同时划出一条边界——信息型工作可以交,承担后果的决策不能交。

核心机制 ​

先划清人机交接线 ​

能交:需求问题清单、规格与方案初稿、编码实现、测试执行、CR 初筛、触发 CI。
不能交:范围与优先级、验收标准签字、架构选型、权限合规判定、合并 Approve。
必须人签字:日常只有规格与合并两道门禁,架构与合规按触发条件升级,逐阶段分工见 07-企业工作流与大代码库 的七环节表。

人工决策有五类:需求澄清定范围、规格评审签验收标准、架构决策选方案、权限与合规判边界、验收判定是否达标;共性是它们都要为结果负责——不是信息不足,而是取舍与担责,Agent 答得再像也不能替代签字,规格写法可直接套用 03-SDD规格驱动。

整体架构 ​

编排是唯一知道“现在到哪一步”的组件,运行时可以随时被杀并从 checkpoint 重建,扩容和崩溃恢复都不用搬迁会话。工具网关是唯一出口,权限、限流、审计收在这一层,运行时拿不到长期凭证。人工卡点不阻塞运行时,只阻塞状态推进——人四小时后点通过,会话从原地继续。

模拟人 Agent:三层能答,一层必须人答 ​

层依据典型问题动作
L1 规则规范、红线、错误码表命名规范、要不要写单测直接答,引用条目号
L2 检索知识库、API 文档、数据字典接口参数、字段含义答 + 出处 + 置信度
L3 历史决策相似需求的结论与理由上次类似需求怎么定的给参考,建议确认
L4 升级置信度低于阈值或无出处做不做、选哪个、能否外露通知真人,会话挂起

经验值上 L1–L3 覆盖约 80% 的交互,L4 约 20%,比例随知识库成熟度变化,不是承诺值。不做全自动的理由有三条:没有出处的回答无法验证,错一次的成本高于问一次人;有些问题是取舍不是查询,没有标准答案;责任无法转移,签字必须是人。真人回答会被结构化成“问题 / 答案 / 出处 / 适用条件”入库,下次进入 L2 或 L3,稳定后沉淀为 L1 规则;这套学习闭环同时放大错误,所以必须配抽检与回滚——错误答案要能降级回 L4。

一需求一会话:状态与恢复 ​

三条回边(规格驳回、测试失败、评审打回)是成本中心,也是质量来源:它们保证错误在进入下一步之前被挡住。状态变更写库而不是留在内存,所以任何容器被杀都能从最后一个 checkpoint 继续,恢复时只读 state 不读聊天记录。设计不进入日常状态机:日常两道门禁是规格与合并,设计按触发条件升级为架构卡点。并发上,一个会话对应一个分支和一个沙箱,同仓库的并行需求按目录加锁;会话之间不共享上下文,只共享只读知识库。

端到端时序 ​

人只出现在两处:规格和合并;中间所有问答走模拟人,所有校验走 CI。门禁失败是回编码而不是回人,所以“等测试”这段时间不占用任何人。最容易被忽略的是最后一步——回写工单,它决定追溯链是否闭环。

组件交互:谁调谁、数据在哪 ​

  • 编排 → 运行时:容器 API + 任务消息;运行时无状态,状态写会话库,工作区随容器销毁。
  • 运行时 → 工具:MCP(JSON-RPC)/ HTTP,经网关鉴权与限流,审计落网关日志;接入与治理见 09-工具链与MCP平台。
  • 运行时 / 模拟人 → 知识库:只读检索 API;规范与决策记录由人维护,Agent 不写。
  • 编排 → 人工卡点:IM 卡片 / 审批页;审批记录与状态变更同库,append-only。
  • 约束:只有编排能改阶段,只有网关能碰外部系统,只有会话库是权威——绕过任一条,追溯就留断点。

异常路径 ​

异常检测处置
工具失败超时 / 5xx / schema 不符退避重试 ≤3 次;仍失败换只读路径或降级
测试失败退出码 / 断言不重试,带日志回编码;同任务连续 3 次升级(经验值)
Agent 跑偏改动超出影响面清单 / 循环调用阻断,回滚到 checkpoint,重新出计划
人工久不响应超过 deadline提醒 → 升级备份审批人 → 挂起并通知需求方
上下文溢出token 接近上限摘要 + 结论落盘,新会话从 checkpoint 续
权限拒绝网关 403不重试,转人工授权,记录被拒工具与参数

卡点与攻坚点(难度与优先级为经验值) ​

卡点难度影响处置优先级
测试环境依赖:沙箱没有 DB / 中间件,TDD 跑不起来高编码门禁失效,Agent 只能“写完就算”提供带依赖的测试环境或容器化 compose;退化为契约测试 + 本地复现P0
MR 评论自动处理中人要在多轮评论间来回搬运上下文评论结构化为文件 / 行 / 建议,Agent 只处理可定位项,其余升级P1
CI 失败自动修复中小失败阻塞整条流水线区分机械失败与语义失败;前者自动重跑或修复,后者带日志回编码P1
多角色模拟人高答错一次比不答更贵,错误还会进入知识库L1–L4 分层 + 出处 + 抽检;无出处一律升级真人P2
遗留项目无测试高G2 无法执行,闭环失去验证基础先补特征测试锁住现状,再逐步接入流程P1

落地分四期,顺序不能反:P0 手动触发跑通单点(疑问直接问人),退出条件是“一个真实需求被合并”;P1 串起闭环(状态机 + 持久化 + 规格与合并两个卡点),退出条件是“中断后能恢复且不用重跑”;P2 加治理(模拟人、权限收口、审计、预算与超时),退出条件是“人工交互明显下降且追溯链完整”;P3 规模化(自动触发、多团队、指标看板),退出条件是“并行需求不互相踩”。模拟人是 P2 的优化项,不是 P0 的阻塞项——它只减少交互次数,不解决流程跑不通。

实战场景 ​

案例:一次容器驱逐,需求重跑三小时并留下两个重复 MR ​

某周三凌晨节点回收,一个正在编码的需求会话随容器一起消失。第二天早上人回来追问进度,编排没有“继续”,而是从原始需求重新起跑:Agent 重新读需求、重新拆任务、重新写实现,最后推了一个新分支,与前一晚已经推过的分支内容几乎相同,两个 MR 都带着通过状态的 CI。三小时算力白烧,评审人对着两份 diff 无法判断哪一份是权威。

排查从“恢复时到底读了什么”开始。平台声称有 checkpoint,但 state 写在运行时容器的本地文件里,容器销毁即失效;恢复逻辑发现读不到状态,就退回到“按工单描述重跑”这条兜底路径——兜底路径不看提交历史,所以它不认为自己在重跑。定位到这一层,问题就不是模型不听话,而是三个事实:状态没有外置、恢复没有硬失败、写操作没有幂等键。

对症做法三条,顺序也不能反:

修什么怎么做判据
状态落库stage、plan、checkpoint.commit、pending_human 全部写会话库,容器本地不留唯一副本杀掉容器再起,stage 与 task 完全一致
恢复不兜底重跑读不到 state 就置为待人工,禁止退回“按需求描述重来”恢复日志里不出现新的拆任务事件
写操作幂等分支名与提交信息带 session_id 与 task_id,推分支前先查远端是否已有同键分支同一会话重跑不产生第二个 MR
text
on_resume(session):
    state = load_from_db(session.id)          # 唯一权威,不从聊天记录推断
    if state is None: return escalate("无 checkpoint,等待人工确认起点")
    if remote_branch_exists(state.checkpoint.branch): reuse(state.checkpoint.branch)
    verify_passed_tests(state.done_tasks)       # 先验已完成的,再决定跑什么
    continue_from(state.stage, state.task)

复盘要点:这类事故的代价不是重跑本身,而是重跑产生的第二个真相源。只要恢复路径允许“没有状态就从头开始”,平台就随时可能把同一个需求变成两个需求。

案例:模拟人一句没出处的回答,被三个需求复用 ​

一个字段口径问题,Agent 提问,模拟人(见上一节 L2 检索层)答“按金额取整到分”,并写进知识库。后续三个需求都按这个口径实现,直到财务在验收时指出口径应为“按币种规则”。此时已完成合并的 MR 有三个,回滚加返工合计约两人天,而当初真人回答这个问题只需要两分钟。

排查不是从代码开始的,是从这条知识记录开始的:按出处字段反查,发现该条记录的出处为空——它是 L3 历史决策层从一次相似需求里推断出来的,而那次相似需求本身口径就是错的。也就是说,学习闭环把一次错误固化成了三次复用。这正是正文里“不做全自动”的第二条理由被低估的地方:错误答案不只影响一次决策,还会通过入库变成系统输入。

对症做法:

  • 入库即四元组,缺一不入库:问题 / 答案 / 出处 / 适用条件。出处必须是可点开的规范条目号或文档链接,历史需求 ID 只能作为 L3 参考、不能作为 L2 答案的出处。
  • 无出处一律升级真人:置信度低于阈值(经验值,需按团队基线校准)或找不到出处的回答,直接走 L4,不允许“先答了再补出处”。
  • 错误可降级:知识记录有 status(生效 / 存疑 / 已废弃)。验收发现口径错误时,先把记录降级为存疑并停止注入,再修实现;只修代码不降级记录,下一个需求还会踩。
  • 抽检按层分:L1 规则类可只看条目号是否存在,L2 检索类抽查出处是否指向当前有效版本(经验值抽 20%),L3 历史类全部保留“仅供参考”的前缀,不得写成结论句。

场景:两个并行需求改同一模块,CI 交错变红 ​

并行需求量上来后出现的现象很迷惑:单跑都绿,合到集成分支就红,且失败用例每次不一样。根因是会话之间共享了工作区:同一沙箱容器里两个需求交替改同一个文件,checkpoint 的 commit 互相覆盖。解法就是正文那条并发约束——一个会话对应一个分支和一个沙箱,同仓库并行需求按目录加锁;锁只加在写路径,只读知识库共享。这条约束在单需求阶段看不出价值,两个需求并行时立刻显形,所以它是 P3 规模化的前置条件,不是可选优化。

最小上手 ​

前提:仓库能一条命令跑测试,有一个工单入口,有一台能起容器的机器。最小闭环只需三道门禁:

  • G1 规格:范围清单已确认 → 验收标准可测、范围外写清 → 不满足回澄清。
  • G2 编码:规格已签、影响面清单已出 → 每个任务先有失败测试 → 不满足回规格(拆任务与红绿循环见 05-SDD+TDD双驱动实战)。
  • G3 合并:CI 全绿 → 人 Approve、追溯链完整 → 不满足回编码。
json
{
  "session_id": "REQ-123", "stage": "CODING", "task": "T2",
  "plan": [{"id": "T1", "status": "done"}, {"id": "T2", "status": "doing"}],
  "checkpoint": {"branch": "feat/REQ-123", "commit": "abc1234"},
  "pending_human": null, "spec_hash": "sha256:...", "updated_at": "2026-10-24T10:05:00Z"
}

恢复规则:进程启动读 state;pending_human 非空就重发通知并等待,否则从 checkpoint.commit 继续,先核对已通过测试再决定是否重跑当前任务。任务执行必须幂等,否则重跑会产生重复提交。

生产动作 ​

  • 超时与重试(经验值):澄清 24h、单任务 30min、审批 8h;工具超时与 5xx 可重试 ≤3 次并退避,测试失败、权限拒绝、参数错误不重试。超时只升级不静默重试,避免会话卡死而无人知情。
  • 人工卡点与接管:所有卡点统一走审批页;一键暂停即置 pending_human,会话不销毁;人可改规格或跳阶段,但必须写理由并留审计。
  • 审计与预算:状态变更 append-only,追溯链覆盖需求 → 规格 → 提交 → 测试 → MR → 审批人;每需求设 token 预算,80% 告警、100% 挂起。
  • 排障:会话停在某阶段 → 查 state.stage 与最后事件 → 区分“等人工”“重试耗尽”“队列堵塞”;重复提交 → 查 checkpoint 与幂等键。

边界 ​

  • 自动化率不是承诺:80/20 是经验值,取决于问题分布;需求越偏业务取舍,升级率越高。
  • 全自动不可能:不是模型不够强,而是责任不能委托。声称无人审批即可合并的方案,风险都在事后才显现。
  • 小团队不要建:平台成本高于收益,先用工具 + 约定;等并行需求多到人协调不过来再上。
  • 状态机会僵化:例外流程需要逃生门,允许人跳阶段但留痕;没有逃生门,团队会绕过系统。
  • 遗留无测试项目:G2 无法执行,先补特征测试锁住现状,再谈闭环。

讲清楚 ​

全闭环架构解决的不是让 AI 更聪明,而是把人从数据通路上挪走:人带 Agent 时,人就是总线,上下文、答疑、担责全压在一个人身上。做法是状态机化并落库,中断后从 checkpoint 继续;重复提问交给分层代理,有出处才答,没出处升级;外部系统收进工具网关,权限与审计只在这一层。剩下三个节点必须由人做:定范围、做取舍、签字合并,这是担责问题。先跑通单点再谈治理,顺序反了会做出没人用的平台。

适用:2026 年企业级 Agent 平台设计 | 初稿 2026-10

把 AI 工程讲到既懂也会用