论文 1 链接:Do Coding Agents Reuse Existing Code or Reinvent the Wheel? (arXiv:2609.35357) 论文 2 链接:VulContextBench: A Benchmark for Security Context Retrieval in Coding Agents (arXiv:2609.32601) 代码仓库:VulContextBench 开源于 github.com/yikun-li/vul-context-bench;RepoReuse 暂未开源(Work In Progress) 发表时间:2026 年 9 月 机构:RepoReuse——北京大学(第一单位,通讯作者 Wentao Zhang)+ 复旦大学 + 上海交通大学 + 清华大学 + 香港中文大学(深圳)+ 中关村学院,全高校合作、无企业参与;VulContextBench——新加坡管理大学(主导,资深软件工程学者 David Lo 挂名)+ Monash University + GovTech(新加坡政府科技局,公共部门而非企业) 领域标签:cs.SE / cs.CR(软件工程 / 安全与隐私)

为什么把两篇论文放在一起读

把这两篇论文放在一起,不是随机配对,而是因为它们回答了同一个问题的两个面。

这个共同的问题是:当 coding agent 通过了所有功能测试,我们凭什么相信它做对了?

  • RepoReuse 审计写了什么:agent 交付的代码是复用了仓库既有模块和自己上一轮的实现,还是悄悄把同一个轮子造了五遍?它发现 agent 的 pass 率全程几乎不动,但跨轮重复实现链的比例从 9–21% 一路涨到 51–69%——测试全绿,代码库却在持续腐烂。
  • VulContextBench 审计看了什么:agent 判断"这个提交是否引入漏洞"时,最终报告里引用的证据代码,是它真的检索并依赖的吗?它发现所有 7 个前沿模型都浏览了 73–92% 的金标准代码块,但只把 9–36% 写进最终报告——37 到 73 个百分点的"看到但不上报"差距。

两篇论文的方法论骨架惊人地一致:把一个单一的结果指标(pass 率 / 二值裁决),拆解成过程链条上的多个分离测量(recall vs reuse、viewed vs declared)。它们合起来构成代码 agent 过程审计的"双镜":一面照产出侧(代码质量),一面照证据侧(推理依据)。


一、论文背景

1.1 代码复用:软件工程的"第一美德"为什么在 agent 时代成了问题

代码复用(code reuse)是什么? 写新代码时,不重新实现仓库里已经存在的功能,而是直接 import 并调用它。听起来是常识——没人会自己写一个 sqrt 函数。但复用在真实仓库里远比调用标准库难:你需要发现仓库深处有个内部函数能干这件事(它往往藏在没有文档的子包里),读懂它的约定(参数顺序、返回结构、边界行为),然后决定用它而不是自己写一个。

为什么这件事在 agent 时代突然重要了?论文 1 的动机段写得很直白:每一次重复实现,都是一个要打两遍的补丁、一份会悄悄分叉的平行拷贝、一块后来者(无论人还是 agent)都要跋涉的额外泥沼。而 agent 写代码的速度远超人类审计的速度——这种失败模式在无人监督下加速堆积,最终变成"意大利面条代码"(spaghetti code)。

已有的观察也支持这个担忧:长程迭代任务中 agent 代码冗余持续上升(SlopCodeBench 发现结构重复在 72.1% 的轨迹中增长 66%),agent 补丁明显长于复用既有模块的参考解(Orlanski et al. 2026; Li et al. 2026)。

但现有评估仪器在原理上看不见这一切。 HumanEval、MBPP 只测单函数;SWE-bench 只测 issue 是否解决(测试是否通过)。复用维度的基准要么只在函数级迭代(CodeFlowBench),要么只有单轮(MaintainCoder),仓库级的工作停在一次性补全或文档齐全的入口点上。没有人在"真实仓库 + 多轮迭代"的设定下问:agent 到底复用了没有?

1.2 V-SZZ 与漏洞引入者追溯:标签从哪来,为什么会错

V-SZZ 是什么? 要研究"漏洞引入提交"(Vulnerability-Introducing Commit,VIC),得先知道每个漏洞是哪个提交引入的。SZZ 算法(Śliwerski et al. 2005,以三位作者首字母命名)的思路是:从修复提交(VFC)出发,看它改了哪些行,然后在版本历史里反向追溯这些行最早是哪个提交写下的——那个提交就是"嫌疑人"。V-SZZ(Bao et al., ICSE 2022)把这套思路专门适配到 CVE 漏洞场景。

问题在于这个"嫌疑人"经常抓错。 Rosa et al.(ICSE 2021)用开发者确认的真值评估 SZZ 家族实现,发现大比例分歧——SZZ 指向的常常只是"最后触碰那行代码的提交",而不是"让代码变脆弱的提交"。一个只做了重命名、重排版或整项目导入的提交,会因为"最后碰了每一行"而被错标为引入者。这正是论文 2 必须做逐案人工审计的原因:一个建立在错误标签上的基准,无论评估指标多精巧,都是在给错误的答案打分。

1.3 安全证据检索:裁决对了 ≠ 推理对了

漏洞检测基准怎么评? 从 Devign、Big-Vul 到 PrimeVul,主流做法是给模型一个函数或提交,让它输出"有漏洞 / 无漏洞"的二值裁决,然后和标签比对。这有两个深层问题:

  1. 无法区分记忆与推理。 漏洞都带公开编号(CVE)、公开通告、公开修复,全都在预训练语料里。一个在训练时背过 CVE 描述的模型,不读一行代码也能"答对"。PrimeVul(Ding et al. 2024)已经证明:一旦标签噪声和重复样本被现实地处理,报告的性能断崖式下跌。Steenhoek et al.(ICSE 2023)进一步发现模型常常因为与漏洞无关的原因做对题目。
  2. 过程完全不可见。 一个二值裁决不告诉你 agent 看了哪些代码、依赖哪些证据。而安全审查恰恰是最需要证据的场景:审阅者要复核的正是"你凭什么说它有漏洞"。

