本节摘要:本节先算清素材供给的两本账:预装把整份文档常驻窗口,付的是每轮全价重付的复利成本——一份 60k 的手册在 40 轮会话里累计 2.4M 输入 token(示意),而其中与任务相关的可能只有两页;按需(just-in-time,Anthropic 官方倡导)在本轮需要时才取回相关片段,付的是一跳检索延迟与检索质量风险。供给决策是权衡,不是信仰。然后讲两种按需形态:RAG——查询构造、top-k 检索、注入的三步流水线,配三条供给纪律(查询用本轮问题构造、k 由预算倒推、片段当轮有效用完即逐);repo map——编码场景的供给形态,代码库百万 token 级(1.1 节)永远装不下,改为常驻一张 2k~10k(示意)的仓库"地图"(符号骨架与摘要),具体文件按需读取,检索的决策权在模型手里(agentic 检索)。最后给按需供给的代价清单与兜底。检索与 repo map 的实现深潜见《语义代码检索》第 6 章。
阅读完本节,你应当能够:
1.1 节的事故案例值得重算一遍(示意数字):128k 窗口,预装 60k 产品手册全文,挂 20 个工具(5k),跑 30 轮历史(20k)。
| 供给方式 | 单轮素材成本 | 40 轮累计输入(示意) | 附带代价 |
|---|---|---|---|
| 预装手册全文 | 60k | 2.4M token | 注意力稀释:相关的只有两页,其余 58k 每轮都在稀释它们(1.1) |
| 按需取片段 | 2k(4 段 × 0.5k) | 80k token + 40 次检索调用 | 一跳延迟;取错了答题依据就错 |
差距是 30 倍量级(示意),方向一边倒——但按需不是免费的,它引入三笔新成本:延迟(每次检索多一跳,几十到几百毫秒,示意)、检索质量风险(检索不准,模型要么答错要么硬编)、兜底复杂度(检索为空时系统要有一条定义良好的退路,5.2 节)。所以供给决策的完整形式是:
预装的适用面:极小(单份文档 < 数 k token 且每轮必用,如一段格式约定) 按需的适用面:几乎一切大素材(文档库、代码库、日志、工单历史) 判据:相关密度 × 使用频率 —— 相关密度低的大素材,预装即是负资产
💡 别忘了 1.1 节的成本推论:多数 API 按输入 token 计费——预装素材是复利成本,按需供给省下的每一个 token 都乘以轮数。
RAG(Retrieval-Augmented Generation)的三步流水线:构造查询 → 检索 top-k → 注入窗口。工程上实现千差万别,但供给纪律只有三条:
⚠️ "检索结果不是记忆"的另一种表现:把查到的片段追加进会话历史永久保留——这是 4.1 节边界辨析的事故变体,窗口里堆满过期片段,预算被昨日之食吃光。
编码智能体的素材是代码库——中型代码库 500k5M+ token(1.1 节量级表),预装连讨论的资格都没有。编码场景的标准解法是 repo map:给窗口常驻一张仓库的地图而非领土——文件树、符号定义(类 / 函数 / 常量的名字与签名)、每文件一行职责摘要。量级 2k10k token(示意),换取的是模型对"仓库里有什么、在哪"的全局感。
工作循环长这样:
看地图(repo map 常驻)→ 锁定目标("退款逻辑在 payments/refund.py") → 按需读取(read / grep 工具调用,结果作为素材进窗口) → 结论引用化(读过即逐,留"路径 + 一行结论",2.1 节) → 需要时再看地图、再读文件
注意这个循环里检索的决策权在模型手里——由模型决定调用 grep 还是 read、读哪个文件,而不是管道固定"查询 → top-k"。这类把检索当作工具交给 Agent 自主调用的做法,社区称 agentic 检索。它与 RAG 的分工:
| RAG | repo map + agentic 检索 | |
|---|---|---|
| 决策权 | 管道(每轮固定检索) | 模型(自主决定查什么、读哪里) |
| 常驻开销 | 无(查询时才有) | 一张地图(2k~10k,示意) |
| 适用素材 | 非结构化文档(政策、FAQ) | 结构化大仓库(代码、配置) |
| 失效模式 | 检索不准 → 答案错 | 地图过时 / 模型不会用工具 |
repo map 怎么生成、符号怎么抽取与摘要、agentic 检索的工程细节——实现层全部外委:repo map 实现见《语义代码检索》第 6 章(纯文字互引,不在此展开)。
💡 两种形态不是二选一:编码 Agent 也常配一个文档级 RAG(查 README、查历史决策记录),文档问答系统也会给模型一个"目录工具"让它自主翻库——按需供给是纲,RAG 与 repo map 只是这条纲在两类素材上的惯用形。
| 代价 | 症状 | 兜底 |
|---|---|---|
| 延迟 | 每轮多一跳检索,流式响应被卡 | 并行检索(多路查询同时发);会话内缓存(同查询复用上一轮结果,注意 TTL) |
| 检索质量 | top-k 全不相关,白占预算还带偏答案 | 分数阈值:低于阈值的宁可不取(5.2);粗排 + 重排两级(重排深潜见《语义代码检索》第 5 章) |
| 空结果 | 检索无果时模型凭参数记忆硬答 | 行为契约写进输出:检索为空 = 明确告知"未找到依据",禁止编造(5.2 的引用约束) |
| 缓存失效 | 复用了过期片段(文档已改) | 缓存条目带 TTL + 来源版本号;素材的时效属性(1.2 节)同样适用于缓存 |
⚠️ 按需供给把一个质量问题(窗口装什么)转嫁成了另一个质量问题(检索准不准)。预算侧你赢了 30 倍,检索侧你欠了新债——这笔债的还法(索引、切块、重排、评测)是检索工程的领土,本书只负责把边界画清:检索器吐出来的 top-k 是候选,进不进窗口、进几段、摆哪里,仍是上下文工程的决策——正是下一节的内容。
片段取回来了,窗口里的素材位也留好了——但"取回来的东西"离"能答题的上下文"还差四道工序:选几段、按什么顺序摆、怎么标注、拿什么约束模型只能引用它们。下一节讲组装与引用。