Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第18章 AI Coding Agent 系统解析:从工作协议到 Harness 工程

AI Coding Agent 的本质,不是“自动写代码”,而是把软件工程任务转化为可规划、可执行、可验证、可隔离、可审查的工程闭环。

引言

前两部分已经讨论了 LLM 能力边界、Prompt Engineering、Context Engineering、Harness Engineering,以及 Agent 的工具调用、工作流、RAG、Memory、Eval、Guardrails 和可观测性。从本章开始,我们进入成熟系统解析。

本章选择 AI Coding Agent 作为第一个成熟系统案例,因为它几乎包含了 Agent 工程的全部核心问题:

  • 它要理解自然语言需求;
  • 它要读取和筛选大型代码库上下文;
  • 它要规划多步修改;
  • 它要调用搜索、文件、Shell、Git、测试等工具;
  • 它要处理权限、失败、回滚和用户中断;
  • 它要把人的意图转化为可审查的代码变更。

Claude Code、Cursor 和 Codex 的产品形态不同:一个偏终端,一个偏 IDE,一个偏本地与云端任务执行。但从系统设计视角看,它们都在回答同一个问题:

如何让一个概率模型可靠地参与确定性的软件工程流程?

这个问题不能只靠模型能力解决。模型负责理解、推理、规划和生成行动意图;真正让 Agent 能在真实工程环境中工作的,是模型外部的 Harness。

可以把 Coding Agent 看成下面这个组合:

Coding Agent = Model + Harness

Model:
  理解任务、推理方案、选择行动、解释结果

Harness:
  工具、上下文、状态、权限、验证、隔离、审计、交付界面

本章的目标不是做产品评测,而是从成熟产品中抽象出可迁移的工程原则。读完本章,你应该能回答:

  1. Vibe Coding 和 Spec Coding 分别适合什么阶段;
  2. 一个成熟 Coding Agent Harness 由哪些模块组成;
  3. Claude Code、Cursor、Codex 的架构取舍有什么差异;
  4. 终端原生 Coding Agent 为什么需要 Agent Loop、Tool Plane、Task State、Context Compact、Subagent、Worktree Isolation;
  5. 如何从 MVP 演进到生产级 Coding Agent;
  6. 如何评价一个 Coding Agent 系统是否可靠。

17.1 从 AI 编程范式到 Coding Agent 工作协议

AI 编程工具不是突然从“代码补全”跳到“自动程序员”的。它经历了从局部辅助到闭环执行的演进。

代码补全
   ↓
对话式代码生成
   ↓
项目级上下文编程
   ↓
Coding Agent 闭环执行

这条演进线的关键变化,不是模型一次能写多少代码,而是模型是否被放进了一个能观察、行动、验证和修复的工程环境里。

17.1.1 从代码补全到闭环执行

第一阶段是代码补全。模型根据当前文件和光标附近上下文预测下一段代码。这类工具的优势是低延迟、低风险、低学习成本;局限是只能处理局部代码,不理解完整任务。

第二阶段是对话式代码生成。开发者用自然语言描述需求,模型生成代码片段、解释方案、给出调试建议。相比补全,它开始参与设计和分析,但仍然主要停留在“建议者”角色。

第三阶段是项目级上下文编程。IDE Agent 能读取打开文件、选区、诊断信息、项目规则、代码索引和相关文件。这一步的变化是:模型不再只看一个文件,而是开始围绕代码库工作。

第四阶段是 Coding Agent 闭环执行。Agent 能搜索代码、读取文件、修改文件、运行测试、分析失败、继续修复,并输出 diff、验证结果和剩余风险。这时模型不再只是生成答案,而是进入一个由工具、权限、状态、验证和审计组成的运行环境。

闭环执行可以抽象为:

Intent
  ↓
Plan
  ↓
Context Gathering
  ↓
Tool Use
  ↓
Patch
  ↓
Verification
  ↓
Review

这就是 Coding Agent 和普通 Chatbot 的分界线。

17.1.2 Vibe Coding:探索式编程的价值

Vibe Coding 指的是开发者通过即兴 prompt、多轮对话和模型共同探索实现方案。

它不是坏方法。在探索阶段,它非常有效:

  • 快速了解新框架;
  • 验证一个技术方案是否可行;
  • 生成一次性脚本;
  • 做原型和 Demo;
  • 解释陌生代码;
  • 比较几种实现路径。

Vibe Coding 的优势是启动快、反馈快、心理负担低。它把“先想清楚再写”变成“边试边看”,特别适合需求还不稳定、技术空间还不清楚的阶段。

例如你想验证“能否把一段日志转成 Mermaid 调用链图”,用 Vibe Coding 很合适:

先让模型写一个解析 demo;
再贴一段脱敏日志;
再让模型生成图;
再观察哪些字段不稳定;
最后决定是否值得工程化。

这种阶段的目标不是交付,而是学习。

17.1.3 Vibe Coding 的天花板

Vibe Coding 一旦被误用为生产交付方式,问题会快速积累。

典型过程是:

用户:实现一个用户注册功能
模型:生成基础代码

用户:加邮箱验证
模型:补一段逻辑

用户:密码要加密
模型:继续修改

用户:还要防重复注册
模型:再改一轮

用户:补测试
模型:补测试,但只覆盖快乐路径

几轮之后,代码可能“看起来能跑”,但系统性问题已经出现:

  • 需求边界不清;
  • 安全约束靠后补;
  • 错误处理不完整;
  • 测试覆盖滞后;
  • 文件结构随着对话漂移;
  • 模型为了满足最新指令破坏早期约束;
  • 人很难判断最终代码是否满足最初目标。

Vibe Coding 的本质是探索工具,不是交付协议。探索阶段允许混沌,交付阶段必须有约束。

17.1.4 Spec Coding:把意图变成任务协议

Spec Coding 的核心思想是:先把人的意图写成可执行、可验证、可审查的任务协议,再让 Agent 执行。

Intent
  ↓
Spec
  ↓
Plan
  ↓
Implementation
  ↓
Verification
  ↓
Review

Spec 不是为了写更多文档,而是为了把隐性判断显式化。

一个高质量 Spec 至少回答八个问题:

问题说明
做什么功能目标是什么
不做什么当前任务边界在哪里
输入是什么API、参数、事件、用户操作
输出是什么返回值、状态变化、UI 行为
业务规则是什么状态机、权限、幂等、并发
失败模式有哪些校验失败、外部依赖失败、超时
安全要求是什么权限、脱敏、审计、高风险动作
什么算完成测试、构建、diff、人工验收

对 Coding Agent 来说,Spec 是任务接口。它类似传统系统里的 API Contract:输入、输出、约束、错误和验收标准都必须清楚。

一个简化的 Spec 可以这样写:

# 功能:订单取消

## 目标
用户可以在订单未支付前取消订单。

## 业务规则
- 只有 `pending_payment` 状态可以取消;
- 已支付订单不能直接取消;
- 取消后释放库存;
- 重复取消必须幂等。

## 验收测试
- pending_payment -> canceled 成功;
- paid -> canceled 失败;
- 重复取消返回相同结果;
- 库存释放只执行一次。

这个 Spec 不长,但它已经足够让 Agent 规划修改、寻找相关代码、补测试和判断完成。

17.1.5 Spec 不是瀑布,而是探索到交付的转换

Spec Coding 不意味着一开始写出完美方案。更健康的流程是:

Vibe 探索
  ↓
提炼 Spec
  ↓
Agent 执行
  ↓
验证反馈
  ↓
修订 Spec

探索阶段可以用 Vibe Coding 打开问题空间;一旦要进入交付,就要把探索结果收束成 Spec。

这也是成熟 Coding Agent 的工作方式:它可以和你一起探索,但当它要修改真实代码、运行命令、提交 diff 时,必须进入任务协议和验证闭环。


17.2 从成熟 Coding Agent 产品抽象通用 Harness 架构

如果只看表面,Coding Agent 像是“LLM + 工具调用”。但这个理解太浅。

