第 22 章 · 通往大模型

用好大模型:Context、Harness 与 Agent

绝大多数人既不训练也不部署大模型,而是直接使用别人训练好的那个。 这一章把“用”这件事讲透:从 prompt engineeringcontext engineering, 再到 harness engineering。你会看到:提示词、RAG、工具调用、memory、MCP、Agent 并不是一堆散乱热词,而是在一步步给模型接上上下文、工具、状态、验证和工程护栏。

路线图 · 你在这一段的哪一站

上一站(第 21 章)讲了工程与基建;本站讲你不训练、也不部署,只使用它时的系统方法——Prompt / Context / Harness / Agent。这也是这条主线的终点

读完这一章,你会明白

  • 为什么“用好模型”的重心正在从 prompt engineering → context engineering → harness engineering 迁移;
  • 提示词(prompt)、上下文学习、few-shot、思维链(CoT)分别是什么;
  • RAG、工具调用和 MCP 怎样把外部知识、工具说明和执行结果放进上下文;
  • 为什么幻觉只能靠证据、工具、自检和系统兜底层层压低,不能靠一句提示词根除;
  • 为什么很多评测会奖励“不会也猜”,以及机制可解释性怎样开始解剖模型内部电路;
  • 提示、RAG、微调三招各自改什么、该在什么时候用;
  • Agent 为什么会把“上下文管理”和“外部护栏”变成系统问题;
  • 上下文工程为什么是 Agent 的工作记忆:动态压缩、外部 memory、经验手册、子 Agent 隔离上下文;
  • Harness 工程怎样用执行循环、工具注册、上下文管理、状态存储、hooks 和评测接口,把模型变成稳定工作系统;
  • 用大模型时该守的安全与常识底线;
  • 为什么未来工程师的重点会从“写代码”转向“设计 Agent 的工作环境”。

从 Prompt 到 Context,再到 Harness

早期大家谈“用好大模型”,重点几乎都在 prompt engineering: 怎么写指令、怎么给例子、怎么让它一步步想。后来任务变长、工具变多、Agent 开始循环做事, 问题就不再只是“这一句话怎么写”,而是模型每一步应该看见什么——这就是 context engineering。再往后,模型要真的写代码、点浏览器、跑测试、维护状态、接受审查, 就需要一整套包在模型外面的工程外壳,也就是 harness engineering

用好模型的三层工程 Prompt 把话说清楚 指令 / 示例 / CoT Context 每步该看什么 RAG / memory / 压缩 Harness 让它稳定做事 工具 / 状态 / 评测 / 护栏 模型越会做事,人类越要从“写提示”转向“设计它工作的环境”

Prompt 是给模型一句好指令;Context 是给它一份好工作记忆;Harness 是给它一套能执行、能验证、能恢复的工作环境。

层级核心问题典型手段失败时的表现
Prompt engineering这次该怎么问?角色、目标、格式、few-shot、思维链答非所问、格式不对、一步硬猜
Context engineering这一步该给它看什么?RAG、上下文压缩、memory、经验手册、子 Agent 摘要上下文污染、忘记目标、看了也抓不住重点
Harness engineering怎样让它长期稳定做事?文件系统、沙箱、工具执行、计划/交接、评测器、hooks、后台清理做一半停下、无法复现、越改越乱、自评过度乐观

1. Prompt engineering:把话说清楚

模型参数固定了,你唯一能调的就是输入——也就是提示词(prompt)。 回忆第 17、19 章:模型会把你给的整段文字当上下文,一路影响它对“下一个词”的预测。所以 提示写得好,等于把模型往你要的方向“推”了一把。这件事有个正经名字叫 上下文学习(in-context learning):不改一个参数,只靠上下文就让模型临场“学会”做某件事。

采样参数也在你手里

第 19 章temperature / top-k / top-p 通常也开放给你调。要稳定、确定的答案 (如改代码、抽取信息),把温度调低;要发散、有创意的内容(如头脑风暴),把温度调高。 道理和第 19 章完全一样,只是换了个使用场景。

写好提示词的几条实用技巧

