跳到正文
返回

Agent(二):模型已经会用工具,为什么还是做不成事?

9分钟阅读

“修改完成。命令执行成功。”

一个编码智能体找到文件、写入补丁,终端也返回了退出码 0。它正确调用了工具,参数没有填错,生成的代码甚至语法合法。但你打开页面,旧数据仍然留在缓存里;再看工作区,它还顺手覆盖了你没有提交的一处修改。

它并不是完全不会写代码。恰恰相反,失败发生在一个能力看起来已经足够强的模型身上:它会推理,会使用终端,会编辑文件,也会解释自己的改动。问题在于,它不知道工作区原来是什么状态,不知道项目要求写入后必须使缓存失效,也没有得到能够否定“已经完成”的验收结果。

当模型能力变强,智能体失败的重心会悄悄移动。早期我们反复研究怎样让模型服从指令、选择工具、输出正确参数;当这些交互模式逐渐被后训练做成较稳定的能力,最大的缺口不再总是“模型会不会做”,而是:

它是否正在根据真实、当前、可验证的任务状态行动?

这是 Agent 系列的第二篇。上一篇讨论的是提示词怎样从训练形成的行为可能中选择一种工作方式。可提示词只能规定模型怎样处理信息,不能补回没有进入输入的事实,也不能让模型直接看见外部世界。行为入口已经打开之后,下一层问题就是怎样让正确的信息持续覆盖每一次决策。

这就是上下文工程。

会用工具,不等于看见任务现场

语言模型不会直接站在你的工作区里。

文件是否被别人改过、数据库现在有多少行、上一条命令实际改变了什么、页面是否真的符合需求,这些环境状态都在模型之外。模型能看到的,只是运行系统把其中一部分转换成文本或结构化对象,再放回下一次调用的内容。

因此,工具调用包含两个方向:

  • 模型把意图变成动作,交给环境执行;
  • 环境把发生的事情变成观察,送回模型继续判断。

第二个方向一旦缺失,工具就只是模型伸出去的一只手,却没有带回触觉。模型可以连续执行一套看似合理的计划,但环境早已偏离它脑中的假设。

ReAct把推理与行动交替放进同一条轨迹:行动从外部取得新信息,推理再据此更新计划和处理例外。它的重要性不在于发明了一种固定格式,而在于揭示了长程任务的最小闭环——模型的下一步必须能够被上一步产生的现实改变。

问题也由此从“提示词写了什么”扩大为“下一次调用究竟看见什么”。

上下文是一次决策的完整状态

人们说起上下文,常常首先想到上下文窗口:一个模型最多能接收多少 token。这个定义只描述了容器大小,却没有描述容器里应该装什么。

对于一次真实的智能体调用,上下文更像模型此刻的任务状态:

  • 目标说明希望环境变成什么样,也说明哪些结果不可接受;
  • 知识提供项目规则、相关事实和已有约定;
  • 当前状态说明环境现在是什么样,而不是任务开始时是什么样;
  • 可用动作告诉模型能怎样继续探索或改变环境;
  • 观察说明刚才发生了什么;
  • 反馈判断发生的事情距离目标还有多远。

这些内容并不都来自最初的用户消息。任务每前进一步,环境会改变,旧判断会失效,新的证据会出现。上下文工程因而不是在任务开始前写好一段宏大的前言,而是在整个行动过程中维护一个不断变化的认知现场。

同一个模型,会随任务状态改变下一步行动逐项移除进入上下文的信息。模型与目标始终不变,变化的只是它下一次决策时能够看到的证据。概念示意图:表达信息怎样进入决策,不代表某个编码智能体的真实轨迹或评测结果。
同一个模型目标固定 · 修复请求缓存

哪些信息进入下一次模型调用

这一次决策的上下文4 / 4 项信号在场
目标

修复请求缓存,同时保留工作区内的已有修改。

知识

保持路由契约,并在写入后使旧缓存失效。

当前状态

工作区有一处用户修改;cache.ts 刚刚被编辑。

观察

编辑命令退出码为 0 · 一个文件发生变化。

下一步行动

检查缓存失效路径,修正后重新运行失败的验收检查。

退出码为 0 是观察;验收检查失败才是反馈,因为它按目标评价了行动结果。

图里模型与目标始终固定。关掉“必要知识”,下一步会退回读取项目规则;移除“当前状态”,它必须先检查工作区;去掉压缩,关键结果会重新埋进原始日志;拿走验证反馈,它就没有证据判断任务是否完成。

上下文改变的不是模型拥有的能力,而是这一次能力能够依据什么行动。

上下文工程优化的是四种不同的缺口

把上下文工程简单理解为“给模型更多信息”,会把几个性质不同的问题混在一起。信息不足确实会失败,信息太多、太旧、无法验证同样会失败。更有用的分法,是分别观察四个方向。

需要的知识能否到达

模型不必在每一轮都记住整个代码库,但必须能在需要时找到项目约定、接口定义和相关实现。这里优化的是信息的可得性:检索、文件索引、搜索工具和按需读取,都在建立从问题到事实的路径。

“让模型知道更多”不等于把所有资料预先塞入窗口。很多知识只需要保持可取回。模型先看到文件名、目录和摘要,再决定是否读取正文,往往比一次性载入全部内容更接近真实工作。

任务状态能否连续保存

长任务会跨越几十次工具调用,甚至超过一次上下文窗口。模型需要记住已经做过什么、哪些判断仍成立、哪里尚未解决。更长的窗口能提高容量,外置笔记、阶段状态和压缩摘要则让关键状态跨越窗口继续存在。

