作者:Codex 整理时间:2026-04-23 03:20:00 CST 来源:基于 AI Agent 架构形态详解:从单 Agent 到 Claude Code 与 Codex 式系统 进一步扩展 主题:以“修复一个仓库里失败的测试并准备提交补丁”为具体例子,讲清 Claude Code / Codex 式 Coding Agent 如何在权限、沙箱、项目规则、工具层、子代理、验证闭环与日志审计约束下推进任务。 说明:本文讨论的是“Codex 式 coding agent 的合理运行时抽象”,不是对任何产品私有内部实现的披露。
关联文章:
从一句请求开始:Coding Agent 不是直接写代码,而是在运行时里推进任务
假设用户给出一句很常见的请求:
这个仓库测试挂了,帮我修一下并提交补丁。
如果把 Coding Agent 理解成“一个会写代码的模型”,你可能会以为它下一步就是直接改文件。 但真正可靠的 Coding Agent 不应该这么做。
它首先要建立任务边界:
- 当前工作目录是什么
- 项目有什么规则
- 是否已有用户改动
- 是否允许写文件
- 是否允许运行命令
- 是否允许联网查资料
- 是否需要提交 commit
- 哪些动作需要用户确认
也就是说,Coding Agent 的核心不是“马上写代码”,而是:
在一个受约束运行时中,持续感知、计划、行动、验证、修正,并最终交付可审计结果。
一、运行时抽象总览:模型、工具与工作区之间如何分工
在这个抽象里,可以把 Coding Agent 分成四个大区:
- 模型 / 推理核心:理解任务、形成计划、解释错误、决定下一步
- 工具层:读文件、搜索代码、运行测试、调用 Git、访问浏览器或 MCP 服务
- 工作区状态:源码、测试、配置、日志、git diff、依赖环境
- 治理层:权限、沙箱、审批、项目规则、审计日志
其中最容易被低估的是工作区。 对 Coding Agent 来说,工作区不是普通文件夹,而是任务推进的状态载体。
例如它会通过下面这些观察来判断现实:
git status显示哪些文件已有改动- 测试日志告诉它哪里失败
package.json或pyproject.toml告诉它该如何运行测试AGENTS.md或项目规则告诉它哪些动作不能做git diff告诉它最终补丁是否干净
模型提供推理,工具连接现实,工作区承载状态,治理层限制风险。 四者合在一起,才像一个真正可用的 Coding Agent 运行时。
二、权限、沙箱与审批:Agent 能做什么,不能做什么
Coding Agent 的第一层边界是权限。
权限不是“麻烦的限制”,而是让 Agent 能进入真实工程环境的前提。 如果一个 Agent 能随意删文件、联网、安装依赖、推送代码,那么它越强,风险越大。
常见权限边界包括:
- 文件系统权限:只读、工作区写入、指定目录可写、全盘访问
- 命令权限:普通命令自动执行,高风险命令需要确认,危险命令直接禁止
- 网络权限:是否允许查官方文档、拉依赖、访问外部 API
- Git 权限:是否允许 commit、push、改分支、改历史
- 外部系统权限:是否允许访问 GitHub、CI、数据库、工单系统
这些边界会直接改变 Agent 的行为。
例如:
- 如果不能联网,它就会优先读本地文档和源码
- 如果不能安装依赖,它就会报告缺失依赖,而不是偷偷安装
- 如果推送需要确认,它最多准备好 commit,不会自动 push
- 如果检测到危险命令,它应该停下来说明风险
所以权限与沙箱不是附加功能,而是运行时架构的一部分。 它们决定 Agent 的行动空间,也决定事故能否被控制在可恢复范围内。
三、项目规则与记忆:AGENTS.md、用户偏好和仓库惯例如何影响执行
进入一个仓库后,Agent 不应该只看代码。 它还要看规则。
常见规则来源包括:
AGENTS.mdREADME.mdCONTRIBUTING.md- 测试说明
- package scripts
- 用户在当前对话里给出的限制
- 长期偏好或项目记忆
这些规则会影响很多细节:
- 搜索时优先用什么工具
- 能不能改生成文件
- 测试命令是什么
- 是否必须运行格式化
- 提交信息怎么写
- 是否不能覆盖用户已有改动
例如一个项目规则可能写着:
搜索代码时优先使用 rg。
不要修改 dist/ 下的生成文件。
提交前至少运行 npm test。
如果发现 unrelated changes,不要回滚。
这些看起来像小事,但对 Coding Agent 很重要。 因为没有规则,Agent 会把所有仓库当成同一个仓库;有了规则,它才开始像一个真正进入项目的工程师。
四、MCP 与工具层:从推理到可执行动作
模型本身不能直接改变现实。 它要通过工具层把“我应该做什么”变成“我实际做了什么”。
工具可以包括:
- shell
- 文件读取
- 代码搜索
- 代码编辑
- Git
- 测试运行器
- 浏览器
- GitHub / CI
- 日志系统
- 数据库
- MCP 服务
MCP 可以理解为一种外部能力适配层。 它把文档、服务、工具、资源、企业系统暴露成 Agent 可调用的接口。
这件事的价值不只是“工具更多”,而是:
工具让 Agent 能通过现实反馈校正自己的判断。
例如,Agent 猜测某个函数导致测试失败,这只是一个假设。 它必须读源码、运行测试、看错误栈、检查 diff,才能把假设变成证据。
没有工具层,Agent 只能像顾问一样给建议。 有了工具层和验证闭环,它才开始像工程师一样推进任务。
五、一个具体任务怎么跑:修复失败测试的完整执行链
下面用一个具体任务串起来:
修复一个仓库里失败的测试,并准备提交补丁。
1. 接收请求并建立边界
Agent 首先不会直接改代码,而是确认:
- 当前仓库在哪里
- 工作区是否干净
- 用户是否要求 commit
- 是否允许运行测试
- 是否允许联网或安装依赖
这一步的关键是避免一上来就破坏用户现场。
2. 读取项目规则与测试入口
接着它会找:
AGENTS.mdREADME.mdpackage.jsonpyproject.tomlpytest.iniMakefile- 测试目录
目标是确定项目语言、测试框架、约定命令和禁止操作。
3. 运行基线测试
Agent 会运行最小合理测试命令,例如:
npm test
pytest
make test
如果全量测试太慢,它可能先运行失败用例或相关测试文件。 这一步的产物不是“通过或失败”四个字,而是错误栈、失败断言、文件路径和复现条件。
4. 读取相关源码与测试
根据错误栈,Agent 读取:
- 失败测试文件
- 被测模块
- fixture
- mock 数据
- 相关配置
- 最近相关变更
它会搜索函数名、错误消息、断言文本和调用路径,逐步缩小问题范围。
5. 制定小计划
一个合理计划可能是:
1. 修复 parser 对空 metadata 字段的处理。
2. 保持现有接口返回结构不变。
3. 运行失败测试文件。
4. 如果通过,再运行相关包测试。
5. 检查 git diff,确认没有无关改动。
计划不需要很宏大,但必须可执行、可验证、可回滚。
6. 应用最小补丁
Agent 应该优先修改业务代码,而不是简单删除测试或放宽断言。 除非能证明测试期望已经过时,否则“让测试不报错”不等于“修复问题”。
7. 局部验证与失败重试
第一次修改后,Agent 运行局部测试。 如果仍然失败,它会读取新错误。
例如:
- 第一次错误是
TypeError - 修改后变成断言不匹配
这说明第一个问题已经解决,但输出格式仍不符合预期。 于是 Agent 更新假设,继续读格式化逻辑,做第二次小修改。
8. 全量验证与 diff 检查
局部测试通过后,还要做更大范围验证:
- 相关测试
- 全量单元测试
- 类型检查
- lint
- 构建
然后检查:
git diff
git status
确认没有带入日志、缓存、构建产物、用户无关改动。
9. 准备提交与最终交付
如果用户要求提交,Agent 可以准备 commit message,例如:
fix parser handling for empty metadata fields
最终交付应该包括:
- 改了什么
- 为什么这样改
- 运行了哪些验证
- 是否已提交
- 还有哪些风险或未验证项
没有这些交代,任务就不算完整闭环。
六、子代理与并行探索:把不确定性拆成多条路径
复杂任务里,最耗时间的往往不是修改,而是定位。 这时可以把不确定性拆成几条并行探索路径。
例如主 Agent 可以并行派出:
- 子代理 A:分析失败日志和错误栈
- 子代理 B:搜索相关源码路径
- 子代理 C:查看最近变更或提交差异
- 子代理 D:检查文档和项目规则
但关键原则是:
- 子代理优先只读
- 主代理负责合并结论
- 避免多个子代理同时写同一批文件
- 并行结果必须带证据
- 有冲突时由主代理仲裁
Multi-Agent 的价值不是“人多势众”,而是把不确定性隔离成多个低风险探索任务。
七、验证闭环:读、改、测、失败、再改
Coding Agent 的可靠性来自验证闭环。 没有验证的补丁,只能算“生成了一段代码”,不能算“完成了工程任务”。
一个健康闭环通常是:
建立假设
-> 最小修改
-> 局部测试
-> 读取失败
-> 修正假设
-> 再次修改
-> 更大范围验证
-> 检查 diff
-> 交付
失败不是异常,而是正常推进机制。 真正危险的不是测试失败,而是测试失败后 Agent 仍然假装已经完成。
所以成熟的 Coding Agent 应该区分:
- 快速局部验证
- 相关范围验证
- 最终全量验证
- 未能验证的残留风险
如果某些测试因为依赖缺失、环境限制或权限不足无法运行,最终交付时必须明确说明。
八、日志审计与最终交付:为什么过程也很重要
工程任务不是只看最后一段代码。 过程同样重要。
至少应该留下这些可审计痕迹:
- 读取过哪些关键文件
- 运行过哪些命令
- 哪些测试失败过
- 做过哪些修改
- 验证结果是什么
- 是否跳过了某些检查
- 是否需要人工确认
最终交付也应该结构化:
- 变更摘要
- 修改文件
- 验证命令与结果
- commit 信息
- 残留风险
- 未做事项
如果需要提交补丁,还要特别检查:
- 是否包含无关改动
- 是否覆盖用户未提交修改
- 是否把生成文件、日志、缓存带进去了
- commit message 是否清楚
这也是 Coding Agent 与普通代码生成器的差别:
它不是替代工程纪律,而是把工程纪律自动化、显性化、可追踪化。
总结:Coding Agent 的价值在于把工程闭环变成运行时能力
用这一个“修复失败测试”的例子回看,Coding Agent 真正做的事情不是单点写代码,而是持续推进一个工程闭环:
- 理解目标
- 建立上下文
- 遵守项目规则
- 在权限与沙箱中行动
- 调用工具观察现实
- 做最小修改
- 用测试验证
- 根据失败修正
- 检查 diff
- 结构化交付
这就是 Claude Code / Codex 式系统最值得学习的地方: 它们把模型能力放进了一个可执行、可验证、可治理的运行时里。
所以,如果要判断一个 Coding Agent 是否真正成熟,不要只问“它会不会写代码”。 更应该问:
- 它是否理解项目规则
- 它是否尊重权限边界
- 它是否能利用工具验证现实
- 它是否能从失败中修正
- 它是否能交付可审计过程
一个真正可靠的 Coding Agent,本质上不是“更会补全代码的模型”,而是能把工程任务从模糊目标推进到可验证补丁的代理运行时系统。