Agent Coding Governance:上下文地图、运行时护栏与自进化 Loop 如何重塑 AI 编程交付

AI Coding 从提示词驱动,走向有护栏、有证据、可恢复的工程治理 系统。

原文链接AI 小老六

导语

把 AI 接进研发流程以后,最容易被误判的一件事是:只要模型足够强,编码交付就会自然变快。真实落地时会发现,模型生成代码的速度并不是瓶颈,瓶颈常常出现在它周围的工程环境里。

一个编码智能体可以快速读文件、改代码、跑命令,但它也会忘记上下文、误判团队约束、绕过分层边界,甚至在验证没有完成时给出"已完成"的结论。工程师被迫反复补充提示词、贴报错、纠偏、复查,最后形成一种很别扭的状态:表面上是在用 AI,实际是在给 AI 当流程调度器。

本文讨论的不是"怎么写更好的 Prompt",而是另一个更工程化的问题:如果要让 AI 真正参与服务端交付,需要在大模型和 Code IDE 之间补上一层什么样的治理系统。

答案可以概括为两层:

核心职责
Harness 把知识、权限、状态、证据、失败处置和自进化机制组织成一套可执行的研发治理框架
Loop 驱动 Harness 自动推进,把人从重复的过程干预里拿出来,只在关键判断点介入

这套体系的目标不是让人退出研发,而是让工程师不再被迫一拍一拍地驱动 AI,把注意力重新放回架构判断、风险取舍和最终交付质量上。

从"模型能力问题"转向"工程治理问题"

一次普通 AI Coding 任务里,模型真正写代码可能很快,慢的是它不知道该怎么安全地完成这件事。

它可能不知道仓库分层约束,把 infra 反向 import 到 biz/strategy;它可能改了一个调用点,却漏掉另一个入口;它可能跑通了局部测试,却顺手改了不该碰的函数;它也可能在失败后不知道该回滚、重试,还是停下来问人。

这些问题看起来像模型不够聪明,但根因并不全在模型。更准确地说,是模型被放进了一个过于裸露的工程现场:

  • 没有稳定的项目地图,它只能临时猜仓库结构。
  • 没有硬边界,它可以在规划阶段直接动业务代码。
  • 没有证据闭环,它会把"我认为完成了"当成交付结果。
  • 没有跨会话记忆,上一次纠正过的问题下一次还会重犯。

这类问题很难靠"提示词写详细一点"解决。提示词是软约束,工程交付需要的是硬机制。

图:人工驱动的 AI Coding 循环,问题集中在人反复补上下文与纠偏。

真正需要补齐的,不是另一个更长的提示词,而是一层能把 AI 行为纳入工程秩序的运行环境。

四层分工:智力、工具、治理和驱动

图:AI Coding 体系中,智力、工具、治理和驱动需要分层协作。

AI Coding 体系里,至少要区分四件事:谁负责思考,谁负责执行,谁负责治理,谁负责推动流程。

层级 负责什么 类比 不负责什么
大模型 理解需求、生成代码、做语义判断 一颗强但健忘的 CPU 不记住组织约束,不保证每次正确
Code IDE / CLI 读写文件、跑命令、调用工具、连接 MCP 操作系统或容器运行时 不判断这一步该不该做
Harness 知识、权限、状态、证据、失败处置、自进化 框架、网关、流水线、配置中心的组合 不产生智力,不替代 IDE 工具
Loop 自动推进流程,在卡点找人 CI/CD 流水线 不亲自写代码,不绕过确认

大模型提供智力,Code IDE 提供工具,这两层都会持续变强。但它们叠加起来仍然缺一层东西:谁来规定当前阶段允许做什么、产出是否可信、失败后往哪里退、经验如何沉淀。

Harness 解决的就是这层治理。Loop 则负责把 Harness 驱动起来,让流程不再依赖人每一步手动敲"继续"。

图:大模型、Code IDE、Harness 与 Loop 的四层职责边界。

开发前:把仓库变成 AI 能安全进入的工作区

智能体每次会话都近似从空白开始。它不会天然知道这个仓库的模块边界、接口入口、构建命令、分层约束,也不会知道哪些行为是团队长期禁止的。

