跳到主要内容

Agent 上下文工程

上下文工程要解决的是:Agent 做下一步时,需要看到哪些指令、文件和近期结果。长期记录仍需单独保存,不能只依赖提示词。上下文窗口限制了模型一次能接收多少信息,却不保证这些信息都能被有效利用。《Lost in the Middle》发现,信息在长输入中的位置可能影响检索质量。因此,应优先提供与当前行动相关、仍然有效的证据,而不是把窗口填满。

本页关注一次任务的工作集:模型现在必须看到什么,哪些材料可以留在窗口之外。怎样找到候选材料见检索流程,怎样跨任务保存和更新信息见Agent 记忆。

在二十篇文档中,含答案的文档移到中间时,回答准确率下降;虚线表示不提供文档的基线。查看清晰大图

沿横轴看:总共 20 篇文档、约 4,000 个 token,变化的是含答案段落的位置。纵轴是问答准确率,不是检索器的召回率。在这次 GPT-3.5-Turbo-0613 实验中,答案放在中间时的表现低于两端;虚线是不提供文档的闭卷基线。可以据此测试所用模型对证据位置是否敏感,但不能把这条历史曲线当作所有模型的成绩。

上下文中该放什么​

前四层可以进入 Prompt。持久状态留在外部,仅在需要时按需加载。对话记录(Transcript)只是交互历史,不应作为项目的唯一事实来源(System of Record)。

先检索,再压缩​

在让模型总结之前,先通过符号、调用点、测试用例和定义搜索确凿的证据。总结无法恢复从未被检索到的材料,而反复总结容易将猜测悄悄固化为事实。

实用的输入预算计算如下:

可用输入=模型上限−预留输出−工具/schema 开销−安全余量.\text{可用输入}=\text{模型上限}-\text{预留输出}-\text{工具/schema 开销}-\text{安全余量}.

规则、证据和输出之间没有通用的比例分配。下一步行动应决定任务包的内容。本地模型可能在达到宣传的上下文极限之前,就先触碰到 KV 缓存或内存限制。

任务包示例​

针对一个在处理分割 UTF-8 序列时失败的解析器,一个有效的任务包可能如下所示:

contract:
write_scope: [src/parser.py, tests/test_parser.py]
success: targeted test and parser suite pass
state:
attempted: boundary check after byte slicing
result: still fails on a split multibyte code point
working_set:
- parser function and two callers
- three relevant tests
- exact traceback
open_question: should truncation operate on bytes or Unicode code points?

包含整个仓库、完整的测试日志和所有早期假设虽然内容更多,但并不一定更有帮助。

保持工作集精简的方法​

技术适用场景主要风险
精确或符号搜索已知标识符和依赖项可能遗漏概念上的同义词
语料库检索从大量资料中挑出相关内容排序错误、文档过时或存在恶意内容
滚动总结关闭对话中已完成的部分来源丢失、总结偏差
提示词缓存提供商支持的稳定前缀重复使用前缀微小变化可能导致缓存失效
有界工具输出大型日志和命令结果被省略的中间内容可能包含关键原因
磁盘支持的任务记录需要跨重启保持状态的会话记录与仓库可能出现分歧

提示词缓存在指令和模式真正稳定不变时效果最佳。实际节省取决于提供商、模型、请求形状和缓存策略,应通过实测数据评估,而非直接套用宣传的百分比。

大型输出应完整存储;放进上下文时,只带上有用片段和原始文件位置。首尾截断只是一种选项,不能保证重要行一定被保留。

压缩时不掩盖不确定性​

总结时应保留:

  • 主张背后的来源或原始文件;
  • 陈述是观察所得、推断得出还是仅提出假设;
  • 失败的尝试,以避免重复错误;
  • 未解决的矛盾;
  • 下一个决策点,而非每一轮对话细节。

结构化状态通常比散文式回顾更易于检查,但这并不意味着它自动正确。尽可能原子化地更新状态,并在恢复时与当前文件进行核对。

如何测试上下文策略​

将相同的证据分别放置在开头、中间和结尾进行测试。添加无关和冲突的文档。包含一个正确答案为“证据不足”的案例。测量任务成功率、遗漏的约束、归因准确性、延迟和 Token 使用情况。

有用的失败标签包括:上下文堆砌、近因偏差、总结漂移、检索偏差和隐藏状态依赖。这些名称是诊断捷径,而非引入另一个框架的理由。解决办法通常是移除无关材料、检索更好的证据,或将持久状态移出提示词。

探索关联打开关联网络