· 给角色和目标:“你是一位资深 C++ 工程师,帮我 review 下面这段代码的内存安全问题。”
· 说清输出格式:要表格就说“用表格”,要 JSON 就把字段列出来,别让它猜。
· 一次交代清上下文与约束:相关背景、必须遵守的限制,别挤牙膏。
· 复杂任务拆步骤:先让它“列个计划”,再逐步执行,比一句“全给我做完”靠谱得多。
· 给范例(few-shot):想要什么风格/格式,甩一两个例子最省事。

2. Context engineering:让模型看见该看的

Context engineering 不是“把所有东西都塞进去”,而是为这一步选择最该看的材料、工具结果、长期记忆和任务状态。 RAG、工具调用、memory、AGENTS.md、playbook、MCP,本质上都在回答同一个问题:这次调用模型时,上下文窗口里应该放什么?

2.1 RAG:把外部知识放进上下文

第 20 章说过大模型的两个硬伤:知识截止(不知道最新的事)和幻觉(没依据也敢编)。 最实用的解药叫 RAG(检索增强生成)——不重新训练,而是先查资料,再让它带着资料回答

你的问题"公司请假流程?"
检索在知识库里找最相关的片段
拼接问题 + 找到的资料
大模型带着资料作答

RAG:把“开卷考试”的资料先塞进上下文,模型据此回答,而不是凭记忆硬编。

它的核心机制,处处都是你学过的东西:

  1. 把你的文档切成小片段(chunk),每段几百字;
  2. 用专门的文本/句向量 embedding 模型把每段变成向量,存进“向量库”;
  3. 提问时,把问题也变成向量,用向量相似度(点积/余弦)找出最相关的几段;
  4. 把这几段和问题一起塞进提示,让模型“看着材料”回答。
为什么 RAG 能治幻觉

把它想成从“闭卷”变“开卷”:闭卷时模型只能凭记忆(容易编),开卷时正确资料就摆在上下文里, 它只需照着答。这也解释了为什么片段不能太大——太大既降低检索精度,又可能撑爆上下文窗口(第 20 章)。

2.2 可靠回答:幻觉、证据与验证

RAG 是最实用的一招,但它只是一道防线。你可能会问:那今天最顶级的模型,是怎么把幻觉压到“少见且可控”的? 先接受一个前提——幻觉无法被彻底消除,只能层层拦截。根因在第 20 章说过:模型本质是概率续写器, 在它内部,“我知道”和“我编一个通顺的”并没有一条天然的分界线。所以顶级模型不追求“消灭幻觉”,而是在从训练到产品的每个环节都设一道关卡,像漏斗一样逐层过滤。

2025 年的一个重要提醒

OpenAI 等作者的论文 Why Language Models Hallucinate 把这个问题说得很清楚:幻觉不只是“模型笨”,也是训练和评测制度在奖励它猜。 预训练只教它“什么文本像真的”,却很少系统告诉它“哪些相似说法是假的”;而很多排行榜又把“不知道”直接判 0 分。 于是模型在不确定时,猜一个答案往往比诚实弃权更像“好考生”。

爱编 可信得多 ① 训练阶段 对齐时惩罚“自信瞎说”、奖励“不知道就说不知道” ② 推理阶段 RAG 检索 + 工具调用 + 先推理再答 + 给出处 ③ 输出后 多次采样自检、另一个模型当“事实核查员” ④ 系统层 证据不足就说“无法确认”、高风险交人工复核

对抗幻觉是组合拳而非单一银弹:从训练、推理、输出后到系统层,四道防线层层收窄,把幻觉率一级级压低。

训练阶段:让它倾向于“诚实”

推理阶段:给它外挂和草稿纸

这一阶段是效果最立竿见影的,核心思路是:别让它只靠“脑内记忆”硬答,而是把答案锚定到外部的真实证据上。

输出后:自检与交叉验证

复杂任务的新范式:生成、验证、修复、选择

MaxProof 这类数学证明系统说明了一件事:难题不一定要押宝“模型一次答对”。 更稳的做法是把一次回答拆成一个小型搜索系统:先生成多条候选路线,再让验证器挑错, 把有希望的路线交给修复器局部补洞或整体重写,最后用排序/投票选出一个提交答案。 这和 Agent 做事很像——大模型不只是“说出答案”,而是在一个生成 → 验证 → 修复 → 选择的循环里逐步逼近答案。