论文 2 的任务设定因此非常克制:agent 只拿到仓库快照和引入 diff(没有 CVE 编号、没有 CWE 标签、没有漏洞描述),要探索仓库并最终申报它认为支撑结论的证据代码块。评分对象从裁决换成了检索到的证据。

1.4 共同的空缺:结果指标无法刻画过程质量

两篇论文的动机在结构上是同一个:结果指标(outcome metric)对过程质量(process quality)结构性失明。

  • pass 率看不见重复实现:重复造的轮子一样能通过功能测试。
  • 二值裁决看不见证据来源:背下来的答案和追踪数据流得出的答案得分相同。

这不是"指标不够多"的问题,而是单一结果指标在数学上就无法区分达到同一结果的无数条过程路径。要测量过程,必须把过程本身变成可测量的对象——这就是两个基准共同的构造思想。


二、论文定位和关联工作

2.1 论文 1(RepoReuse)的谱系:从"测结果"到"测行为"

RepoReuse 站在一条清晰的演化链上,每一代都往"过程"靠近一步:

代际代表工作测什么与 RepoReuse 的关键区别
函数级功能正确性HumanEval (2021)、MBPP (2021)单函数测试通过率无仓库、无多轮、无复用维度
仓库级 issue 解决SWE-bench (2024)真实 issue 补丁 + 测试只测结果,不审过程行为
仓库级补全CrossCodeEval (2023)、RepoBench (2023)、ML-Bench (2024)跨文件补全正确率一次性补全,不迭代;依赖文档完善的入口点
多轮迭代(文件级)CodeFlowBench (ACL 2026)单文件内多轮迭代限于单文件,无仓库级探索
多轮迭代(需求变更)MaintainCoder (2025)可维护性下的需求变更单轮测量
长程演化SWE-Chain、EvoCode-Bench、SWE-EVO、LoopsBench、SlopCodeBench迭代中的产出与退化测制品(补丁膨胀、结构侵蚀、冗余上升),不测复用行为本身
探索质量SWE-Explore (2026)行级探索 recall静态快照、移除执行;只有探索侧,无复用侧

值得说明的是,CodeFlowBench 与本文是同一批作者(北大 Wentao Zhang 组)的前作——RepoReuse 是该团队从"多轮代码生成"(CodeFlowBench)向"多轮复用行为审计"的自然推进。

RepoReuse 的空隙:此前没有任何基准同时满足(a)仓库级、(b)多轮迭代、(c)工作区累积 agent 自己的历史代码、(d)逐轮测量对仓库代码与自有历史代码的复用。

2.2 论文 2(VulContextBench)的谱系:从"测裁决"到"测证据"

谱系代表工作评分单位过程信号标签审计与 VulContextBench 的关键区别
漏洞检测(函数级)Devign (2019)、Big-Vul (2020)、PrimeVul (2024)二值裁决✗部分(PrimeVul 做了标签清洗)只评分判断,不审计证据;标签噪声已被证明严重
漏洞引入追溯V-SZZ (ICSE 2022)、VCCFinder、ICVul数据集构建—部分人工提供候选但 Rosa 2021 证明 SZZ 分歧大;本文全部逐案重审
上下文检索(issue 域)ContextBench (Li et al. 2026a)检索的上下文(file/block/line P/R/F1)✓✓(测试验证)面向 issue 解决,有测试作为结果信号兜底
上下文复用SWE Context Bench (2026)准确率/时间/成本✓✓测跨任务上下文复用收益
本文VulContextBench检索的安全证据 + 角色标签✓(viewed/declared 双阶段)✓(四准则逐案人工审计)安全域中检索质量是唯一可用的过程信号(没有测试会因 CVE 失败)

论文 2 自己说得很准:issue 解决域有测试信号部分校验终态,而安全域没有测试会因为"三年前引入了 CVE"而失败——所以检索质量在安全域不是结果信号的补充,而是唯一的过程信号。此外它对 ContextBench 的评估框架做了两处领域化改造:金标准块带角色标签(证据之间有依赖结构),且真值必须先人工审计才能标注。

2.3 两篇合起来在研究版图上的位置

用一个坐标系看:横轴是"过程审计的环节"(探索 → 决策 → 产出),纵轴是"审计对象"(agent 行为 / 制品质量)。

  • 此前的工作大多落在"产出制品审计"(SlopCodeBench 测冗余度上升)或"探索侧审计"(SWE-Explore 测行级 recall)。
  • RepoReuse 补上了中间环节:探索(recall)→ 复用决策(reuse rate)→ 产出后果(Cdup)的完整三角。
  • VulContextBench 补上了两端分离:探索期浏览与最终申报,证明两者严重脱节。

二者的共同突破是把"单一结果指标"替换成"过程链条上的分离测量",并用严格构造的真值保证测量本身可信。


三、问题定义

3.1 各自的具体问题

论文 1:在仓库级多轮迭代开发中,agent 每轮收到新需求,在累积的工作区(初始仓库 + 自己前几轮的提交)上开发。问题:agent 是否复用了(a)仓库既有模块、(b)自己历史轮次的函数?复用缺失时,漏掉的逻辑去了哪里?

论文 2:给定仓库快照 S 和漏洞引入 diff d_vic(无任何 CVE/CWE 信息),agent 探索仓库后申报它认为支撑"是否引入漏洞"结论的证据代码块。问题:agent 申报的证据与真实必需的证据(金标准上下文)重合度多少?它浏览过的和申报的差多少?

3.2 抽象后的共同问题

剥掉领域外壳,两篇论文做的是同一件事:

给定一个"结果可验证但过程不可见"的 agent 行为序列,构造可验证的过程真值,把单一结果指标分解为过程链条上的至少两个分离测量,从而区分"结果对但过程错"与"结果对且过程对"。

