Papers

Impact-driven Context Filtering:用真实 completion likelihood 训练代码上下文过滤器

CodeFilter 怎样筛上下文:系统先用 ground-truth completion 的 likelihood change,把检索 chunk 标为正、负或中性。代码模型在线输出“是否检索”和“该 chunk 是否保留”的控制 token,只留下有用的跨文件上下文,prompt 也随之缩短。

本文目录 · 16 节
  1. 1. 问题与 baseline
  2. 2. 如何定义“影响”
  3. 3. 两组控制 token
  4. 4. 完整在线数据流
  5. 5. 一个完整例子
  6. 6. 训练与评测设置
  7. 7. 准确结果
  8. 8. 消融:阈值不是越严格越好
  9. 9. 方法贡献
  10. 10. 局限与适用边界
  11. 11. 与合集其他论文的关系
  12. 12. 为什么相似 chunk 会产生负影响
  13. 13. 标签构造中的三个关键选择
  14. 14. 如何公平核算效率
  15. 15. 泛化时应先检查什么
  16. 16. 前置背景、工程复现与结论边界

1. 问题与 baseline

repo-level completion 只看当前文件经常缺少 API 定义、相邻模块用法和项目约定,因此常见做法是把当前代码作为 query,从其他文件取 top-10 chunks,拼进 prompt。baseline 有三类:No Retrieve 只用 in-file context;Full Retrieve 总是加入 top-10;RepoFormer 先判断要不要检索,但一旦检索仍把候选整体交给 generator。它们都把“检索相似”近似成“对这次 completion 有帮助”。

作者在 RepoEval-API 上逐 chunk 检查后发现,top-10 中只有约 15% 是 positive,5.6% 会降低正确 completion 的 likelihood,影响 19.81% instances,其余大多 neutral;大约一半 instance 连一个 positive chunk 都没有。StarCoderBase-3B 的 Full Retrieve EM 为 47.27%,删掉 negative 后为 49.96%,只留 positive 为 49.47%。因此问题不只是 token 浪费,而是负上下文会把生成分布推向错误代码。

2. 如何定义“影响”

目标 completion: Y = (y1, ..., yT)
in-file context: C_in
候选跨文件 chunk: c_i

L(Y | C) = sum_{t=1..T} log P(y_t | y_<t, C; G)

S(c_i | C_in, Y) =
  [L(Y | C_in, c_i) - L(Y | C_in)] / L(Y | C_in)

polarity(c_i) =
  Positive, if S > T_p     (论文设 T_p = +10%)
  Negative, if S < T_n     (论文设 T_n = -5%)
  Neutral,  otherwise

分数直接问:“加入这个 chunk 后,模型给已知正确答案的 log-likelihood 提高还是降低?”它比 Jaccard 或 embedding similarity 更靠近最终生成目标。线上当然没有 ground truth,所以该式只用于离线标注;部署时由 fine-tuned CodeFilter 预测控制 token,这也是方法最重要的训练/推理边界。

3. 两组控制 token

训练数据使用 FIM verbalization。一个极性学习样本会呈现打乱顺序的候选及其标签;另一个生成样本只呈现 positive chunks,随后是 <EC><MIDDLE>[Target]。若没有 positive,直接生成 <EC>,教模型不要为检索而检索。目标函数同时训练代码和 signal token:

L = -log P_G(Y | C_in, C_cc)
    + lambda * [-log P_G(T | C_in, C_cc)]

lambda = 2.0
计算 loss 时 mask 掉作为条件的 in-file/cross-file 内容,
只监督 signal tokens 与 target tokens。