生成 多条候选 验证 找错/打分 修复 补洞/重写 选择 投票/排序 不满意就回到候选池继续改,而不是硬交第一版

复杂任务的可靠性来自系统结构:多候选扩大搜索空间,验证器压低明显错误,修复器把“差一点”的答案救回来,选择器负责最后提交。

一句话记住

对抗幻觉靠的是组合拳:训练时让它倾向诚实、会拒答 → 推理时用 RAG / 工具 / 推理链把答案锚在真实证据上 → 输出后自检和交叉验证 → 系统层加护栏和人工兜底。 对普通开发者最够用的三样是:RAG + 工具调用 + 要求给出处

评测也会塑造模型:别把“不知道”判成错

很多事实没有规律可推,比如某个人的生日、冷门论文标题、一个小项目的真实配置。 训练集中没见过,模型就不能靠“更聪明”凭空算出来。此时最可靠的行为应该是承认不确定, 或者要求检索/工具/更多上下文。但如果评测只看最终答案对不对,问题就来了:

模型不确定时0/1 评分下的结果学到的倾向
说“不知道” 通常直接 0 分 诚实没有收益
猜一个看似合理的答案 错了 0 分,但猜中就 1 分 不会也要试着答
说明证据不足并请求检索 许多榜单仍不给分 谨慎反而吃亏

这就是论文说的“好考生”效应:在许多 benchmark 里,猜测有期望收益,弃权没有。要减少幻觉,主流评测也要给合理的不确定表达、证据不足和请求澄清留分。

所以“抗幻觉”不只是模型公司的训练技巧,也是整个生态的评分问题。 如果主流榜单继续奖励硬猜,模型就会被优化成看起来什么都敢答;如果榜单奖励校准、引用证据和合理弃权, 模型才会更像一个可信助手。

可解释性:不只看输出,还看内部电路

另一条正在发展的路线,是机制可解释性:不只问“模型答了什么”,还追问“它内部为什么这么答”。 Anthropic 2025 年的 On the Biology of a Large Language Model归因图(attribution graph) 去追踪 Claude 3.5 Haiku 的内部计算: 节点是被激活的概念特征,边表示这些特征怎样影响后面的特征和最终输出。

归因图:把“为什么这样答”画成内部电路 输入特征 词、位置、线索 中间概念 事实、计划、风险 输出倾向 回答、拒答、编造 抑制 / 替换特征,验证它是否真的影响输出

归因图像一张粗略的“神经通路图”:先提出内部机制假设,再通过抑制或替换某些特征验证它是否真的影响输出。

这类工作已经能看到一些很具体的内部过程:多步推理里先出现中间事实,写押韵诗前会预先激活候选押韵词, 拒答时会把具体危险线索汇入更抽象的有害请求特征,幻觉时也可能是“应该补一个看似合理答案”的路径压过了“我知道/不知道”的信号。 它还远不是完整解剖,但方向很重要:可信模型不只要输出正确,还要逐步变得可检查、可干预、可追责

2.3 提示、RAG 还是微调:三招该用哪个?

讲完提示和 RAG,一个很自然的问题冒出来了:要让模型在我的场景里表现更好,到底是改提示接 RAG, 还是干脆微调(fine-tune,拿你的数据接着训一小段,属于第 20 章后训练的范畴)? 它们不是三选一的对立关系,而是成本从低到高、按需叠加的三层台阶。

手段改的是什么最适合解决成本
提示工程 只改输入(上下文) 让它听懂任务、按格式输出;通用能力它本来就有 最低,改一句话即可
RAG 输入 + 一个外挂知识库 补上最新的、私有的知识;治幻觉、防知识截止 中,要搭检索/向量库
微调 模型参数本身 固化一种稳定的风格/口吻/领域习惯,或压缩提示长度 最高,要数据、算力和训练
一个实用的排查顺序

先用提示,不行再上 RAG,最后才考虑微调。 大多数问题(“它不按我要的格式来”“它没理解任务”)其实改提示就解决了,根本不用动模型。 如果问题是“它不知道某些事实”(公司内部文档、今天的新闻),那是知识缺口,RAG 最对症。 只有当问题是“它知道、但就是不肯照我要的风格/领域习惯稳定地做”,而且提示怎么调都不够,才值得为微调付出数据和算力的代价。

