这是《深入理解 AI Agent》精读专题的第五篇,正式进入第 2 章正篇。读的是李博杰的开源书第二章的 API 消息结构与 KV Cache——上下文工程的地基。
本章思维导图见 专题页 · 章节思维导图
上下文在 API 里长什么样
上一阶段说过:上下文由五个部分组成,包括静态前缀和动态轨迹。到了 API 层面,它就是 messages 列表里的一条条消息。每条消息都带角色标记,一共四种角色:
- system(系统):开发者写的规则与说明
- user(用户):用户输入
- assistant(模型):模型生成的回复,可能携带 tool_calls
- tool(工具):Agent 框架执行工具后写回的结果,靠
tool_call_id与调用一一对应
三个容易忽略的细节:
- 每次调用都是无状态的——模型不会「记住」上一次的对话,Agent 框架必须每次把完整历史送回去。所谓多轮对话,其实是同一个列表被反复发送。
- 模型上一轮的 assistant 消息要原样放回消息列表——让模型「看到」自己之前做了什么决策。
- Agent 框架的核心工作就是管理这个 messages 列表:在合适的时机往里追加,然后整个送给模型。本章后续所有的上下文工程技术,本质上都是在优化这个列表。
ReAct 的终止,就一行判断
第 1 章讲了 ReAct 循环怎么转,第 2 章补上了它在 API 层面的实现和终止判断:模型直接回复用户、不携带工具调用指令,循环就结束;只要返回里还有 tool_calls,就执行工具、追加结果、再来一轮。书里核心循环的退出判断就一行:
1 | if not assistant_message.tool_calls: |
异常退路另有几条:调用最终输出工具、遇到错误、达到最大轮数——但正常收工的信号就是这一条。
KV Cache:静态前缀放最前面的原因
上下文设计里,静态前缀放在最前面,模型会使用 KV cache——Transformer 架构里缓存下来的 Key 和 Value(注意力机制的两类向量):已经算过的 token 键值对留在缓存里,新 token 只算增量,不必每轮重跑整个前缀。
书里有个故事把代价讲得非常具体:某客服 Agent 每天处理 10 万次对话,工程师为了让模型「知道」当前时间,在系统提示词里加了一行 Current time: {{now}}。第二天监控告警:首 token 延迟从 0.5 秒涨到 3–5 秒,月度推理账单几乎翻倍——时间戳每次都不同,从它所在位置起,缓存全部失效。
精确一点,缓存有两个层级,原理相同(前缀不变性)、层级不同:
- KV Cache:模型内部,缓存单次推理中已计算的键值对
- Prompt Cache:推理引擎/服务商,在多次 API 请求之间复用相同前缀的计算结果,缓存读取约为首次计算的十分之一价格
静态前缀放最前面且保持稳定,跨请求命中的主要是 Prompt Cache——但原理都一样:前面不能动,后面尽管加。
这个区分还有一个落点:fork 子 Agent 时的字节级对齐。主 Agent 派生子 Agent 或发起旁路查询时,如果子 Agent 继承父 Agent 的上下文,那么提示词、工具定义、模型配置、消息前缀和思考配置都要与父 Agent 逐字节匹配——这样才能命中 API 服务商的 Prompt Cache,省下费用和延迟。原文也注明了边界:如果子 Agent 本来就用不同的上下文或提示词,自然不要求字节级对齐。
三条铁律
书里把这个技术密度最高的章节压缩成三条核心结论,我把它们当上下文设计的铁律:
- 静态前缀一旦确定就不要随意修改——哪怕多一个空格,首个不同 token 之后的缓存全部失效;改动越靠前,代价越大。
- 只增不改,动态信息永远追加到末尾——时间戳、用户状态这些变化的内容,作为新消息追加,而不是去改系统提示词。第一章设计模式里的「只增不改」在这里再次出现:Append-only 换来缓存命中率,还顺手可重放、可审计。
- 遵守 API 规范,不要自行拼接消息——结构化消息会被 Chat Template 翻译成模型训练时见过的固定 token 序列;自行拼成
"USER: ... ASSISTANT: ..."的根本问题不在缓存(缓存只认字节序列,拼得稳定照样命中),而在偏离了训练格式:模型要多花注意力去推断角色边界,把工具结果拼成 user 消息还会破坏思维链保留机制——相当于模型算到一半,草稿纸被收走了,多步推理只能从零再来。
下一步
- 第 2 章继续:提示注入攻防、Agent Skills、上下文压缩
kv-cache与context-compression两个实验,找时间一起跑
参考来源
- 《深入理解 AI Agent:设计原理与工程实践》第 2 章「上下文工程」,李博杰著,GitHub 开源
- 本篇覆盖第二章「API 消息结构」「KV Cache 友好的上下文设计」;官方学习建议