Practical Code RAG at Scale: Task-Aware Retrieval Design Choices under Compute Budgets
Timur Galimzyanov, Olga Kolomyttseva, Egor Bogomolov
cs.LG, cs.AI, cs.IR
2025-10-23
JetBrains在Long Code Arena上扫了一遍代码RAG的分块、打分和切词。补全任务BM25加词级切分最好且快一个数量级;缺陷定位则是Voyage-3-Code的NDCG 0.72压过BM25的0.57。
代码 RAG 的工程选择很多:整文件还是按行切开、BM25 还是稠密向量、按词切还是按 BPE 切、要不要上语法感知分块。每篇方法论文通常只推销自己那一套。仓库又大、上下文窗口又贵,缺一张在固定算力预算下把这些旋钮一起拧过的对照表。
JetBrains Research 拿 Long Code Arena 的两个互补任务来填这个表。代码补全是 PL→PL:根据当前文件上文,生成下一行,且目标行引用了仓库别处的类或方法。缺陷定位是 NL→PL:根据 issue 文本给可能有 bug 的文件排序。
检索被拆成三个正交模块。分块器把源文件切成整文件、固定行窗(8/16/32/64/128 行)或 LangChain 语法感知递归切块。稀疏检索的切分器把块打成行、词或 BPE 词袋。打分器覆盖 IoU、BM25、E5 系列、Voyage-3 家族,以及 DraCo 数据流图和按目录距离的启发式。
补全用 DeepSeek-Coder-1.3B 生成,主指标是下一行 exact match;检索预算扫 128、4096、8192、16384 token。缺陷定位按文件排,指标是 NDCG,语言覆盖 Java、Kotlin、Python。为了不跑爆炸的全网格,分四阶段:先在整文件上选打分器和切分器,再扫块大小,再对比语法感知切块,最后把结构方法与最优稀疏/稠密检索混排。
补全任务上,BM25 加词级切分是质量-延迟的默认解。4K/16K 上下文下 exact match 为 0.55/0.60,E5-large 只有 0.39/0.52,BM25 大约高出 10 个百分点。词切和 BPE 切质量几乎一样,词切建索引快约 9 倍。行级切块略优于语法感知切块。32–64 行块在 ≤4K 窗口最好,16K 时整文件能追上。DraCo 在中等窗口不如切块检索,大窗口才和它打平。按目录距离检索一直更差。
缺陷定位则反过来。Voyage-3-Code(512 token)平均 NDCG 0.717,E5-large 0.590,BM25 词切 0.574。Python 上稀疏方法更接近:BM25 0.635,E5-large 0.606。延迟差一个数量级:BM25 词切 0.07 秒/百万符号,E5-large 2.8 秒,Voyage-3-Code 约 19 秒。
补全侧延迟跨度大约 180 倍:IoU 行切 0.02 秒/百万符号,E5-large 3.3 秒。一个 230 万符号的仓库,路径距离约 1.2 毫秒,BM25 词切约 0.5 秒,E5-large 约 7.5 秒。
| 设定 | 指标 | 最优 / 对照 |
| 补全 4K/16K | exact match | BM25-word 0.55/0.60 vs E5-large 0.39/0.52 |
| 缺陷定位 | 平均 NDCG | Voyage-3-Code 0.717 vs BM25-word 0.574 |
| 延迟 | 秒/百万符号 | IoU-line 0.02 vs E5-large 3.3 |
这是一张能直接拿去配系统的表,不是新检索器。PL→PL 先上 BM25 加词切;NL→PL 再考虑付费稠密编码。块大小跟着窗口走,别一上来上 AST 切块。交互式补全场景里,IoU 行切能用延迟换几个点的 exact match。
结论是任务依赖,不是「稠密一定更好」。补全靠词面重叠,缺陷定位要跨模态对齐,两条线不该共用一套索引。
没做去重和上下文压缩,小窗口模型吃不到更大块的信息密度。生成只用 DeepSeek-Coder-1.3B,作者说更大变体趋势类似,但没有完整对照表。任务停在单行补全和文件级缺陷定位,多行修复、长补丁生成可能改写最优块大小。稠密延迟按每次查询现场编码来报,预计算 embedding 的线上延迟会低一截。Voyage 数字来自专有 API,复现成本和限额跟论文当时的 batch 限制绑在一起。