常见误区:拿微调去补知识

很多人一上来就想“用我的文档微调一个模型”。但微调更擅长教风格和形式, 往里灌事实既低效又容易带来遗忘和新的幻觉——而且知识一更新就得重训。 要“记住并用上一批资料”,RAG 通常才是更省、更准、更好维护的选择

2.4 工具调用:把工具说明和结果放进上下文

大模型不擅长精确计算,也查不到实时数据(第 20 章)。那就别让它硬算——让它调用外部工具。 这套机制最早叫 function calling(函数调用):

  1. 你把可用的工具清单(计算器、搜索、日历……)连同问题一起给模型;
  2. 模型判断该用哪个工具、要传什么参数,把这个“意图”返回;
  3. 由程序真正执行工具、拿到结果,再喂回模型;
  4. 模型结合工具结果,给出最终回答。

于是“3897 × 421 等于几”“今天北京天气”这类它本来做不好的事,就交给计算器和天气 API,它负责理解、调度、总结。 模型从“一张嘴”升级成了“会用工具的手”。

2.5 Agent:从回答问题到循环做事

当模型从“一次回答”升级成循环做事的 Agent,context engineering 就不再只是“塞几段资料”, 而是变成工作记忆问题:每一步该看什么、工具结果怎么回流、哪些探索噪声该隔离出去。

当一个系统能感知环境 → 思考决策 → 执行动作,还能看着结果继续下一步,它就成了一个 Agent(智能体)。如果负责“思考决策”的大脑是一个大模型,那它就是我们现在常说的 AI Agent。

感知读你的话/看图/收数据
思考(大模型)该做什么?用哪个工具?
执行调用工具/写文件/发请求
看结果不满意就再来一轮

Agent = 大模型当“大脑”,加上感知与执行的“手脚”,并能循环多步,直到把任务办成。

你正在用的这个编程助手,本质就是一个 Agent:它读你的需求(感知)、决定改哪个文件、跑什么命令(思考), 真正去编辑和执行(执行),再根据报错继续修(循环)。RAG 和工具调用,都是喂给这个“大脑”的能力。

2.6 Agent 的工作记忆:动态压缩、memory 与子 Agent

到这里,你可能会觉得 Agent 的关键是“会不会调用工具”。其实还差一块更底层的东西: 上下文工程(context engineering)。它关心的不是“提示词怎么写得漂亮”, 而是每一次调用模型时,到底该把哪些信息放进上下文窗口

上下文窗口不是仓库,是注意力预算

很多人以为窗口越长越好,把日志、网页、工具输出、历史对话全塞进去就万事大吉。但模型的注意力不是无限的。 上下文越长,模型越容易“看见了但没抓住重点”,这类现象常被称为 context rot: 不是超过某条线突然失效,而是随着 token 增加,检索细节、保持目标和长距离推理的精度逐渐下降。 所以上下文工程的目标是:用最少的高信号 token,换最大的任务成功率

每一步都重新“配上下文” 当前目标 工具说明 / MCP 检索证据 / 文件 memory / 笔记 Context Curator 筛选 · 压缩 · 排序 · 去噪 模型一步 思考并行动 工具结果、失败经验、未完成事项会沉淀回 memory,下一步再被选择性取回

Agent 不是把所有历史都塞给模型,而是每一步都重新组织一份“刚好够用”的上下文。

动态压缩:保留状态,丢掉噪声

长任务做着做着,对话历史、工具输出和中间尝试会迅速膨胀。最直接的办法叫 compaction(上下文压缩):当窗口接近上限时,把历史压缩成一份高保真状态摘要, 再带着这份摘要开启新的上下文窗口继续工作。

好的压缩不是“越短越好”,而是能让 Agent 接着干活。它应该保留:

该保留为什么重要常可丢掉
当前目标与验收口径防止后续动作偏离任务寒暄、重复确认
关键决策与约束避免反复推翻已经确定的方向无关分支讨论
已完成/未完成清单让 Agent 知道下一步从哪里接过期 TODO、已解决报错全文
重要文件、接口、命令结果保留可复现线索和边界条件大段原始日志、完整工具输出
失败原因与排除路径防止同一个坑重复踩中间失败的冗余堆栈

