上下文工程:Agent 的上限是 Context
接着第 1 章的地图,这一章钻进”上下文”——也就是 Agent 每次调模型时,模型真正能看到的那一坨信息。
拉胯的模型
标准测试里模型亮眼,一上业务就拉胯。原因往往不是模型笨,是它没背景:不知道你的产品架构、业务规则、历史对话。
书里一句话点透:人和模型一样,最重要的都是 Context。中等模型配精心设计的上下文,能压过顶级模型配信息匮乏。
更狠的是:上下文不只是技术问题,还是组织问题。团队知识要是都藏在老人脑子里,Agent 也无计可施。所以构建 AI 原生团队,第一步其实是文档化运动。
(我的理解:这解释了为什么很多公司 RAG 做不起来——根子在知识没沉淀成文档,而不是检索算法不行。)
Agent 怎么调大模型
先纠正一个错觉:大模型 API 是无状态的。每发一次请求,得把完整历史重新发一遍。框架在背后帮你干这事——典型循环就是第 1 章说的 ReAct:请求 → 模型返 tool_calls → 框架执行 → tool 结果回传 → 再请求。
代码骨架其实就是个 while True:不断往 messages 里追加,模型不再调工具就断。
KV Cache 是个隐藏的架构约束
这块是生产级 Agent 最容易被忽略的。推理时,算过的 token 的 K/V 向量会被缓存(KV Cache),下次同样前缀直接复用,又省又快。前提是:前缀得一模一样。
三条结论(踩过坑才懂):
- 系统提示词和工具定义一旦定下,就别改——改一个字缓存可能就失效
- 动态信息(比如时间戳)永远追加到末尾,别插前面
- 用标准 API 格式传消息,别自己拼 “USER: … ASSISTANT: …” 字符串
书里举了个真实翻车:给客服 Agent 的系统提示词里加了个 Current time: {{now}},结果每次请求前缀都变,KV Cache 全废,首 token 延迟从 0.5s 飙到 3–5s,账单直接翻倍。
缓存经济性不是事后优化,是设计初期就得想清楚的架构约束。
提示工程:把系统提示词写明白
- 语气:关键约束用大写,别写成长篇辩护
- 结构化:XML 标语义、Markdown 管层次,俩配合
- 流程优于规则堆砌:与其写一百条散规则,不如写一份 SOP 流程
- 业务规则要可执行:书里例子,退款计费”绝不用百分比”,得是产品经理拍板的硬规则
- 难描述的给 few-shot:2–3 个例子塞进静态前缀,稳定
- 工具定义写清边界和示例
- 防提示注入:外部内容可能藏指令劫持 Agent,靠来源标记 + 角色结构化 + 清洗
前面聊了上下文为什么重要、怎么喂对。接着讲三个进阶手段。
能力太多,塞不进系统提示词怎么办
全塞进系统提示词,又费 token 又稀释注意力。书里的解法是 Agent Skills——把领域能力做成可组合单元,按需加载。
Skill 分三层:
- 元数据目录(SKILL.md 的 name + description):常驻上下文,就一小段
- 核心流程:被触发时才加载完整 SKILL.md
- 细则:再引用的子文档
这套叫”渐进式披露”。目录常驻、正文按需,KV Cache 只首载付一次费。
(我的理解:这跟第 1 章”渐进式披露”设计模式对上了,也解释了为什么现在 MCP / Skill 生态这么重要——本质是给上下文做懒加载。)
Agent 状态栏:给模型一个”便签”
上下文窗口像个只有一半的检索引擎:检索强,但没有提炼层。模型自己不会把”进度到哪了”提炼出来。
解法是在上下文末尾注入一段结构化元信息,叫 Agent 状态栏:任务 TODO、侧信道(时间/位置)、环境观察摘要。实现上作为末尾的 user 角色消息(注意不是真用户)。
两种更新方式:
- 每轮替换:移旧加新,缓存友好但要处理短后缀失效
- 持久追加:不删改,完全缓存友好,但陈旧信息会累积
书里给了个成本估算公式,结论挺直觉:状态变化频繁、且需要保留大量历史时,追加更划算;否则替换。
实验也验证了:没状态栏的小模型容易违反约束,加了就稳。
上下文压缩:爆了就压
动机有三:长度/成本卡死、提升思考质量(总结后更好用)、缓解”上下文焦虑”(模型误以为窗口要满就提前收尾)。
内部机制有点反直觉:上下文学习≈检索而非推理,压缩是把”要思考的结论”变成”可检索的知识”。
策略从简单到高级:
- 不压缩 → 个体摘要 → 组合摘要 → 上下文感知压缩 → 带引用 → 自适应窗口化
生产级一般分层做:工具结果控预算、噪声直接删、API 层微压缩、归档式摘要、最后全量压缩(带熔断器)。
一个关键原则:隔离优于压缩。海量噪声塞给子 Agent 处理,只回传摘要,比在主上下文里硬压更干净。
几个容易踩的坑
- 误以为 Agent 有状态——API 无状态,框架每轮重发全历史
- 改 system 前缀任意字符(含空格)都会破 KV Cache
- 自己拼 “USER:… ASSISTANT:…” 偏离 Chat Template,思维链可能丢
- 不同模型对历史思考处理不同:DeepSeek R1 会剥掉历史 CoT,Claude 原样回传 thinking block 还带签名。接模型前查最新文档