04 - 卸载到外部
前置:03 篇。压缩和裁剪都是有损的;本篇是第三种选择 —— 不砍,挪出去。
本篇回答:把内容放到上下文之外的三条路线各自怎么工作,以及它们分别把问题推到了哪里 —— 卸载不消灭成本,只是换一种形式付。
本篇会用到的词:
| 词 | 意思 |
|---|---|
| 卸载(offload) | 内容存在上下文之外,上下文里只留一个能取回它的指针 |
| 结构化笔记 | Agent 自己在外部维护的进度、决策、待办文件。它写,它自己读 |
| 子 Agent | 独立开一个上下文窗口去做某个子任务,只把结论返回给主 Agent |
| 即时检索 | 不预先把内容塞进上下文,等真正需要时再去取。区别于"启动时全部加载" |
| 指针 | 文件路径、记录 ID、URL 这类几十 token 的引用 |
一、共同结构:上下文里只留指针
三条路线的形式不同,骨架是一样的:
report.md 这样的名字模型没法判断该不该读;report_2026Q2_财务_含分季度明细.md 才能让它在不打开的情况下做决策。这一点和记忆专题 05 篇里"文件式记忆靠模型看文件名猜"是同一个约束。二、路线 A:结构化笔记
Agent 在外部维护一组自己写、自己读的文件:进度、已做的决策、待办、踩过的坑。
<!-- progress.md —— 每个会话开头读、结尾写 -->
# 当前任务:把订单服务从 REST 迁到 gRPC
## 已完成(端到端验证过才写进这里)
- [x] proto 定义 —— 见 `api/order.proto`
- [x] 服务端实现 —— 单测通过,集成测试通过
## 进行中
- [ ] 客户端迁移 —— 已改完 3 个调用方,还剩 `billing` 和 `notify`
## 已确定的约束(不要重新讨论)
- 保留 REST 端点到 2026-12-31,两套并存
- 不引入新的序列化库,用现有的 protobuf 版本
## 踩过的坑
- `billing` 的超时是在网关侧配的,改客户端没用
三个设计要点:
- "已完成"的判据是端到端验证通过,不是代码写完。否则进度文件会越来越不可信,而它一旦不可信,整条路线就废了
- "已确定的约束"这一节比进度更重要。它防的是压缩之后模型重新讨论已经定过的事
- 一次只推进一个条目。同时开三件事,写回时容易把状态写乱
这条路线的实现形态在记忆专题 05 篇里讲透了(memory 工具的六个命令、路径穿越防护、Letta 的 git 版本化目录)。区别只在目的:那边关注跨会话保管,这边关注给当前上下文腾地方。
三、路线 B:子 Agent 隔离上下文
主 Agent 把 一个需要大量阅读的子任务交给子 Agent,子 Agent 用自己独立的上下文窗口去做,只把结论返回来。Anthropic 给的返回量级是 1,000 到 2,000 token。
代价要说清楚:
| 代价 | 具体 |
|---|---|
| 信息压缩比极高 | 110K 压到 1.5K,压缩比约 70:1。主 Agent 拿不到细节,也没法追问原文 |
| 不可回溯 | 子 Agent 的上下文用完即弃。主 Agent 后来发现摘要里某句话可疑,没法回去看依据 |
| 总 token 没降 | 三份资料照样被完整读了一遍,只是读在别处 |
| 延迟可能更高 | 能并行时更快,不能并行时是串行叠加 |
| 调试变难 | 出问题时要看四条 trace 而不是一条 |
适用判据:子任务是"读大量内容、产出一个结论"这种形状, 且结论本身足以支撑后续决策。如果主 Agent 后面还需要回到细节,这条路线就不合适 —— 改用路线 A(子 Agent 把细节写成文件,主 Agent 拿到路径)。
四、路线 C:即时检索
不预先加载,等需要时再取。这条路线在两个地方都在用:
- 文件系统:上下文里放目录列表,模型自己决定读哪个文件
- 工具定义:上下文里不放全部工具定义,模型搜索到再加载 —— 这就是05 篇的工具搜索
关键设计是元数据要足够模型做判断:
# ❌ 只给路径,模型只能靠猜或者全读一遍
context += "\n".join(["docs/a.md", "docs/b.md", "docs/c.md"])
# ✅ 给足够判断的元信息,让模型不打开就能筛掉大部分
# 多花的这几十 token,换回的是少读两个文件的几千 token
context += """
docs/api-v2-迁移指南.md (4.2K, 2026-07 更新) —— 从 v1 迁到 v2 的步骤与断点
docs/api-v1-历史设计.md (18K, 2024-03 更新) —— v1 的设计背景,已归档
docs/部署手册.md (6.1K, 2026-08 更新) —— 环境变量、灰度、回滚
"""
这里有一个和"卸载"方向相反的取舍:元数据本身也占上下文。三个文件的元信息才几十 token,三千个文件的目录列表就是几万 token —— 那时候元数据本身就成了要卸载的对象,得再套一层(先列目录、再列子目录)。
五、三条路线怎么选
| 维度 | A · 结构化笔记 | B · 子 Agent | C · 即时检索 |
|---|---|---|---|
| 卸载的是什么 | 进度与决策 | 一整段阅读与推理过程 | 尚未用到的资料与工具 |
| 主上下文里留什么 | 文件路径 | 1,000–2,000 token 的摘要 | 带元信息的索引 |
| 细节还能不能取回 | 能,重新读文件 | 不能,子上下文已弃 | 能,重新检索 |
| 额外的模型轮次 | 每次读写各一次 | 每个子任务一次完整会话 | 每次取回一次 |
| 总 token | 略增(读写的往返) | 基本不变 | 明显下降(大部分资料从没进过上下文) |
| 主要适合 | 长周期、可中断的任务 | 读得多、结论短的子任务 | 资料库大、单次只用一小部分 |
三条可以叠加,而且在成熟的 Agent 里通常是叠加的:子 Agent 把调研结论写成文件(B + A),主 Agent 通过带元信息的索引按需读(C)。
六、卸载把问题推到了哪里
这一节是这条路线最容易被跳过的部分。
七、小结
- 卸载不消灭成本,把"token 占用"换成了"模型轮次",是换货币不是免费
- 指针的质量决定成败:文件名必须让模型在不打开的情况下就能判断该不该读
- 结构化笔记的两个纪律:完成的判据是端到端验证通过,"已确定的约束"那一节比进度更重要
- 子 Agent 不省 token,省的是主 Agent 的上下文质量;代价是 70:1 的压缩比和不可回溯
- 即时检索的元数据本身也占上下文,资料量大到一定程度要再套一层索引
- 卸载的四类新问题里,"模型可能不去取"没有好办法 —— 关键信息不要卸载
下一篇:05 - 工具与检索结果的占用,第三类手段 —— 从源头上就别让它进来。
← 回到 专题索引