微信扫一扫,关注公众号

  • 科技行者

  • 算力行者

见证连接与计算的「力量」

首页 蚂蚁集团发布"代码搜索考官"COREB:当AI编程助手遇上真正的检索难题

蚂蚁集团发布"代码搜索考官"COREB:当AI编程助手遇上真正的检索难题

2026-05-14 09:47
分享至:
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-
2026-05-14 09:47 科技行者

这项由蚂蚁集团(Ant Group)研究团队主导的工作发布于2025年5月,以预印本形式挂载于arXiv,编号为arXiv:2605.04615。有兴趣深入阅读的读者可以通过该编号在arXiv平台查阅完整论文。

**代码搜索,一件比你想象中复杂得多的事**

每天,全球数以百万计的程序员打开编辑器,敲下几个关键词,期待工具能给他们找出最合适的代码片段。这件事看起来简单,就像在图书馆找书一样——但如果图书馆里装满了用五种不同语言写成的技术手册,而且还有不少书名看起来对、内容却完全错误,情况就复杂多了。

现代编程辅助工具,比如Cursor、GitHub Copilot,以及更高级的AI编程代理SWE-agent和OpenHands,骨子里都依赖一套叫做"检索-重排序"的流水线。第一步,用一个向量检索模型快速从海量代码库里捞出一批候选结果,就像图书管理员先根据关键词从书架上抱出一摞书;第二步,再用一个更精细的重排序模型把这一摞书重新排序,把最相关的那本放在最上面。这两步缺一不可,任何一步出了问题,最终呈现给程序员的结果都可能差之千里。

然而,评估这套流水线到底好不好用,学术界长期以来只有一把"残缺的尺子"。

**现有评测体系的四大硬伤**

研究团队对现有最权威的代码检索基准CoIR进行了系统性体检,发现了四个让人头疼的根本性问题,就像一把看起来刻度清晰的量尺,实际上从一开始就没有对准零点。

第一个问题,现有基准完全不评估重排序阶段。它们只测了"图书管理员能不能把书从书架上找出来",却从不测"把书排好顺序"这一步,而这一步在实际系统中同样至关重要。

第二个问题是数据污染。CoIR超过85%的数据量来自CodeSearchNet这个数据集,而这个数据集从2019年就开始作为各大代码理解模型的训练素材。这就好比用语文课本上的原题来考语文,学生们早就背过了,成绩自然好看,但这和真实阅读理解能力没有太大关系。研究发现,训练和测试数据的重叠会让评测指标虚高,最严重时能虚高一倍。

第三个问题是标注噪声。CoIR中唯一经过人工标注的数据集CosQA,经过独立验证,大约有51%的配对是错误的。举个具体例子:查询"python检查文件是否只读",被错误地配对给了一个检查文件可读权限的函数,而"可读"和"只读"在语义上恰恰是对立的;查询"将秒数转换为时间格式",却被配对给了一个做反向操作的函数time2seconds。这种错误不是偶发的,而是系统性的。研究团队对80个测试对进行了手动检查,发现大约60%存在问题。

第四个问题是评分机制的退化。所有十个数据集都只给每个查询分配一个相关文档,用简单的"找到了/没找到"来打分。这就像测试一个厨师的厨艺,只问他"这道菜好不好吃",而不测他是否能把五道菜按口味优劣排出顺序。在这种设定下,两个不同的排名指标nDCG和MRR其实测的是完全一回事,失去了各自应有的评测价值。

正是为了填补这些空缺,研究团队构建了COREB。

**一、从竞赛题库中"炼制"出来的评测基准**

COREB的构建思路,可以用一个精炼矿石的比喻来理解:原材料是新鲜出炉的编程竞赛题,经过一系列"冶炼"工序,最终得到干净可靠的评测数据。

原材料来自LiveCodeBench,这是一个持续更新的编程能力评测平台,专门收录近期的编程竞赛题目,以时间过滤的方式降低污染风险。COREB的研究团队从中取出了两个时间段的题目:第一批(v202602版本)覆盖2024年9月到2025年1月的竞赛题,共167道;第二批(v202603版本)覆盖2025年1月到4月,共175道。两批来自完全不重叠的竞赛窗口。

