AREX Feed Article
GitHub 披露 Copilot agent 四项成本优化:删除 view 行号前缀省约 5% 推理成本
GitHub 官方工程博客在 9 月 2 日(UTC 18:00,北京时间 9 月 3 日凌晨)发表署名文章 ,作者是 Copilot 团队工程师 Erik Krogh Kristensen(Staff Software Engineer,此前参与 Copilot Autofix、Copilot Code Review,最近在做 Copilot CLI)与 Napalys Klicius(Software Engineer,负责 agentic 系统)。文章披露四项已经过离线基准与线上 A/B 实验、正在推向产品的编码 agent harness(承载 agent 运行的框架层)成本优化:选择性输出压缩、删除 view 工具的行号前缀、压缩 task 工具元提示、后台完成结果批量直达。
按文章所述,四项改动的测量结果如下:view 工具此前在每行文件内容前加的行号前缀被删除后,离线 agentic 编码基准上的模型推理成本下降约 5%,成功率落在正常的实验波动范围内、编辑失败没有增加;Copilot CLI 用户的线上实验里,人均日推理成本下降约 3%,质量与满意度指标无实质回退。压缩后的 task 工具元提示每轮省约 1,300 个 prompt token,活跃小时归一化成本降 2.9%;后台完成结果批量直达让 AI Credits 口径下的平均 token 相关用量降约 2.3%;选择性输出压缩器在触发压缩的离线任务上没有检测到统计显著的成功率回退,线上平均成本略降。
按单次调用省 token,整单任务反而变贵
文章先讲了一次只省局部、没省全局的尝试:GitHub 试过 RTK(Rust Token Killer),一个在 agent 读取 shell 输出前把输出截短的实用工具。在他们的 harness 与基准配置下,RTK 确实让部分响应变短,但只要被截掉的内容恰好有用,模型就会重新打开原始输出或重跑命令来补回,这些恢复动作带来额外轮次,并把更多上下文带进后续请求。
结果与直觉相反:单次工具响应变短了,任务平均却消耗了更多 token、耗时更长。作者的原话是「我们本地省下了 token,却在全局花得更多」。文章随即给这条结论画了边界:它只适用于所测的集成方式与工作负载,不代表所有 RTK 配置或所有输出压缩都会这样。真正被确立的是衡量口径:每次工具调用的 token 数不是正确的优化目标,一项效率改动必须放在「从用户请求到最终结果」的完整任务上评估,四项优化都按这个口径设计。
git diff 曾进压缩名单,又被基准撤掉
第一项优化是选择性输出压缩器,针对的是 install、build、test、lint 这类命令输出里的重复噪音。对基准运行结果的分析发现,源码类输出和任意命令结果更可能含有 agent 需要的信息,而构建、测试、安装与进度输出常常只是重复噪音。
原型在 agentic 编码基准和一批开源仓库(跑它们的 build、test、lint 系统)上反复试错,早期版本「过于激进」:团队最初把 git diff 也纳入压缩,但基准任务显示 agent 会重新打开原始输出找回被压掉的信息,这个过滤器随即被撤掉。最终发布的版本执行三条策略:cat、git diff、git show、任意脚本这类源码类与任意输出原样返回;grep 等工具的搜索结果只做无损重组,匹配与文件列表一条不丢;只有可预测的重复噪音(安装、构建、测试、进度输出)在节省足够显著时才压缩。压缩发生时,agent 仍能通过一条直接的恢复通道取回完整原文。
这条恢复通道同时是安全网和评估信号。团队追踪 agent 是否打开已保存的原文、重跑命令、重复探索或增加轮次,频繁恢复就说明压缩器删掉了有价值的东西。在触发压缩的离线任务上,agent「极少」打开已保存的原文。作者解释,发布版之所以保守,是评估一路试出来的结果,而不是预设目标。
行号前缀:旧编辑工具留下的格式
view 工具此前给读入的每一行文件内容加上行号前缀。这套格式来自更早的文件编辑工具:它们靠行号定位修改位置,而当前的编辑工具改为匹配周围代码来定位,行号已不再被使用,前缀却一直留在每次文件读取里。
单个前缀很小,但每读一个文件、每一行都重复一遍,会在整个会话里累积。作者把删除它称作「理想的改动」:没有任何信息被删,模型不需要新指令,没有需要恢复的信息源,也没有新增决策,文件内容原样到达模型。对开发者而言,省下的空间意味着上下文窗口里有更多部分留给任务本身,而不是留给模型用不上的格式。行号并非全局废弃:在 diff 和短代码片段里,它们仍然有用;这个场景的问题是,前缀附着在每一次文件读取上,却不服务当前的编辑流程。
并行 agent 曾被改写为串行,一句话修复
第三项改动改的是 task 工具的提示词,上线前曾翻过一次车。task 工具负责启动专门的子 agent 做并行工作,它的指引长期累积在工具描述、schema、agent 定义、系统指令和配套工具里。GitHub 用一个元提示循环(让 Copilot 迭代改写自己的提示词)把提示词压缩了约一半,再用针对性行为测试核对需要保留的行为。
随后第一次线上实验就暴露了离线评估没发现的回归:元提示循环把原本「谨慎的并行指引」改写成了硬性调度策略,导致相互独立的自定义 agent 被顺序执行。团队叫停了实验,先为被用户暴露出来的行为补写回归评估,再改提示词。最终修复是把显式的 allowlist 与 denylist 换成一句话:「独立 agent 可以并行运行;考虑副作用」(Independent agents can run in parallel; consider side effects.)。这句话更短、限制更少,把是否并行的决定权交还模型。新行为测试通过,已有行为测试无一失败。
作者随之写下一句方法论:「提示词行为需要测试。如果某个行为没有被测试覆盖,更短的提示词可能在没人察觉时把它删掉。」上线版本的收获按每轮计算:task 工具提示词每轮少约 1,300 个 token,相当于每次会话总 prompt token 减少约 1.8%,所测评估中没有检测到质量回退。这类节省在每一轮模型调用上都会重复发生。
后台完成结果不再绕路取回
第四项改动删掉了一整类多余的模型调用。agent 常把独立工作放到后台执行,比如一条长 shell 命令配一个子 agent 调查;任务完成时,harness 唤醒模型并发送通知。问题在于旧版通知不带完成结果,agent 还要再花一轮去取 Copilot 其实已经收到的输出,多个任务相继完成时,这趟绕路会重复发生。
改动后,harness 把可合并的完成通知批量打包,用现有的 tool-result 格式直接把完成结果送达模型,对仍在运行任务的显式读取行为保持不变。以文章中的例子计算:shell 命令与子 agent 先后完成时,改动前每个完成的任务需要一次模型调用请求结果、再一次调用处理它,两个任务共四次模型调用才能继续工作;改动后一次模型调用即可同时处理两个结果,还避免了把整段会话上下文带进不必要的调用。完成结果直接送达,不做压缩、摘要或截留。
证据只属于被测的工作负载
文章给所有数字加了一层限定:同一项改动在不同产品上效果可能相反。一组更紧凑的文件工具指令在 Copilot code review 里效果正面,但放进 Copilot CLI 的线上实验反而推高成本,最终没有上线;删除行号前缀与选择性输出压缩在大规模 Copilot code review 任务集(生产模型)上的独立评估里,各自让平均每次 review 的 prompt token 减少约 5%,review 质量指标无实质变化。这两项发现与此前「code review 迁移到共享文件工具并调优指令、成本降约 20%」相互独立。作者由此总结的五条经验包括:优化完整任务而不是工具调用;不只压缩模型输出,还要优化编排,删掉 harness 能确定性完成的模型轮次;按输出代表什么来决定是否压缩,并测量恢复通道的使用频率;提示词重写可能有意外后果,必须验证行为被保留;证据只属于被测的工作负载,改动要在离线基准、线上实验和每个产品面重新评估。
作者在文末写道:「这些改动没有让模型变得更聪明,只是移除了模型从来不需要做的工作。」按文章说法,这四项改动正在随使用同一 harness 的 Copilot 产品推送,文中示例全部取自 Copilot CLI,Copilot app 与 Copilot code review 同用这套 harness,也因此受益。博客没有披露所用基准与线上实验的具体构成,这些降幅目前以 GitHub 单方测量为准。