一个能真正参与软件工程的 Coding Agent,至少要解决九类问题:

  1. 用户意图如何变成任务;
  2. 模型每轮应该看到什么上下文;
  3. 模型可以调用哪些工具;
  4. 工具调用如何被校验和执行;
  5. 高风险动作如何审批;
  6. 长任务状态如何维护;
  7. 修改如何验证;
  8. 结果如何交付给人审查;
  9. 失败如何沉淀成规则、Skill 或 eval。

这些问题合在一起,才是 Coding Agent Harness。

17.2.1 为什么不能只把 Coding Agent 理解成 “LLM + 工具”

“LLM + 工具”只能解释 Agent 如何行动,不能解释 Agent 如何可靠行动。

例如,模型可以提出:

{
  "tool": "run_shell",
  "arguments": {
    "command": "npm test"
  }
}

但真正的系统要回答更多问题:

  • 这个命令是否允许执行;
  • 当前目录是否正确;
  • 是否会访问网络;
  • 是否会修改文件;
  • 超时多久;
  • stdout / stderr 如何截断;
  • 失败结果如何回填给模型;
  • 测试失败时是否允许继续改代码;
  • 最终是否可以声称完成。

工具调用只是一个动作意图。Harness 才负责把动作意图变成受控执行。

17.2.2 成熟 Coding Agent 的核心模块

成熟 Coding Agent 通常可以拆成九个模块。