4. 完整在线数据流

  1. 将左上下文、右上下文组织为 <PREFIX>...<SUFFIX>...;模型先在 <EC>/<MC> 上做一次小决策。
  2. <EC>,直接加入 <MIDDLE> 并生成代码,不调用 retriever。
  3. <MC>,用当前文件前 10 行作 query,将其他文件按 10 行窗口、5 行 stride 切块,以 Jaccard 排序取 top-10。
  4. 候选按序送给 CodeFilter。模型为当前 chunk 生成 polarity token;<neu>/<neg> 立即丢弃,<pos> 才追加到可见 completion context。
  5. 接受 positive 后再次在 <EC>/<MC> 间选择。上下文已足够就提前停止,否则看下一个候选。
  6. 最终只把 in-file + accepted positive chunks 交给 generator。CodeFilter 自己也可生成;论文另证实 3B 的过滤决策可以作为 plug-in policy 给 7B-16B、GPT-3.5、DeepSeek-R1 等更大模型。

5. 一个完整例子

假设当前文件要补 client.fetch_user(user_id) 的错误处理。top-10 中:chunk A 是项目里同一 client 的重试 wrapper,B 是另一个模块的 interval 数值计算,C 是该 API 返回 None 时抛 UserNotFound 的调用。Full Retrieve 会把 A/B/C 连同七个相似但无关片段都塞入 prompt;B 中同名变量和错误类型可能让模型走错分支。

CodeFilter 首先输出 <MC>。A 后输出 <pos> 并保留,但再次判断仍是 <MC>;B 输出 <neg>,不进入最终上下文;C 输出 <pos>,随后 <EC>,立即停止。最终 generator 只看到 A、C,既学到重试约定,也拿到正确异常语义。离线标签并不是靠作者主观判断:加入 A/C 会让 ground-truth log-likelihood 相对基线提高超过 10%,B 让它下降超过 5%。

6. 训练与评测设置

数据来自 Stack 中近 6,000 个 Python repositories。每个实例取 line、chunk 或 function body 为 target,top-10 Jaccard chunks 做 likelihood 标注;清洗后得到约 43K instances、400K labeled chunks,verbalize 后约 130K training instances,95/5 切分。模型为 StarCoderBase-3B/7B、CodeLlama-7B/13B,训练 2 epochs,初始 LR 2e-5、5% warmup、linear decay、batch 512、max length 4096,4x A100 80GB。推理用 vLLM 与 greedy decoding,in-file/cross-file budget 为 1024/3072 tokens;<MC><pos><neg> threshold 均设 0.3。

benchmark 是 RepoEval(14 个高质量 Python repos 的 line/API/function)与 CrossCodeLongEval(chunk/function),同时测 FIM 与 left-to-right。指标为 EM、Edit Similarity,RepoEval function 另用 unit-test pass rate。

7. 准确结果

模型/设置Full RetrieveCodeFilter含义
StarCoderBase-3B, FIM RepoEval-Line EM56.2560.50更短 context 反而更准
StarCoderBase-3B, FIM RepoEval-API EM47.2750.59接近/超过 7B full retrieval
CodeLlama-13B, FIM RepoEval-API EM48.6651.84跨模型族一致收益
StarCoderBase-7B, negative subset, LTR Line EM7.2328.92负 chunk 场景收益最明显
StarCoderBase-7B, negative subset, FIM API EM10.6322.83过滤确实缓解误导

论文总体概括为平均 EM 相对 RAG baseline 提升约 3%,cross-file prompt tokens 减少近/超过 80%。Full Retrieve 在各 benchmark 都超过 1,500 cross-file tokens;CodeFilter 进一步比 RepoFormer 少得多。negative subset 来自 1,600 test instances,其中 API/Line 分别 285/166 个包含负 chunk;在该子集 Full Retrieve 有时甚至弱于 No Retrieve,支持“negative context 真的有害”而不只是相关性分数不漂亮。

8. 消融:阈值不是越严格越好

StarCoderBase-3B、FIM RepoEval-API 中,<MC> threshold 从 0 到 0.3 时 EM 保持 50.16%-50.59%;升到 1.0 等于禁用检索,EM 掉到 41.15%。两个 threshold 都为 0.3 时,cross-file context 为 355 tokens,不到原始的 30%。<MC> threshold 还决定要评估多少 chunk:signal-token overhead 从 threshold 0 的 10.85 tokens,降到 threshold 1 的 1 token。作者因此推荐 0.2-0.3 的质量/成本折中,而不是最大化过滤。