形式化地说:设 agent 在任务 t 上产生行为轨迹 τ_t = (a_1, …, a_n) 和结果 y_t。传统评估只看 V(y_t, y*)(结果与真值的匹配)。过程审计构造真值过程 P*(应复用的目标集合 / 应申报的证据块集合),把轨迹映射为过程投影 π(τ_t),并测量至少两个量:

  • π_explore(τ):探索侧投影(读过的文件行 / 浏览过的块)
  • π_commit(τ):承诺侧投影(实际调用的目标 / 最终申报的块)

关键洞察是 gap = π_explore − π_commit 这个差值的诊断价值:它把"找不到"(探索能力缺陷)与"找到却不用/不报"(决策或选择性缺陷)分离开。两篇论文的核心发现都住在这个 gap 里。

3.3 对偶关系

维度RepoReuseVulContextBench
探索侧投影recall(读过的目标函数源码行)viewed(浏览过的金标准块)
承诺侧投影reuse(实际调用的目标)declared(最终申报的证据块)
后果指标Cdup(跨轮重复实现链占比)verdict accuracy(裁决准确率,仅作参考)
gap 的名字“seeing is not using”(看到了却不用)“看到但不上报”(views but doesn’t cite)
真值构造方式全自动管线(执行验证的参考解)人工审计 + 角色标注金标准

这个抽象的精妙之处在于:它不需要改变被测 agent 的任何行为,只需要在 harness 层记录轨迹并对照真值投影——这是一种"被动审计"而非"主动干预",因此测到的是 agent 的真实秉性。


四、问题解法

4.1 RepoReuse:全自动构造"什么应该被复用"的真值

要测复用,先得知道每轮任务里哪些东西"应该"被复用。这是整个构造的难点——你不能让人来标(无法规模化),也不能让模型拍脑袋(真值不可信)。RepoReuse 的解法是一条三阶段全自动管线:

阶段一:证据包收集(Evidence Collection)——先找素材。

  1. 用 AST 依赖图给整个仓库建一张"可调用地图":每个函数/方法是节点(带精确行范围、签名、docstring),调用关系是边。**AST(抽象语法树)**是把源码解析成树形结构的标准技术——在树上做静态分析,可以精确回答"这个函数调用了谁、被谁调用",不靠字符串匹配。
  2. 让一个强模型(GPT-5.6 Sol)在图上做引导式游走:从某个内部符号出发,像开发者点开交叉引用一样逐跳选择下一个符号,并给出理由,最终收拢出一组相互依赖的模块作为"证据包"。
  3. 从第 2 轮起,游走从上一轮的产物出发(使复用历史函数成为任务链的自然要求),并注入一个邻近但未用过的仓库符号(防止证据包逐轮退化成自我包裹)。

阶段二:任务合成(Task Synthesis)——把素材变成考题。 模型基于证据包合成一整轮:需求文本(只描述目标行为,绝不点名列出任何证据包符号——否则探索就退化成字符串搜索)、参考解(必须真实调用证据包模块和前轮产物)、测试用例。关键约束:测试期望值来自参考解的实际运行结果,而非模型的口头声称。

阶段三:执行验证(Verification)——给真值上保险。 报错或不稳定的用例被丢弃;参考解必须通过全部测试、空实现必须失败、AST 分析确认参考解真的复用了证据包模块;最后由一个不信任任何生成器输出的独立审计环节重装整条任务链重跑全部测试。

三个防污染细节值得注意:任务开始前删除 git 历史(防止 git log 泄题)、逐文件删除所有测试文件(仓库测试正是构造管线找证据的地方,会暴露任务约定)、参考解永不进入工作区(agent 的工作区里只有它自己写的东西)。

指标三角:围绕 agent 每轮"读代码 → 决定复用什么 → 写代码"的工作流:

指标定义回答什么
reuse rate(中心指标)提交物通过 AST 真实调用边调用的目标占比,repo 目标与 self 目标分开算复用了没有?
recall(上游)本轮文件读取动作与目标函数源码体至少一行重叠的目标占比没复用是因为没找到吗?
Cdup(下游)含跨轮重复实现(不调用目标 f 却重写了 f ≥80% 的被调函数逻辑)的任务链累计占比绕过留下了什么后果?

注意 reuse 的严格性:agent 本地重定义同名函数不算调用;Cdup 只统计调用了至少 3 个非内建函数的目标,避免误判。

4.2 VulContextBench:人工审计 + 角色标注 + 双阶段评估

第一步:任务池(Task Pooling)。 从 6 个既有 VIC 数据集取候选(人工核验的 V-SZZ-C/V-SZZ-Java、VCC-Eval、Vulnerability History Project + V-SZZ 标注的 ICVul、Aladics Java 集);另用 V-SZZ 从 OSV.dev 的 2026 年新 CVE 追溯出第二个池——既覆盖 C/Java 之外的语言,又保证足够新、难以被预训练吸收(旧池最新只到 2024 年,对 2026 年的模型意味着记忆污染风险)。

第二步:四准则人工审计(VIC Audit)。 每个候选对照四条明确标准、逐条检查完整仓库历史:

  1. 真实漏洞 + 真实修复:存在 CVE 且存在移除它的修复提交(VFC)——修复定义了漏洞在哪,没有可信修复标签就无从核验;
  2. 真实引入者:VFC 改动的行在完整历史中追溯到本提交,且脆弱行为此前不存在——只重排版/移动已脆弱代码的不算(这是最常见的失败模式,因为 SZZ 标签指向最后触碰行的人);
  3. 真实改变脆弱代码:不是重命名、重排版、整项目导入,也不是早先的不完整修复;
  4. 该快照处攻击者可达:漏洞在候选提交时点必须可达——后继提交才加入入口或 sink 的"潜伏缺陷"没有可达性上下文可检索,任务无解。

