简介:本文以“代码 Agent 该用什么检索”为评测对象,拆解语义检索与工具驱动检索两类方案的评测维度、测试流程与结果解读方式,帮助开发者判断在何种代码库规模、任务类型与合规要求下,向量索引仍值得保留。
近两年,代码类 AI Agent 的上下文获取方式出现了一次明显的范式迁移。一部分团队把“离线嵌入、建库、top-k 召回、再喂给模型”的检索增强生成链路,换成了让 Agent 自己调用文本检索、符号查找、按行区间读取等工具,按需探索代码库。
公开资料里有一个被反复引用的信号:某主流代码助手在 2025 年年中把向量检索管线整体下线,包括嵌入管线、本地向量库和分块策略,改由模型通过文本检索工具定位代码。据其参与者在公开访谈中回忆,新方案在效果上明显优于原有方案,而且优于预期。此后,同类产品在架构调整中陆续朝同一方向演进,学术评测中也有了“纯关键词工具链路的答案忠实度已接近检索增强生成方案”的测量结果。
需要先说清楚的是:向量数据库并没有“死亡”,它只是从“默认选项”降级成了“备选方案”。本文不打算站队,而是要回答一个更实用的问题:面对一个真实的代码库和业务需求,你如何用可观察、可复现、可解释的指标,判断自己该选哪一类检索方案,以及在什么条件下必须把向量索引重新加回来。
本次评测对象是“代码检索层”,即在 Agent 决定“去看哪一段代码”之前,负责提供候选上下文的整套机制。评测不针对某个具体产品,也不针对某一款模型,而是针对一类可复用的技术方案。
读者收益很具体:读完本文,你可以拿到一套检索层评测框架,知道该准备什么样的任务集、该控制哪些变量、该记录哪些数据,以及在拿到评测数字之后如何避免被单一指标误导。
适合读者包括四类人:一线开发者(关心接入成本和日常调试体验)、架构师与技术负责人(关心长期维护成本和合规风险)、平台与基础设施工程师(关心资源消耗和运维复杂度)、以及安全合规岗(关心数据副本的边界)。
任何检索层评测,最终都应该收敛到下面四个问题上,否则指标再多也无法支撑决策。
这四个问题的优先级依场景而变。日常开发辅助以效果与成本为主;企业内部代码资产以风险为主;平台化对外提供能力则必须同时看可观测性与可维护性。
为了评测可比,先把候选方案分成三类,避免把“模型能力”和“检索能力”混在一起算。
| 方案 | 核心机制 | 优势 | 固有短板 |
|---|---|---|---|
| 方案 A:语义/向量检索 | 离线分块 + 嵌入 + 向量近邻召回 + top-k 注入 | 对自然语言描述到代码的模糊映射友好;适合跨语言、跨命名习惯的概念检索 | 分块破坏结构关系;标识符精确匹配弱;索引随提交漂移;索引是代码副本 |
| 方案 B:关键词与结构检索 | 精确符号查找、文本匹配、语法树查询、调用关系查询 | 精确、零索引滞后、结果可追溯、无额外数据副本 | 依赖查询者知道“要找什么”;对纯语义描述的召回偏弱 |
| 方案 C:工具驱动的 agentic 检索 | 模型自主编排多次检索与读取,逐步收敛 | 多跳推理、按需扩大上下文、可自我纠正 | token 消耗与轮次不可控;易陷入循环;对模型能力依赖高 |
方案 C 在工程上通常是 B 的能力封装:它把“一次召回”变成“多轮定位 + 验证”,本质上是把检索决策权从离线管线交还给模型。这也是为什么很多团队的实测结果是 C 明显优于 A——它们比的不是同一种东西,而是“静态 top-k”对“动态多轮探索”。
一个必须纳入评测的参照项是“无检索基线”,即只把问题描述交给模型、不给任何仓库上下文。如果某个方案相对无检索基线的提升很有限,说明它贡献的主要是“提示工程噪声”而不是真实上下文。
评测维度必须可观察、可验证、可解释。建议采用下表框架,并根据场景调整权重。
| 维度 | 关注点 | 可观测指标 | 验证方式 |
|---|---|---|---|
| 功能完整性 | 是否覆盖定义查找、引用追踪、跨文件跳转、模糊概念检索 | 各检索能力的成功率、能力缺口清单 | 按能力项构造任务,逐项打分 |
| 准确性/有效性 | 定位是否准确,输出是否有据 | 任务解决率、定位首命中率、引用可核验率 | 与官方补丁比对 + 引用回溯校验 |
| 性能表现 | 定位耗时、端到端耗时、token 与读取量、并发承载 | 首字延迟、检索轮次、累计 token、读入字节数、QPS 与资源占用曲线 | 压测 + 埋点统计 |
| 稳定性 | 长会话、异常输入、依赖抖动、资源紧张 | 任务失败率、循环率、超时率、错误恢复率 | 长时运行 + 故障注入 |
| 易用性 | 接入与调试成本 | 接入步骤数、配置项数量、首次跑通耗时、误报定位耗时 | 由未参与开发者实操计时 |
| 兼容性 | 语言、构建体系、仓库布局、既有流水线的适配 | 支持语言清单、单仓与多仓支持、与现有工具链冲突项 | 多语言多布局样本集回归 |
| 安全性 | 权限模型、数据隔离、敏感信息 | 索引存储的访问控制强度、是否产生代码副本、审计日志完整度 | 权限越权测试 + 存储盘点 |
| 可观测性 | 定位过程是否可解释 | 结论是否可回溯到具体文件与行、召回路是否留痕 | 抽查链路记录 |
| 可维护性 | 升级与排障成本 | 版本升级影响面、故障恢复时间、容量规划难度 | 演练式验证 |
| 成本结构 | 构建、查询、运维、迁移四类成本 | 索引构建时长、增量更新频率、每任务 token、人力投入 | 分项计量,不合并成单一数字 |
评测前必须固定以下条件,否则结论不可复现:
第一步,建立基线。 先跑无检索基线,再跑各类检索方案,全部在同一模型、同一提示模板、同一预算下进行。没有基线的绝对数值没有意义。
第二步,控制变量。 一次只改一个因素。想比较分块策略,就固定召回数量;想比较召回数量,就固定分块方式。
第三步,分维度验证。 不要用“总体感觉更好”作为结论,而是分维度出数:效果看任务解决率与首命中率,性能看 token 与延迟,稳定性看循环率与超时率,安全看数据副本与权限。
第四步,记录过程数据。 除了最终结果,必须留痕每一次检索的查询、命中范围与模型采纳情况。判断“是不是检索层的问题”只能靠过程数据。
第五步,异常与边界测试。 包括空结果、超大文件、超长单文件、非 UTF-8 编码、生成代码目录、二进制资源、深层嵌套目录,以及依赖服务抖动和索引落后若干次提交的情况。
示意性的评测骨架伪代码如下,用于说明如何在同一工具接口下做 A/B 对照(纯通用示意,不代表任何真实产品接口):
def evaluate(repo_set, retriever, model, tasks, budget):records = []for repo in repo_set:for task in tasks:trace = run_agent(repo=repo,tools=retriever.build_tools(), # 唯一变量:检索层model=model, # 固定budget=budget, # 固定轮次与 token 上限)records.append({"resolved": judge_by_tests(trace.patch, task.tests),"first_hit": first_hit_rank(trace, task.target_span),"turns": trace.tool_call_count,"tokens": trace.token_usage,"read_bytes": trace.bytes_read,"stale_idx": retriever.index_lag_commits(repo), # 索引落后提交数"unresolved": trace.aborted_reason,})return summarize(records)
先看效果侧。公开基准资料中一个常被引用的对照是:在真实 GitHub issue 的修复基准上,最初的“分块 + 嵌入 + top-k + 生成补丁”最简方案解决率不足 2%;把检索改成工具调用后,第一个 Agent 原型就跳到 12% 以上。这条对照的真正价值不在于 2% 和 12% 这两个具体数字,而在于它揭示了一个评测原则:离线 top-k 召回的天花板很低,因为它无法根据中间结果调整下一步查询。 你在自己仓库里复现评测时,应当把“单轮召回上限”和“多轮探索上限”分开测,才能定位收益来自哪里。
一个容易混淆的点:接近两倍的性能差异,可能只是模型能力差异。判断办法是固定模型、只换检索层做 A/B,看差距是否仍然存在。
再看成本侧。一个方案可能在解决率上略高,但如果每个任务多消耗数倍 token 和数倍首字延迟,在交互式场景里体验会明显退化。成本必须分项呈现:索引构建成本、增量更新成本、每任务查询成本、运维人力成本,不要合成一个“便宜/贵”的结论。
稳定性侧最需要关注的是“自信的错误”。语义检索的失败模式往往是返回一个语义相近但无关的片段(例如把支付处理相关代码误当成目标),模型据此生成的补丁看起来合理却改错位置;精确检索的失败模式往往是直接返回空结果,模型会明确知道没找到并继续探索。在评测表里应把“错误可发现性”单列一栏,这比多几个百分点的解决率更影响真实可用性。
抛开具体数字,从技术机理上看,五类原因可以解释观察到的现象,也构成了评测时应当重点验证的假设。
这五条不是“向量检索无用”的论据,而是它的适用边界:当任务目标可以表述成“找语义相关的内容”时它有价值,当任务目标是“定位唯一确定的符号及其影响面”时它不占优势。
不同场景下应关注的指标完全不同,不存在统一最优解。
| 场景 | 首要关注 | 次要关注 | 建议倾向 |
|---|---|---|---|
| 交互式编码助手 | 首字延迟、token 成本 | 定位准确率 | 以工具化检索为主,精确查找优先 |
| 自动化缺陷修复流水线 | 任务解决率、引用可核验率 | 失败可发现性 | 工具化多轮检索 + 强验证回路 |
| 大规模代码库问答 | 跨仓召回能力 | 索引维护成本 | 结构化索引为主,语义检索作为补充 |
| 强合规内网环境 | 数据副本边界、权限隔离 | 审计完整度 | 避免引入额外代码副本,优先本地无副本方案 |
| 文档与规范检索 | 语义召回、概念模糊匹配 | 更新时效 | 语义检索仍有价值 |
| 多模态或含大量二进制资产的仓库 | 资源占用、文件类型覆盖 | 检索稳定性 | 先明确二进制资源的处理策略 |
一个通用判断规则:任务描述越接近“我知道要找什么”,越应该用精确检索;越接近“我不知道它叫什么”,越需要语义召回或多轮探索。评测的价值就在于用数据确认你的业务落在哪一侧。
评测结论有几个必须承认的边界。
样本偏差:公开基准的仓库以特定几类语言和框架为主,结论迁移到你的技术栈时可能失效。必须用自有仓库重新验证。
环境差异:模型版本、提示模板、上下文窗口、轮次上限的任何变化都可能改变排序结果。跨环境对比的数字不可直接引用。
指标选择偏差:只测解决率会高估高成本方案,只测成本会低估高风险方案。至少三指标联合呈现。
长期不确定性:代码库增长会放大索引构建成本,也会放大多轮检索的 token 成本。评测应包含规模缩放测试,而不是只在当前体量下取一次数。
数据质量:任务集若来自同一批提交历史,可能与模型的训练分布重合,导致高估效果。应保留一部分新提交的任务作为留出集。
基于上述通用评测逻辑,可以给出一组条件化建议,而非绝对结论。
在自建评测环境时,可以借助百度智能云的通用云能力组合来完成资源准备与观测建设:用云服务器或容器平台承载被测 Agent 与检索服务,用对象存储保存评测数据集与轨迹记录,用日志服务留存调用链路,用监控告警跟踪资源与异常,用身份认证与访问控制策略约束索引与数据集的访问边界。这些只是评测环境的承载方式,与被测方案的优劣判断相互独立。
这轮技术转向的实质,不是某个组件被证伪,而是默认值被推翻:当检索决策可以从离线管线交给模型按需编排时,静态 top-k 召回的性价比优势就不存在了。评测要做的,是把“哪个更好”这种无法验证的表述,换成“在什么条件下、以什么代价、达到什么效果、承担什么风险”的可验证命题。
落地时建议按这个顺序推进:固定模型与预算,建立无检索基线;用自建任务集分别测量三类方案的效果、成本、稳定性与安全边界;把过程数据留痕到每一次检索;最后结合场景权重做条件化选型。结论只在你的仓库规模、语言栈与合规约束下成立,换环境就要重新验证。