所以在真正交给 AI 写业务代码前,Harness 先做一件看似"不产出需求代码"、但非常关键的事:把普通仓库整理成 AI 能读懂、有接口资料、有提交护栏的工作区。

这一步可以拆成三层。

准备层 产物 解决的问题
知识层 AGENTS.mdARCHITECTURE.mddocs/AGENTS.md 给模型一张稳定地图,而不是让它临时 grep
接口层 docs/reference/<接口>.md 把调用链、入参出参、PSM、IDL 映射前置成资产
护栏层 .harness/、pre-commit、pre-push、分层校验脚本 在提交点拦住违反工程约束的变更

知识层:地图比百科全书更有用

知识层不是把所有代码解释一遍,而是给模型一张足够稳定的项目地图。

AGENTS.md 负责导航,告诉模型不同任务该看哪里;ARCHITECTURE.md 承载架构约束、依赖方向和不变量;docs/AGENTS.md 按任务场景把文档组织起来。

这里的关键取舍是:知识不是越多越好。过时或低质量的知识会主动误导模型,比没有知识更危险。高层结构、模块边界、构建测试命令、分层约束这些稳定信息,适合沉淀;具体实现细节则不适合每次代码合入后机械同步。

接口层:把一次次检索变成可复用资产

服务端需求经常围绕接口展开。模型需要知道接口入口、调用链、入参出参、IDL 映射、PSM 以及相关目录。如果每次都让模型自己 grep,它会把大量上下文窗口消耗在原始代码扫描上。

AskQuestion 接口为例,读现成接口文档只需要约 5431 字符,约 1.6k tokens;如果让模型自行 grep 并拼出上下文,会命中 10 个业务文件,约 73872 字符,约 22k tokens。后者大约是前者的 13 倍,而且还建立在"模型知道该搜什么、不会重复读"的理想前提上。

接口层的价值在于把检索成本从"每次需求都付一遍"变成"建一次、反复用"。

护栏层:提交点必须有硬门禁

知识层让模型看得懂,护栏层让错误不容易进入仓库。

Harness 会把分层依赖校验、增量 gofmt、go mod tidy 干净性检查、OpenSpec 门禁等能力挂到 Git hooks 上。比如从 ARCHITECTURE.md 中读取依赖方向,生成 check_layer_dependency.sh,拦住 infra 反向 import biz/strategy 这类违反架构不变量的代码。

这一步的边界也要讲清楚:hooks 只在提交或 push 时生效,不能管理开发过程本身;知识和门禁也会过期,需要被检测和刷新。也就是说,开发前准备只是把工地建好,还没有解决"施工过程如何受控"的问题。

开发中:用运行时把 AI 行为管起来

图:运行时护栏把模型行为纳入可控、可观、可恢复的边界。

开发中阶段,Harness 要回答的问题是:一次需求从规划到实现、验证、推送、归档,如何做到可控、可观、可恢复、可扩展。

这四个性质对应四套机制。

Guard Runtime​:正确性不能靠模型自觉

可控是 Harness 的核心。一个会忘、会编、会抄近路的执行者,不能只靠提醒它"请遵守规则"。Harness 用四道防线把不确定性关进确定边界里。

防线 机制 解决的问题
硬执法 pre_tool_use Guard 按 control.yaml 裁决工具调用 让越界写操作在执行前被阻断
验令牌 每代 framework_token 控制运行态修改 防止模型或脚本伪造框架状态变更
证据 + 权限前置 verifier 派生 emit,派单前钉死工具和写路径 结果不靠模型自报,权限不靠临场判断
失败处置 heal 由内核引擎裁定 失败后往哪退,不交给刚失败的执行者决定

Guard 的关键在于它不读 Prompt,也不相信模型自述。它只看运行时投影:当前节点是谁、允许写哪些路径、处于执行还是暂停状态、generation 是否匹配。

同一个 .go 文件,在不同节点下会有完全不同的裁决结果:

图:同一写操作在不同流程节点下会得到不同的 Guard 裁决。

这不是提示词能提供的硬度。提示词最多告诉模型"不要这样做",Guard 则让"这样做"根本执行不了。