307 个候选只留下 111 个——近三分之二被剔除,V-SZZ 标签噪声之重可见一斑。

第三步:金标准上下文标注(Gold Context Annotation)。 对每个幸存案例:

  • 两个不盲的 proposer agent(Claude Opus 4.8 与 GPT-5.5,各拿全部信息:快照、引入 diff、修复 diff、CVE/CWE/描述)在隔离沙盒各自起草候选上下文块;
  • 标注者逐块核对仓库,把金标准写成快照中的精确行范围,块按包围语法单元(函数/方法/类/宏/顶层语句)切分;
  • 每块打角色标签,四类角色对应证据链的不同功能:
    • VIC core:引入漏洞的行本身(严格说是"缺陷"而非"上下文",但定位它本身就是一个检索问题,故也计分);
    • sink:缺陷真正造成危害之处;
    • reachability:从攻击者可控入口到脆弱代码的路径;
    • dependency:被改代码所依赖的定义/不变式/配置——只能靠"想明白为什么这个改动是脆弱的"才能找到。

金标准充分性的盲测验证:一个独立验证器(GPT-5.5)只拿两样东西——引入 diff 和金标准上下文文本——判断提交是否引入漏洞及漏洞是什么;对照组只拿 diff。结果:只有 diff 时识别率 27.0%,加上金标准块后 75.1%,提升 48 个百分点。这个设计的关键在于验证器看不到 CVE 描述(否则它不读代码也能答对,就无法证明金标准块本身携带了足够信息)。

评估协议:在 file / block / line 三粒度上分别算 P/R/F1(宏观平均),且对同一轨迹的两个集合分别评分:

  • viewed(浏览集):探索期间打开过的所有区域,从轨迹恢复;
  • declared(申报集):最终提交报告中的证据列表(含路径、行范围、角色、一句话理由)。

file 级问"有没有找对地方",block 级问"有没有把证据从文件里隔离出来",line 级问"有没有定位到缺陷本身"。precision 在安全审查中有特殊意义:每一个检索来但不属于证据的块,都是审阅者要读一遍再排除的负担。

4.3 两个解法的对照全景

组件RepoReuseVulContextBench
真值来源全自动管线 + 执行验证(参考解的真实依赖)人工四准则审计 + proposer 双案隔离 + 标注者逐块核定
防记忆污染需求不点名符号;删 git 历史/测试不给 CVE/CWE;加入 2026 新 CVE 池
真值可信度保障独立审计重装重跑;空实现必败盲测验证器 +48pt 证明金标准充分
过程投影recall(读)vs reuse(用)viewed(浏览)vs declared(申报)
后果/参考指标Cdup(重复实现链)、pass 率verdict accuracy(仅参考)
规模75 链 × 5 轮 × 2 harness × 4 模型 = 3000 轮111 案 × 7 模型,464 金标准块 / 13,370 行

五、评估指标与实验证据

5.1 RepoReuse 的主要发现

设定:75 条五轮任务链(375 轮/配置),每轮平均 10.8 个执行验证测试;8 个模型-harness 组合(mini-SWE-agent 与 OpenCode × GPT-5.6 Terra / DeepSeek-v4.1-flash / Qwen3.7-plus / GLM-5.3)。每轮全新 agent 会话、工作区持久保留 agent 自己的实现;第 2 轮起需求列出此前实现的公开接口(默认 interface memory)但绝不给出源码,仓库复用目标永不点名。

发现一:复用普遍不及格,且与探索量挂钩。 最强配置(OpenCode + DeepSeek-v4.1-flash)仍漏掉 24.3% 的仓库目标和 13.6% 的自有历史函数;Qwen3.7-plus 在两个 harness 下都漏掉约一半仓库目标。每轮看 ≥900 行源码的配置达到 47–61% 仓库 recall,看 <700 行的只有 35–42%。

发现二:“seeing is not using”。 所有配置对自己历史代码的 recall ≥98.9%(完全饱和——信息就在眼前),但 self reuse 只有 67.0–86.4%。瓶颈不在找到,而在决定建立在已有代码之上的意愿。

发现三:复用随轮次衰退,且两侧机制不同。

现象T1T5/末轮解读
仓库 recall76–91%16–51%探索坍塌:自有代码填满工作区后,agent 不再读仓库
仓库 reuse—跌幅远小于 recall后期复用越来越"没读就调"——大概是从自己代码里的调用点抄的
self reuse83.9%(T2)69.1%(T5,8–24pt 降幅)recall 饱和下仍衰退——决策侧劣化
Cdup9–21%51–69%绕过的目标持续沉积为结构性冗余
pass 率—基本不动(如 DeepSeek 90.8/91.6%)正确性指标对以上一切失明

发现四(记忆形式消融,最有行动价值):固定 Qwen3.7-plus + OpenCode,只改需求中历史记忆的形式:

记忆形式self reuserepo recallCduppass 率
无记忆30.0%55.5%65.1%72.4%
接口记忆(默认)67.8%35.1%46.7%71.9%
全文源码记忆29.2%38.5%70.7%70.2%

三个反直觉点:给全文源码与不给记忆毫无差别(29.2% vs 30.0%);一份紧凑的"函数地图"让 self reuse 翻倍以上;三种设置下 pass 率几乎相同(70.2–72.4%)——再一次,正确性指标分不出三种截然不同的代码库命运。此外记忆与探索存在替代关系:无记忆时 agent 每轮开 27.7 个文件(接口记忆只开 13.5 个),repo recall 反而更高(55.5% vs 35.1%)。

案例研究(mini-SWE-agent + DeepSeek-v4.1-flash,seaborn 任务链):T4 实现了 center_within_groups 并全测试通过;T5 的需求明确列出 T4 接口,agent 完整读过 T4 源码(recall = 1.0)却从不 import,从零重写了 dtype 强制转换、分组掩码、类别排序、均值中心化逻辑,262 行;参考解调用 T4 函数并聚合其输出,68 行。提交通过 10/10 测试——pass 率里没有任何东西记录下工作区里现在躺着两份平行的中心化实现。

