上下文的地基:每次调用都是无状态的
这一章讲三件事: 「上下文」在 API(程序之间相互调用的约定,行话也叫接口)层面到底长什么样;一个最小可用的 Agent 循环有多少行代码;以及那个让后面一切技术(缓存、压缩、Skills)都 站得住的结构事实——上下文分两半,前半不能动,后半一直在长。
1. 这一章讲什么
第 01 章说上下文是「Agent 的眼睛」。这一章把这双眼睛拆到 API 的字节(信息的最小存储单位)层面: 你发出去的每个请求里到底有什么,模型「看到」的顺序是什么,以及为什么 「上一轮说过什么」这件事,必须由外部代码一遍遍替模型重新送。
先给这一章最重要的一句话:上下文工程(系统性地设计、组织 AI 完成任务所需的全部 背景,而不是往提示词里堆料)之所以成立,是因为模型侧有个硬约束——每次调用 都是无状态的:模型不「记住」上一次说了什么,所有它需要的信息,必须在这一次 请求里完整给到1。
2. 顶层全景
你的代码 模型服务
──────── ────────
组装 messages 列表 ──完整历史──▶ 读列表 → 回一条
▲ │
│ 把回复追加进列表 │
└── 需要调工具?执行,把结果也追加 ──┘
│
列表长一圈,再发一遍(从头发)
图说:所谓「对话」,就是同一份列表被反复重发、每轮长一截。
模型是纯函数:同样的列表进去,才有可能同样的回答出来。
3. 核心原理
3.1 先想清楚一件事:决定上限的是上下文, 不是模型
书里开篇讲了个扎心的现象:大模型标准测试成绩亮眼,一到真实业务就让人失望。 原因不神秘——你的产品架构、业务规则、内部约定,模型根本不知道2。 作者引了 OpenAI 研究员翁家翌的一句话:「人和模型一样,最重要的是 Context」, 他自己说,换一个人,只要有他在 OpenAI 积累的全部背景,也能干他的活3。
再往前一步,是本书少见地离开技术的一笔:上下文工程首先是组织问题。 多数团队的关键知识是隐性的——架构决策只在老员工脑子里,业务规则靠口口相传。 要喂给 AI,先得把这些写下来。所以「构建 AI 原生团队」的第一步是一场文档化运动: AI Agent 是一个永远的新员工,你得像给新员工准备入职手册一样准备上下文4。
3.2 消息的四种角色
API 层面,上下文就是一个消息列表,每条消息带 一个角色:
| 角色 | 谁在说 | 内容 |
|---|---|---|
| system | 开发者 | 行为规则(「你是客服,退款前必须核实订单」) |
| user | 用户 | 用户的输入 |
| assistant | 模型 | 模型的回复:文字、思考、或工具调用请求 |
| tool | 框架 | 工具执行的结果,用 tool_call_id 关联到是哪次调用5 |
这四种角色是全部后续章节的舞台:第 04 章讲的提示工程改的是 system, 状态栏借的是 user 的槽位(消息列表里留给某种角色的位置),压缩删的是 tool 与旧轮次。
3.3 主走查:两轮对话,列表怎么长
走查内容与消息结构来自原书的例子(问温哥华时间与天气);工具返回的具体 数值是原书演示 JSON(带名字标签的结构化数据格式)里的示例值。
第 1 轮。 用户问:「现在温哥华几点?」。代码发出的列表只有两条消息: 一条 system(「你是一个助手,可用工具如下:查时间、查天气……」),一条 user (「现在温哥华几点?」)。模型读完,回了一条 assistant 消息——注意, 这条消息里没有给用户的文字,只有一个工具调用请求: 「调 get_current_time,参数 timezone: America/Vancouver」。
框架接手。 代码解析(读出其中的指 令)这条请求,真的去调了时间服务,拿到
「2026-08-27 14:32 PDT」。它做两件事:把模型刚才那条 assistant 消息
原样追加进列表,再把工具结果作为一条 tool 消息(带着 tool_call_id: call_abc123)追加进去。现在列表四条。
第 2 次调用。 代码把整个四条列表重新发给模型。模型这次不再要工具, 直接吐出文字:「温哥华现在是下午 2 点 32 分」。列表五条,任务结束。
紧接着用户追问:「那温哥华天气如何?」 关键时刻来了——这次请求必须包含
前一轮的全部历史:system、第一条 user、第一条 assistant(那次工具调用)、
那条 tool 结果、模型的文字回复,再加上新的 user 提问。模型看到旧历史,发起
第二次工具调用(call_def456,查天气),框架执行、追加,第三次调用拿到
天气后给出最终回答6。
书里特意圈出三个最容易做错的细节7:
- 第二次请求包含第一次的全部历史——因为无状态,少一条模型就「失忆」;
- assistant 消息要原样放回——让模型能「看见」自己上一轮做了什么决策;
- tool 消息靠
tool_call_id对号入座——两个工具调用并行时,模型靠这个 字段(数据里带名字的格子)知道哪个结果对应哪次调用(第 01 章那次三路并行换汇,靠的就是它)。