Evidence Runtime​:过程必须可回放

AI Coding 最让人不安的不是它会出错,而是它出错以后不知道错在哪。Harness 把关键过程都落成结构化记录:

文件 内容 用途
current.yaml 当前节点、状态、恢复点 单一事实源
audit.jsonl 谁通过什么机制改了状态,依据什么证据 回放推进与回退
observations.jsonl Guard 拦截了什么工具、目标路径、原因 追踪越界行为,也是后续自进化原料

这些记录不是普通日志噪声,而是带证据的运行时账本。写入方只能是框架内核,所有写入走统一接口并凭令牌,不接受 by=user 这类自报,也不允许 Prompt 或普通脚本直接改文件。

这样才能保证并发安全、状态一致,也保证可观测性不会因为有人绕开接口偷偷改盘而失真。

Recovery Runtime​:断点续跑不能带病运行

一次需求可能跨多次会话,也可能被上下文压缩中断,甚至换人接手。Harness 的恢复机制分两层。

第一层是流程能续。状态和产物都落盘,续跑时读取 current.yaml,知道上一次跑到哪个节点、当前变更是什么、下一步该从哪里继续。

第二层是环境能自检。续跑不是无条件信任旧状态,而是重新跑一遍就绪校验,包括工具是否存在、环境变量是否齐全、能力注册表是否完整,以及开发前装好的门禁是否过期。

门禁新鲜度不靠感觉,而靠 .harness/.gate-stamp.json 里的版本号和各脚本 sha256 指纹比对:

结果 含义 处理
ok 版本和指纹一致 放行
stale 版本或指纹不一致 触发刷新
uninitialized 从未初始化 阻断并要求初始化

这解决了开发前准备的一个老问题:知识和门禁会过期,但不能指望人每次都想起来检查。把新鲜度检测嵌入每条流程的起点,才是真正可持续的做法。

Flow Runtime​:新增流程不应该改内核

如果每增加一个流程、接入一个能力都要修改框架内核,系统很快会变成一堆特例。Harness 的设计是把流程顺序从代码里挪到模板里,把能力职责收进自包含契约里,内核只认三种结构:

结构 作用
flow 节点和路由
contract 门禁、输入输出、verifier、emit
control 当前节点的权限投影和执法依据

能力是积木,模板是接线,内核是装配工。

图:能力、模板与内核分离后,新增流程不需要改动系统地基。

在内核和 Guard 代码里,不应该写死 plan-writerdag-executorphase-0 这类具体能力名。节点合法性来自模板,路由来自 emit,权限来自 contract 编译后的 control。

这样新增流程时,改的是模板和契约,不是系统地基。

业务视角:一次交付如何形成闭环

从业务架构看,Harness 覆盖三个阶段,Loop 站在上层驱动整条链路。

图:开发前、开发中与跨需求自进化构成完整交付闭环。

开发前的知识和门禁是开发中的基底;开发中产生的纠正信号,又会进入跨需求自进化;自进化结果回写到知识、门禁或框架 lesson,下一次交付的起点就更高。

这不是一次性工具,而是一个会吸收使用反馈的工程系统。

系统视角:控制面只编排,不直接写业务

从系统架构看,Harness 可以拆成入口层、调度层、功能层、基建层,以及旁路的自进化治理。

图:Harness 控制面负责编排、证据与边界,不直接写业务代码。

这里有几个硬原则:

  • 控制面只编排、路由和收证据,不直接写业务代码。
  • 能力节点互不直接调用,只通过 emit 和运行态交互。
  • Guard 是唯一硬边界,按内核写下的 control.yaml 裁决每一次工具调用。
  • 自进化、知识维护、架构守护属于旁路能力,可插拔,不阻塞主链路。

Loop​:自动推进,但不绕过人的判断

Harness 让一次开发过程受控,Loop 让这个过程不再依赖人每一步手动推动。

Loop 不是"设个定时器让 AI 无人值守乱跑"。它真正做的是把非必要的人类干预拿掉:补上下文、决定下一步、跑校验、失败重试这些动作由流程接住;真正需要人负责的地方,例如关键授权、blocking 未决项、最终确认,仍然停下来找人。

