用真实提交检验代码上下文压缩效果
TokenCap 基准同时衡量上下文 token 数和实际修改文件的召回情况,避免把遗漏文件误当成优化。任务来自九个仓库,在提交父版本上评估,并划分开发集与留出集。
AI 深度解读
把上下文压得越短,AI 编程就越高效吗?TokenCap 的这组基准给出了一个更有用的判断标准:先看改代码需要的内容有没有留下,再看省了多少 token。否则,漏掉大半关键文件的工具也能拿到漂亮成绩。
作者用真实提交检验上下文包,得到的结果是:token 用量明显下降,但文件召回和修改行覆盖仍有缺口。它值得读的地方,是把「省了多少」和「丢了什么」放在一起算,也明确承认这些成绩还不能证明模型写代码更准确。
怎样判断上下文有没有漏掉关键代码
这套基准放在 benchmarks/fair/,任务来自九个仓库的真实提交,文中列举了 fastify-example-todo、full-stack-fastapi-template、hoppscotch、flask 和 httpx,覆盖 JavaScript、Python、TypeScript、Vue 等代码。
每个任务只拿提交标题作为需求,把该提交改动过的非测试源码文件当作标准答案。评测时,仓库退回提交的父版本,避免把已经完成的修改交给检索工具。
筛选规则记录在 tasks.json:每个仓库选最近的非合并提交,要求改动 1 至 5 个非测试源码文件,总文件数不超过 8 个,标题至少三个词;排除依赖、发布、文档、lint 和翻译类提交。候选先由脚本列出,作者称没有看完成绩再删除任务。
其中 50 个任务用于调整检索和打包代码,另外 50 个留作评测。还有两个已选提交被跳过,因为它们涉及的文件在父版本中均不存在。
比较对象有三种:tokencap ask "<task>" 及 companion bridge 构建的任务包、关键词 grep 后完整读取所有匹配文件,以及只读取匹配度最高的十个文件。
这里同时检查两层覆盖:需要的文件找到了多少,以及提交实际修改的那些行,有多少出现在上下文包里。后者尤其关键:找到了文件,不代表截取到了要改的位置。
省下的 token,换来了哪些缺口
100 个任务中,任务包的所需文件召回率为 87%,实际修改行平均覆盖率为 73%。完整读取所有 grep 匹配文件的召回率更高,达到 96%;任务包的 token 用量平均少 38 倍,并在召回和 token 用量两方面都胜过十文件基线。
文件召回率高,不等于修改位置覆盖充分。
大文件以选中的函数和代码行进入上下文,因此容易漏掉真正的修改点。在 cobra、ripgrep 和 gson 上,修改行覆盖率只有 56% 至 58%。
收益也受仓库规模影响。小仓库的节省倍数中位数只有 1.6 倍,九个任务中有三个任务包反而比朴素读取更大。全体任务的节省倍数均值是 34.2 倍,但被大仓库拉高;作者认为中位数 18.9 倍更有代表性。这里的「平均少 38 倍」与「节省倍数均值 34.2 倍」不是同一个报告值,给定原文没有展开两者的计算口径。
留出集的文件召回率、修改行覆盖率、节省倍数中位数分别为 88%、74%、18.4 倍;调优集分别为 86%、72%、20.4 倍。不过,前三个仓库的留出任务也曾在早期开发中运行过,因此不能把它当成完全未接触过的测试集。
下面两条命令用于获取评测仓库并运行留出集:
node benchmarks/fair/fetch-repos.js ../bench-repos
node benchmarks/fair/run.js --repos ../bench-repos --set holdout
注意第二行的 --set holdout。CI 使用 --set all --gate 跑全量任务,当文件召回、修改行覆盖或节省倍数中位数低于 tasks.json 中的阈值时失败。限制说明放在 docs/HONEST-NUMBERS.md 的成绩表旁边。
我的判断
我认可它把覆盖率设为约束的做法。作者报告,在 v3.1 检索改动之前,前三个仓库的所需文件召回率只有 25%。只比 token 数,这种大量漏文件的版本也可能显得很优秀。旧结果保留在 benchmarks/fair/results/,100 任务结果放在 benchmarks/fair/results/v2/,便于追查变化。
但这仍是检索评测。全程没有调用模型;答案评测脚本 benchmarks/fair/answer-eval.js 虽然存在,却尚未运行,也没有公开模型结果。目前能支持的结论是上下文更省、覆盖情况可测,不能推导成修复成功率更高。
标准答案也有边界:提交改过的文件是可验证的目标,却不一定包含理解需求所需的全部调用方、配置和测试。提交标题又比开发者通常输入的需求短,真实任务下的表现仍需验证。
相比完整 grep 读取,TokenCap 接受了一部分召回损失;相比只取十个文件,它在这组任务中更占优势。但原文没有模型答题对照,不能替它补上质量结论。评测范围也仅限 tokencap ask 和 companion bridge,不包含 tokencap make capsule。
能拿来做什么
- 给日常 AI 编程的上下文检索增加覆盖指标。可以从团队近期提交取样,在父版本上运行检索,同时记录所需文件召回、修改行覆盖和 token 用量。
- 处理大型 Vue、TypeScript 或 Node 文件时,检查上下文片段是否覆盖待改位置;遗漏时补读相关函数或完整文件,别仅凭文件名命中就继续生成代码。
- 为小仓库保留直接读取的基线。原文已有任务包更大的案例,是否启用压缩,应由本仓库的数据决定。
- 将检索评测和代码结果评测分开。前者通过后,再验证模型生成的修改能否满足任务要求,避免把 token 节省直接记成开发效率提升。