5.2 VulContextBench 的主要发现

设定:7 个前沿模型(GPT-5.5、Claude Opus 4.8、Kimi K3、DeepSeek V4 Pro、Gemini 3.1 Pro、Qwen3-Coder-Next、Llama 4 Maverick),统一 mini-SWE-agent harness、统一 prompt,产出结构化安全报告(裁决 + 根因解释 + 证据列表)。

主发现:“看到但不上报"的 37–73 个百分点。

模型浏览 block recall申报 block recall差距
GPT-5.50.7310.362(最高)36.9pt
Claude Opus 4.80.8080.33647.2pt
Kimi K30.924(最高)0.35556.9pt
DeepSeek V4 Pro0.9070.32358.4pt
Gemini 3.1 Pro0.8140.13667.8pt
Qwen3-Coder-Next0.8630.12973.4pt
Llama 4 Maverick0.7610.08967.2pt

所有模型都打开了大部分金标准代码(block recall 0.731–0.924,最宽的探索者只比最窄的多看 1.3 倍),但申报份额差异悬殊(最佳/最差 4.1 倍)。探索期模型几乎不可分离,申报期才分出高下——模型间差异主要在选择性,不在探索广度。 最能探索的三个模型(Kimi K3、DeepSeek V4 Pro、Qwen3-Coder-Next)申报排名分别只列第三、第四、第六。

申报证据质量(block 级 F1):GPT-5.5 以 0.372 居首,Claude Opus 4.8(0.363)、Kimi K3(0.352)、DeepSeek V4 Pro(0.349)紧随,Gemini 3.1 Pro 0.199(precision 最高 0.698 但 recall 仅 0.136——极端的精准-召回落差)、Llama 4 Maverick 垫底(0.102)。precious 的细节:Kimi K3 申报的金标准比 Gemini 多(0.355 vs 0.136)但裁决准确率反而更低(0.555 vs 0.748)——申报多少与裁对与否没有简单关系。

粒度的价值:file 级 GPT-5.5 与 Gemini 3.1 Pro 几乎同分(F1 0.687 vs 0.679),block 级差近一倍(0.372 vs 0.199)。file 级评分会掩盖"引用了对的文件却没指出文件里对的代码"的差异。

角色分析:金标准块按角色分别计分(申报块必须打对角色标签才计入该角色 recall):

  • 角色平均 recall:VIC core 0.408 > reachability 0.227 > sink 0.166 > dependency 0.115(3.5 倍差距);
  • 角色平均 precision 差异小得多(0.513 / 0.337 / 0.328 / 0.243)——区分角色的是"够到多少"而非"报对时多准”;
  • 模型在 VIC core 上最好并非偶然:它是 diff 本身触碰的代码,等于题目部分地给出了答案;最难的是 dependency——只有想明白"为什么这个改动是脆弱的"才能找到;
  • 约一半支持性上下文"找到但标错角色":忽略角色标签重算,recall 从 0.408/0.166/0.227/0.115 升至 0.620/0.354/0.420/0.237——sink/reachability/dependency 三个支持角色约一半的覆盖被申报在了错误的角色下;
  • precision 与 recall 在 VIC core/sink/reachability 三角色上强相关(r = 0.96/0.91/0.78),唯独 dependency 无关(r = 0.04)——“找到依赖声明"与"认出它是依赖"是两种分离的能力。

5.3 双镜合并的证据表

审计维度RepoReuse 证据VulContextBench 证据
结果指标失明pass 率全程不动(90.8/91.6%)而 Cdup 51–69%verdict accuracy 无法区分记忆与数据流追踪
探索 ≠ 使用/申报self recall ≥98.9% 但 self reuse 67.0–86.4%浏览 73–92% 但申报 9–36%
随时间的劣化recall 76–91%→16–51%、self reuse 83.9%→69.1%(单任务内,无纵向;但最大差距恰好落在最低分模型上)
干预杠杆接口记忆使 self reuse 30.0→67.8、Cdup −24pt角色标签要求暴露一半"找到但标错”
粒度/粒度选择repo 与 self 目标分开测file/block/line 三粒度,block 揭示 file 掩盖的差异

这些实验设计为什么能证明论点?核心在于每个主张都对应一个"分离测量":‘seeing is not using’ 由饱和 recall + 不饱和 reuse 的并存证明;“模型差异在选择"由探索期不分离 + 申报期 4.1 倍分离证明;“file 级不够"由同 file 分 + 异 block 分证明。单一指标下这些主张全部不可表述。


六、效果优势的根源解释

两篇论文不是在比"谁的模型分高”,而是在论证"分离测量揭示常规指标看不见的结构”。因此本部分要解释的"优势"是测量仪器的优势:为什么这些设计必然能揭示那些被隐藏的现象,以及论文对成因的机制解释是否站得住。

6.1 根源机制与证据链

机制 A:为何全文记忆诱发"照抄改写",而接口地图把复用变回查找问题

论文 1 消融的核心结果:source memory(29.2%)≈ 无记忆(30.0%)≪ interface memory(67.8%)。