一个完整 Loop 大致由这些模块构成:

Loop 模块 作用 Harness 中的对应能力
Automations 自动触发和推进 跑完节点、收证据、算下一步、派下一单
Skills 把项目知识沉淀下来 知识层、接口层、节点 contract
Sub-agents 生成和检查分离 coco exec 独立子进程、plan-review、dag-executor
Plugins / Connectors 接入真实平台 Git、Codebase、飞书、TCC 等连接
Worktrees 多任务隔离 独立工作目录
Memory 跨会话状态 .harness/runtime/ 状态与产物

Loop 的关键不在于"能不能继续跑",而在于"该不该继续跑"。

以 OpenSpec 规划为例,第一层是确定性的工程校验:openspec validate --strict 检查格式、章节和 schema。它可以判断方案结构是否合法,但看不懂内容是否真的可执行。

第二层是语义评审:独立的 plan-review 子进程逐条判断 Open Questions 是否存在 blocking 项。

比如下面两段从格式上都合法:

markdown 复制代码
## Open Questions

- 无阻塞当前实现的未决项。
markdown 复制代码
## Open Questions

- GetSelfServiceProgressDisplayRequest.shop_order_ids 在真实接口侧是否要求逗号分隔、JSON 数组字符串,还是允许单个订单 ID 字符串。
- biz_type=4 之外是否还会有其他业务类型接入,以及是否需要做数值到业务枚举名的转换。
- 当展示查询返回空文案但无错误时,是否应保留空字符串原样返回,还是增加服务端兜底文案。

工程校验会认为二者都通过,但语义评审必须把第二段判定为 blocking,因为这些问题直接影响接口实现。如果没有 blocking,Loop 自动往下走;如果存在 blocking,Loop 停下来找人确认。

图:OpenSpec 先过工程校验,再由独立评审判断是否存在 blocking 问题。

Loop 的安全性建立在 Harness 之上。没有 Guard、证据、heal、状态落盘和卡点确认的自动循环,只是把错误也自动化了。

自进化:把同一个纠正只发生一次

图:真实纠正被沉淀为知识资产,下一次交付从更高起点开始。

单次开发跑稳之后,还有一个更长期的问题:同一个坑不应该每个 session 都重新踩一次。

工程师经常会在开发中纠正 AI:"这个接口入参要先校验""这层不能直接依赖那个实现""这个场景之前出过事故"。如果这句话只活在当前对话里,它就会在会话结束时消失。下一次模型从空白开始,仍然可能犯同样的错。

这就是意图债:组织没有沉淀下来的隐性约束,会以一次次人工纠偏的形式反复偿还。

Harness 的自进化机制把纠正变成结构化资产,分三步走。

收集:把纠正落成 correction

纠正信号有四类,其中前三类本来就在运行时产生,只是过去没有被系统性消化。

来源 触发点 记录位置
guard_deny Guard 拦下一次越界 observations.jsonl
heal_fail 同类失败撞到预算上限 heal 记录
review_reject 评审给出 blocking 结论 评审结论
user_correction 工程师当场纠正 /harness-correct 新增入口

一条 correction 可以长这样:

json 复制代码
{
  "source": "guard_deny | heal_fail | user_correction | review_reject",
  "node": "implement",
  "signal": {
    "what": "把 infra 直接 import 了 biz/strategy",
    "expected": "infra 只能依赖 biz/shared/port",
    "evidence_ref": "observations.jsonl#L42 | audit run-id | 用户原话"
  },
  "scope_hint": "project_knowledge | framework"
}

收集不应该打扰主流程。写入失败最多留痕,不能影响当前需求继续交付。

分析:聚类根因,只给建议

不是每条 correction 都立刻改文件,而是在会话收尾或同类问题累计到阈值时,由独立判定者聚类根因,判断它属于项目知识缺口还是框架问题。

