结构化方法材料
Agent 协作控制回路
一个面向复现的最小实践框架
- 作者:Key of the Door(GitHub:Key-of-door)
- 版本:v0.1
- 版本日期:2026-07-11
- 许可:CC BY-NC-SA 4.0
- 项目仓库:Key-of-door/code-risk-review-v0.1
- 项目 Release:v0.1(c5054ac)
Word 下载版:下载《Agent 协作控制回路:一个面向复现的最小实践框架》v0.1
目的:降低 Agent 在实现过程中悄悄改写产品语义的概率,并让关键判断可见、可校验、可追溯。
这套框架来自单人、单项目实践。它展示了如何把部分产品语义外化为可检查、可追溯的工程证据,但尚未证明其在不同项目、团队和工程环境中都能稳定降低 Agent 语义漂移。
v0.1 的作用,是提供一个可以被讨论、复现、修改和反驳的实验起点。
1. 适用范围
适合:
- 开发周期较长,涉及多个模块或多次迭代的 Agent 编程项目。
- 有明确产品承诺、隐私边界、错误状态或交付责任的项目。
- 希望代码、测试、文档与 Git 历史共同构成证据的项目。
- 使用者愿意参与产品定义、边界判断和关键验收的项目。
不适合:
- 一次性脚本、低风险实验或无需交付的小任务。
- 使用者完全无法判断产品边界,也不准备参与关键决策的场景。
- 只想让 Agent 无监督地从模糊目标一路生成完整系统的场景。
- 希望仅依靠提示词、测试通过或 Agent 自我检查证明产品正确的场景。
这不是让 Agent 自动产生正确判断的机制。它只是把人的部分判断外化、固定,并建立一个持续暴露偏移、验证边界和保存证据的控制回路。
2. 最低配实践
第一次使用这套框架时,不需要一次搭完所有机制。
最低限度可以先完成四件事:
- 写一张协作启动卡,明确产品是什么、不是什么。
- 在较大改动前完成一次理解检查点。
- 围绕至少一条关键产品承诺,设计一项语义边界 mutation 或等价退化测试。
- 用发布证据模板记录实际验证结果,以及它证明什么、不证明什么。
随着项目持续时间、风险和复杂度提高,再逐步加入职责分层、语义 diff 审查、失败报告和更完整的 release evidence。
“最小”不意味着省略关键判断,而是允许控制回路从最重要的边界开始生长。
3. 先保留产品定义权与解释权
开始实现前,先写一张“协作启动卡”:
| 字段 | 填写内容 |
|---|---|
| 产品是什么 | |
| 产品不是什么 | |
| 目标用户 | |
| 当前版本明确不做什么 | |
| 谁负责生成核心事实 | |
| 哪些承诺不能被实现层改写 | |
| 本轮允许 Agent 自由决定什么 |
其中最重要的一项是:
决定“产品是什么、不是什么”的权力,由人保留。
例如,代码风险审查工具可以报告“当前规则范围内可识别的可能风险”,但不能因为 Agent 增加了更多文案、评分、自动修复或视觉包装,就被悄悄定义成“代码安全认证工具”。
Agent 可以帮助补充方案、指出冲突和提出不同解释,但不能默认获得最终的产品定义权与解释权。
4. 按稳定性与落点整理约束
不要把所有规则都写成永久宪法,也不要把临时实现选择误认为产品原则。
整理一条约束时,应分别回答两个问题:
- 这条约束预计持续多久?
- 它应该由哪些工程载体保存和验证?
4.1 按稳定性区分
| 类型 | 含义 | 示例 |
|---|---|---|
| 长期原则 | 决定产品可信度、责任和基本边界,不应被局部实现随意突破 | 不运行用户代码、不保存源码、不承诺代码安全 |
| 阶段护栏 | 限制当前版本的实现范围,可由未来版本通过明确决策调整 | v0.1 只支持 Python、暂不进行数据流分析 |
长期原则并不等于永远不能变化,但其变化应被视为产品级决策,而不是局部实现或 Agent 自主补全。
阶段护栏也不是低价值约束。只要它仍属于当前版本,就需要被实现、测试和文档共同维护。
4.2 按约束落点区分
产品说明:
说明产品是什么、不是什么,以及它向用户作出哪些承诺。
接口契约:
固定当前版本可观察的输入、输出、字段和状态语义。
工程护栏:
限制各层职责、事实来源和当前实现范围。
测试与语义边界变异测试:
验证已识别的关键约束没有发生退化。
Git 与 release evidence:
保存决策、实现和实际验证结果的可追溯证据。
同一条约束可以同时落在多个载体中。
例如,“不保存用户源码”既可能是长期原则,也应反映在产品说明、日志策略、存储行为、测试和发布检查中。
5. 在关键节点建立理解检查点
每次开始较大改动前,要求 Agent 明确回答:
| 字段 | 填写内容 |
|---|---|
| 当前理解 | |
| 已确认事实 | |
| 待确认假设 | |
| 本次修改范围 | |
| 不应改变的语义边界 | |
| 验证方式与失败条件 |
理解检查点不是让 Agent 决定产品语义,而是让它暴露当前理解、假设和修改范围。
如果它把“阶段性限制”说成永久原则,或者把“前端渲染”理解成“前端判断”,偏移就可能在写代码前被发现。
普通对话也可以承担理解检查点的作用,前提是使用者会观察其中的歧义,并在进入实现前完成校准。
理解检查点不需要出现在每一个微小修改之前。它更适合以下情况:
- 新增模块或跨层修改。
- 改变接口、状态或数据结构。
- 触及隐私、权限、错误处理或对外承诺。
- Agent 主动扩大了任务范围。
- 当前实现依赖尚未确认的产品假设。
- 改动看似局部,但可能改变用户如何理解产品。
6. 何时收权,何时放权
一个实用判断是:
会改变产品被如何理解的,由人决定;只改变既有边界内实现路径的,可以交给 Agent。
应由人保留决定权的内容包括:
- 产品定位、目标用户和核心承诺。
- 隐私边界、权限边界和交付责任。
- 错误状态的含义及不得误导的表达边界。
- 风险事实、业务事实和状态事实由谁生成。
- 前后端职责与单一事实源。
- 是否扩大当前版本范围。
- 是否接受某项已知风险或不确定性。
可以交给 Agent 自由决定的内容包括:
- 函数拆分、局部重构和命名建议。
- AST 遍历方式或同类实现路径。
- 测试组织、辅助函数和序列化细节。
- 样式、布局和纯展示逻辑。
- 在既有契约内选择更清晰或更稳妥的实现方案。
目标不是让 Agent 沿唯一轨迹执行,而是限制不可接受的状态空间。
语义自由度要小,实现自由度可以大。
7. 固定单一事实源
每一类核心事实,都应有一个权威的定义和生成来源。
其他层级可以传递、裁剪、排序、聚合或展示这些事实,但不能重新定义它们。
例如:
风险命中、等级、置信度、行动优先级:后端规则层
状态语义与响应结构:后端契约层
HTTP 状态码映射:HTTP 层
展示、排序和交互:前端
前端可以渲染后端返回的风险,也可以进行不改变事实含义的纯展示运算;但不能自行补写风险原因、改变风险等级,或在后端没有提供相关事实时生成“看起来合理”的安全结论。
序列化层可以根据 "report_depth" 裁剪披露字段,但不能因此改变风险是否命中、风险数量、等级或状态语义。
单一事实源不是为了形式整齐,也不是要求只有一个文件能够接触数据。
它要避免的是:同一份产品事实在不同层级拥有多个相互竞争的权威定义。
8. 审查语义 diff
测试只能拦住已经被写成断言的退化。语义 diff 审查用于发现尚未被编码进测试的边界变化。
在较大改动完成后,可以人工检查:
本次 diff 是否改变了产品的对外含义?
是否引入了新的产品承诺、限制或默认行为?
某类核心事实是否被移动到了新的层级?
是否产生了第二个事实源?
是否把阶段护栏写成了长期原则,或反过来?
是否引入了契约和测试尚未描述的新行为?
Agent 是否修改了原本未被授权修改的范围?
当前实现是否仍位于已授权的实现自由区内?
语义 diff 审查不要求逐行重新设计代码。它关注的是代码变化是否改变了:
- 产品是什么。
- 用户会观察到什么。
- 哪一层拥有事实解释权。
- 失败和异常意味着什么。
- 当前版本承诺做到什么、不做到什么。
当语义 diff 审查发现新边界时,应决定是否补充产品说明、接口契约、测试或 mutation,而不是只在本轮人工记住它。
9. 从产品承诺反推语义边界变异测试
普通 mutation 测试常问:
实现被改坏后,测试会不会失败?
语义边界变异测试还要问:
产品承诺被悄悄改写后,测试会不会失败?
设计步骤:
- 写出一条具体的产品承诺。
- 找到它在代码中的实现位置。
- 设计一个最小的“背叛性修改”。
- 让测试证明该修改会失败。
- 记录这份证据证明什么,以及不证明什么。
示例:
| 产品承诺 | 变异 | 应有结果 |
|---|---|---|
| 语法错误应返回部分报告 | 将 "partial" 改为 "user_error" | 状态语义测试失败 |
| "source_size" 表示 UTF-8 字节数 | 改回 Python 字符数 | 中英文边界测试失败 |
| 带有可解析 "Content-Length" 的超大请求应在读取前被拒绝 | 移除读取前的长度拦截 | HTTP 边界测试失败 |
| summary 只披露约定字段 | 让 summary 返回 detail 专属字段 | 响应契约测试失败 |
| "report_depth" 不改变分析事实 | 让它参与规则选择或过滤风险 | 分析不变量测试失败 |
“全部 mutation 被杀死”不代表测试没有遗漏。
它只代表:
当前明确设计出的这些退化行为,没有在现有测试中漏网。
语义边界变异测试也不应只追求数量。一个 mutation 的价值取决于它是否对应真实产品承诺,以及失败时能否清楚说明哪条语义被破坏。
10. 用 Git 保存决策证据
一次提交应尽量对应一个可以说明的小闭环:
触发问题 -> 决策 -> 实现 -> 测试 -> 语义边界变异测试 -> 文档 -> 提交
提交前检查:
本次改动是否主要服务于一个明确问题?
契约、实现、测试和文档是否同步?
是否引入了无关文件、临时产物或敏感信息?
验证是否真实运行,而不是只由 Agent 声称通过?
提交信息能否说明本次决策?
Git 历史不需要为了形式追求绝对整齐。
在提交尚未被文档、博客、release evidence 或外部讨论引用时,可以根据协作需要整理历史,但应保留关键决策和验证证据。
一旦某个 commit hash 已被作为证据引用,就不应再仅仅为了历史美观而重写它。
可复查的历史,比脱离证据目的的漂亮历史更有价值。
11. 发布前证据模板
| 字段 | 填写内容 |
|---|---|
| 对应版本或 commit | |
| 验证环境 | |
| 执行命令 | |
| 准备确认的结论 | |
| 验证方式 | |
| 预期结果 | |
| 实际结果 | |
| 这份证据证明什么 | |
| 它不证明什么 |
验证环境最低可以包括:
操作系统:
运行时版本:
关键依赖版本或锁文件:
例如:
在指定 commit 和验证环境中,从干净检出运行测试,44 个测试通过,12 个已设计 mutation 被杀死。
这份证据可以证明:
- 当前仓库在该环境中能够复现这些验证结果。
- 当前测试能够捕获这 12 个已明确设计的退化行为。
- 被这些测试覆盖的部分契约在该版本中没有发生相应退化。
它不能证明:
- 产品不存在其他缺陷。
- 测试覆盖了所有语义漂移。
- 项目适用于所有运行或部署环境。
- 相同方法在其他项目中具有相同效果。
- 当前产品已经达到安全认证或生产级保证。
发布证据的作用不是制造“已完成一切”的印象,而是让读者知道:哪些结论有证据,证据适用于什么范围。
12. 失败报告模板
当发现语义漂移、契约冲突或测试漏网时,记录:
| 字段 | 填写内容 |
|---|---|
| 发现时间 | |
| 对应版本或 commit | |
| 变化是什么 | |
| 它改变了哪条产品语义 | |
| 它是如何被发现的 | |
| 为什么现有文档、检查点或测试没有提前发现 | |
| 本次修复范围 | |
| 新增或调整的验证 | |
| 是否需要调整契约或工程护栏 | |
| 仍然存在的未知 |
失败报告不是追究谁“写错了”,也不是为了证明 Agent 不可靠。
它的作用是识别控制回路中缺少的观测点,并决定下一次应在哪里增加:
- 更明确的产品说明。
- 更早的理解检查点。
- 更清晰的职责边界。
- 新的测试或语义边界变异测试。
- 更具体的发布检查。
成功案例说明控制回路在哪里生效,失败报告说明控制回路接下来应该在哪里生长。
13. 最小控制回路
人定义产品 -> 外化长期原则、阶段护栏与接口契约 -> 理解检查点暴露 Agent 的当前理解 -> Agent 在实现自由区内工作 -> 人审查语义 diff -> 测试与语义边界变异测试验证已知退化 -> 文档、Git 与 release evidence 保存证据 -> 失败报告补强观测点 -> 回到下一轮理解检查点
这套流程不保证项目正确,也不替代工程能力、业务判断、人工审查或真实环境测试。
它试图做到的是:
当 Agent 拥有较高实现自由时,让关键产品判断不只存在于人的脑中;让偏移更早暴露,让退化能够被验证,让每一轮决策留下可复查的证据。
最终目标不是让 Agent 永远不犯错,而是降低产品在“代码能跑、测试全绿、文档看似完整”的表象下,被悄悄写成另一个东西的概率。
Agent 可以选择实现路径,但没有因此获得产品定义权与解释权。
14. 项目案例证据索引
以下链接用于复查 Code Risk Review v0.1 中与本框架对应的工程闭环。测试数量和变异数量只描述对应提交时的验证状态。
| 闭环 | 提交 | 测试 / 变异 | 边界 |
|---|---|---|---|
| source_size 语义统一 | 14e746e | 34 / 9 | 字段语义与 UTF-8 字节边界 |
| HTTP 请求体读取前限制 | 4c5c256 | 36 / 10 | 入口边界与业务边界分离 |
| filename 辅助元数据 | 1d85c2e | 40 / 11 | 辅助元数据不可越权 |
| report_depth | f030294 | 44 / 12 | 披露深度不改变分析事实 |
| 发布证据 | 4c4fe7e | 44 / 12 | 干净克隆、仓库卫生与发布检查 |
| v0.1 发布封口 | c5054ac | 44 / 12(CI) | 标签、Release 与证据同步 |
最终发布引用:v0.1(c5054ac);完整记录见 Release Evidence。
15. 许可与使用边界
本文档采用 CC BY-NC-SA 4.0 协议发布。
允许非商业学习、研究、复现、分享和改编;使用时应按协议提供适当署名、许可链接并注明修改,改编内容应以相同协议共享。商业使用需要另行取得授权。
本框架不保证项目正确,也不构成安全、法律、合规或生产级认证。术语和模板用于帮助使用者暴露判断与保存证据,不能代替使用者作出产品和工程决策。