GitHub Copilot 如何在不牺牲任务质量的前提下降低 AI 编码成本
How we make AI coding more cost efficient without sacrificing task quality
精选理由
GitHub 用四项改动说明压缩 token 为何要看整个任务而非单次调用,并给出可复用的评估方法与踩坑教训。
AI 摘要
GitHub 工程师 Erik Kristensen 分享了 Copilot 降本的四项改动:选择性压缩工具输出、移除 view 工具行号前缀(线下推理成本降约 5%,线上用户日均推理成本降约 3%)、压缩 task-tool 提示词(每轮省约 1300 token,每活跃小时归一化成本降 2.9%)、后台任务完成后直接交付结果(AI Credits 用量降约 2.3%)。
正文 · AI 翻译
在使用 AI 编程智能体时,输出质量固然重要,但真正的效率来自于快速、高效地完成任务,并掌握正确的上下文。
正因如此,单次交互的 token 数量本身并不能作为衡量效率的有效指标。目标不应该是使用更少的 token,而是调用适量的上下文来推进任务。一个简洁的工具响应如果遗漏了智能体所需的信息,有时反而会引发额外的调用或工作,最终使任务变得更慢、成本更高。
因此,我们希望以最终结果而非工具调用本身为优化目标。本文探讨了 GitHub Copilot 中将这一原则付诸实践的四项变更:
在减少重复输出的同时,保留有用的上下文。
移除对任务没有价值的格式。
在不改变有效行为的前提下缩短指令。
直接交付已完成的背景工作,无需额外的检索步骤。
可能的改动会先使用智能体编码基准进行离线评估。最有前景的改动随后会在发布前通过受控的在线实验进行验证。本文中的示例来自 GitHub Copilot CLI。其他多个 Copilot 产品,例如 GitHub Copilot 应用和 Copilot 代码审查,也使用相同的底层测试框架,并通过这些改进变得更加高效。
图 1:四项使用同一 AI 信用度量的独立 A/B 实验。各分段并列展示以便比较;其效果不一定严格可叠加。
局部度量的陷阱
缩短每次工具调用的输出以降低智能体成本,是一种常见做法。RTK(Rust Token Killer)是一个在智能体读取 shell 输出之前将其缩短的实用工具。我们使用智能体编码基准测试评估了它对 GitHub Copilot 的影响。
在我们的测试框架和基准配置中,RTK 缩短了一些响应,但当被省略的文本很重要时,模型有时会重新打开原始输出或重新运行命令来恢复它所需的信息。
这些恢复步骤增加了交互轮次,并携带了更多上下文向前推进。单个工具响应更短了,但平均而言,任务消耗了更多 token,耗时也更长。我们在局部节省了 token,却在全局花费了更多。
图 2:当缺失的细节迫使智能体重新读取输出、重新运行命令并携带更多上下文向前推进时,更短的工具响应反而可能使整个任务的成本更高。
这一结果适用于我们所测试的集成和工作负载,并不适用于每一种 RTK 配置或一般的输出压缩。这意味着“每次工具调用的 token 数”是错误的优化目标。一项效率改进必须从用户请求到最终结果的完整任务维度进行评估。
更有用的做法是思考:在不让模型重复劳动的前提下,哪些内容可以被移除。
压缩噪声,保留有用信息
目标是缩短重复性输出,同时保留智能体完成任务所需的上下文,使其无需回溯步骤。
对基准测试运行的分析表明,安装、构建、测试和 lint 输出往往包含重复性噪声,而类源代码输出和任意命令结果更可能包含智能体所需的信息。这一分析催生了一个选择性输出压缩器,其设计部分参考了 RTK 及类似方法。
该原型在智能体编码基准测试以及一系列开源代码仓库上进行了评估,覆盖了它们的构建、测试和 lint 系统。
早期版本过于激进。它们导致模型重复劳动或读取完整保存的输出,从而增加了端到端成本并降低了任务成功率。例如,我们最初对 git diff 进行了压缩,但在基准测试任务显示智能体会重新打开原始输出以恢复缺失信息后,我们移除了这一过滤。
这些早期失败催生了一项三部分策略:
保留类源代码和任意输出。诸如 cat、git diff、git show 以及任意脚本等命令的输出均原样返回。
在不丢失内容的前提下重新组织搜索结果。来自 grep 等工具的匹配项和文件列表可以被更高效地分组,同时保留每一条结果。
有选择性地压缩重复性噪音。安装、构建、测试和进度输出仅在节省量可观时才进行压缩。
最终发布的版本经过了反复评估与打磨。它之所以保守,并不是因为目标是构建一个保守的压缩器,而是因为评估结果支持这样做。
当输出被压缩时,智能体仍然可以通过一条直接的恢复路径取回完整的原始内容。
图 3:发布的压缩器保留了类似源码的输出,无损失地重新组织搜索结果,并且只压缩可预测的重复性噪音,同时保留完整的原始内容。
这条恢复路径既是一种安全机制,也是一个评估信号。我们跟踪了智能体是否打开保存的原始内容、重新运行命令、重复探索、缩小搜索范围或增加额外的交互轮次。频繁的恢复行为将表明压缩器移除了某些有价值的内容。
在触发输出压缩的离线任务中,未检测到具有统计显著性的任务成功率回退,而且智能体极少打开保存的原始内容。在在线实验中,平均成本略有下降,在跟踪的质量指标中未检测到实质性回退。
先移除格式,再移除信息
一个简洁的 token 优化来自 view 工具,智能体用它来读取文件内容到上下文中。
以前,view 在向模型展示内容之前,会给每一行加上行号前缀。早期的文件编辑工具使用这些行号来定位修改目标,但当前的工具改为匹配周围代码,不再使用行号。尽管正常的工作流程已不再需要行号前缀,它们却仍然保留着。
每个前缀都很小。然而,当它重复出现在每一行、每一次文件读取中时,这种无用的格式就会在整个会话期间不断累积。于是,我们移除了它。
图 4:移除行号前缀在精确保留源代码的同时,消除了每次文件读取时都会重复出现的格式。
行号在 diff 和简短代码片段中仍然有用。但在这里它们是浪费的,因为它们附着在每一次文件读取上,却并未服务于当前的编辑工作流程。
在离线智能体编码基准测试中,移除行号使模型推理成本下降了约 5%。成功率保持在预期的运行间波动范围内,编辑失败率也没有增加。
随后,我们与 Copilot CLI 用户一起测试了这一改动。在线实验将每位用户的日均模型推理成本降低了约 3%,在我们追踪的质量或满意度指标中未检测到实质性回退。
对开发者而言,这意味着上下文窗口中有更多空间可用于实际工作本身,而不是被智能体用不到的格式所占用。
这是一次理想的改动:无需为模型增加新的指令,无需恢复任何信息来源,也无需做出额外的决策。文件内容原封不动地到达模型。
压缩提示词而不压缩意图
提示词承载着塑造智能体工作方式的指令,并且在每一轮对话中都会被发送给模型。只有在智能体保持开发者所依赖的行为的前提下,缩短提示词才能真正提升效率。
在 GitHub Copilot 中,任务工具会启动专门的智能体进行并行工作。其指导说明此前分散在工具描述、模式、智能体定义、系统指令和配套工具中,不断累积。
通过一个元提示循环——Copilot 在其中迭代地编写自己的提示词——该提示词被缩减了大约一半。Copilot 生成并优化了更小的候选版本,而针对性的行为测试则检验了我们希望保留的各项要求。
首次在线实验发现了一个最初的离线评估未能捕捉到的性能回退。元提示循环将原本谨慎的并行指导改写成了硬性的调度策略,导致独立的自定义智能体被串行执行。
我们停止了这项实验。在再次修改提示词之前,我们针对用户暴露出的行为编写了一个回归测试。最终的修复方案是用一句话取代了原先明确的允许列表和拒绝列表:
独立智能体可以并行运行;请考虑副作用。
这句话更短,限制也更少;它将是否并行运行子智能体的选择权交给了模型,而不是依赖之前那种明确的指导。有了这句话,我们新的行为测试顺利通过,同时也没有导致任何现有的行为测试失败。
提示词行为需要测试。如果某个行为没有被测试覆盖,那么一个更短的提示词就可能在无人察觉的情况下移除该行为。
图 5 只有在回归测试暴露了串行化智能体问题、并且用一句话修复恢复了并行性之后,提示词压缩才变得安全;由此节省的 token 在模型的每一轮交互中都会持续产生。
正式发布的提示词每轮可减少约 1,300 个任务工具提示词 token,相当于每个会话的总提示词 token 减少约 1.8%,每个活跃小时的标准化成本降低 2.9%,并且在所评估的各项指标中未检测到质量回退。
无需额外的检索轮次即可交付已完成的后台工作
智能体经常在后台运行独立的工作,例如在子智能体进行调查的同时运行一个长时间执行的 shell 命令。通知机制让智能体可以继续运行,直到该工作完成,而无需花费一次工具调用来等待。
如果智能体没有显式等待其中任一任务,测试框架会唤醒模型,并在 shell 命令或子智能体完成时通知它。
此前,该通知不包含已完成的结果,因此智能体不得不额外花费一轮去取回 Copilot 已经收到的输出。当多个任务在相近时间内完成时,这种绕路可能会反复发生。Copilot 现在会将符合条件的完成通知进行批处理,并直接以现有的工具结果格式交付已完成的结果。智能体可以带着所需信息继续推进,无需额外花费一轮再次请求。对于仍在运行中的工作,显式读取的行为与之前保持一致。
图 6 此前,每个后台完成事件都可能唤醒一轮仅用于检索的模型调用。现在,测试框架会将符合条件的完成事件进行批处理,并以现有的工具结果格式交付已完成的结果。
在此变更之前,每个已完成的任务都需要一次模型调用来请求其结果,另一次调用来处理该结果。对于上面展示的 shell 命令和子智能体而言,这意味着在继续工作之前需要四次模型调用。
现在,测试框架会将两个完成事件一并批处理并同时提供其结果,因此单次模型调用即可处理两者。移除这些检索绕路还避免了在不必要的调用中携带完整的会话上下文。
通过直接交付已完成的结果——不进行压缩、摘要或保留任何内容——测试框架将平均 token 相关用量(以 AI Credits 计量)降低了约 2.3%。
衡量上下文中的变化
在一个 Copilot 工作流中节省 token 的改动,可能会在另一个工作流中推高成本。
例如,一套更精简的文件工具指令,其灵感来自 Copilot 代码审查中的积极结果。但在 Copilot CLI 的在线实验中,它反而推高了成本,因此我们没有将其上线。
相比之下,在一大批 Copilot 代码审查任务上使用生产模型进行的独立评估中,移除行号前缀和有选择性地压缩输出,各自将每次审查的平均提示词 token 数降低了约 5%。我们未发现所追踪的审查质量指标发生实质性变化。
这些发现与早前 Copilot 代码审查迁移到共享文件工具的工作是两回事——后者连同审查指令调优一起,将代码审查成本降低了约 20%。
每一项改动都需要在其实际运行的工作流中去衡量效果。
构建高效 AI 编程智能体的五条经验
优化的是完成后的任务,而不是工具调用本身。如果智能体需要花费更多轮次去恢复被移除的内容,那么更短的输出并不等于更便宜。
优化的是编排,而不仅仅是模型输出。要消除那些本可由执行框架以确定性方式完成的模型轮次。
根据输出所代表的内容来进行压缩。保留精确内容,优先采用无损变换,并衡量智能体使用恢复路径的频率。
提示词改写有时会带来意想不到的后果。请验证预期行为是否得到保留。
证据是特定于具体工作负载的。请在离线基准测试、在线实验以及功能上线的每一个产品界面中重新评估改动效果。
这些改动都没有让模型变得更聪明。它们只是移除了模型本不需要做的工作。
本文所述改动正在 GitHub Copilot 各体验中推出,这些体验均使用相同的底层框架。
使用 GitHub Copilot CLI,将智能体工作流带到你的终端 >
原文
Original Title
How we make AI coding more cost efficient without sacrificing task quality
Source
GitHub Blog
Site
github.blog
Author
Erik Kristensen
Published
2026-09-03 02:00