因果链(论文实验已支持部分 + 阅读者推测部分):

  1. 【论文实验支持】源码全文在场时,重写一段逻辑的"上下文距离"最短——模型此时做的是抄写改写(把眼前的实现换个名字再写一遍),这在 next-token 生成上是比"理解接口约定 → 组织一次跨模块调用"更局部的操作。T5 案例中 agent 重写 262 行而非调用 68 行的现成函数,正是这个模式。
  2. 【论文实验支持】接口记忆只给"函数地图"(模块、名字、签名、返回值、行为),源码不在眼前——重写的原料被抽走了,剩下最短路径变成"按图索骥地调用"。self reuse 因此翻倍。
  3. 【论文实验支持】后果落在 Cdup 上:source memory 下 Cdup 高达 70.7%(T5 达 94.7% 的链含重复实现),interface memory 46.7%,差 24 个百分点。
  4. 【阅读者推测】更深层的原因可能与 LLM 的复制倾向(repetition/copy bias)有关:Liu et al.(2025,“Code Copycat Conundrum”,论文 1 自己引用)已系统记录 LLM 代码生成中的重复现象——上下文中存在可复制的实现时,复制改写在解码分布上占优。论文 1 的消融可视为该倾向在"跨轮复用"场景的体现。此环节论文未直接检验,属于合理推测。

注意论文自己承认的混杂:interface memory 的措辞里含"鼓励复用",source memory 不含——两个因素(接口形式 vs 显式鼓励)无法完全分离。这是该消融设计的诚实边界。

机制 B:为何裁决级评估无法区分记忆与追踪,而证据评分强制过程可观测

论文 2 的核心设计推理:

  1. 【论文引证支持,前人已证】漏洞带公开标识/通告/修复,全在预训练语料中;PrimeVul(Ding et al. 2024)证明标签与重复现实化后性能大跌;Steenhoek et al.(2023)证明模型常因与漏洞无关的特征做对。
  2. 【论文实验支持】因此本文的 agent 只拿快照 + 引入 diff,无任何标识;且任务池加入 2026 年新 CVE(超出旧数据集的 2024 截止)——记忆通路被两头收窄。
  3. 【论文实验支持】金标准充分性由盲测验证(+48pt),“证据评分"的真值本身可信。
  4. 【推论】在这种设定下,一个模型要拿高 declared recall,必须真的浏览并识别了证据代码——记忆捷径无处附着。37–73pt 的 viewed-declared 差距随之成为可测量的事实而非可辩解的噪声。

机制 C:为何模型间差异主要在选择性而非探索广度

【论文实验支持】探索期 block recall 区间 0.731–0.924(1.3 倍),申报期 0.362 vs 0.089(4.1 倍);探索最多三模型的申报排名 3/4/6。机制上:探索是一个有兜底的行为——多开文件总没坏处,且受 harness 预算而非模型判断约束;申报是一个判断行为——要在打开的几十个块里识别哪些承载证据并正确归类角色,考验的恰是对漏洞结构的理解。Gemini 3.1 Pro 的极端形态(precision 0.698 / recall 0.136)说明选择性内部还有第二层权衡:宁可少报不可错报。【阅读者推测】这种策略差异可能来自后训练对"引用准确性"的偏好差异,本文未检验。

机制 D:为何探索衰退是"结构性的"而非"随机波动”

【论文实验支持】仓库 recall 从 T1 76–91% 崩到 T5 16–51%,而 self recall 全程饱和——衰退精确发生在"自有代码开始填充工作区"之后。机制解释:每轮新会话没有对话历史,agent 的第一信息源是需求与手头工作区;当工作区里满是(自己名义上写的)历史代码时,从需求到已有实现的"最短满足路径"绕过了仓库探索。接口记忆进一步放大这一点:它把历史信息压缩进需求文本,探索的动力再减(无记忆时反而被迫探索,repo recall 55.5% vs 35.1%)。8 个配置 × 5 轮的一致趋势排除了随机性。

6.2 相关工作检索与对照

围绕上述机制做外部检索交叉验证(anysearch,2026-09-30;注:检索中途遭遇持续限流,最后一组查询未能完成,以下为成功检索到的证据):

研究(可核验链接)相似尝试相关结论与本文的差异与适用边界对根源解释的影响
SlopCodeBench(Orlanski et al., arXiv:2603.24755)让 agent 反复扩展自己的方案,测结构重复结构重复在 72.1% 轨迹中增长 66%;代码持续退化方法相似(长程迭代 + 冗余度量),但它测制品退化,RepoReuse 测复用行为并分离 recall/reuse支持机制 D:迭代中冗余上升是跨基准的稳健现象;RepoReuse 把它归因到探索坍塌 + 决策衰退的分离
“To What Extent Does Agent-generated Code Require (Re)work?"(arXiv.org/html/2605.06464v2)实证测 agent 代码的重复率上升记录到 notable rise in code duplication实证口径,非基准;未做复用率与 recall 的分离支持论文 1 的动机前提(冗余在真实 agent 开发中上升)
ContextBench(Li et al., arXiv:2602.05892)1136 个 issue 任务的金标准上下文 + file/block/line P/R/F1高级 agent 设计对检索质量改进有限issue 域有测试信号兜底;VulContextBench 明确声明借用其指标框架并迁移到安全域支持机制 B 的方法学前提;论文 2 报告"探索多≠申报多"在 issue 域同样出现(Li et al. 2026a),且安全域差距更大——跨域相近结论
PrimeVul(Ding et al., arXiv:2403.18624)最大化标签准确率的漏洞检测基准标签噪声/重复现实化后报告性能大跌只修标签、仍评分二值裁决,无过程审计支持机制 B 前提:裁决级评估的记忆/捷径问题已被独立证实
Rosa et al. SZZ 评估(arXiv:2308.05060;ICSE 2021 版为论文 2 引用)六种 SZZ 算法对 Linux 内核 76,046 对补丁-引入提交SZZ 家族与开发者确认真值大比例分歧通用 bug 域;论文 2 只问漏洞域且逐案审计而非聚合评估支持论文 2 四准则审计的必要性:不审计则近三分之二标签错误直接污染真值(307→111 的剔除率与之吻合)
V-SZZ(Bao et al., ICSE 2022)漏洞版 SZZ 行映射追溯提供了论文 2 的第二个候选池本身不评估 agent背景:论文 2 对其输出的态度是"信任但逐案核验”,307→111 即核验结果
Steenhoek et al.(ICSE 2023,论文 2 引用)深度学习漏洞检测实证模型常因与漏洞无关的原因做对分类器时代结论,非 agent 时代支持机制 B:捷径成功先于 agent 时代已被证实
Liu et al. “Lost in the Middle”(TACL 2024,论文 2 引用)长上下文中部信息利用率模型对上下文中部信息系统性欠利用序列召回任务,非代码审查补充(限定性):为"浏览过但未申报"提供一种注意力层面的候选解释,但不能直接证明因果
Code Copycat(Liu et al. 2025,论文 1 引用)LLM 代码生成重复现象学系统记录复制/重复偏好函数级生成,非多轮仓库补充(推测级):为机制 A 第 4 步"复制倾向使全文记忆诱发照抄"提供旁证,非直接检验