9. 方法贡献

CodeFilter 没有再训练一个 relevance ranker。它用 generator 对正确 completion 的因果式对照构造标签:同一 in-file context 下只加一个 chunk,观察目标 likelihood 的变化。标签除了“相关/不相关”,还会标出让模型更容易出错的 negative。随后,retrieval sufficiency 与 chunk polarity 被编码成模型可生成的 tokens,检索、过滤、停止由一个自回归过程统一控制;做决策的小模型也可以与更大的 generator 解耦。

10. 局限与适用边界

11. 与合集其他论文的关系

Rethinking KV Cache Compression 说明压缩虽减少显存,却可能拉长输出;CodeFilter 说明检索虽增加信息,却可能拉低 likelihood。两篇都把端到端请求结果置于局部资源指标之上。PACE/CONCUR 从 agent 生命周期控制并发,CodeFilter 从 prompt 构造减少 prefill token,可在同一 code agent serving stack 组合。与一般 RAG router 相比,它优化的不是选哪个大模型,而是进入模型前哪些代码证据值得保留。

12. 为什么相似 chunk 会产生负影响

代码仓库里常见同名函数、旧版本接口、测试 mock 和不同子模块的局部约定。词法相似检索会把这些片段排得很高,但 generator 并不知道哪个定义处于当前 import path。一个旧 API 示例可能包含几乎相同的符号,却让模型选择错误参数顺序;一个测试 double 可能把真实异常吞掉。negative label 捕捉的是这种“看起来相关、实际把正确答案概率拉低”的情况,neutral 则只是没有提供新增信息。二者在资源上都可删,在错误风险上却应分开分析。

13. 标签构造中的三个关键选择

一次只加入一个候选

贡献分数比较 C_inC_in+c_i,避免多个 chunk 同时出现后无法归因。代价是它没有直接建模互补关系:两个单独 neutral 的片段合在一起可能足以解释调用。训练 verbalization 通过逐步接受 positive 并重新判断 <EC> 部分弥补组合需求,但初始 polarity 标签仍是一阶近似。

用相对变化而不是原始 likelihood

不同 target 的长度和难度不同,原始 log-likelihood 不可直接横比。相对基线变化把问题变成该 chunk 对同一个 target 的增益;正负阈值又故意不对称,positive 需提升超过 10%,negative 下降超过 5% 就进入风险类。这个标准更重视避免有害信息,但阈值和标注模型一起决定数据分布。

控制 token 与代码 token 联合训练

若模型只学 polarity classification,它可能知道 chunk 好坏却不知道何时停止;若只学 <MC>/<EC>,则会复现 RepoFormer 的“要么全取、要么不取”。联合 loss 让判断与最终 completion 共享表示,lambda=2 又避免稀少 signal token 被长 target loss 淹没。部署时这些 token 是执行协议,必须从用户可见代码中剥离。

14. 如何公平核算效率

论文清楚报告 prompt token 缩短,但生产系统还要加上过滤阶段的 decode、逐 chunk KV 构建与 retriever latency。可采用两阶段 serving:小 CodeFilter 独立批处理所有候选,只把 positive chunk ID 返回大 generator;常用仓库片段的编码和检索结果可缓存。应同时测总 TTFT、generator prefill tokens、过滤 signal tokens、最终 EM/UT,而不能只把减少的 80% prompt 当作等比例 latency speedup。

15. 泛化时应先检查什么

迁移到 Java/C++ 时,需要保留 package/include、重载、类型与 build target 等结构,单纯 10 行窗口可能切断语义;迁移到 agentic editing 时,target 也从一段 completion 变成多文件 patch,单 chunk likelihood 标签要重新定义。若更换 generator,先抽样重算 polarity agreement;若 3B policy 与目标大模型对同一 chunk 经常意见相反,就不能直接复用 plug-in 结论。最稳妥的做法是保留线上 shadow evaluation,让 full-retrieve 与 filtered prompt 在不执行写操作时并行评分。