原材料到手后,第一道"冶炼"工序是反事实改写。研究团队让GPT-o1对每道题的描述进行表面形式上的改写,同时保留其核心算法逻辑。具体来说,改写会替换所有专有名词和人物姓名(比如把"爱丽丝想要整理她的书架"改成"马库斯需要整理他的收藏"),改变题目的背景领域(比如把"计算股票交易的利润"改成"计算游戏锦标赛的得分变化"),替换关键对象(比如把"一列书"改成"一组产品"),以及用同义词替换动词和形容词。同时,纯数字的测试用例保持不变,只对含有领域词汇的测试用例做最小程度的修改。所有改写结果都经过人工核验,并重新运行完整测试套件,确认原来能通过的解法在改写后依然能通过。

为什么要这么做?研究团队设计了一个精妙的对照实验来验证其必要性。他们让两个主流AI模型(谷歌的Gemini 3 Flash和Anthropic的Claude Sonnet 4.5)分别在原题和改写后的题目上求解,对比通过率。结果相当清晰:Gemini在两批题目上的通过率在改写后均一致下降,v202602批次下降了8.6个百分点,v202603批次下降了6.5个百分点,且五种编程语言无一例外。这说明Gemini在某种程度上"记住"了原题的表述,当表述变了,它的"记忆"就失灵了。Claude则呈现出更有意思的模式:在较旧的v202602批次上,改写后通过率大幅下滑12.3个百分点,而在较新的v202603批次上几乎没有变化(甚至略有上升),恰好与Claude已知的训练数据截止日期2025年1月高度吻合。这个实验有力地证明,数据污染的程度因模型和数据集而异,难以预判,而改写正是阻断这种污染的有效手段。

第二道工序是代码生成和执行验证。针对每道改写后的题目,研究团队让Gemini 3 Flash和Claude Sonnet 4.5分别用Python、Java、C++、Go、Ruby五种语言各生成一份解法,然后在完整的测试套件上执行,记录每份代码是否通过所有测试。两个版本共生成了3414份代码候选,其中1065份完全正确(通过所有测试用例),其余的带着"不合格"标记一并保留。

第三道工序是查询生成。研究团队为三种不同的检索方向生成了不同类型的查询。第一类叫"文字找代码"(Text-to-Code),用自然语言描述找对应代码,分三个难度层级:全文描述(平均431个词元,包含所有题目细节)、缩略描述(平均120个词元,只保留核心目标和关键约束)、以及开发者风格的短关键词查询(平均仅19个词元,模拟真实搜索场景)。第二类叫"代码找代码"(Code-to-Code),用一种语言的代码去检索语义等价的另一种语言实现。第三类叫"代码找文字"(Code-to-Text),用代码去找对应的自然语言题目描述。

第四道工序是相关性标注。这里的做法和以往所有基准都不一样:不再是简单的"相关/不相关"两档,而是三个等级。对于"文字找代码"和"代码找代码",通过所有测试的正确解法被标为相关度2(真正相关),对同一道题的错误解法被标为相关度1(硬负样本,即"看起来像但其实错了"),完全不相关的代码被视为相关度0。对于"代码找文字",对应的题目描述被标为相关度2,LLM特意生成的"混淆性描述"(改变了核心算法目标、优化方向或问题领域的干扰项)被标为相关度1。

这个三档设计的意义在于:如果一个检索模型把一段"看起来像但其实是错误解法"的代码排在了正确解法前面,它会被扣分。这比以前简单的"找到就算对"严格得多,也更接近真实需求:程序员需要的不是任何相关代码,而是真正能跑通的代码。

经过这一系列工序,最终的COREB包含5087个查询,分布在三个主要任务方向。其中"文字找代码"占45%,"代码找文字"占49%,"代码找代码"占7%。按编程语言分布相对均衡,Python、Java、C++、Ruby、Go各占约13%-16%,另有约16%的查询不限定语言。

**二、十一个检索模型上擂台,没有全能冠军**

研究团队邀请了十一个向量检索模型和五个重排序模型参与评测。检索模型涵盖了专门为代码场景训练的小型专精模型(参数量仅5亿的C2LLM-0.5B、Jina-code-embeddings系列)和通用大型编码模型(80亿参数的Qwen3-Embedding-8B)以及闭源商业API(GemEmb-2)。