yaml 复制代码
clusters:
  - root_cause: "infra 层反向依赖 biz/strategy(架构不变量被违反)"
    occurrences: 3
    scope: project_knowledge
    target_doc: "ARCHITECTURE.md"
    proposed_patch: "在「依赖方向」补充:infra 仅依赖 biz/shared/port,禁止 import biz/*/strategy 实现"

  - root_cause: "Guard 对 sed -i 判定误拦了合法的 action 脚本"
    occurrences: 4
    scope: framework
    proposed_fix: "judge_bash 放行带 token 的 action 声明前缀"

判定者只给建议,不能直接改盘。改不改、怎么改,必须进入下一步确认。

回写:项目知识走分支,框架问题走 lesson

如果判定为项目知识缺口,回写目标就是开发前那套资产:

缺口类型 回写位置
架构约束、依赖方向、不变量 ARCHITECTURE.md
模块边界、项目地图、常用命令 AGENTS.md
接口入参出参、调用链、PSM docs/reference/<接口>.md
其他长期项目约束 项目 lesson

回写不能直接落主干。框架在新分支上生成知识 patch,给出 diff 摘要,人确认后再提交,最终合入仍走正常 MR。

如果判定为框架问题,例如某个门禁误拦合法操作、某个流程设计不合理,则自动登记为框架 lesson,交给维护者消化。原文中的 OpenClaw 示例说明了这类机制的价值:当 developer-plugin 仍引用 v1 skills/harness-entry/setup/reference 旧目录结构,而 v2 已迁移到 kernel/guard/flow/selfguard 后,问题被提报、定位为文档协作类缺陷,并在后续版本中通过更新 guardian_audit.py 的 REQUIRED_SOURCES 等方式修复。

自进化的关键不在于"AI 自己变聪明",而是把真实使用中的纠正不断写回系统。下一次开发开始时,模型读到的已经是吸收过上次教训的知识和规则。

模型变强以后,治理层仍然有价值

一个常见问题是:如果未来 Codex、Claude Code 这类通用 Code Agent 越来越强,这套框架会不会很快失效?

答案取决于我们把问题分成哪两类。

第一类是模型能力不足带来的问题,例如代码质量不稳定、复杂任务拆解不好、局部逻辑想不周全。这类问题会随着模型升级持续缓解。

第二类问题不会因为模型变强自然消失:

  • 模型不会天然知道你团队的分层规约、内部中间件、历史事故和接口禁忌。
  • 组织需要权限边界、审计证据和可回放过程,而不是"模型说完成了"。
  • 推远端、合主干、发布等关键动作必须有人负责拍板,这是责任归属问题。
  • 每次会话从零开始的问题,仍然需要外部记忆和知识沉淀机制来解决。

通用 Code Agent 未来可能内置更好的记忆、子代理、任务拆解和自动循环,但它不可能天然对齐每个组织的工程上下文。内部平台、Codebase、飞书流程、TCC、发布规范、团队架构习惯,都需要团队自己定义治理层。

因此,Harness 押注的不是某个模型,而是一层可替换、可演进的组织​工程治理 ​:

图:治理层稳定承载组织约束,模型、执行器和平台都可以替换。

模型会换,执行器会换,平台连接也会换。真正稳定的是知识层、契约、Guard、流程、证据、审计,以及它们背后承载的组织习惯。

结语

AI Coding 的核心矛盾,不是"模型能不能写代码",而是"组织敢不敢把真实交付过程交给一个不完全可信、会遗忘、会误判边界的执行者"。

只靠提示词,工程师会一直留在循环里,负责补上下文、贴报错、纠偏、确认下一步。HarnessLoop 要解决的是这件事:把可确定、可重复、可验证的部分交给系统,把真正需要判断和负责的部分留给人。

Build the loop, stay the engineer。搭建 Loop 的意义,不是让工程师变成按启动键的人,而是让工程师从低价值的过程驱动里退出来,继续站在目标、架构、风险和交付质量的判断位置上。

推荐阅读

AI Native 架构:有限上下文、确定性边界与质量闸门

Loop Runtime 架构拆解:别再手动催 Agent,先把工程闭环跑起来

Hermes Agent Skill Runtime 架构拆解:让 AI Agent 不再从零开始

GEPA 架构拆解:让 Prompt 和 Skill 优化不靠玄学

Agent 工具链工程化: Skill 负责编排判断,CLI 稳定交付的执行边界