16. 前置背景、工程复现与结论边界

跨文件补全为什么先要检索

单文件补全可从光标左右的代码推断局部语法,但真实仓库中的类型、函数签名、错误约定和辅助工具常定义在其他文件。仅依赖预训练记忆会生成通用写法,无法知道当前仓库的私有接口。跨文件检索因此把光标附近代码作为查询,从仓库其他位置找相似片段,放到填空提示前。填空模式同时给前缀和后缀,模型生成中间;左到右模式只给前缀。CodeFilter 同时评测两种。

词法检索的优势是便宜、无需索引模型,问题是相似度衡量文本重叠,不衡量候选对具体正确补全的因果影响。仓库中测试、旧实现和不同模块会复用同名变量;一个相似片段甚至比无关片段更危险,因为模型会高置信模仿错误约定。论文先通过逐候选干预证明 negative context 存在,再训练线上控制器,这条证据链比直接比较新 ranker 更完整。

Likelihood 影响分数的符号与长度

目标序列 Y 有 T 个 token,L 是在给定上下文下逐 token 对数概率之和。对数概率通常为负;论文公式用加入候选前后的差再除基线值,阈值按其实现定义解释。复现不能只看公式符号自行反转标签,应在一个已知提高目标概率的候选上检查输出确实标 positive。目标长度固定时差值可比,同一候选对不同目标的相对归一化减少难度尺度差。

标注每个 chunk 时其他候选不出现,所以 S 衡量一阶边际影响。若两个片段只有合并才有帮助,它们可能都被标中性;若两个 positive 内容重复,依次加入后第二个新增价值可能很小。在线算法按序查看并在保留正片段后重新判断是否已足够,能处理部分冗余,却没有重新预测剩余候选在新上下文下的 polarity。它以有限控制 token 换取可执行复杂度。

正阈值百分之十高于负阈值绝对值百分之五,意味着保留需要更强证据,删除风险更敏感。Neutral 占大多数,既不明显提升也不明显伤害;删除它主要省 token。Negative 比例虽只有百分之五点六,却分布在近五分之一实例中,解释了为什么平均比例小仍能显著影响请求子集。

离线数据构造的完整流水线

  1. 从近六千 Python 仓库抽取可形成 line、API、function completion 的位置,保留光标前后代码和 ground truth。
  2. 排除当前文件,将其他文件按十行窗口、五行步长切块;用当前文件前十行等查询做 Jaccard 排序,取前十候选。
  3. 冻结用于标注的 generator,分别计算只有文件内上下文与额外加入单一候选时的目标对数似然,按阈值标正、负、中性。
  4. 构造 signal 学习样本:把候选及 polarity 控制 token verbalize;构造生成样本:只保留 positive,并在足够位置监督 EC,目标区监督真实代码。
  5. 清洗后约四万三千 completion、四十万 chunk 标签,展开约十三万训练样本,按九十五比五划分。

仓库级拆分必须避免同一项目的相似代码同时进入训练与测试,否则过滤器可能记住文件。论文主 benchmark 是独立的十四个高质量仓库。复现还要固定 tokenizer 与最大长度四千零九十六;候选拼接超过预算时的截断顺序会改变哪个 chunk真正可见。

联合目标和控制 token 如何进入一次 forward

训练 loss 第一项监督 target code,第二项监督 EC、MC 与 polarity token,权重二。条件中的文件内代码、候选正文被 mask,不计算语言建模损失,防止模型把容量花在复述输入。控制 token 要加入 tokenizer 词表并初始化 embedding;若只用普通字符串,可能被拆成多个 token,阈值概率和协议都失效。

