最近看到一些围绕“RAG 已死”和“Coding Agent 为什么不使用传统 RAG”的讨论。对我来说,比判断一种技术是否过时更有价值的,是弄清楚:任务到底需要找什么信息,用什么方式找到它,以及找来的内容如何帮助模型回答。
这篇笔记保留我对检索方案的理解和选型思考,不推断具体产品当前的内部实现,也不把讨论中的观点当成已经完成的实验结论。
一、先明确讨论中的 RAG 指什么
我会先把两个概念分开:
- 广义的检索增强生成:先获取外部信息,再把相关内容交给模型生成回答。这里的检索可以是关键词搜索、代码搜索、网页搜索或数据库查询。
- 讨论中常见的向量 RAG 流水线:文档切块、生成 embedding、建立向量索引、召回相关片段,再组织上下文。
这只是为了明确本文的讨论范围,并不是说 RAG 只能由这两种方式定义。关键词检索、向量检索、混合召回和多轮搜索,本来就可以组合。
因此,看到“某个 Agent 不用 RAG”时,我首先会追问:它不依赖外部检索,还是没有采用预先建立向量索引的那条路径?这两个判断差别很大。
我不认同直接把“某些场景不使用向量索引”推导成“检索增强已经失去价值”。
二、数据怎么组织,会影响检索的起点
| 观察维度 | 文档知识库 | 代码库 |
|---|---|---|
| 可利用的组织信息 | 标题、章节、目录、元数据,完整程度因资料而异 | 文件路径、模块、符号、导入关系等 |
| 常见检索需求 | 按含义寻找相关论述、规则和依据 | 定位符号、调用位置、行为实现和相关测试 |
| 字面检索的优势 | 精确条款号、术语、标题等明确线索 | 函数名、错误信息、配置键等明确线索 |
| 语义检索的价值 | 查询表述与原文措辞不同的时候 | 只知道行为描述、不知道符号名称的时候 |
如果我已经知道函数叫 generateResponse,优先搜索符号和字面内容通常是一个直接的起点。但如果问题是“哪里处理流式回复中断”,又不知道具体实现名,语义线索和多轮探索仍然可能有帮助。
同样,法律或业务文档也不一定缺少结构,它们可能有清晰的章节、条款和元数据。不能仅凭“代码”或“文档”两个标签决定检索方案。
我更关心的是:当前问题有没有可靠的定位线索,数据是否提供可以利用的结构。
三、高频变更增加了索引同步的要求
代码频繁变化时,我会特别关注检索结果是否对应当前工作区。即使找到的片段很相关,如果它来自旧版本,也可能把模型带到错误方向。
采用向量索引,需要考虑变更检测、增量更新、删除处理,以及不同分支或工作区之间的隔离。这些是工程成本,但不意味着每次修改都必须重建整个索引。
直接搜索当前文件也有自己的成本:搜索范围可能过大,结果可能嘈杂,复杂问题可能需要多轮查询和读取。
我的判断方式是把两类成本一起看:维护索引要付出什么,放弃索引后又会增加多少搜索时间和模型调用。
四、长上下文改变了取舍,但没有替我们完成检索
上下文容量变大之后,有些小型资料集可以直接放入模型,也有些任务值得保留完整文件,以免切块丢失依赖关系。
但“能装进去”和“适合全部装进去”是两回事。我仍然会问:
- 资料是否真的能放入当前上下文预算?
- 输入的成本和延迟是否可以接受?
- 无关内容会不会干扰定位和推理?
- 当前任务需要完整关系,还是只需要少量证据?
长上下文可以减少某些任务对复杂检索流程的依赖,却不能自动保证信息利用效果。反过来,片段也不是越短越好:缺少定义、前提和调用关系,可能让回答失去依据。
我倾向于根据任务在完整内容与相关片段之间选择,而不是把“全部塞进去”或“只给 top-k”当成固定答案。
五、Agentic Search 与向量检索可以互相补充
我理解的 Agentic Search,是让模型根据已有结果决定下一次搜索或读取动作:
提出初始查询
→ 阅读搜索结果
→ 发现新线索或缺口
→ 改写查询、切换工具或继续读取
→ 收集足够证据后回答
它强调的是检索过程如何被组织,不是某一种底层搜索算法。循环里既可以使用字面搜索、BM25,也可以使用向量检索。
多轮探索的吸引力在于:模型不必一次猜中正确问题,可以逐步从路径、符号和相关内容中扩大或缩小范围。对应的代价是额外轮次、模型调用和上下文开销,也依赖模型能否判断下一步该查什么。
向量召回则可以作为候选发现的一步,再配合关键词、元数据过滤、重排和后续读取。是否更快、更省或更准确,需要在实际任务上测量。
我不会因为一种方法是多轮的,就认为它一定优于单次召回;也不会因为检索由向量完成,就认为整个回答流程已经高效可靠。
六、把质量、成本、时效性和权限一起纳入选型
做检索选型时,我会从以下几个问题入手:
| 问题 | 我会考虑的方案与检查点 |
|---|---|
| 已知精确名称、编号或错误文本吗? | 先尝试字面、符号或字段查询 |
| 用户只知道含义,原文表述可能不同吗? | 尝试向量召回或混合检索 |
| 数据有可用的字段、目录和关系吗? | 优先利用过滤、结构化查询和导航信息 |
| 一次检索经常无法得到完整证据吗? | 评估多轮搜索、查询改写和关联读取 |
| 数据变化频繁吗? | 检查版本一致性、索引更新延迟和当前文件读取 |
| 延迟和成本限制严格吗? | 限制轮次、候选量和读取规模,并实测端到端成本 |
| 数据有访问权限或隔离要求吗? | 在检索和结果读取阶段验证权限、存储及缓存边界 |
安全性也不能只根据“有没有索引”判断。索引存储、检索服务、日志、缓存和模型输入都有各自的数据边界,直接搜索同样需要访问控制。
对我来说,选型不是先挑一个技术名字,而是先明确任务的证据需求,再选择能够满足它的最小可行组合。
七、减少 token 消耗,要关注实际读进来的内容
如果 Agent 已经定位到一个函数,却仍然反复读取整个大文件,我会检查能否使用行范围、符号范围或相关片段缩小输入。
但不能为了减少 token 切掉必要上下文。函数依赖的类型、调用方、配置和测试,可能正是判断行为所需要的证据。
我会优先尝试:
- 先搜索定位,再按范围读取。
- 对已读取内容去重,避免重复塞入上下文。
- 保留路径、行号或来源信息,方便回到原文核实。
- 证据不足时按需扩展,而不是一次读取所有资料。
- 给多轮检索设置停止条件,避免无目的地循环。
这些方法是否有效,应该观察任务成功率、遗漏情况、延迟和输入输出 token,而不是只比较输入长度。
八、我会怎样回答“RAG 是否过时”
我的回答会先明确对方指的是广义检索增强,还是切块、embedding 和向量索引的具体路线。
随后围绕数据规模、结构、变更频率、权限、延迟和成本展开:已知明确符号时可以先做字面定位;需要跨表述发现相关内容时,可以考虑语义或混合检索;需要逐步探索时,可以由 Agent 编排多轮检索。
最后用真实任务验证。至少比较答案是否有依据、是否遗漏关键信息、检索内容是否最新,以及整个流程的成本和延迟。没有同口径评估,就不轻易宣称某种方案全面胜出。
这次讨论带给我的提醒是:不要用“已死”替代工程判断。检索方案的价值,最终体现在它能否以可接受的成本,为当前任务提供正确、及时、权限合规的证据。