这里最容易犯的错是摘要化过猛:把“为什么这么做”“哪些尝试失败过”“哪个文件刚改过”都压没了。 Anthropic 的工程经验里,压缩更像给接班人写交接单:保留架构决策、未解 bug、实现细节和最近访问文件, 而不是把历史改写成一段漂亮短文。

Memory:把长期经验放在窗口外

memory 是另一种思路:别把所有信息一直留在上下文里,而是让 Agent 把关键状态写到外部, 需要时再读回来。它可以很简单,比如一个 TODO.mdNOTES.md、项目记忆文件, 也可以是数据库、向量库或专门的记忆服务。

memory 不是“聊天记录永久保存”

有价值的 memory 更像工作手册:记录稳定事实(项目结构、接口约定)、过程状态(做到哪一步、还差什么)、 失败经验(某命令会超时、某参数不能这么传)、偏好与规范(输出风格、验证命令)。 它不应该存一切原文,而应该存“以后真的会用到的压缩知识”。

真正难的是什么时候写、什么时候读。写得太少,下一轮忘事;写得太多,检索回来又污染上下文。 一个实用做法是把 memory 分层:

可演化 playbook:从执行反馈里长经验

ACE 论文把上下文看成一份会演化的 playbook,而不是一段每次整体重写的 prompt。 它把过程拆成三种角色:

关键是它用增量条目而不是整段重写。每条经验都像一颗小积木,有自己的编号、内容和“有用/有害”计数。 这样能避免两个常见问题:

- id: tool-calendar-timezone
  helpful: 7
  harmful: 0
  note: 调日历工具前先确认 timezone;缺省时不要猜,先查用户资料或请求澄清。

- id: codebase-anchor-check
  helpful: 12
  harmful: 1
  note: 修改电子书 h2/h3 标题后,必须跑 check_anchors.py;不要手算 slug。

这类条目比“以后注意工具参数”更有用,因为它具体、可检索、能被计数淘汰。Agent 下一次遇到类似任务时, 只需要取回相关条目,不必重读全部历史。

子 Agent:把探索噪声隔离出去

还有一种重要技巧是隔离上下文。复杂研究或大代码库排查时,一个主 Agent 如果亲自读完所有文件、日志和网页, 很快会把自己的上下文塞满。更稳的做法是让子 Agent 在独立窗口里深挖一个局部问题,最后只返回一份高密度摘要。

手段解决什么适合场景
动态压缩长对话快满时保留连续性持续编码、长时间调试、连续研究
外部 memory把稳定经验放到窗口外,按需取回项目长期协作、反复执行的工作流
可演化 playbook从执行反馈中沉淀策略,避免每次从零开始Agent 产品、领域任务、工具链使用
子 Agent隔离大量探索噪声,主 Agent 只读结论并行研究、大仓库定位、复杂信息搜集

所以,Agent 的“聪明”不只来自模型参数,还来自这套上下文操作系统: 该压缩时压缩,该外存时外存,该检索时检索,该隔离时隔离。 会管理上下文的 Agent,才能在很长的任务里保持方向感。

2.7 MCP:工具和数据源的标准上下文接口

Agent 要调用各种外部工具和数据源,如果每接一个都要定制一套对接,就太乱了。 MCP 模型上下文协议由 Anthropic 提出,给“Agent ↔ 外部工具/数据源”定义了一套标准插头: 工具说明、资源、数据和调用结果都能用统一方式进入上下文。有了它,任何遵守协议的工具都能被任何 Agent 即插即用, 不用一个个定制(可以类比 USB 之于外设)。

A2A 也曾试图规范 Agent 与 Agent 之间怎么通信、协作,但这条线还不如 MCP 稳定,本章只点到这里,不展开成主线。 你只需要记住一个方向:大模型正从“一个聊天框”,长成一个能连接工具、数据源和专职 Agent 的工作生态。

3. Harness engineering:让模型可靠做事

如果说上下文工程解决的是“模型每一步看什么”,那 Harness 工程(harness engineering) 解决的是“模型怎么在真实环境里长期、安全、可恢复地做事”。LangChain 有个很干脆的说法: Agent = Model + Harness。模型负责智能;Harness 负责把这种智能接到状态、工具、文件、沙箱、评测和控制流上。