相反/限定性证据:本次检索范围内未发现"接口式记忆劣于全文记忆"或"探索广度决定申报质量"的反向结论;也未发现对"viewed-declared gap 不存在"的反驳。需注意的边界:(a) RepoReuse 的记忆消融存在鼓励措辞混杂(论文自认);(b) VulContextBench 的 verdict accuracy 与 declared F1 无简单单调关系(Kimi vs Gemini),说明证据质量与裁决质量的关系本文未建立因果——这是留白而非矛盾。

6.3 综合判断与未决问题

多项研究共同支持的机制:(1) 迭代开发中冗余上升、探索衰退是跨基准稳健现象(SlopCodeBench + RepoReuse + arXiv:2605.06464 三处独立证据);(2) 裁决/结果级评估无法排除记忆与捷径(PrimeVul + Steenhoek + Croft 独立证据);(3) 过程级评分(file/block/line)能揭示结果级掩盖的差异(ContextBench + VulContextBench)。

仍属推测的机制:全文记忆诱发照抄的复制偏好在解码层面的成因(Code Copycat 是旁证);模型选择性差异的后训练成因;探索衰退的"最短满足路径"解释(与数据一致但未被直接检验)。

适用条件:RepoReuse 目前限于 5 个纯 Python 库、5 轮链长、2 harness × 4 模型(论文自述为局限);VulContextBench 规模适中(111 案)但每案全人工审计、且 verdict 与证据质量的因果关系未闭环。若任务改为"修复漏洞"而非"判断/复用",或链长大幅延长,量化数字可能变化,但"分离测量"的仪器逻辑不受影响。


七、必要知识反推

假设让一个完全没背景的人重做这两项工作,最少需要知道什么?

7.1 领域知识层

  • 软件仓库的组织形态:公开 API 之下还有大量无文档的内部子包;真实开发者靠交叉引用点击式的探索发现它们——不知道这一点,就不会想到用"依赖图游走"模拟开发者找代码的过程。
  • 代码复用的真实成本结构:复用难在"发现 + 读懂约定",不在"写 import"——不理解这一点,会误以为复用率低是模型不会写 import。
  • CVE 生态与版本历史:CVE → 通告 → 修复提交 → 引入提交的证据链;git blame / 行级追溯的技术含义及其失效模式(最后触碰者 ≠ 引入者)。
  • 安全分析的证据结构:一个漏洞的"证据"不是一个点而是 core/sink/reachability/dependency 的依赖链——不懂安全审查实务,设计不出角色标签。

7.2 方法论知识层

  • AST 静态分析:把"调用了谁"从字符串匹配提升为语法树上的精确边;识别"本地重定义同名函数"的作弊。不知道 AST,reuse 指标会被轻易骗过。
  • SZZ 家族及其已知缺陷:必须知道 Rosa 2021 的评估结论,才会把"逐案人工审计"当作必选项而非锦上添花。
  • 基准构造的可信度工程:执行验证的测试合成(期望值来自真实运行而非模型声称)、独立审计不信任生成器、盲测验证金标准充分性、防污染的快照处理(删 git 历史/测试文件)——这是一整套"如何让真值可信"的手艺。
  • 分离测量的评估设计:recall/reuse 分离、viewed/declared 分离、file/block/line 三粒度、角色标签条件计分——本质上是实验设计里的"因子分离"思想在 agent 评估上的应用。
  • 前沿 agent harness 生态:mini-SWE-agent / OpenCode 的差异、self-invoking 协议(每轮新会话 + 工作区持久)——不熟悉 harness 变量会污染测量。

7.3 工程知识层

  • 用强模型(GPT-5.6 Sol)做管线工具而非被测对象的角色分配;
  • proposer 双案隔离 + 确定性 diff 合并(行范围重叠决定共现/独有块);
  • 从 agent 轨迹恢复"浏览集"的轨迹解析工程;
  • 3000 轮 / 777 次运行(111×7)的规模与预算管理。

7.4 知识融合的关键节点

  • 节点 1(论文 1):“复用是一个从探索到产出的决策链”(领域知识)× “AST 能给调用以可验证语义”(方法论)→ 指标三角 recall/reuse/Cdup。单一学科视角只会得到三个数字;融合后得到一条可归因的因果链。
  • 节点 2(论文 1):“SWE-bench 式环境管理”(工程)× “记忆形式是可控变量”(方法论)→ 记忆消融实验,把"agent 不复用"从现象升级为可干预的机制发现。
  • 节点 3(论文 2):“SZZ 标签不可信”(方法论)× “修复提交定义漏洞位置”(领域)→ 四准则审计的判定逻辑(每条准则都对应一种已知的标签错误模式)。
  • 节点 4(论文 2):“漏洞证据有角色结构”(领域)× “条件计分”(方法论)→ 角色标签评估,从而发现"找到但标错角色占一半"这一更深层的失败。
  • 节点 5(两篇共同):“结果指标在数学上无法区分过程路径”(第一性原理)× “轨迹是可投影的”(工程)→ 把过程变成可测量对象这一共同范式。

八、论文中可以提取的通用性灵感