比赛结果一出,最引人关注的发现是:没有任何一个模型能在三个任务方向上同时夺冠。GemEmb-2在"代码找文字"和"代码找代码"方向排第一,但在"文字找代码"方向被C2LLM-7B超越;C2LLM-7B在"文字找代码"上最强,却在代码间互查方面略逊于GemEmb-2。这说明这三个任务确实在考查不同的能力,用单一任务的成绩来推断模型的全面水平,会产生严重误判。

更令人意外的是规模与效果之间的关系。以常识来看,参数越多的模型应该表现越好,但现实完全打破了这一直觉。80亿参数的Qwen3-Embedding-8B的综合得分(nDCG@10为0.481),竟然低于仅有5亿参数的C2LLM-0.5B(综合nDCG@10为0.603),差距超过12个百分点。同样,同属一个系列的F2LLM,1.7亿参数的版本反而在总体上输给了0.6亿参数的版本。研究团队的解释指向了训练数据的构成:在代码领域,用针对性的代码语料专门训练,比单纯堆砌参数量更有决定性作用。

如果从"每十亿参数能买到多少检索质量"这个角度来衡量性价比,差距就更为悬殊了。C2LLM-0.5B的参数效率(nDCG@10除以参数量)高达每十亿参数1.21分,Jina-code-0.5B紧随其后达到1.19分,而8亿参数的通用模型Qwen3-Embedding-8B仅有0.05分,相差约24倍。对于需要在算力有限环境下部署代码搜索的工程团队来说,这组数据的参考价值极高。

三个任务的难度分布也颇为耐人寻味。"代码找文字"是三者中最容易的,所有模型在这个方向上的平均nDCG@10高达0.73,而且在增加检索数量k时提升有限,说明相关文档通常很快就能排到前面。"文字找代码"是最难的,平均仅有0.39,而且从k=1到k=10有明显提升空间,说明正确代码确实被检索到了,但就是没能排到最前面。"代码找代码"居中,平均0.52,但是不同模型之间的差异是三个任务中最大的——擅长的模型领先不擅长的模型将近两倍,这使得这个方向成为区分模型能力的最好试金石。

Qwen3系列模型在这里展示了一个典型的失衡案例:它在"代码找文字"方向上表现中规中矩,但在"代码找代码"方向上表现极差,8亿参数的版本nDCG@10仅为0.320,而仅有5亿参数的Jina-code-emb-0.5b却达到0.677,几乎是前者的两倍。这背后的原因在于跨语言代码对训练:Jina-code模型在训练时专门接触了大量不同语言间的代码配对,而Qwen3主要依靠通用语言对齐能力,在面对"Java代码找Python等价实现"这类跨语言任务时就捉襟见肘了。

**三、短查询这道坎,所有模型都迈不过去**

在所有发现中,最具现实冲击力的一个,是短关键词查询让所有模型集体崩溃。

真实世界里,程序员搜索代码的方式往往不是写一段详细的需求描述,而是敲几个关键词,比如"binary search sorted array"或者"find kth character string repeat invert"。COREB的Search子任务就模拟了这种场景,平均查询长度仅19个词元。

结果是:每一个参与评测的模型,在这类短查询上的nDCG@10都跌至接近零。GemEmb-2得到0.000,C2LLM-7B得到0.004,最高的Qwen3-4B也只有0.015,与同一批模型在完整描述查询上的0.5以上分数相比,差距超过两个数量级。

这个崩溃并非来自语料库太难,因为三种子任务用的是同一个语料库,完整描述的查询能拿到不错的分数。真正的问题在于:这些向量检索模型被训练得很擅长用"丰富上下文"匹配"丰富内容",但当查询方只有几个词,没有足够的上下文让模型理解你在找什么时,它们就彻底迷失了方向。研究团队指出,查询扩展技术(如HyDE或Query2doc,这些方法会先让语言模型把短查询扩写成完整描述,再去检索)可能是突破这个瓶颈的最有希望的方向,但目前没有任何现成模型能原生解决这个问题。