Harness 不是更长的提示词

原始模型只能接收输入、吐出文本。它不会天然保存状态,不会真的执行代码,不会访问实时世界,也不会自动知道什么时候该停。 Harness 就是模型外面的工程系统:给它文件系统保存中间产物,给它工具和浏览器操作世界,给它沙箱限制风险, 给它测试和评测器判断好坏,给它 hooks/middleware 做确定性检查,给它交接文档跨越上下文重置。

Agent = Model + Harness Model 推理 · 规划 · 生成 状态 / 文件系统 保存进度和产物 工具 / 浏览器 操作真实环境 沙箱 / 权限 限制副作用 评测 / 测试 判断是否够好 编排 / Hooks 交接、重试、清理

Harness 把模型包进一个可执行系统:状态能落盘,工具能调用,风险有边界,结果能验证,长任务能交接。

还可以把 Harness 理解成一座约束金字塔。越往下越便宜、越普及,但越依赖模型自己记住规则; 越往上越少见、成本越高,却越像外部系统给模型加的硬护栏。

prompt 在 chat 里说清任务、格式和临时限制 context AGENTS.md / memory / playbook 持续塑造行为 agent 独立上下文审查、测试、复核交付结果 hook 程序化检测与拦截危险动作

Harness 的约束从下到上越来越硬:prompt 和 context 让模型“记住规则”,独立 Agent 负责复核,hook / sandbox / CI 则用程序直接拦截高风险行为。

从软规则到硬护栏

Prompt 和 context 很有用,但它们本质上仍是软约束:上下文一长,规则会被稀释,模型可能忘记早先的限制。 所以关键边界不能只押在模型记忆上。独立 reviewer / tester / evaluator 用另一个上下文检查结果, 能减少模型既当运动员又当裁判的问题;hooks、权限、沙箱和 CI 则是不靠模型“记得”的最后防线。

注意,hook 也不是神谕。它不会因为注意力涣散而忘规则,但它可能写漏、误杀或接错位置,所以仍然要被测试和维护。 真正可靠的 Harness,是把软规则、独立审查和硬拦截叠在一起。

3.1 Harness 的六个部件

一篇 2026 年的 Agent Harness survey 把这层工程外壳写成一个很清楚的六元组: H = (E, T, C, S, L, V)。它的意思不是让你背公式,而是提醒你: Agent 的可靠性不只取决于模型多强,还取决于模型外面这六件事有没有被设计好。

字母部件它负责什么坏掉时的表现
EExecution loop 执行循环观察环境、调用模型、执行动作、读回结果、进入下一步做一步就停、失败不重试、状态和行动脱节
TTool registry 工具注册表告诉模型有哪些工具、参数怎么填、权限和返回值是什么工具太多选错、参数乱填、危险工具暴露给错误任务
CContext manager 上下文管理器决定每一步给模型看哪些需求、文件、检索结果、工具回执和历史摘要关键事实被冲淡、旧错误反复回流、长上下文里抓不住重点
SState store 状态存储把计划、进度、文件、记忆、checkpoint 和交接产物放在窗口外上下文一重置就失忆,长任务无法恢复或复现
LLifecycle hooks 生命周期钩子在开始、工具调用前后、提交前、结束时做确定性检查和自动维护危险命令没人拦、格式没人查、临时产物没人清理
VEvaluation interface 验证接口把测试、CI、截图、日志、reviewer、rubric evaluator 接进反馈回路模型自己给自己打高分,结果看似完成但不可用

这也是为什么“换一个更强模型”不总能解决 Agent 的问题。模型像发动机,但执行循环、工具、上下文、状态、hook 和验证接口决定了它能不能把能力稳定地传到真实任务上。很多所谓“模型不行”,其实是工具接口混乱、上下文污染、 没有状态恢复,或者没有外部验证。

把这篇 survey 当作工程框架,不要当作定论

这篇文章目前还是 preprint,而且引用了不少产业报告和工程博客。它最有价值的地方不是某个单点数字, 而是把分散的经验归纳成一个可检查清单:一个 Agent 系统如果缺了执行、工具、上下文、状态、hook 或验证中的任何一层, 长任务可靠性就会很快掉下来。