灵感 1:把单一结果指标拆成"探索投影 + 承诺投影"的差值诊断。 核心思想:任何"结果对但过程存疑"的系统,都可以定义 gap = 探索到的 − 实际采用的,用 gap 定位失败环节(找不到 vs 找到不用)。 论文证据:RepoReuse 的 recall-reuse gap(self recall ≥98.9% vs self reuse 67–86%);VulContextBench 的 viewed-declared gap(37–73pt)。 推广场景:① 法律 AI——检索到的判例 vs 判决书实际援引的判例;② 医疗诊断 AI——调阅的检查项目 vs 结论实际依据的项目;③ RAG 客服——召回的文档 vs 回答中引用的段落;④ 科研 agent——浏览的文献 vs 综述中真正论述的文献。

灵感 2:给"知道"与"说出"分开打分,因为承认不知道也是一种能力。 核心思想:浏览过金标准却不在结论中申报,与根本没看过,是两种完全不同的失败;只有分开测量才能对症下药(前者改进选择性/角色理解,后者改进探索)。 论文证据:探索期模型几乎不分离(1.3 倍差距)、申报期 4.1 倍分离;探索最多的三个模型申报排名 3/4/6。 推广场景:① 教育——“看过教材"与"答题时用上"的分离诊断;② 面试评估——区分"没听说过"与"知道但不会组织表达”;③ 多 agent 协作——消息已读未采用的信息流失审计。

灵感 3:接口地图 > 全文供给——帮助系统复用的最好方式是"可查找性"而非"可复制性"。 核心思想:把已有资产以紧凑索引(名字、签名、行为约定)形式提供,复用率翻倍;以全文形式提供,等于不提供,甚至诱发照抄改写。 论文证据:interface memory 67.8% vs source memory 29.2% vs 无记忆 30.0%;Cdup 46.7% vs 70.7%;而 pass 率三者几乎相同。 推广场景:① 组织知识管理——内部 wiki 的"目录 + 契约卡片"优于全文堆砌;② API 设计——好的 API 文档应是地图而非源码镜像;③ agent 记忆系统设计——记忆模块应存接口摘要而非原始轨迹全文;④ 人事管理——岗位说明书(职责契约)比工作日志全文更利于协作复用。

灵感 4:真值本身需要"可信度工程",且防作弊设计要内建于真值构造。 核心思想:评估的上限由真值质量决定;自动生成的真值要用"独立于生成器的验证"(执行重跑、盲测、空实现必败)闭环,人机混合的真值要显式审计每个来源的已知错误模式。 论文证据:VulContextBench 307→111 的四准则剔除率;盲测验证器 +48pt;RepoReuse 的独立审计重装重跑 + 防污染快照处理(删 git 历史/测试)。 推广场景:① 数据集构建——任何从自动工具(爬虫/标注模型)产生的标签都应设独立审计层;② 考试命题——防"字符串搜索可解"的需求措辞设计;③ 基准防污染——时间切分(2026 新 CVE)与信息屏蔽(不给 CVE 编号)的组合拳。

灵感 5:粒度是区分力——粗粒度同分可能掩盖细粒度的倍差。 核心思想:评估粒度从 file → block → line 逐级细化,能在"同分"的表象下暴露"引用对文件但没定位对代码"的实质差异。 论文证据:GPT-5.5 与 Gemini 3.1 Pro file F1 几乎相同(0.687/0.679),block F1 差近一倍(0.372/0.199)。 推广场景:① 代码评审——按文件统计审查覆盖 vs 按变更行统计;② 医疗影像——器官级定位 vs 病灶级定位;③ 推荐系统——品类命中 vs SKU 命中;④ 检索增强生成——引用页面级 vs 段落级归因。

灵感 6:过程审计不需要改变被审计者——“被动投影"是一种可推广的评估范式。 核心思想:不干预 agent 行为,只记录轨迹并对照真值做投影,即可测得真实秉性;这使审计可以无缝叠加到任何现有系统上。 论文证据:两篇论文均只解析轨迹/提交物(RepoReuse 的文件读取动作、VulContextBench 的浏览区域与最终报告),被测 agent 无感知。 推广场景:① 自动驾驶——影子模式审计决策依据与传感器数据的对应;② 金融交易——成交记录与研究所依据的研文对应审计;③ 编译器——生成的机器码与优化决策日志的对照审计。

灵感 7:警惕"绿色测试"的麻痹效应——正确性指标不动不等于没有劣化。 核心思想:当过程质量劣化不反馈到结果指标时(重复实现照样过测试),系统会在"全绿"表象下积累结构性债务;必须引入结果之外的存量指标(如 Cdup 的累计、单调不减设计)。 论文证据:pass 率 90.8/91.6% 几乎不动,而 Cdup 从 9–21% 涨到 51–69%;三种记忆设置 pass 率 70.2–72.4% 几乎相同而 Cdup 46.7–70.7%。 推广场景:① 技术债管理——功能可用性指标与架构腐化指标并行看板;② 个人健康——“能上班"不等于无慢性病累积,需要存量体检指标;③ 组织管理——季度 KPI 全达成时的流程债务/人员倦怠存量审计;④ AI 对齐——任务成功率和奖励黑客行为存量的分离监测。


附:一图总览

RepoReuse(写了什么)VulContextBench(看了什么)
一句话测试全绿,轮子已造了五遍证据都看过,报告只交一成
真值执行验证的参考解依赖四准则审计 + 角色标注金标准
分离测量recall(读)vs reuse(用)viewed(浏览)vs declared(申报)
gap 发现recall 饱和但 reuse 仍衰退37–73pt 看到但不上报
干预杠杆接口记忆:self reuse 30→68角色标签:暴露一半"找到标错”
失明指标pass 率verdict accuracy
共同结论功能通过 ≠ 过程正确;分离测量是过程可信的仪器同左