容量解决的是“能不能保留”,却不保证“能不能用好”。

有效信号能否压过噪声

一万行日志包含的信息可能比十行摘要多,却未必让下一步判断更好。重复进度、旧版本文件、已经排除的错误路径和过时计划都会争夺注意力。

Lost in the Middle发现,即使模型支持长输入,相关信息位于长上下文的不同位置时,模型利用它的能力仍会显著变化。长窗口不是一个超过之后才突然失效的硬边界;在到达上限之前,信息位置、冲突和噪声就已经可能降低精度。

所以压缩不是为了单纯省 token,而是提高会改变决策的信息所占的比例。Anthropic 对智能体上下文工程的总结也把目标描述为:在有限注意预算中保留尽可能小而高信号的内容,并用渐进式披露、工具结果清理和阶段摘要维持长任务。

工具回复更精简,首先优化的正是这一方向。

行动结果能否及时修正判断

前面三个方向仍然可能组成一个静态资料包。智能体真正进入环境工作后,还需要第四个方向:新状态必须回流,而且回流的信息要能改变后续行动。

这不是“记住更多”,而是“让上下文保持新鲜”。一次文件修改、一次网页点击或一次数据库写入都会改变环境。如果下一轮仍基于行动前的状态推理,再大的上下文也只是在精确保存一个过时世界。

但环境回流还不等于反馈。这里必须再做一次区分。

工具成功是观察,满足目标才产生反馈

命令退出码为 0、文件内容发生变化、服务器返回 HTTP 200,都在说明环境发生了什么。它们是观察。

观察本身并不回答结果是否正确。一个返回 200 的页面可能展示错误内容;一段通过编译的代码可能破坏原有行为;一个写入成功的补丁可能根本没有实现用户要求。

只有当系统依据目标、约束或完成标准评价这些观察时,才会产生反馈:

  • “文件已修改”是观察;
  • “修改保留了用户已有改动”是反馈。
  • “测试进程结束”是观察;
  • “缓存失效场景仍然失败”是反馈。
  • “页面可以打开”是观察;
  • “窄屏没有横向溢出且交互可用”是反馈。

因此,精简的工具回复不天然等于反馈。它可以让观察更清楚,却仍可能只是在简洁地报告一件与目标无关的事。反馈需要一把尺子:模型先知道什么算完成,评测再把当前结果放到这把尺子旁边。

这也是为什么“工具返回成功,不等于任务完成”。工具只对一次动作的执行负责,任务完成则是对环境最终状态的判断。

当反馈重新进入上下文,它不会更新模型权重,却会更新当前任务里的判断、计划和行动倾向。模型看到测试失败后选择修复,看到人类不接受后重新理解目标,看到事实与假设冲突后放弃原路径。能力没有在几秒钟里增长,但有反馈和无反馈的系统会表现出完全不同的有效能力。

可检查的环境,把正确性变成下一步输入

编码任务格外适合今天的智能体,不只是因为训练数据里有大量代码,还因为软件环境会说话。

编译器能指出语法和类型错误,测试能把输入映射到期望结果,静态检查器能发现一部分规则违背,版本控制能展示精确差异。这些机制把模糊的“好像不对”转换成结构化、局部而且可以重复取得的反馈。

SWE-agent的研究表明,为模型重新设计浏览、编辑和执行测试的计算机接口,仅改变模型与环境的交互方式,就能显著影响软件任务表现。界面不只是让工具“可以调用”,还决定模型看见什么结果、需要承担多少无关输出,以及能否从错误中恢复。

测试驱动开发(TDD)在这里显得尤其契合。它并不是因为智能体才出现,也不能保证测试本身正确;但“先得到一个可重复的失败,再修改,最后看它变绿”天然形成了短而明确的反馈回路。模型不必仅靠自己的文字判断代码是否正确,环境会持续否定不满足约束的候选方案。

Lean 一类证明检查器把这个性质推到了更严格的程度。DeepMind 的 AlphaProof在 Lean 中搜索证明,并利用形式系统检查候选证明是否成立。语言模型可以提出看似合理的步骤,证明检查器则提供不依赖措辞流畅度的判断。

这里仍有边界。测试只能检查被写进测试的要求,形式系统只能证明形式化命题;如果验收标准漏掉了真实意图,系统可以非常可靠地完成错误目标。可验证性解决的是“结果是否满足这把尺子”,不能自动保证“这把尺子是不是我们真正想要的”。

真正重要的迁移直觉不是“所有任务都应该形式化”,而是:

环境越能把状态暴露为可解析的观察,把目标暴露为可重复的评价,模型的行动就越容易形成有效闭环。

上下文工程维护现场,Harness 工程维护循环

现在可以回到开头那个过早宣布完成的编码智能体。

让它写一段更长的系统提示,或许能提醒它“请认真检查”。但真正改变结果的,是让项目规则、工作区状态、精简后的工具结果和验收失败在正确时刻进入下一次调用。前者是在要求一种行为,后者是在提供行为所依据的现实。

这给上下文工程划出了边界:

  • 检索让必要知识能够到达;
  • 长上下文与外置状态维持任务连续性;
  • 选择和压缩提高有效信号密度;
  • 观察与反馈让当前判断追上环境变化。

提示词工程设计能力的入口,上下文工程维护模型眼中的任务现场。可当我们继续追问:谁负责安全地执行动作、采集观察、运行评测、保存状态、压缩历史,并保证这些信息在下一轮准时回来?问题就已经从“该给模型看什么”,走向了“用什么系统让这个循环可靠发生”。

那会是下一篇的主题:Harness 工程。