本文收录于专栏《AI Agent原理与实战》2026版—— 专栏系统覆盖 AI Agent 的记忆、工具、插件与实战,点击订阅可跟踪后续更新。
本课定位:跑得越久,上下文越挤。本课讲上下文工程:构成与权衡、四大操作(写入/选择/压缩/隔离)、四种失败模式、token 账本实战。第 7 课的"工具描述烧 token"在这里算总账;第 26 课的成本控制以此为地基。
阶段 2|单 Agent 核心机制 | 来源:【微·12】(微软 AI Agents for Beginners 第 12 课)
关键字:上下文工程、Context Engineering、上下文压缩、token管理、信息选择、上下文隔离、失败模式、长对话管理
本节目录
- 13.1 上下文的构成与权衡
- 13.2 与 Prompt Engineering 的分界
- 13.3 四大操作:写入、选择、压缩、隔离
- 13.4 四种上下文失败模式
- 13.5 检查上下文:别只管进,还要看进了什么
- 13.6 核心代码
- 13.7 实测账本
- 13.8 动手练习
概念讲解
13.1 上下文的构成与权衡
微软原课把 Agent 需要管理的上下文分成五类:
| 来源 | 内容 | 增长行为 |
|---|---|---|
| 指令(Instructions) | 系统提示、few-shot 示例、工具描述 | 固定,每轮都在 |
| 知识(Knowledge) | RAG 检索结果、数据库查询结果 | 每次检索跳涨 |
| 工具(Tools) | 工具定义 schema + 调用结果 | 定义固定,结果累积 |
| 对话历史(History) | 用户/助手往来消息 | 随轮次线性增长 |
| 用户偏好(Preferences) | 长期学到的用户习惯 | 缓慢增长 |
权衡的两端都不好受:太少——模型缺信息,瞎猜、编造、反复问;太多——不只是贵:注意力被稀释后判断质量下降(“上下文腐烂”,context rot——Anthropic 的提法:窗口内每个 token 都在消耗注意力预算,窗口越满精度越低,200K 窗口的任务可能在半满时就开始劣化)。原课给的直觉:错误常在窗口装满之前就发生。
13.2 与 Prompt Engineering 的分界
一句话分界(原课口径):prompt engineering 优化一段静态指令;context engineering 管理一个动态信息系统。前者是写好一份说明书,后者是设计"什么信息、什么时候、怎么进窗口"的流水线——包括把信息挪出窗口(文件、记忆库、子 Agent)再按需取回。
原课还给了配套的三步规划法(在写任何策略之前先走):①定义明确的结果——任务完成时世界是什么样?用户拿到什么变化/信息/回应;②绘制上下文图谱——完成任务需要哪些信息?这些信息分别在哪里;③创建上下文流水线——Agent 怎么获取这些信息?RAG、MCP 服务器、工具调用都是管道选项。这三步与第 10 课规划是同一件事的两面:第 10 课拆"做什么",这里拆"每一步窗口里该有什么"。
13.3 四大操作:写入、选择、压缩、隔离
原课的策略清单可以归纳为四个动词——写入(write)、选择(select)、压缩(compress)、隔离(isolate)。这个四动词框架由 LangChain 于 2025 年 7 月在《Context Engineering for Agents》一文中系统化提出,微软原课的六条实践策略(便签、记忆、压缩、多 Agent、沙箱、运行时状态对象)以及 Anthropic 在《Effective context engineering for AI agents》(2025-09)中的论述都能映射进这四个动词——三家口径在操作层面高度一致:
写入(Write):Agent 用 scratchpad(便签)把任务关键状态记到窗口外的文件或运行时对象,需要时再读回。窗口里只留指针,不留全文。Claude Code 的 TODO 文件、进度文件都是这个模式。
选择(Select):进窗口前先筛选——RAG 的 top-k 截断、工具描述的按需加载(第 8 课的 response_format 是选择手段之一)、记忆检索的相关性排序。原则:宁可漏掉可再取的,不可塞进用不上的。
压缩(Compress):窗口逼近上限时,摘要 + 裁剪。做法:旧轮次压成摘要消息、超长工具输出只留结论、保留最近 N 轮原文 + 更早的摘要。工程上各家阈值不同(Claude Code 在窗口约 95% 时自动压缩,有的框架默认 85%)——关键是触发条件要确定性(按 token 计数,不靠模型自觉)。
隔离(Isolate):把大任务拆给子 Agent,各自开干净窗口,只回传 1-2K token 的摘要给父 Agent。第 22 课的 orchestrator-workers 本质上就是隔离策略的组织化。
13.4 四种上下文失败模式
原课总结了四个典型翻车场景,诊断时按图索骥:
| 失败模式 | 症状 | 解法 |
|---|---|---|
| 毒化(Poisoning) | 一条幻觉/错误信息进窗口,被反复引用,Agent 追不可能的目标 | 入窗前校验 + 隔离坏信息(第 12 课外部验证) |
| 分心(Distraction) | 窗口塞满旧细节,Agent 纠缠历史而忽略当前请求 | 定期摘要压缩 |
| 混淆(Confusion) | 工具太多,描述重叠,选错工具 | 工具分组按需加载(第 8 课命名空间 + RAG over tools) |
| 冲突(Clash) | 窗口内新旧信息矛盾,推理摇摆 | 剪枝过时信息 + 显式标注信息新旧 |
13.5 检查上下文:别只管进,还要看进了什么
原课特别强调一步常被跳过的工程动作:审查每次模型调用实际收到了什么。调试三问:"装太多了?装错了?还是漏了该装的?"生产环境不需要记录原始 prompt(隐私+体积),记账本就够:候选多少条、选中多少条、压缩前后 token 数、哪个子任务的输出被隔离在窗口外。这就是下一节案例的主角——token 账本。
案例实战:长任务的 token 账本
目标
一个"逐篇读论文做笔记"的研究助理 Agent(10 篇、每篇约 700 字),对比两种上下文策略的逐轮 token 账本:
- 策略 A 累积式:全部历史塞着走(基线)
- 策略 B 滚动摘要式:每 3 篇把旧笔记压缩成摘要消息,窗口只保留 [系统提示 + 总任务 + 摘要 + 最近 2 组消息]
环境
- Windows(推荐):Windows 10/11 + Python 3.9+,
pip install openai==3.6.0,setx DEEPSEEK_API_KEY "sk-..."后新开终端运行python 13_context_ledger.py——脚本无操作系统相关依赖 - Linux(本课实测环境):Ubuntu 22.04,Python 3.10.12,openai 3.6.0,deepseek-chat,2026-10-01 实测
- 两种策略各约 5-8 次 API 调用,全程约 3-4 分钟。注意:模型行为有随机性,绝对 token 数每次运行会有浮动,但"累积式单调递增 vs 滚动摘要锯齿形"的形状稳定可复现
- 换国内模型(GLM/MiniMax/MiMo):接入参数与实测行为见第 7 课"国内模型适配"节,代码改
base_url与model两行;token 账本的具体数值随模型分词器不同而不同,对比结论(形状)不受影响
13.6 核心代码
# 13_context_ledger.py(节选:B 的滚动窗口,配对完整性是关键)defstrategy_rolling(n_papers=10,keep_recent=2,compress_every=3):summary,ledger,raw_tail=None,[],[]# raw_tail 每元素 = 一组配对完整的消息foriinrange(1,n_papers+1):view=[系统提示,总任务]# 骨架永远保留ifsummary:view.append({"role":"system","content":f"[已读论文要点摘要]\n{summary}"})view+=[mforgroupinraw_tailformingroup]r=client.chat.completions.create(model=MODEL,messages=view,tools=...,...)# ...执行工具调用,组 = 决策消息 + 所有 tool 响应 + 一句话笔记ifi%compress_every==0:# 确定性触发,按篇数不按模型自觉notes=[...旧组里的 assistant 笔记...]summary=compress(notes)# 一次额外 LLM 调用换窗口瘦身raw_tail=raw_tail[-keep_recent:]# 只留最近 2 组returnledger,messages【已实测】2026-10-01,deepseek-chat。
13.7 实测账本
策略 A(累积式):
第 1篇: prompt= 320 completion=332 ← 起步很便宜 第 3篇: prompt= 5062 completion=50 ← 模型批量预读,历史暴涨 第 5篇: prompt= 5559 completion=50 第 7篇: prompt= 6056 completion=50 ← 单调递增,看不到头 第 9篇: prompt= 6553 completion=50 A 总消耗: 24,082 tokens策略 B(滚动摘要式):
第 1篇: prompt= 320 completion=329 第 3篇: prompt= 5075 completion=88 ← 压缩前最后一次全量 第 5篇: prompt= 947 completion=105 ← 压缩生效!窗口瘦回 1/5 第 6篇: prompt= 1975 completion=66 第 8篇: prompt= 2434 completion=68 ← 在低位缓慢爬升(2 组原文 + 摘要) 第10篇: prompt= 1427 completion=78 ← 又一次压缩后回落 B 总消耗: 17,908 tokens(为 A 的 74.4%)三条解读:
- 账本形状即策略指纹。A 的 prompt 单调爬升(每轮都为全部历史付费,且越往后越贵);B 呈锯齿形——压缩点回落、组间缓升。10 篇只省 26%,但差距随任务长度放大:A 是 O(n²) 累计(n 轮每轮带 n 轮历史),B 是 O(n)——100 篇的任务里 B 会便宜一个数量级。
- 压缩不是免费的。每次压缩多一次 LLM 调用(把旧笔记变成摘要的这次调用本身也花钱),且压缩会丢细节——若最终问题恰好问"第 2 篇的实验数字是多少",B 只能从摘要里答"关于稀疏化的改进方法",答不出具体数字。压缩比和保留策略是业务决策:摘要保结论、原文保最近、关键数据写文件(写入策略)三件套配合。
- 窗口裁剪的第一坑:消息配对完整性。本案例实测踩到:裁剪窗口时把 assistant 的 tool_calls 决策消息切在了边界外、对应的 tool 消息留在窗口内,API 直接 400(“insufficient tool messages following tool_calls message”)。裁剪必须按组为单位——决策消息和它的所有 tool 响应同生共死。这也解释了为什么生产系统都用框架管理这段逻辑(第 15-17 课)。
13.8 动手练习
- 把
keep_recent改成 1、compress_every改成 2,观察 B 的总消耗先降后升——压缩太频繁时,压缩调用本身的开销反噬。找出这组参数下的最优点。 - 在最终汇总前,问 Agent"第 2 篇论文的具体实验数字"——亲测压缩的信息损失边界,体会什么信息必须走"写入文件"而不是摘要。
小结
- 上下文窗口是统一预算:指令/知识/工具/历史/偏好五类信息在此竞争;太少缺信息,太多稀释注意力(context rot 在装满前就发生)。
- 四大操作:写入(挪出窗口)、选择(进前筛选)、压缩(摘要+裁剪)、隔离(子 Agent 干净窗口);触发条件要确定性。
- 四种失败模式:毒化、分心、混淆、冲突——按症状对号入座。
- 实测账本:累积式单调膨胀 O(n²),滚动摘要锯齿形 O(n);压缩有信息损失,关键数据走文件不走摘要;窗口裁剪以消息组为单位保配对。
上下文管的是"这一次会话内"的信息流。跨会话要记住用户偏好、历史经验,就需要外部存储与检索——第 14 课《记忆管理》收束单 Agent 机制的最后一块。
扩展阅读
🌐 网络提示:github.com 需代理(clone 可走 ghproxy 加速、push 优先 SSH);anthropic.com 需代理(核心结论已摘进本课正文);pip 安装建议加清华镜像
-i https://pypi.tuna.tsinghua.edu.cn/simple。详见总纲附录《国内网络访问与国产适配指南》。
- 微软原课第 12 课(Context Engineering):https://github.com/microsoft/ai-agents-for-beginners/tree/main/12-context-engineering
- Anthropic《Effective context engineering for AI agents》(2025-09):https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- LangChain《Context Engineering for Agents》(2025-07,write/select/compress/isolate 四动词框架的出处;原文页已随博客域名迁移,若链接失效可搜标题):https://blog.langchain.dev/context-engineering-for-ai-agents/
- 原课配套 notebook(chat 摘要压缩实操):课程仓库 12-context-engineering/code_samples/
我的专栏
| 蛋白 / 抗体 / 多肽 / 核酸 | 分子模拟 / 动力学 / 对接 | 药物 / 设计 / 案例 | AI / Agent / 大模型 |
|---|---|---|---|
| 开源蛋白结构预测 | 分子模拟基础 | 小分子药物设计案例 | AI Agent系列 |
| 开源蛋白生成方法实践 | 分子动力学模拟-Amber | 蛋白药物设计案例 | 化学大模型 |
| 开源多肽设计模型 | 分子动力学模拟-Gromacs | 多肽药物设计案例 | 《AI Agent原理与实战》 |
| 开源多肽性质预测 | 分子动力学模拟-OpenMM | 开源小分子生成设计 | CADD中的机器学习模型 |
| DNA/RNA药物设计 | 結合自由能 | 高效计算配置 | 《MCP 入门实战》 |
| siRNA药物设计模型 | UCSF DOCK系列 | 我胡师兄说药 | 《AI入门实战2026》 |
| ASO药物设计模型 | rDock系列 LeDock系列 gnina系列 | 《经典机器学习实战》 |