推理先对 EC 与 MC 的概率做阈值决策。阈值零点三不等于必须 argmax 超过一半;模型可在多个普通 token 中分散概率,控制 token 达到零点三就触发。Polarity 同理。采用 greedy completion,但控制阶段可以读取指定 token 概率,而不是让模型自由生成任意文本。每接受一个 positive 后再次判断 EC,形成早停;negative 与 neutral 都不进入 generator 上下文。

若 CodeFilter 与最终 generator 是同一模型,保留上下文后可继续生成;若作为三十亿 policy 给更大模型,控制器只输出候选标识和停止点,再由大模型重新 prefill 过滤后的 prompt。后者多一次小模型成本,却可大幅减少昂贵大模型 token。跨模型有效的前提是小模型判断与大模型收益相关,论文实验提供经验支持,没有理论保证。

端到端手算一个 polarity 标签

假设正确补全包含四个 token,只有文件内上下文时逐 token 对数概率相加为某个基线值。候选甲给出同一 API 的正确异常处理,加入后四个正确 token 概率整体上升,相对变化越过正阈值,标 positive。候选乙来自旧版本,第二个参数顺序相反,模型在关键 token 上把概率分给旧参数,使总似然下降超过负阈值,标 negative。候选丙只是相同 import,概率几乎不变,标 neutral。

线上没有这四个正确 token,因此不能重算 S。模型先判断文件内上下文不足,依次看甲乙丙的正文。甲被接受,乙丢弃;接受甲后若输出 EC,丙甚至无需判断。最终大模型只见甲。若过滤器把乙错标 positive,负影响仍存在,所以 polarity 分类准确率与最终 EM 都要测;若把甲错删,系统退化为文件内补全,但通常比保留强误导片段安全。

实验主表的多维读法

RepoEval 分 line、API、function,CrossCodeLongEval 分 chunk、function;每格同时有精确匹配和编辑相似度,function 另可跑单测。三十亿 StarCoder 在填空 line 中 Full Retrieve 精确匹配五十六点二五,CodeFilter 六十点五;API 从四十七点二七到五十点五九。十三亿 CodeLlama 的 API 从四十八点六六到五十一点八四,说明收益跨架构。

平均提高约三个百分点看似不大,negative subset 更能隔离机制。七十亿 StarCoder 左到右 line 中 Full Retrieve 七点二三,过滤后二十八点九二;填空 API 从十点六三到二十二点八三。这里样本专门包含负 chunk,巨大差距证明过滤不只是节省 prompt。总体数据中许多请求无负片段,提升被中性/易样本稀释。

跨文件 token 从普遍一千五百以上降到约三百多,减少超过八成,但过滤阶段仍会查看候选正文。论文报告的是最终 generator context,不应直接称总读取量下降八成。生产延迟需把 retriever、policy prefill、signal decode、最终 generator prefill 和 completion 全部计入。

阈值消融与错误权衡

MC threshold 越高,越少请求检索;到一等价禁用检索,API 精确匹配降到四十一点一五。零到零点三区间保持约五十点一六到五十点五九,说明模型在低阈值内稳。信号 token 开销随阈值上升从约十点八五降到一个,因为更早判断足够。论文推荐零点二到零点三,是质量与控制成本折中。

Polarity threshold 高会删更多候选,context 更短,但 false negative 会丢 API 证据;低会保留 neutral/negative,接近 Full Retrieve。部署应分别画 EC/MC 与 polarity 的校准曲线,不要用同一阈值假定两类概率同样校准。还可按候选名次设成本:越靠后检索价值通常越低,判断开销却持续增加,早停应结合剩余预算。

实现、复现与最终结论

数据泄漏检查要在仓库层执行。相同项目的 fork、复制文件和生成代码可能跨 split,Jaccard 又会轻易找到近重复,导致控制器看似准确。应按仓库来源去重,报告训练与 benchmark 的项目重合;候选检索必须排除 target 所在文件,不能让 ground truth 同窗口进入。构造 function completion 时,右上下文应只包含真实光标后代码,不能额外泄漏函数体。