3.2 长任务 Harness:Planner、Generator、Evaluator

Anthropic 在长时间应用开发实验里,把单个“全能 Agent”拆成三个角色:

这个设计的关键不是“多几个模型一起聊天”,而是职责隔离。做事的 Agent 不负责给自己打高分; 评估者用独立上下文、明确标准和真实环境反馈来挑错。长任务中间如果上下文变脏,可以直接重置 Agent, 通过结构化 handoff artifact 把当前状态和下一步交给新 Agent,而不是让同一个 Agent 背着越来越重的历史继续硬撑。

多 Agent 协作在软件工程里还有一个更硬的版本。2026 年论文 Effective Strategies for Asynchronous Software Engineering Agents 提出 CAID(Centralized Asynchronous Isolated Delegation):一个中央 manager 先把任务拆成带依赖的子任务, 多个 engineer Agent 在各自隔离的 git worktree 里并行实现,完成后用 git commit / git merge 回到主线,并用可执行测试验证整合结果。它的重点不是“大家在同一个聊天里讨论”,而是把人类软件团队早就成熟的 branch-and-merge 搬给 Agent 用。

协作问题CAID 的做法为什么重要
任务怎么拆?Manager 先建依赖图,只分配依赖已满足的任务避免两个 Agent 各做各的,最后拼不起来
并行怎么不互相踩?每个 engineer 使用独立 worktree,不要共用同一份工作区指令里的“别改同一文件”是软约束,隔离 workspace 才是硬边界
进度怎么回主线?完成后提交 commit,再显式 merge 到 main冲突会在 merge 时暴露,不会悄悄污染最终代码
质量怎么判断?Engineer 自测,manager 整合,测试和错误日志进入下一轮把“我觉得做好了”变成可执行验证

这篇论文的实验也给了一个很实用的提醒:多 Agent 不是越多越好。并行度要匹配任务本身的模块化程度和 manager 的调度能力; 人数太多、切得太碎,反而会增加合并冲突、沟通成本和验证成本。对长代码任务来说,正确问题不是“要不要多个 Agent”, 而是哪些任务能隔离并行,哪些依赖必须先合并验证

3.3 Harness 里的确定性护栏

Harness 还要处理模型不擅长但工程系统很擅长的事:确定性约束。比如 OpenAI 的 Harness Engineering 讨论里, 他们让 Codex 从空仓库开始生成应用逻辑、测试、CI、文档、可观测性和内部工具;人的主要工作从“写代码”转成 设计环境、明确意图、构建反馈回路。这不是把一个巨大说明书塞进上下文,而是把知识、约束和反馈做成 机器可读、可执行、可维护的仓库结构。

一个关键经验是:AGENTS.md 不该是百科全书,而该是地图。真正的信息放进结构化的 docs/、 架构文档、执行计划、产品规格、生成的 schema、参考资料和质量评分里;简短入口告诉 Agent 下一步该去哪查。 这样既避免上下文爆炸,又让知识有所有权、可交叉链接、可被 lint/CI 检查新鲜度。

另一条经验是让应用本身对 Agent 可读:让 Codex 能按 worktree 启动独立实例,用浏览器协议查看 DOM 和截图, 用日志/指标/追踪回答“启动是否低于 800ms”“关键用户旅程是否超过 2 秒”。当 UI、日志和指标都能被 Agent 读取, 它才有能力复现问题、验证修复,而不是只靠人类 QA 口头描述。

最后是熵管理。完全由 Agent 高速产出的代码会复制仓库里已有模式,包括坏模式。OpenAI 的做法是把“黄金原则”编码成 架构约束、结构测试、自定义 lint 和后台 Codex 任务,定期扫描偏差、更新质量评级、发起重构 PR。可以把它想成给 Agent 生成的代码加垃圾回收:小问题定期扫掉,技术债不要等积成山再一次性还。

Harness 组件它给模型补什么例子
文件系统 / Git持久状态、版本、回滚点代码、计划、handoff、checkpoint
沙箱 / 权限可控执行边界跑代码、装依赖、浏览网页但限制危险操作
测试 / 评测器外部反馈单测、Playwright、lint、rubric evaluator
编排逻辑流程和角色分工Planner/Generator/Evaluator、子 Agent、重试
可观测性让 Agent 自己看见运行状态DOM 快照、截图、日志、指标、trace
Hooks / Middleware确定性检查和自动维护压缩、继续执行、格式检查、后台清理 PR

