Context Engineering:Agent 架构里最被低估的一层
Agent 表现不稳定很多时候不是模型问题,而是上下文窗口中的信息排布出了问题——Context Engineering 可能是被最多人忽视的关键环节。
最近在调一个多 Agent 协作系统,遇到一个很诡异的现象。
同一个模型,同一个 API,同一个工具集。昨天跑得好好的任务,今天换了个输入,Agent 就开始魔怔——它不停地调一个跟任务完全无关的工具,连续调了五次,把 Token 烧光了才停。
我第一反应是模型抽风了。换个更强的模型试试,结果只是抽风的方式不一样。
排查了一下午,最后发现病根在哪——上下文里塞了太多没用的工具描述,模型在信息洪流里抓瞎了。
这件事之后我认真想了一个问题:Agent 做得好不好,到底瓶颈在哪?
大部分人以为答案是模型
刚开始做 Agent 的时候,我跟大多数人的直觉一样:效果不好就是模型不够强。
工具调错了?换个推理能力更强的模型。任务跑偏了?升级到最新旗舰版。Token 窗口不够?上 200K 的。
这个思路不能说错,但它掩盖了真正的问题。
我见过用 GPT-4o 跑 Agent 翻车的场景,换成 Claude Sonnet 一样翻。也见过反过来的。换模型能解决一部分问题,但解决不了核心问题——Agent 的信息处理方式跟传统 LLM 调用完全不同。
普通的 LLM 调用就一次往返:你塞一段 prompt,它吐一段回复。
Agent 是一个循环。每一轮都在往上下文里追加新东西:工具返回的结果、模型的推理过程、用户的额外输入。跑几轮之后,上下文的"底噪"越来越大,关键信息被稀释到几乎找不到。
这时候再强的模型也救不了。
Context Engineering 到底在解决什么问题
先分清楚两个常被混为一谈的东西。
Prompt Engineering 管的是"提示词怎么写模型才听得懂"。Context Engineering 管的是"什么信息该喂给模型、以什么顺序、放多少"。
前者更多是写指令的技巧。后者是一个系统工程问题。
做个 Agent 系统最少要搞定三层:LLM Call、Tools Call、Context Engineering。
LLM Call 负责模型调用,管接口差异、流式输出、重试这些。Tools Call 负责让模型能跟外部世界交互,管 Function Calling、MCP、工具注册。这两层现在都有成熟的框架和最佳实践。
但 Context Engineering 没有。它没有统一的理论,也没有现成的库可以调。每个做 Agent 的团队都在自己摸索。
它的核心挑战说白了就一个:有限 Token 窗口里,怎么保证模型看到的信息正好是它最需要的那一部分。
具体踩过的坑
第一个坑:工具描述太长。
我一个项目里注册了 15 个工具,每个工具的 JSON Schema description 都写得很详细——使用场景、参数说明、返回值格式,生怕模型看不懂。
结果模型反而看不懂了。15 个工具的描述加起来快两千字,模型每次推理都要在这堆文字里翻找该调哪个。明明只需要调一个搜索工具,模型硬是在前三个工具之间反复横跳,像在纠结菜单。
后来我把工具描述压缩了一半。把场景限定句去掉,只保留"做什么"和"参数是什么",禁用条件单开一行短的。效果立竿见影——工具调用的准确率从 70% 出头直接拉到 90% 以上。
第二个坑:历史上下文太重。
Agent 跑一个复杂任务通常要 10-20 轮迭代。每一轮都记录了思考过程、工具调用、返回结果。跑到第 8 轮的时候,光是历史对话就有五六千字。模型要从开头重新读一遍才能理解当前状态。
解决方案很粗暴:做上下文压缩。每跑完一轮,把旧的推理记录折叠成一个简短的结构化摘要,保留关键信息但把文字量砍到十分之一。下一轮只加载最近两轮的完整上下文 + 前面的压缩摘要。
这招不是我想出来的。LangChain 开源社区里很多项目都在用类似的方法,只不过大部分人做到第五轮才意识到需要它。
第三个坑:不加限定条件的工具。
最经典的事故:我写了一个"发送邮件"的工具,没加任何权限约束。结果 Agent 在调试过程中真的给同事发了封测试邮件,里面写着"这是一封 AI 自动发送的测试邮件,请忽略"。
同事回了一句:"你能不能让它别发了?"
现在我的工具描述里一定会带上安全约束:"这个工具只能在用户明确要求发送时调用。系统自动触发的流程里不要调用。" 模型确实会读这些描述,你写清楚它就遵守,你不写它就放飞。
为什么说它是 Agent 架构里最被低估的一层
看一下现在主流的四层架构图:
LLM(推理核心)→ Agent(执行循环)→ MCP/Skills(能力封装)→ 外部工具/数据
大部分人关注的是 Agent 层的 ReAct 模式怎么设计,MCP 层的协议怎么对接,工具层的 API 怎么封装。这些当然重要。
但真正决定 Agent 能不能稳定工作的,是 Context Engineering 有没有做好。因为这层出了问题,其他三层做得再好也没用。
模型强,但上下文乱了,它一样跑偏。MCP 对接得再好,如果工具描述写得不清不楚,模型也不会正确调用。工具 API 再稳定,如果历史上下文中夹杂了大量噪声,模型还是会在无关的信息里打转。
这就像盖房子。LLM 是地基,Agent 框架是承重结构,MCP 和工具是水电管线。Context Engineering 是房间里的空气——看不见摸不着,但没有它,住进来的人会窒息。
一些可以立刻用的技巧
经验积累到现在,有几条我觉得适用性比较广的:
工具描述分层写。 把"工具是做什么的"单独写成一行简短标签,把参数说明放第二层,把使用场景和约束放第三层。模型可以先扫第一层决定要不要调,再读第二三层获取细节。
上下文压缩是必修课。 任何规划跑超过 5 轮的 Agent,都必须引入压缩机制。可以折叠、可以摘要、可以滑动窗口,但不能让上下文无限膨胀。
禁用比启用更重要。 工具描述里明确写清楚"什么情况下不要用这个工具",比写一百字使用场景更有效。模型对否定约束的响应出奇地好。
阶段性重置。 如果一个任务天然可以拆成多个阶段,在每个阶段结束的时候主动清理上下文,只保留阶段结果摘要,不保留中间推理过程。这比跑完整个任务再清理效果好得多。
实测,不要靠猜。 每条工具描述的改动,都拿一个测试集跑一遍看看工具调用率的变化。我改过一条工具描述,自认为优化了,结果准确率掉了 15 个百分点——改的地方让模型理解偏差了。
聊到这儿
我还在持续踩坑。这个领域没有教科书,大家都在黑暗中摸索。
不过有件事越来越确定:Agent 工程的下一个瓶颈不会在模型能力上,也不会在工具生态上,而是在你往上下文里放了什么、放了多少、怎么放的上面。
Context Engineering 这个名字听起来没有 MCP 或者 ReAct 那么酷,但它在生产环境里决定的事情,比大部分酷东西都多。
你遇到过类似的 Agent 抽风问题吗?
评论
发表评论