Likelihood 标注成本约等于每个实例为基线和十个候选多次跑 generator。可以把同一文件内前缀的 KV 或 hidden 复用,但加入候选会改变 prompt 排列,缓存必须保证位置编码一致。批处理应按长度分组,保存每个候选的原始分数、相对分数和标签,之后改变阈值无需重跑模型。标签生成模型要用 eval 模式和固定精度,避免 dropout 或量化差异让阈值附近样本随机翻转。

Polarity 数据的类别极不平衡:正约一成多、负更少、中性占多数。只看总准确率会让全预测中性的模型显得很好。应报告每类 precision/recall,特别是 negative recall 与 positive precision;负漏检会伤质量,正误删会损失跨文件收益。最终 EM 是联合结果,但分类指标能定位是检索充分性还是 polarity 出错。

EC/MC 监督如何产生也应明确。没有正候选时,文件内上下文被视为最终可用输入并监督 EC,教模型避免无意义检索;存在正候选时,初始通常需要更多上下文,逐个加入正证据后在足够位置输出 EC。若数据只在最后监督 EC,模型可能总看完十个才停,无法获得 token 节省。候选顺序打乱可减少死记 top rank,但线上仍按 retriever 顺序,训练应覆盖不同正片段位置。

插件模式还涉及分布差异。三十亿 policy 的 positive 是相对自身 completion likelihood 学得,大模型可能利用 policy 认为 neutral 的细节,或被它认为 negative 的代码纠正。论文跨七十亿到更大模型实验说明平均可迁移,部署仍应在目标 generator 上抽样做四种对照:无检索、全检索、policy 过滤、用目标自身离线 oracle 过滤。Policy 与 oracle 差距才是跨模型代价。

Retriever 变化会改变候选难度。Jaccard 候选常词面相近,UniXcoder 等语义检索可能带来词面不同但逻辑相关片段,旧过滤器未见过这种分布。不能只替换检索器后沿用阈值;应重新统计 positive/negative/neutral 比例与控制概率校准。更强 retriever 也不会消除过滤需要,因为高相关旧版本或测试 mock 仍可能有害。

对于 function-level 单测,执行环境必须隔离依赖、超时和副作用。Exact Match 偏严:两个语义等价实现文本不同算错;Edit Similarity 连错误代码也可能很高;unit test 更接近功能,却只覆盖有限路径。三者联合说明过滤是否改善语法、文本和行为,不能挑一个最有利指标。

延迟实验可把控制器部署成独立 worker pool。多个 completion 的候选判断可批处理,但每个请求在接受 positive 后需要重新 EC 决策,形成状态依赖。可一次为所有候选预测 polarity,再按顺序模拟停止以提高吞吐,但这与论文逐步条件不同,后面候选没有看到已接受上下文。若做这种近似,必须重新测质量,不应仍称相同算法。

隐私和安全方面,跨文件检索可能把仓库敏感片段送入外部大模型。过滤器减少最终 prompt,但它自己仍读取候选;若 policy 本地部署而 generator 远程,只把 positive 发送可降低暴露。Negative 片段不一定恶意,也可能含旧密钥、测试数据或许可证受限代码,检索层还需独立访问控制,不能把模型 polarity 当安全分类。

上线监控应保存匿名化的检索率、停止 rank、保留 token 数和生成接受反馈。若模型版本更新后 MC 比例突然升高,可能是控制 token embedding 或模板不兼容;若 positive 比例下降,可能索引过期;若 prompt 变短但 EM/测试失败上升,可能阈值过严。按仓库和语言分桶比全局平均更容易发现漂移。

一个容易忽略的复现变量是候选在 prompt 中的格式。文件路径、起止行、代码围栏和分隔 token 会影响模型判断,也会占用跨文件预算。路径本身可能提供模块语义;完全删除路径会让两个同名实现难以区分。应沿用论文 verbalization,并把格式 token 计入长度,不能只统计源码 token。