所以这条演进线可以这样记:Prompt 让模型听懂你;Context 让模型看见该看的;Harness 让模型在真实系统里可靠地做完。

4. 用它,但别全信它

几条实用底线

· 关键事实要核对:它会一本正经地编(第 20 章的幻觉),涉及数字、引用、法律医疗等,务必自己复核。
· 小心提示注入:让它读的网页/文档里可能藏着“骗它执行的指令”,给 Agent 授予真实权限(删文件、付款)时要谨慎。
· 注意隐私:别把敏感信息随手贴进第三方模型。
· 它没有立场也没有真正的“懂”:它在做极其复杂的模式延续,语气再笃定也不等于正确。

把这些记在心里,你就能既享受它的强大,又不被它的“自信”带偏。理解原理的人,用起工具来总是更稳、更有分寸。

小结

  • 提示词是你唯一的旋钮:zero-shot 直接问、few-shot 给例子、CoT 让它一步步想。
  • RAG = 先检索再回答,用词嵌入+相似度找资料,把“闭卷”变“开卷”,治幻觉与知识截止。
  • 对抗幻觉是组合拳:训练时让它倾向诚实/会拒答,推理时用 RAG+工具+推理链锚定证据,输出后自检交叉验证,系统层加护栏与人工兜底;幻觉只能压低、无法根除。
  • 复杂任务越来越像搜索系统:生成多个候选,用验证器挑错,用修复器补洞或重写,最后排序/投票选答案。
  • 幻觉也来自评测激励:如果“不知道”永远 0 分、猜测有机会得分,模型就会被塑造成爱猜的考生;机制可解释性则尝试用归因图追踪内部特征和电路。
  • 提示 / RAG / 微调是成本递增的三层:先改提示,缺知识上 RAG,只有要固化风格才微调——别拿微调补知识。
  • function calling 让模型调用计算器/搜索/API,补上它不会算、查不到的短板。
  • Agent = 大模型当大脑 + 感知与执行 + 多步循环;上下文工程负责管理它的工作记忆:压缩历史、写外部 memory、维护经验手册、用子 Agent 隔离噪声;MCP 则把工具和数据源变成标准上下文接口。
  • Harness 工程把模型包进工作系统:执行循环负责多步推进,工具注册表治理可用能力,上下文管理器决定每步看什么,状态存储保存进度,hooks 提供硬拦截,测试/评测器提供外部反馈;多 Agent 协作还要靠依赖图、隔离工作区、显式 merge 和测试验证来避免互相踩踏。
  • 始终核对关键事实、防提示注入、护隐私——理解原理才能用得稳。

动手与思考

问题 1:few-shot 和 CoT 都不改模型参数,为什么还能提升表现?

因为它们改变的是上下文。模型预测下一个词时会被整段输入影响(上下文学习):给了示范,它照着模仿;让它“一步步想”,它就把推理写出来、逐步推进,而不是一步硬猜。参数没变,但输入把它推向了更好的轨道。

问题 2:RAG 为什么能缓解幻觉和知识截止?它用到了哪些前面的知识?

它先从知识库检索出相关资料,连同问题一起给模型,让它“看着材料答”而非凭记忆编,同时资料可以是最新的。用到的正是第 20 章的词嵌入,和第 1 章的向量点积/余弦相似度检索。

问题 3:为什么要让大模型“调用工具”,而不是让它自己算、自己查?

因为它本质是概率文本预测器,不擅长精确计算,也没有实时数据。把算术交给计算器、把实时信息交给搜索/API,让模型负责理解意图、调度工具、总结结果,整体又准又可靠。

原理讲完了,但别急着合上

从一个神经元到大模型的原理主干,到这里就全通了(强化学习那套学习范式,我们已在第 12 章讲过)。 接下来第六部分 · 代码实战对着三份 C++ 程序把全书对一遍号: 第 23 章 MNIST, 第 24 章 字符级语言模型, 第 25 章 井字棋 Q-learning。

下一章进入代码实战:第 23 章 先把 MNIST 程序逐行对上号。