与此类似,当查询指定了特定编程语言时,检索质量也会有规律性下滑。不限语言的查询平均nDCG@10约为0.714,而指定Python时降至0.649,指定Java时降至0.514,指定C++时降至0.465,指定Ruby或Go时更是低至0.383到0.387。这条下滑曲线和各语言在公开代码训练数据中的占比高度吻合:Python和Java代码在互联网上铺天盖地,模型见过太多,自然表现更好;而Ruby和Go相对小众,模型对它们的"语感"就差了许多。这对实际应用的启示是:如果你的代码库主要是用小众语言写的,现有的检索模型可能还不够用。

**四、硬负样本:那些让模型"差点被骗"的代码**

COREB的三级相关性标注设计揭示了一种此前被忽视的失败模式。研究团队统计了"硬负样本入侵率"——即在检索排名前10的结果中,有多大比例的查询出现了"硬负样本排在真正相关文档前面"的情况。

在"文字找代码"方向上,每一个模型的入侵率都超过55%。换句话说,对于超过一半的查询,检索模型把一段"针对同一道题目但无法通过测试的错误代码"排到了"真正能解题的正确代码"前面。GemEmb-2的入侵率高达64%,这看起来比一些表现较差的模型(如Qwen3-8B的53%)还要高,但这是因为GemEmb-2整体检索能力更强,能找回更多来自同一道题目的代码,自然也有更多机会遭遇排序错误。

在"代码找代码"方向上,入侵率从43%(GemEmb-2)到59%(F2LLM-4B)不等,代码专精模型的排序失误率普遍低于通用模型。在"代码找文字"方向上,入侵率相对较低(6%到30%),但最好和最差的模型之间仍然有五倍的差距。

这种失败模式在以前的基准中是完全看不见的:以前的基准不管你排了什么进前10,只要那个唯一的正确答案也在前10里,就算满分。但在真实应用中,程序员复制的往往是排在第一的代码,而不是仔细看完所有10个结果再挑。COREB的设计让这种"虽然找到了、却没排到最前面"的问题得以量化和暴露。

**五、重排序模型:高风险的双刃剑**

研究团队把四个现成的重排序模型(Jina Reranker v2、Jina Reranker v3、Qwen3-Reranker-0.6B、Qwen3-Reranker-4B)接在检索结果后面,对C2LLM-7B检索出的前128个候选结果重新排序,看看能不能进一步提升质量。

结论出人意料:没有任何一个现成重排序模型能在三个方向上同时带来提升。在"代码找文字"方向上,四个模型全部让结果变差,Jina Reranker v2甚至让nDCG@10下降了22.4个百分点,相当于把本来不错的结果砸了个稀烂。原因在于这个方向原本就相对简单,检索模型已经接近饱和(nDCG@10约0.8),重排序模型引入的噪声反而帮了倒忙。在"文字找代码"方向上,四个模型全部产生负面影响,最好的Qwen3-4B也让指标下降了0.1个百分点。只有在"代码找代码"方向上,Qwen3-4B带来了3.3个百分点的提升,因为跨语言的语义对齐确实能从更细粒度的逐对比较中受益。

最好和最差重排序基准在同一任务上的差距高达12个百分点,这意味着选对重排序模型的重要性,不亚于决定要不要用重排序。用错了,反而是给自己挖坑。

为了解决这个问题,研究团队基于Qwen3-Reranker-4B进行了针对性微调,得到COREB-RERANKER。训练数据混合了COREB v202602版本、CodeSearchNet、APPS、CosQA以及CodeFeedback等多个来源,共310万条训练样本。每条训练样本被格式化为一个问题:给定任务指令、查询和文档,模型回答"yes"或"no"来判断文档是否与查询相关。正确答案标为"yes",包括错误解法和混淆描述在内的硬负样本和简单负样本都标为"no"。为了平衡数据,正样本被双倍采样,每个正样本配一个简单负样本和一个硬负样本。

最终发布的COREB-RERANKER是两个用不同随机种子和数据打乱顺序独立训练的LoRA变体的"权重平均"(即模型汤技术,把两个模型的权重做等比例加法再融合进基础模型),这种方法被证明能在不增加推理时间的前提下提升平均表现。

在三个任务方向的评测中,COREB-RERANKER是唯一一个在所有三个方向上都带来净正向提升的重排序模型,验证了针对性的领域内训练对于代码重排序任务的必要性。

**结尾:一把更精准的尺子,为了量出真实的距离**