右上下文在填空任务中尤其重要。候选可能与左侧调用相似,却与右侧变量使用冲突;影响分数由完整文件内前后文计算,能够捕捉这种不一致。迁移到只支持左到右的模型时,过滤器少了右侧证据,polarity 会改变,所以论文分别训练/评测模式,不能直接把 FIM checkpoint 当 LTR policy。

控制信号权重二是经验设置。权重太低,长代码 loss 淹没几个 signal token,模型会补代码但不会可靠路由;太高,模型可能学会分类却损伤生成能力。消融可分别报告 signal 准确率与 completion EM,寻找二者折中。若采用独立 policy 而不让它生成代码,可重新设计纯分类目标,但那已不是论文的统一模型。

当文件内上下文已经包含完整 API 定义时,MC false positive 会造成额外检索和延迟,即使之后所有 chunk 都丢弃。EC/MC 的价值因此不只是 prompt 缩短,还减少 retriever 与十次 polarity 判断。统计应把“初始 EC 直接生成”“检索后无正片段”“检索后早停”分开,分别定位充分性模型与过滤模型。

Oracle 实验中删除所有 negative 后三十亿模型 API 精确匹配从四十七点二七到四十九点九六,只保留 positive 为四十九点四七。只留 positive 略低于删除 negative,说明部分 neutral 可能有微弱组合价值,或阈值把有用片段划为 neutral。CodeFilter 达五十点五九,可能还受联合训练改善生成能力影响,不能把全部差值简单归因于完美 polarity。

最终部署应保留可关闭的开关。仓库索引缺失、控制 token 概率异常或过滤器超时时,可回退文件内生成,而不是默认 Full Retrieve;论文负样本分析说明后者可能更危险。对于需要最高召回的低风险离线补全,也可保留更多 neutral,策略应随错误代价调整。

检索只负责扩大候选,生成前仍要按任务影响做准入。相似度高表示片段可能相关,likelihood 标签检验它对指定模型与正确补全是否有帮助,EC/MC 再判断当前证据是否已经足够。三层判断回答的是不同问题;少掉任何一层,系统都会退回总是检索、全量拼接或过早停止的旧行为。完整复现应保留这三个边界,不能把方法简化成普通的二分类 reranker。

复现固定四张 A100 八十吉字节、两轮训练、学习率二乘十的负五次方、预热百分之五、线性衰减、有效 batch 五百一十二;推理用 vLLM、greedy、文件内预算一千零二十四、跨文件三千零七十二。记录 label 分布、控制 token accuracy、检索率、平均查看候选数、保留正负中性数、最终 prompt token、TTFT、EM、编辑相似度与单测。

正确性测试应验证输入正文 loss 被 mask、特殊 token 单 token 化、EC 真正停止、negative 不进入最终 prompt、插件模式不把 signal token 传给大模型。更换 retriever 或语言后重新生成 likelihood 标签;更换 generator 先测 polarity agreement。代码库更新时索引和候选版本要与 completion 样本一致。

CodeFilter 的核心贡献是把“相似”换成“对正确补全概率的影响”,显式识别有害上下文,再让同一个代码模型学会是否检索、逐块极性和何时停止。它在主表提高准确率并显著缩短最终 prompt,在负上下文子集收益最大。边界是离线标签依赖 generator、一阶 chunk 影响忽略组合、主数据以 Python 为主,以及小 policy 本身有延迟。把这些条件纳入端到端核算后,它才是一套可复现的跨文件上下文控制方法。

最终判断应以功能测试和真实延迟为准:过滤器既要减少误导,也要保留完成当前仓库接口所需的最小证据;任何只追求最短上下文的实现都偏离了论文目标。

方法的成功标准始终是更可靠的补全,而不是过滤比例本身。上线验收也应围绕补全正确性、仓库测试和真实响应时间展开,不能把过滤掉多少 token 当成独立的成功指标。