┌──────────────────────────────────────────────────────────────┐
│                    Coding Agent Runtime                       │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  User Intent / Issue / Spec                                   │
│      ↓                                                        │
│  Task Planner                                                 │
│      ↓                                                        │
│  Context Builder ─────► Code Index / Git / Docs / Rules       │
│      ↓                                                        │
│  Skill Registry ──────► bugfix / test / refactor / incident   │
│      ↓                                                        │
│  Tool Registry ───────► read / search / edit / shell / git    │
│      ↓                                                        │
│  Policy Engine ───────► allow / deny / ask / sandbox          │
│      ↓                                                        │
│  Agent Loop ──────────► observe / decide / act / repair       │
│      ↓                                                        │
│  Verifier ────────────► test / lint / typecheck / build       │
│      ↓                                                        │
│  Review Surface ──────► diff / PR / summary / trace           │
│                                                              │
└──────────────────────────────────────────────────────────────┘
模块职责最小原型关键风险
Task Planner把需求拆成步骤JSON plan / todo list计划过粗、遗漏验证
Context Builder找相关代码和规则repo map + search + read上下文过多或漏掉关键文件
Skill Registry加载任务流程skills/*/SKILL.md规则冲突、误触发
Tool Registry暴露可调用能力函数注册表工具语义模糊
Policy Engine裁决危险动作allowlist + sandbox越权、破坏用户修改
Agent Loop驱动多轮执行while loop + tool result死循环、偏航
Verifier判断是否完成test / lint / build只验证快乐路径
Review Surface展示变更git diff + summary解释和实际 diff 不一致
Eval Loop复盘失败样本trace + case store没有持续改进闭环

这些模块的边界要清楚。模型可以建议行动,但工具和权限由 Runtime 控制;模型可以总结结果,但完成判定必须由 Verifier 和人审共同支撑。

与第8章组件地图的对应关系

第 5 章把生产级 Agent Runtime 拆成 13 个核心组件。放到 Coding Agent 场景里,这些组件会更具体:入口不再只是聊天,而是 issue、diff、终端、IDE、PR、CI;上下文不再只是文档,而是代码仓库、Git 状态、测试输出、项目规则和历史变更。

第8章组件Coding Agent 中的典型实现Claude Code / Cursor / Codex 的差异
Event & Intake Router接收自然语言任务、issue、PR 评论、终端命令、IDE 操作和后台任务Claude Code 偏终端入口,Cursor 偏 IDE 入口,Codex 同时覆盖本地任务和云端任务队列
Intent Normalizer把“修一下这个问题”转成 bugfix、refactor、test、review、explain、migration 等任务类型IDE 产品更依赖当前文件和选区,终端/云端产品更依赖任务说明、仓库和分支
Task Planner生成 todo、计划、文件阅读顺序、修改路径和验证步骤Claude Code / Codex 更强调长任务计划,Cursor 更强调人机共编中的局部计划
Context Builder选择代码片段、规则文件、Git diff、测试输出、日志、文档和工具结果Cursor 的 IDE 上下文更细,Claude Code 的终端上下文更宽,Codex 的 sandbox 上下文更任务化
Memory Layer项目规则、用户偏好、历史会话、失败样本、常用 workflowClaude Code / Cursor 偏项目规则和用户设置,Codex 更强调任务状态、会话、日志和云端任务历史
Execution State & Checkpoint计划、已读文件、已改文件、工具结果、验证结果、checkpoint、worktreeCursor 的 checkpoint 面向编辑体验,Codex 的 worktree/sandbox 面向并行任务,终端 Agent 依赖会话状态和 Git
Capability Registry读文件、搜索、编辑、Shell、Git、MCP、浏览器、测试、review agent终端 Agent 的 Shell 能力最强,IDE Agent 的编辑能力最贴近人,云端 Agent 的环境隔离和批量能力更强
Policy Engine & Human Control Planeread-before-edit、路径沙箱、命令 allowlist、网络限制、secret 保护、人工审批Claude Code 侧重 permission/hooks,Cursor 侧重 review/checkpoint,Codex 侧重 approval mode、sandbox 和 PR review
Agent Loop多轮“读代码 -> 推理 -> 改动 -> 运行验证 -> 修复”三类产品都有 loop,但 UI 和执行节奏不同:终端偏连续执行,IDE 偏交互接管,云端偏异步任务
Model Router & Handoff Manager根据任务选择模型、子 Agent、reviewer、后台任务或人工接管Cursor / Codex 更容易接入后台任务和 review agent,Claude Code 更偏终端内 subagent 与 hooks
Verifier & Eval Harness测试、lint、typecheck、build、CI、diff check、回归样本成熟 Coding Agent 的分水岭是能否把“完成”绑定到验证结果,而不是 final answer
Review Surface、Trace & Auditdiff、patch、PR、commit message、summary、tool trace、失败原因IDE review 最直观,终端 review 依赖 diff/summary,云端 review 依赖 PR、CI 和任务 trace
Learning Loop从失败任务、review comment、测试失败和用户反馈沉淀规则、Skill、Eval case大多数产品都有部分闭环,但“自动学习”通常要受 owner review 和 release gate 约束

这张表说明一个关键点:Coding Agent 的成熟度不取决于它会不会写代码,而取决于它能否把代码修改放进任务契约、上下文治理、权限裁决、验证门禁和审查表面里。第 19 章会把这些组件落成一个最小可运行版本。

17.2.3 Coding Agent 的实现分层

从产品实现看,Coding Agent 不是一个单独的聊天窗口,而是一组围绕模型建立的控制面。

User Surface
  │  CLI / IDE / Web / GitHub / Slack
  ▼
Task Envelope
  │  用户请求、issue、branch、cwd、权限、预算
  ▼
Context Control Plane
  │  规则、代码索引、检索片段、终端输出、Git 状态、Skill
  ▼
Model Reasoning Loop
  │  规划、选择工具、解释工具结果、修复失败
  ▼
Tool Execution Plane
  │  file / search / edit / shell / git / MCP / browser / CI
  ▼
Policy & Sandbox
  │  路径、命令、网络、secret、审批、租户隔离
  ▼
Verification Gate
  │  test / lint / typecheck / build / diff / review / eval
  ▼
Delivery Surface
     patch / PR / commit / review comment / report / trace

不同产品的差异,本质上是这些层的取舍不同。

层次关键问题设计判断
User Surface用户在哪里发起任务,在哪里接管结果CLI 适合闭环任务,IDE 适合共编,云端适合异步并行
Task Envelope每次任务的边界是什么cwd、branch、repo、模型、权限、预算、时区都要显式化
Context Control Plane模型每轮看到什么规则、证据、工具结果和历史状态要分层
Reasoning Loop模型如何推进任务action schema、max steps、repair loop、stop condition 缺一不可
Tool Execution Plane外部能力如何被调用schema、错误返回、超时、幂等和审计是基础能力
Policy & Sandbox哪些动作必须系统裁决写文件、Shell、网络、secret、Git 操作不能只靠模型自觉
Verification Gate完成由谁判定测试、diff、CI、review 比 final answer 更可信
Delivery Surface人如何理解结果diff、PR、trace、风险说明和回滚路径是交付的一部分

17.2.4 Claude Code:终端原生 Runtime

Claude Code 的核心选择是:把 Agent 放在终端里,而不是只放在 IDE 里。

这带来几个工程优势:

  • 终端天然连接真实工具链;
  • 可以执行测试、构建、脚本、Git 命令;
  • 不绑定特定 IDE;
  • 适合远程开发和自动化工作流;
  • 容易与 MCP、Hooks、Subagents、Skills 等机制组合。

从系统角度看,它更像一个终端原生 Agent Runtime:围绕当前工作目录启动,加载项目规则,读取文件和工具结果,通过 Bash、文件编辑、搜索、Git、MCP 等工具推进任务。

它的关键风险也来自终端:Shell 权限过强、secret 误读、危险 Git 操作、项目规则污染、外部工具信任边界不清。

17.2.5 Cursor:IDE 原生 Context Control Plane

Cursor 的核心选择是:把 Agent 放在开发者正在编辑代码的界面里。

它的优势在于:

  • 与当前文件、选区、打开 tab、诊断信息天然结合;
  • 适合局部修改和交互式重构;
  • 对前端、UI、组件级开发体验更顺;
  • diff review 和 checkpoint 更贴近人的编辑习惯。

从系统角度看,Cursor 的强项是 IDE 原生 Context Control Plane。它知道用户正在看什么、改什么、选择了什么,也能把 Project Rules、User Rules、代码索引和编辑器状态组合成上下文。

它的主要风险是上下文过度贴近当前焦点:用户正在看的文件不一定是任务的全部边界。IDE Agent 很容易做出“局部看起来合理、全局破坏约束”的修改。

17.2.6 Codex:云端任务型 Sandbox

Codex 的核心选择是:同时支持本地配对编程和云端任务委托。

本地形态里,Agent 在开发者工作区中读取仓库、编辑文件、运行命令。云端形态里,Agent 在隔离 sandbox 中接收任务,基于仓库和环境完成修改,生成 patch、PR 或可拉回本地继续工作的结果。

这种形态适合:

  • 修复明确 bug;
  • 实现小到中等规模功能;
  • 批量处理 issue;
  • 并行探索多个方案;
  • 把任务从“一个终端会话”提升到“任务队列和工程工作台”。

它的主要风险是环境复现、权限边界、私有依赖、云端数据治理和并行任务状态管理。

17.2.7 三类 Coding Agent 的架构对比

维度Claude CodeCursorCodex
核心界面终端IDECLI / IDE / App / Cloud
最强场景端到端任务、脚本、测试、Git交互式编辑、局部重构、前端开发并行 issue、PR 生成、后台任务
上下文来源文件系统、命令、项目规则、MCP、hooks编辑器、选区、代码索引、Rules、checkpoints仓库快照、任务描述、本地状态、worktree、sandbox 结果
执行环境本地或远程终端本地 IDE + 远程 background agent本地工作区 + 云端 sandbox
权限模型permissions、hooks、工具权限、MCP 权限模式、review、checkpoint、GitHub appapproval modes、sandbox、RBAC、仓库授权
审查表面终端总结、diff、hooks、subagent review文件级 diff review、selective acceptpatch、PR、app review、CI、review agent
风险重点Shell 和文件权限错误上下文、误编辑、远程 Agent 外传风险数据边界、环境复现、并行任务治理

成熟团队不一定只选择一种形态。更现实的组合是:

  • Cursor 负责高频交互式开发;
  • Claude Code 负责终端原生任务和本地自动化;
  • Codex 负责并行 issue 和云端 PR 任务;
  • 统一用 Spec、测试、代码审查和 CI 把它们约束到同一工程标准。

17.2.8 共同失败模式:上下文、工具、验证、权限与协作

不同产品形态不同,但失败模式高度相似。

失败模式表现应该在哪一层修
上下文误召回修改了相似但无关的文件Context Control Plane:改索引、规则、检索和引用
未读文件直接改生成 patch 覆盖现有逻辑Tool Policy:强制 read-before-edit
工具结果误解测试失败被当作通过Tool Result Envelope + Verifier
长任务偏航越做越偏,开始重构无关模块Task State:计划、预算、stop condition
Shell 权限过大执行危险命令或联网外传Sandbox + command allowlist + approval
Diff 过大大范围格式化或重写文件Patch Policy:diff size limit、路径范围、人工确认
解释和变更不一致summary 说改了 A,diff 实际改了 BReview Surface:自动 diff summary 校验
Prompt injectionREADME、issue、日志诱导 Agent 忽略规则Context Firewall:外部内容降级为 data
版本漂移换模型后老任务变差Eval Loop:固定回归集和 release gate
本地状态污染旧会话、旧缓存或旧规则影响新任务State Store:作用域、TTL、显式清理

这些失败模式说明:Coding Agent 的可靠性不是靠一个更强模型单独解决的,而是靠上下文、工具、策略、验证、隔离和审查共同收敛。

17.2.9 从产品取舍反推 Harness 设计原则

从成熟产品反推,可以得到几个通用原则。

第一,模型负责决策,Harness 负责边界。模型可以选择工具,但能否执行、如何执行、失败后如何恢复,必须由 Runtime 控制。

第二,上下文是产品能力,不是 prompt 拼接。IDE、终端、云端 sandbox 的差异,本质上是上下文来源和上下文控制方式的差异。

第三,工具是权限边界,不是函数列表。文件编辑、Shell、Git、网络、MCP、浏览器都必须有 schema、超时、审计和审批策略。

第四,完成必须可验证。没有测试、diff、CI、review 或 trace 支撑的“完成”,只是模型声明。

第五,长任务必须外置状态。计划、待办、工具结果、失败原因、修改文件和验证结果,不能只存在模型上下文里。

第六,并行必须隔离。多 Agent、多任务、云端并行和后台任务,都需要 branch、worktree、sandbox 或任务目录隔离。


17.3 真实工作流:Codex + MCP + 日志 + 代码仓库生成架构图

在深入 Claude Code 之前,先看一个真实工作流。Coding Agent 的价值不只是“改代码”,还可以把外部事实源和本地实现源串成一条可审查的工程分析链路。

一个典型场景是:

用户给出线上 trace id
  ↓
Codex 通过 MCP 查询日志和 trace
  ↓
从日志里提取服务、接口、错误、耗时和关键字段
  ↓
再搜索本地代码仓库
  ↓
把日志事实和代码结构对齐
  ↓
生成接口调用链、数据流程图或排查报告

这类任务非常适合观察成熟 Coding Agent 的系统边界:模型不直接访问生产系统,Runtime 执行工具,MCP 连接外部平台,日志平台返回事实,代码仓库提供实现结构,最终输出必须标注证据等级。

17.3.1 任务背景:为什么这个工作流适合观察 Coding Agent

这个工作流同时包含五种能力:

能力具体表现
外部工具通过 MCP 查询日志和 trace
本地上下文搜索和读取代码仓库
证据抽取从日志中提取时间线、服务名、错误码、span
推理合成把日志事实与代码调用关系对齐
可审查输出生成图、结论、不确定性和脱敏说明

它比“修一个 bug”更能暴露 Agent 的架构能力,因为它要求 Agent 区分事实、代码确认和推断。

17.3.2 端到端架构

flowchart LR
    User["用户\n自然语言排查目标"] --> App["Coding Agent UI\nCLI / IDE / Web"]
    App --> Runtime["Agent Runtime\n上下文组装 / 工具调度 / 权限控制"]
    Runtime --> Model["远端大模型\n理解 / 规划 / 总结"]
    Model --> Runtime

    Runtime --> MCPClient["MCP Client\n结构化 tool call"]
    MCPClient --> MCPServer["Log MCP Server\n本地进程"]
    MCPServer --> LogAPI["Log / Trace Platform\nOpenAPI / SSE"]
    LogAPI --> Store["日志、Trace、Span、Service Map"]
    Store --> LogAPI
    LogAPI --> MCPServer
    MCPServer --> MCPClient
    MCPClient --> Runtime

    Runtime --> Repo["本地代码仓库\nsearch / read / grep"]
    Repo --> Runtime
    Runtime --> Diagram["架构图 / 调用链 / 排查报告"]

各层职责要分清:

职责不是
大模型理解目标、规划步骤、选择工具、解释证据不是日志存储,也不直接访问生产系统
Agent Runtime组装上下文、校验工具调用、执行工具、维护 trace不是业务事实源
MCP Server把工具调用转换成日志平台 API 请求不负责判断业务含义
Log / Trace Platform返回日志、span、service map 等事实不理解本地代码实现
本地代码仓库提供 route、handler、processor、client、日志打印点不代表线上一定部署同一版本
绘图流程把分析结果转成可读图形不制造新事实

这条链路的本质是:

模型负责推理,Runtime 负责执行,MCP 负责连接,日志平台负责事实,代码仓库负责结构。

17.3.3 一次请求的生命周期

假设用户提出一个脱敏后的请求:

请用 live 日志工具查询 trace_id=<trace-id> 最近 20 分钟的日志,
并结合当前代码仓库画出订单查询接口的调用链。

Agent 不会直接知道答案,而是经历多轮循环:

第 1 轮:解析任务
  环境: live
  查询对象: trace_id
  时间范围: now - 20min 到 now
  输出目标: 日志摘要 + 调用链图

第 2 轮:调用 MCP 日志工具
  search_log_by_trace_id(trace_id, start_time, end_time)

第 3 轮:分析日志结果
  提取入口 API、服务名、错误级别、时间线、span 信息

第 4 轮:搜索代码仓库
  search_code("/api/order/query")
  search_code("OrderQueryHandler")
  search_code("CalculatePrice")

第 5 轮:读取关键文件
  route -> handler -> processor -> rpc client -> log statement

第 6 轮:合成图
  标注哪些节点来自日志,哪些边来自代码

第 7 轮:输出结论
  请求是否成功、异常是否影响主流程、剩余不确定性

这就是 Agent Loop 在真实排障中的样子:每一轮不是闲聊,而是围绕证据继续推进。

17.3.4 MCP 工具调用不是网络请求本身

模型生成的通常不是 HTTP 请求,而是结构化工具调用意图:

{
  "tool": "log_live.search_log_by_trace_id",
  "arguments": {
    "trace_id": "<redacted-trace-id>",
    "start_time": "2026-04-30T10:00:00+08:00",
    "end_time": "2026-04-30T10:20:00+08:00",
    "limit": 100
  }
}

真正执行链路是:

模型输出 tool call
  -> Runtime 校验工具名和参数
  -> MCP Client 找到对应 MCP Server
  -> 本地 MCP Server 请求远端日志平台
  -> 日志平台返回结果
  -> Runtime 把 tool result 放回下一轮模型上下文

这个边界非常重要。模型没有直接访问日志平台的能力,它只是提出“我需要调用哪个工具”。能不能执行、怎么执行、执行结果是什么,都由 Runtime 和工具系统决定。

17.3.5 Runtime 每一轮给模型什么

一次模型调用前,Runtime 会把当前任务打包成上下文:

context_package:
  instruction_layers:
    - system_contract
    - developer_policy
    - project_rules
  user_request:
    goal: "基于 trace id 还原调用链"
  environment:
    cwd: "/workspace/order-service"
    timezone: "Asia/Shanghai"
    approval_mode: "ask_for_network_and_shell"
  available_tools:
    - log_live.search_log_by_trace_id
    - search_code
    - read_file
    - render_mermaid
  selected_skill:
    name: "trace_to_architecture"
  evidence:
    logs: []
    code_snippets: []
  process_state:
    plan:
      - "查询日志"
      - "提取线索"
      - "搜索代码"
      - "生成图"

模型看不到全量代码仓库,也看不到全量日志平台数据。它只能基于 Runtime 放进上下文的材料推理;材料不够时,就要继续调用工具收集证据。

17.3.6 日志事实如何变成代码搜索线索

日志平台返回的通常是事实字段:

日志字段模型可提取的信息
timestamp请求时间线和相对顺序
application涉及服务列表
severityERROR / WARN / FATAL 过滤
message错误类型、业务语义、关键函数名
trace_id / span_id同一次请求关联
path / method入口接口
source file / line代码定位线索
status / error code请求是否失败

这些字段会被模型转换成代码搜索任务:

rg "/api/order/query"
rg "OrderQueryHandler"
rg "CalculatePrice"
rg "inventory availability"
rg "promotion eligibility"

日志告诉我们“线上发生了什么”,代码告诉我们“为什么会这么走”。两者必须对齐,才能形成可靠结论。

17.3.7 证据等级:哪些能写进图里

从日志到架构图,最容易犯的错误是把推断画成事实。建议把证据分成三档:

证据等级来源图中表达
强证据日志包含 source file / line,代码中能找到同一日志打印点“日志确认”
中证据日志 message 与代码中的 log format 匹配“代码匹配”
弱证据服务名、方法名、业务名相似,但没有直接日志点“推断路径”

架构图最好显式区分:

实线:日志和代码都确认
虚线:代码推断,日志未直接覆盖
红色标注:日志中出现的 ERROR / WARN
灰色节点:可能的异步或外部依赖

这样图不是“看起来完整”,而是“知道哪里有证据,哪里只是推断”。

17.3.8 脱敏后的示例图

下面是一个公开可用的脱敏示例:

flowchart TD
    Client["Client"] --> API["order-api\nPOST /api/order/query"]
    API --> Handler["OrderQueryHandler\nbind / validate / enrich context"]
    Handler --> OrderSvc["order-service\nQueryOrder"]
    OrderSvc --> Inventory["inventory-service\ncheck availability"]
    OrderSvc --> Pricing["pricing-service\ncalculate price"]
    Pricing --> Promotion["promotion-service\napply campaign"]
    Promotion --> User["user-service\nuser segment"]
    Inventory --> OrderSvc
    Pricing --> OrderSvc
    OrderSvc --> API
    API --> Client

    Promotion -.-> Note1["WARN: eligibility not matched<br/>日志确认"]
    Inventory -.-> Note2["推断依赖<br/>代码确认,日志未覆盖"]

这个图的价值不在于节点多,而在于它能说明:

  • 入口接口来自日志 path 和 route 代码;
  • order-service 来自 trace application 和 handler 调用;
  • pricing-service 来自代码中的 client 调用;
  • promotion-service 的 WARN 来自日志;
  • inventory-service 只在代码里确认,当前 trace 未必覆盖。

17.3.9 公开发布时必须脱敏

如果把这类案例写进公开文章,必须做脱敏。

类型不要公开推荐替换
公司和组织真实公司名、团队名、仓库名ExampleCorpdemo-repo
内网域名真实日志平台域名、内部 API 域名log.example.internal
Token 和配置API key、cookie、secret、内部代理配置<redacted>
Trace 信息真实 trace id、span id、request id<trace-id>
服务名真实应用名、CMDB 名order-apipricing-service
接口路径真实业务 path/api/order/query
代码路径真实仓库目录和文件名api/router.goservice/handler.go
日志内容真实用户、订单、价格、商户、权益信息摘要化错误类型
图产物内部文件路径docs/diagrams/example-trace-flow.svg

脱敏不是简单替换几个字符串,而是要避免通过组合信息反推出业务、组织和系统结构。

17.3.10 最佳实践 Prompt

用户可以这样向 Coding Agent 提需求:

请基于 trace_id=<trace-id> 查询最近 20 分钟日志,
并结合当前代码仓库还原调用链。

要求:
1. 先按时间线列出日志事实;
2. 再用代码搜索定位 route、handler、processor、client;
3. 区分“日志确认”“代码确认”“模型推断”;
4. 生成 Mermaid 调用链图;
5. 输出剩余不确定性;
6. 不输出任何 token、内部域名、真实用户数据。

这类 prompt 的关键不是“画个图”,而是要求 Agent 保持证据边界。

17.3.11 常见失败点

现象可能原因修复方式
日志为空时间窗口错、环境错、trace id 错、权限不足明确时区,扩大窗口,检查 live / test 环境
图很完整但不可信模型用常识补全太多要求标注证据等级
ERROR 被误判成请求失败业务诊断日志也可能用 ERROR 打印同时检查 status、error code、最终响应
代码搜索不到关键词来自日志但代码命名不同改搜 path、日志 message、RPC method
调用链缺边trace 只覆盖同步路径,异步链路缺失标注为未确认异步路径
暴露敏感信息原样贴日志或配置输出前做字段级脱敏

17.3.12 对 Coding Agent 设计的启示

这个案例说明,一个成熟 Coding Agent 不只是代码编辑器里的自动补丁生成器。它还可以成为工程分析工作台:

外部事实源  -> MCP / API / Browser / DB
本地实现源  -> Code Search / File Read / AST / LSP
推理与表达  -> Model
执行与边界  -> Runtime / Policy / Sandbox
证据沉淀    -> Trace / Report / Diagram

当 Agent 能同时连接“线上事实”和“代码实现”,它就可以完成传统 IDE 很难完成的任务:从一次真实请求出发,还原系统行为,并生成可以 review 的架构解释。


17.4 Claude Code 深度解析:终端原生 Coding Agent Harness

Claude Code 是理解 Coding Agent Harness 的好样本。它不是把模型塞进一个聊天窗口,而是把模型放进终端、文件系统、代码仓库、工具链和权限系统组成的工作环境。

本节不会把 Claude Code 当成产品说明书来讲,而是从 Harness 工程角度拆解它代表的核心机制。

17.4.1 Claude Code 的产品定位:不是 IDE 插件,而是终端 Runtime

Claude Code 的核心定位是终端原生 Runtime。

这意味着它的默认工作场景不是“补全当前文件”,而是:

在一个真实代码仓库中,
围绕一个任务,
读取上下文,
调用工具,
修改文件,
运行命令,
分析失败,
输出可审查结果。

终端原生带来两个特点。

第一,它贴近真实工程工具链。测试、构建、包管理、Git、脚本、日志工具、MCP server,本来就通过终端工作。把 Agent 放在终端里,可以让模型参与真实开发流程,而不是只能生成片段。

第二,它必须面对真实权限风险。终端可以删除文件、联网、提交代码、读取配置、运行危险脚本。终端 Agent 的设计难点不是“能不能执行命令”,而是“如何让命令执行可裁决、可审计、可恢复”。

17.4.2 Claude Code 的核心架构:Model + Harness

可以把 Claude Code 抽象为:

Claude Code
  = Model
  + Agent Loop
  + Tool Registry
  + Context Loader
  + Task State
  + Permission Engine
  + Verification Surface
  + Session / Trace

其中 Model 提供理解和决策能力,Harness 提供行动空间。

Model:
  - 理解需求
  - 制定计划
  - 选择工具
  - 解释工具结果
  - 生成修复策略

Harness:
  - 暴露文件、搜索、编辑、Shell、Git、MCP 等工具
  - 加载项目规则和任务上下文
  - 维护任务状态和会话状态
  - 执行权限裁决
  - 运行测试和构建
  - 输出 diff、trace 和总结

这个边界很关键。不要试图用代码写死“Agent 应该如何思考”;Harness 的职责是让模型能看见正确材料、调用正确工具、被正确约束、接受正确验证。

17.4.3 Agent Loop:Coding Agent 的最小心跳

所有 Coding Agent 的内核都可以简化为一个循环:

messages
  ↓
LLM
  ↓
response
  ↓
stop_reason == tool_use ?
  ├─ yes: execute tool -> append tool_result -> loop
  └─ no: return final answer

伪代码如下:

def agent_loop(messages, tools):
    while True:
        response = model.generate(messages=messages, tools=tools)
        messages.append(response.as_assistant_message())

        if response.stop_reason != "tool_use":
            return response.final_text

        tool_results = []
        for call in response.tool_calls:
            result = tool_runtime.execute(call)
            tool_results.append(result.as_tool_result())

        messages.append({
            "role": "user",
            "content": tool_results,
        })

这个循环看起来简单,但它定义了 Agent 的基本生命形式:

  • 模型观察当前上下文;
  • 模型决定下一步行动;
  • Runtime 执行工具;
  • 工具结果成为下一轮观察;
  • 循环直到模型停止或 Runtime 终止。

真正复杂的不是 loop 本身,而是 loop 周围的 Harness。

周边机制解决什么问题
Tool Registry模型能调用什么
Permission Engine哪些调用允许执行
Context Builder每轮模型看到什么
Task State长任务如何不偏航
Verifier什么时候算完成
Trace Store为什么这么做可复盘
Budget Control防止无限循环和成本失控

Agent Loop 的设计原则是:循环保持简单,控制面保持强。

如果把太多业务规则写进 loop,系统会变得难以扩展;如果 loop 周围没有控制面,Agent 就会变成一个能执行任意命令的聊天模型。

17.4.4 Tool Execution Plane:给模型一组受控的手

Coding Agent 的工具不是越多越好,而是要原子化、可组合、可描述、可裁决。

一个终端原生 Coding Agent 至少需要这些工具:

工具用途风险
list_files了解仓库结构输出过大
search_code找符号、错误、调用链误召回相似代码
read_file阅读相关文件读取 secret 或无关文件
edit_file局部修改代码覆盖用户改动
run_shell测试、构建、脚本危险命令、联网、长时间阻塞
git_diff查看变更diff 太大或误读
git_status识别工作区状态忽略用户未提交改动
mcp_tool连接外部系统权限、数据泄露、工具结果污染

工具注册可以抽象为 dispatch map:

TOOL_HANDLERS = {
    "read_file": read_file,
    "search_code": search_code,
    "edit_file": edit_file,
    "run_shell": run_shell,
}

def execute_tool(call):
    handler = TOOL_HANDLERS[call.name]
    return handler(**call.arguments)

但生产系统不能只停在 dispatch map。每个工具都需要 schema、权限、超时、错误封装和审计。

tool:
  name: run_shell
  description: "Run a command in the current workspace"
  parameters:
    command:
      type: string
    timeout_seconds:
      type: integer
      maximum: 120
  policy:
    allowed_commands:
      - npm
      - pytest
      - make
      - go
    denied_tokens:
      - rm
      - sudo
      - curl
      - ssh
      - chmod
  audit:
    record_stdout: true
    redact_secrets: true

工具调用执行链应该是:

model proposes tool call
  ↓
schema validation
  ↓
policy decision
  ├─ deny -> return rejection as observation
  ├─ ask  -> wait for human approval
  └─ allow
      ↓
sandbox execution
      ↓
tool result envelope
      ↓
trace + next context

工具结果也应该标准化,而不是把 stdout 原样丢回模型:

{
  "tool": "run_shell",
  "ok": false,
  "exit_code": 1,
  "stdout": "...",
  "stderr": "...",
  "truncated": true,
  "duration_ms": 12403,
  "retryable": true,
  "risk": "low"
}

这样模型下一轮才能判断是继续修复、换工具、请求人工,还是停止。

17.4.5 Task State:让多步任务不偏航

模型可以临场规划,但长任务不能只靠模型上下文里的自然语言计划。

Coding Agent 需要显式 Task State:

task_state:
  task_id: "fix-order-cancel-idempotency"
  goal: "修复订单取消重复调用导致库存重复释放"
  todos:
    - id: "t1"
      content: "阅读订单取消逻辑"
      status: "completed"
    - id: "t2"
      content: "定位库存释放调用"
      status: "completed"
    - id: "t3"
      content: "增加幂等保护"
      status: "in_progress"
    - id: "t4"
      content: "补充重复取消测试"
      status: "pending"
    - id: "t5"
      content: "运行订单相关测试"
      status: "pending"
  changed_files:
    - "service/order_cancel.go"
  blockers: []

Task State 的价值有三点。

第一,让目标持久化。上下文压缩、子任务切换、工具输出很长时,模型容易忘记原始目标。Task State 是任务锚点。

第二,让进度可观察。人可以看到 Agent 当前在做什么,是否偏离目标。

第三,让 Runtime 能约束行为。例如同一时间只允许一个 in_progress,任务完成前必须有验证步骤,长时间没有更新计划时提醒模型修正。

一个好的 Task State 不应该保存模型的全部推理,而应该保存可执行状态:

不该长期保存应该保存
模型临时猜测当前目标
未验证根因已确认事实
大段思考过程当前步骤
无来源摘要工具结果引用
模糊计划可检查 todo

这也解释了 Task State 和 Scratchpad 的区别:

Scratchpad:
  模型临时思考空间,可信度低,通常不长期保存

Task State:
  Runtime 维护的任务状态,影响后续行动和恢复

17.4.6 Context Control Plane:让模型看到该看的内容

模型无法天然“读懂仓库”。所谓读懂,实际上是 Runtime 不断替模型选择上下文。

终端原生 Coding Agent 的上下文通常来自七类来源:

来源示例风险
项目规则AGENTS.mdCLAUDE.md、团队规范规则过期、互相冲突
代码索引文件树、符号、引用、测试名索引滞后、召回错误
活动上下文当前目录、Git 状态、最近命令焦点不等于任务边界
工具结果search、read、test、lint、MCP 返回工具错误被当事实
任务状态plan、todos、changed files、blockers状态不更新导致误导
历史摘要previous steps、trace、memory摘要污染
Skill / Workflowbugfix、test-writing、trace-to-architecture误触发、规则过泛

成熟 Context Control Plane 至少做五件事。

第一,分层注入。系统指令、项目规则、用户请求、工具结果、任务状态和历史摘要不能混成一段文本。它们的可信度、优先级和生命周期不同。

第二,按需检索。大仓库不能一次性塞进上下文。通常先给 repo map,再让模型通过 search / read 逐步取证。

第三,上下文预算管理。工具结果、测试输出、diff 和日志都可能很长。Runtime 要截断、摘要、去重,并保留来源和时间。

第四,污染控制。README、issue、外部网页、日志都可能包含指令式文本。它们应该作为 data,而不是 instruction。

第五,压缩与恢复。长任务上下文总会满。压缩不是把聊天记录缩短,而是把任务重构成稳定状态。

一个更可靠的压缩结果应该像这样:

compact_summary:
  original_goal: "修复订单取消重复释放库存"
  confirmed_facts:
    - "重复取消会再次调用 release_inventory"
    - "订单状态 canceled 没有提前返回"
  changed_files:
    - "service/order_cancel.go"
    - "service/order_cancel_test.go"
  current_todos:
    - "运行订单相关测试"
    - "确认库存释放只调用一次"
  open_risks:
    - "未检查并发重复取消"
  forbidden:
    - "不要重构整个订单状态机"

这比“我们已经修了一些代码,还需要跑测试”可靠得多。

17.4.7 Skill / Command / Workflow:把工程经验变成可复用流程

Skill 是介于“规则文件”和“工具调用”之间的一层能力抽象。

Tool:
  Agent 能调用什么能力

Skill:
  遇到某一类工程任务,应该按什么可靠流程完成

例如,修 bug 的稳定流程不是“直接改代码”,而是:

先复现或读取失败证据
  ↓
搜索错误信息和调用链
  ↓
阅读最小相关文件
  ↓
形成根因假设
  ↓
做最小修改
  ↓
补回归测试
  ↓
运行验证
  ↓
输出 diff 和剩余风险

这个流程就适合沉淀成 Skill:

# Bugfix Skill

## Trigger
当用户要求修复缺陷、失败测试、异常日志或线上报错时使用。

## Procedure
1. 先复现或读取失败证据,不要直接修改代码;
2. 搜索错误信息、函数名、测试名和相关调用链;
3. 阅读最小相关文件,避免一次性加载整个仓库;
4. 做最小修改,优先保持现有接口和行为;
5. 新增或更新回归测试;
6. 运行最小验证命令;
7. 输出 diff、验证结果和剩余风险。

## Stop Conditions
- 无法复现;
- 缺少权限;
- 验证命令持续失败且原因不明;
- 修改范围超过原始任务边界。

Skill 的关键是“按需加载”。不要把所有 Skill 都塞进 system prompt。成熟 Runtime 应该:

  1. 发现可用 Skill;
  2. 根据任务选择少量相关 Skill;
  3. 把 Skill 的触发条件、步骤、验证要求注入当前上下文;
  4. 记录本次任务加载了哪个 Skill、哪个版本、是否有效;
  5. 任务失败后决定是否修改 Skill 或新增 eval case。

这让工程经验从“人脑经验”变成“可版本化、可审查、可评估的上下文资产”。

17.4.8 Verification Gate:完成不是模型说了算

Coding Agent 最危险的幻觉,不是编造事实,而是“没有完成却宣布完成”。

成熟系统要把完成判定拆成多层:

层级检查内容失败时怎么办
格式层final schema 是否完整要求模型修复输出
变更层diff 是否存在、是否超范围阻止提交或请求人工确认
语法层format、lint、typecheck把错误回填给模型
行为层unit / integration / regression tests进入 repair loop
风险层secret scan、权限、依赖、迁移影响阻止自动完成
人审层review summary、PR comment、owner approval交给 reviewer

Verification Gate 的核心原则是:

done criteria > model final answer

也就是说,模型说“我完成了”只是一个候选结论。真正的完成必须由测试、构建、diff、CI、审查或用户验收支撑。

验证结果也应该进入下一轮上下文:

{
  "verification": {
    "command": "go test ./service -run TestCancelOrder",
    "status": "failed",
    "exit_code": 1,
    "summary": "TestCancelOrder_Idempotent failed: inventory released twice",
    "retry_budget_remaining": 2
  }
}

Agent 看到这个结果后,不应该解释失败为成功,而应该进入 repair loop。

17.4.9 Async、Subagent 与 Multi-Agent 协作

终端任务中有很多慢操作:

  • 安装依赖;
  • 跑完整测试;
  • 构建前端产物;
  • 查远端日志;
  • 运行大规模搜索;
  • 等待 CI。

如果主 Agent 被这些操作阻塞,它就无法继续规划。更好的方式是把慢操作变成 background task:

main agent:
  start background test
  continue reading related files
  receive notification when test finishes

后台任务需要三个机制:

  1. 任务句柄:Agent 能知道哪个后台任务还在跑;
  2. 通知队列:任务完成后把结果注入上下文;
  3. 超时和取消:防止长命令无限运行。

Subagent 则解决另一个问题:上下文隔离。

大任务可以拆给专门角色:

Subagent适合职责权限
Explorer阅读代码、找相关文件、总结调用链read / search
Debugger复现失败、定位根因read / search / shell
Test Runner运行测试、分析失败输出shell limited
Reviewer检查 diff 风险、遗漏测试、安全问题read / diff
Doc Writer更新文档和说明read / edit docs

Subagent 的价值不是“多开几个模型更强”,而是:

  • 每个子任务有干净上下文;
  • 每个角色有更窄权限;
  • 主 Agent 不被探索过程污染;
  • 多个独立方向可以并行推进。

多 Agent 协作进一步需要协议。最小协议至少包括:

message:
  from: "main"
  to: "reviewer"
  task_id: "review-diff-001"
  request: "检查当前 diff 是否遗漏测试或破坏接口"
  expected_output:
    - findings
    - severity
    - suggested_fix
  deadline: "10m"

没有协议的多 Agent,很快会变成多个聊天窗口互相制造噪声。

17.4.10 Worktree Isolation:并行执行的隔离层

当 Agent 支持并行任务时,只靠“请小心不要互相覆盖”是不够的。并行需要文件系统级隔离。

Git worktree 是 Coding Agent 很自然的隔离手段:

main repo
  ├─ task-101 worktree: fix-login-bug
  ├─ task-102 worktree: refactor-payment-client
  └─ task-103 worktree: add-order-tests

Worktree Isolation 解决四个问题:

  1. 文件修改隔离:不同任务不会在同一目录互相覆盖;
  2. 依赖状态隔离:构建产物、临时文件、测试状态不混在一起;
  3. Git diff 清晰:每个任务有独立 diff;
  4. 失败可丢弃:某个任务失败,可以直接删除对应 worktree。

Task 和 worktree 应该绑定:

task:
  id: "task-102"
  branch: "agent/task-102-refactor-payment-client"
  worktree: "/workspace/.worktrees/task-102"
  status: "in_progress"
  owner: "worker-agent-2"

设计原则是:

Task 管目标,worktree 管目录。

任务系统负责分配、依赖和状态;worktree 负责文件系统隔离。把两者混在一起,会导致任务状态和目录状态互相污染。

17.4.11 Permission 与安全边界

终端 Agent 的权限模型必须比普通聊天产品严格得多。

至少要区分四类权限:

权限示例风险
Read读代码、读文档、读 Git 状态secret 泄露、越权读取
Write修改文件、创建文件覆盖用户改动、误改生成文件
Execute运行测试、构建、脚本危险命令、长时间阻塞
Network / ExternalMCP、浏览器、API、数据库数据外传、权限扩大

权限裁决不应该只依赖 prompt。Runtime 应该有明确策略:

permission_policy:
  read:
    allowed_paths:
      - "src/**"
      - "tests/**"
      - "docs/**"
    denied_paths:
      - ".env"
      - "secrets/**"
  write:
    allowed_paths:
      - "src/**"
      - "tests/**"
      - "docs/**"
    require_approval:
      - "package-lock.json"
      - "migrations/**"
  shell:
    allowlist:
      - "npm test"
      - "npm run build"
      - "go test ./..."
    require_approval:
      - "git push"
      - "npm install"
    deny:
      - "rm -rf"
      - "sudo"
      - "curl | sh"

权限系统的目标不是让 Agent 什么都不能做,而是让风险动作从“模型自觉”变成“系统裁决”。

17.4.12 Claude Code 的优势、局限与适用场景

Claude Code 的优势很明确:

  • 适合真实仓库中的端到端任务;
  • 贴近测试、构建、脚本和 Git;
  • 容易把团队流程沉淀成命令、规则、Skill 和 Hook;
  • 适合后端、基础设施、CLI、工具链和跨文件修改;
  • 能和 MCP 等外部工具结合,形成工程分析工作流。

它的局限也很明确:

  • 终端权限风险高;
  • 对项目规则和上下文质量敏感;
  • 长任务需要压缩、状态和验证机制支撑;
  • 不如 IDE Agent 贴近用户当前选区和可视化编辑体验;
  • 多 Agent 和并行任务必须有隔离,否则容易污染工作区。

适合使用 Claude Code 的任务:

  • 修复明确 bug;
  • 补测试;
  • 跨文件重构;
  • 运行和分析测试失败;
  • 生成脚本和工具;
  • 根据日志、trace、代码生成排查报告;
  • 自动化重复性工程流程。

不适合完全交给它自动执行的任务:

  • 高风险生产变更;
  • 无明确验收标准的大型重构;
  • 涉及敏感数据或凭据的操作;
  • 需要大量产品判断或组织协调的任务;
  • 测试环境无法复现的业务变更。

17.4.13 从 Claude Code 反推 Coding Agent Harness 设计原则

从 Claude Code 这类终端原生 Agent 可以反推出一组通用设计原则。

第一,相信模型的推理能力,但不要相信模型能自我约束所有风险。让模型决策,让系统裁决。

第二,工具要小而清楚。新增工具时,最好只是新增 handler,不要改 Agent Loop。

第三,计划要外置。没有计划的 Agent 会走哪算哪;计划外置后,Runtime 才能提醒、恢复和审查。

第四,知识按需加载。用到什么 Skill、规则、文档,就加载什么;不要把所有知识塞进 system prompt。

第五,上下文总会满。必须有 compact、summary、task state 和 trace 引用,而不是无限追加聊天记录。

第六,慢操作异步化。测试、构建、日志查询应该能后台运行,结果通过通知回到 Agent Loop。

第七,多 Agent 需要协议。没有消息协议、任务边界和权限边界的多 Agent,只会放大混乱。

第八,并行执行必须隔离目录。worktree、branch、sandbox 是并行 Coding Agent 的基础设施。

第九,验证是交付的一部分。没有验证结果的代码生成,只能算候选 patch。

第十,trace 是系统资产。失败任务、工具调用、权限裁决、测试结果和人类反馈都应该能进入复盘和 eval。


17.5 从 MVP 到生产级 Coding Agent

如果要从零实现 Coding Agent,不要一开始就追求“全自动程序员”。更稳妥的路线是按风险递增。

17.5.1 MVP 1:Read-only Agent

第一阶段只允许读取和搜索,不允许修改。

开放工具:

  • list_files
  • read_file
  • search_code
  • git_status
  • git_diff

目标是让 Agent 能回答:

  • 这个需求可能涉及哪些文件;
  • 当前代码是怎么工作的;
  • 应该怎么改;
  • 需要哪些测试。

Read-only Agent 是最安全的第一步,适合接入真实大仓库。

17.5.2 MVP 2:Patch Agent

第二阶段开放局部编辑,但不开放任意 shell。

开放工具:

  • replace_in_file
  • create_file
  • format_patch

重点能力:

  • path sandbox;
  • read-before-edit;
  • old text 精确匹配;
  • diff 输出;
  • 人工确认。

这一阶段的目标不是自动完成,而是生成小范围 patch 供人审查。

17.5.3 MVP 3:Verified Agent

第三阶段开放测试类 Shell 命令,让 Agent 形成“修改 -> 测试 -> 修复”的闭环。

新增能力:

  • command allowlist;
  • timeout;
  • stdout / stderr 截断;
  • 失败摘要;
  • retry budget。

典型流程:

edit file
  ↓
run targeted test
  ↓
observe failure
  ↓
repair
  ↓
run test again
  ↓
summarize diff and verification

这一阶段必须明确:验证失败时,Agent 不能假装完成。

17.5.4 MVP 4:Workflow Agent

第四阶段加入计划、任务状态和多步骤工作流。

目标是支持更长的任务:

  • 重构一个模块;
  • 迁移一个 API;
  • 增加一组测试;
  • 修复一类 lint 问题;
  • 根据日志定位线上问题。

需要补齐:

  • todo state;
  • step status;
  • stop condition;
  • 中途汇报;
  • 任务暂停和恢复;
  • 变更范围控制。

17.5.5 MVP 5:Skill-enabled Agent

第五阶段加入 Skill Registry,让 Agent 复用团队工程经验。

适合沉淀为 Skill 的流程:

Skill触发场景核心约束
bugfix失败测试、异常日志、用户报 bug先复现,后修改,必须补回归测试
test-writing补单测、提升覆盖率先读现有测试风格,覆盖失败路径
refactor模块整理、接口迁移保持行为等价,小步验证
dependency-upgrade升级库、框架、运行时查破坏性变更,跑兼容测试
trace-to-architecture根据 trace / log 还原调用链区分日志事实、代码确认、模型推断
release-check发布前检查只读检查优先,高风险动作审批

这一阶段要重点做 Skill 的触发条件、版本管理、加载 trace 和 regression eval。

17.5.6 MVP 6:Team Agent

第六阶段加入 subagent、background task、worktree、reviewer 和 CI 集成。

目标是让 Agent 进入团队工程流程,而不是只服务个人本地实验。

需要补齐:

  • explorer agent;
  • test runner agent;
  • reviewer agent;
  • task queue;
  • worktree isolation;
  • PR bot;
  • 失败样本库;
  • 权限审计。

Team Agent 的关键不是“多几个模型”,而是任务边界、通信协议、工作区隔离和质量门禁。

17.5.7 从原型到生产系统还缺什么

MVP 能跑,不代表可以生产使用。生产级 Coding Agent 还需要:

能力为什么重要
RBAC不同用户、仓库、环境权限不同
Secret Boundary凭据不能进入 prompt、trace 或 diff
Audit Log能解释谁让 Agent 做了什么
Eval Dataset防止模型、prompt、Skill 升级造成回归
CI Integration验证不只靠本地命令
Rollback失败任务能恢复工作区
Cost Control限制步数、token、工具调用和云端资源
Data Retention会话、日志、产物要有保留和删除策略
Human Approval高风险动作必须人审

生产化的核心不是堆更多工具,而是让 Agent 的每一次行动都在可控边界内发生。


17.6 设计清单与常见反模式

这一节把本章收束成设计清单。你可以用它评估一个 Coding Agent 系统,也可以用它准备系统设计评审。

17.6.1 Coding Agent Harness 设计清单

任务入口

  • 是否支持从自然语言、issue、PR comment、告警、trace 等入口创建任务;
  • 是否显式记录 cwd、repo、branch、用户、权限、预算;
  • 是否区分探索任务和执行任务;
  • 是否有清晰的 done criteria。

上下文

  • 是否加载项目规则;
  • 是否有 repo map 或代码索引;
  • 是否让模型按需 search / read;
  • 是否避免把全仓库塞进 prompt;
  • 是否区分 instruction、data、tool result、memory;
  • 是否有上下文压缩和状态恢复。

工具

  • 是否只暴露注册过的工具;
  • 每个工具是否有 schema;
  • 是否有路径沙箱;
  • 是否优先局部替换而不是整文件重写;
  • Shell 是否有 allowlist、timeout 和审批;
  • 工具失败是否被结构化返回给模型。

状态

  • 是否有显式 Task State;
  • 是否记录当前步骤、已完成步骤、阻塞点;
  • 是否区分 task state、scratchpad、memory;
  • 是否能暂停和恢复;
  • 是否能处理用户中途修改需求。

权限

  • 是否区分 read、write、shell、network;
  • 是否禁止读取 secret;
  • 是否禁止 repo 外写入;
  • 是否对 Git push、发布、迁移等高风险动作要求审批;
  • 是否记录权限裁决。

验证

  • 是否有标准验证命令;
  • 是否捕获 stdout / stderr;
  • 是否处理超时和 flaky test;
  • final answer 是否包含验证证据;
  • 验证失败时是否返回失败而不是假装成功。

隔离

  • 并行任务是否使用 branch、worktree 或 sandbox;
  • 后台任务是否有句柄、通知、超时和取消;
  • subagent 是否有独立上下文和权限;
  • 云端任务是否隔离依赖和环境变量。

交付

  • 是否输出 diff;
  • 是否解释修改动机;
  • 是否列出验证结果;
  • 是否列出剩余风险;
  • 是否能生成 PR、review comment 或报告。

改进闭环

  • 是否记录 trace;
  • 是否把失败任务沉淀为 eval;
  • 是否把重复流程沉淀为 Skill;
  • 是否有 prompt、Skill、Tool、Policy 的版本管理;
  • 是否能回滚配置变更。

17.6.2 常见反模式:Prompt 堆叠、无验证、无隔离、无状态

反模式一:把所有规则塞进 system prompt

表现:

  • system prompt 越来越长;
  • 规则互相冲突;
  • 模型忽略后半段;
  • 无法知道哪条规则生效。

修复方式:

稳定规则 -> 项目规则 / policy
任务流程 -> Skill
权限边界 -> Runtime
输出格式 -> Schema
失败样本 -> Eval

反模式二:让模型自己判断是否完成

表现:

  • 测试没跑却说完成;
  • 测试失败但 summary 写“已通过”;
  • diff 和解释不一致。

修复方式:

  • 引入 Verification Gate;
  • final answer 必须引用验证结果;
  • 没有验证时明确标注“未验证”;
  • 高风险任务必须人审。

反模式三:Shell 权限过大

表现:

  • 模型执行危险命令;
  • 联网下载未知脚本;
  • 修改 repo 外路径;
  • 读取 secret 文件。

修复方式:

  • command allowlist;
  • path sandbox;
  • network approval;
  • secret scan;
  • shell output trace。

反模式四:没有 Task State

表现:

  • 长任务中途偏航;
  • 重复做同一步;
  • 忘记用户约束;
  • 上下文压缩后丢失目标。

修复方式:

  • 显式 todo;
  • 每步状态;
  • 当前目标和禁止事项;
  • compact 后重建状态;
  • Runtime 对长时间无计划更新进行提醒。

反模式五:并行任务共享同一工作区

表现:

  • 两个 Agent 改同一个文件;
  • 测试产物互相污染;
  • diff 混在一起;
  • 一个任务失败影响另一个任务。

修复方式:

  • branch / worktree / sandbox 隔离;
  • task id 绑定工作目录;
  • 每个任务独立验证;
  • 合并前统一 review。

17.6.3 设计评审表达:如何讲清一个 Coding Agent 系统

如果评审者问“你如何设计一个 Coding Agent”,不要只回答“接入 LLM 和工具调用”。可以这样表达:

我会把 Coding Agent 设计成 Model + Harness。

Model 负责理解任务、规划步骤、选择工具和解释结果;
Harness 负责上下文、工具、权限、状态、验证、隔离和审计。

系统入口可以是自然语言、issue 或 PR comment。
任务进入后先形成 Task Envelope,包括 repo、branch、cwd、权限、预算和验收标准。
Context Builder 根据项目规则、repo map、代码搜索、文件读取、工具结果和 Skill 构建上下文。
Agent Loop 让模型在每一轮选择工具行动,Runtime 对工具调用做 schema 校验、权限裁决、sandbox 执行和 trace 记录。
长任务用 Task State 管理进度,慢操作用 background task,复杂任务用 subagent 隔离上下文,并行任务用 worktree 或 sandbox 隔离工作区。
完成不能由模型自我声明,必须经过 test、lint、typecheck、build、diff review 或 CI 验证。
所有失败都进入 trace 和 eval,重复流程沉淀为 Skill。

这个回答的重点是:你不是在描述一个聊天机器人,而是在描述一个可治理的软件工程执行环境。


本章小结

AI Coding Agent 的成熟,不是因为模型能写更多代码,而是因为系统开始围绕模型建立工程闭环。

本章的关键结论是:

  1. Vibe Coding 适合探索,Spec Coding 适合交付;
  2. Coding Agent 的核心不是“LLM + 工具”,而是 Model + Harness;
  3. Claude Code、Cursor、Codex 的差异,本质上是 CLI、IDE、云端 sandbox 在上下文、工具、权限和交付面上的取舍;
  4. 真实工作流里,Agent 可以连接外部事实源和本地实现源,但必须保留证据等级;
  5. 终端原生 Coding Agent 的核心机制包括 Agent Loop、Tool Plane、Task State、Context Control、Skill Loading、Verification Gate、Subagent、Background Task 和 Worktree Isolation;
  6. 完成不是模型说了算,必须由验证、diff、CI、review 或用户验收支撑;
  7. 生产级 Coding Agent 要解决权限、隔离、状态、审计、eval、成本和数据治理;
  8. 重复的工程经验应该沉淀为 Skill,失败的任务应该沉淀为 eval。

最重要的变化是:

AI 编程的核心能力,正在从“亲手写代码”转向“定义任务、组织上下文、约束执行、审查结果”。

如果你要从零实现原型,不要先追求“全自动程序员”。先实现一个能读文件、搜代码、局部修改、运行测试、输出 diff、保留 trace 的最小 Agent。这个原型足够小,却已经包含了 Coding Agent 的本质。


参考资料

  1. Claude Code Documentation - Anthropic Docs
  2. Claude Code Subagents - Anthropic Docs
  3. Claude Code Hooks - Anthropic Docs
  4. Claude Code Memory - Anthropic Docs
  5. Claude Code Slash Commands - Anthropic Docs
  6. Claude Code Settings - Anthropic Docs
  7. Claude Code MCP - Anthropic Docs
  8. Cursor Rules - Cursor Docs
  9. Cursor Agent Modes - Cursor Docs
  10. Cursor Diffs & Review - Cursor Docs
  11. Cursor Background Agents - Cursor Docs
  12. OpenAI Codex CLI Getting Started - OpenAI Help Center
  13. Using Codex with your ChatGPT plan - OpenAI Help Center
  14. shareAI-lab/learn-claude-code - GitHub