归根结底,COREB这项工作干的事情,是为一个快速发展但评测体系严重滞后的领域,做了一次扎扎实实的"校准"。代码搜索不是一个简单的"找到了吗"的问题,而是一个"找到的对不对、排得准不准"的复杂判断。现有工具在长描述查询上已经做得相当不错,但真正接近程序员日常使用习惯的短关键词查询,目前所有模型都还没有好的答案。小众编程语言的检索质量显著低于主流语言,这个问题随着多语言编程越来越普及,会变得越来越重要。重排序这一步的选择和训练,对最终结果的影响远超大多数人的预期,用错了甚至适得其反。

这个基准本身也是一个活的系统,它会随着LiveCodeBench持续发布新的竞赛题而定期更新,这使得"刷分"和"背答案"在设计上就被阻断了。当然,研究团队也坦诚了这套体系的局限:数据来源仍然局限于竞赛题,未必能完整代表企业级或开源库代码的检索场景;只覆盖了五种主流语言;查询都是LLM生成而非真实用户搜索日志;且只评测了单次静态检索,没有涉及多轮交互的代码搜索场景。

对那些正在构建或使用AI编程工具的团队来说,这项研究提供了几条可以立即拿去参考的实践建议:在算力有限的部署场景下,0.5亿参数的代码专精嵌入模型是性价比最高的选择,没有之一;在选用重排序模型时,务必在目标任务上进行验证,否则弄巧成拙;而短关键词查询的问题,目前还没有现成解法,值得关注查询扩展方向的进展。完整的数据集和COREB-RERANKER模型权重已通过项目主页(https://hq-bench.github.io/coreb-page/)开放,感兴趣的研究者和工程团队可以直接取用。

---

Q&A

Q1:COREB基准和CoIR基准有什么本质区别?

A:COREB在多个维度上做了系统性改进。在相关性标注上,COREB采用三级相关度(真正相关、硬负样本、不相关),而CoIR所有数据集都只有二值标注且每个查询只对应一个相关文档,导致排名指标退化为简单的"找到了吗"。在数据污染上,COREB通过反事实改写新鲜的竞赛题构建,CoIR超过85%的数据来自2019年就已公开的CodeSearchNet,对许多经过该数据训练的模型存在严重的考前"押题"风险。在任务覆盖上,COREB同时评测检索和重排序两个阶段,CoIR完全不涉及重排序。在语言覆盖上,COREB五种语言均匀分布,CoIR有意义的任务只覆盖Python、SQL和C++。

Q2:为什么短关键词查询会让所有代码检索模型都完全失效?

A:这是因为当前向量检索模型的工作机制依赖于查询和文档之间丰富的语义重叠。当查询只有十几个词(比如"binary search sorted array"),模型没有足够的上下文来准确推断用户意图,也无法与包含几百行代码的文档建立可靠的语义联系。这类模型在训练时通常使用完整的自然语言句子或代码注释作为查询,没有专门针对极短搜索词的优化。更根本的问题是,同样的几个词可以对应完全不同的代码需求,歧义性极高,而模型缺乏从上下文推断具体意图的能力。研究团队认为,查询扩展技术(先让语言模型把短查询扩写成完整描述再检索)是目前最有希望的解决方向,但还没有成熟的现成方案。

Q3:COREB-RERANKER是怎么训练出来的,为什么它比现成重排序模型效果更好?

A:COREB-RERANKER基于Qwen3-Reranker-4B,使用LoRA方法进行参数高效微调。训练数据来自多个来源的混合,共310万条,包括COREB v202602的代码检索数据、CodeSearchNet的代码-文本对、APPS编程题数据集、CosQA代码问答数据等。训练格式是让模型判断给定查询和文档是否相关,输出"yes"或"no"。关键在于训练数据中专门包含了三类代码检索任务(文字找代码、代码找代码、代码找文字)的有标注样本,且显式引入了硬负样本(错误代码解法、混淆性描述)进行对比学习。最终模型是两个不同随机种子训练的变体的权重平均。现成重排序模型主要在通用文本任务上训练,面对代码相关的特殊语义(比如跨语言代码等价、错误解法识别)时表现失衡。领域内有针对性的训练是COREB-RERANKER获得全任务正向提升的核心原因。

分享至
0赞

好文章,需要你的鼓励

推荐文章
----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.- ----..---.-...-/--...-.-......./-...-....-..--../-............-.-