提升VS Code中GitHub Copilot的令牌效率

Lobsters Hottest 产品

摘要

VS Code团队详细介绍了最近对GitHub Copilot代理功能的优化,例如提示缓存和工具搜索,以提高令牌效率并在基于用量的计费模式下降低成本。

<p><a href="https://lobste.rs/s/tgjz7s/improving_token_efficiency_for_github">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/07/02 06:08

# 提高 VS Code 中 GitHub Copilot 的令牌效率 来源:https://code.visualstudio.com/blogs/2026/06/17/improving-token-efficiency-in-github-copilot 2026年6月17日,作者:Ryan Caldwell (https://github.com/RyanJamesCaldwell) 与 Bhavya U (https://github.com/bhavyaus) 随着 GitHub Copilot 近期转向基于使用量的计费模式,代理会话中的每一个令牌都至关重要。它们影响你的配额、延迟,以及代理完成任务所需的上下文窗口大小。每一代新模型在处理每个任务时往往消耗更多令牌——这一点我们自己的数据也能佐证。因此,在 harness 层面提升效率以对抗这一趋势变得愈发重要。随着代理承担更长时间、更自主的工作,一个低效的 harness 会迅速累积成本。 图表显示连续几代模型中每个回合的令牌消耗在增加 让 VS Code 中的 GitHub Copilot 代理 harness 更节约令牌是一项持续的工作,也是对抗这一趋势的最佳方式。对于大多数改动,我们会在生产环境中运行 A/B 实验,并结合任务套件进行离线评估 (https://code.visualstudio.com/blogs/2026/05/15/agent-harnesses-github-copilot-vscode),以确保任务成功率得以保持或提升,同时令牌消耗下降。很少有一步到位的大幅提升,通常是一系列小幅改进的积累。下面,我们将介绍近期取得的进展,首先针对 OpenAI 模型,然后是 Anthropic 模型。 ## 代理请求如何消耗令牌 每个代理请求的核心存在两种成本,而两种思路有助于我们减少它们。这两种思路同时适用于 OpenAI 和 Anthropic 模型,尽管每个提供商以不同的方式暴露它们。 截图显示缓存浏览器以水平堆叠条形图展示提示的各部分。*提示签名的图形概览,高亮显示提示的不同部分。* **提示前缀与缓存。** 在代理编码会话中,每个请求的大部分内容会跨回合重复:系统指令、工具定义、仓库上下文以及对话历史。这个重复的开头部分被称为**提示前缀**。当多个请求共享完全相同的前缀时,推理提供商可以重用已缓存的模型状态,而无需在每个请求时从头重新计算。尽管名为“缓存”,但缓存产物并非人类可读的提示副本,而是处理该前缀时计算出的模型状态,内部表示为键/值张量。重用前缀可以同时降低费用(缓存令牌的**价格可便宜至十分之一**)和延迟,这也是我们致力于保持提示缓存命中率高的原因。 **工具定义开销。** 代理可能引入大量工具:由 MCP 服务器暴露的工具、内置工具或扩展提供的工具。每个工具都会随其完整定义(名称、描述和完整的 JSON 参数模式)发送给模型,而历史上每个工具在每次请求时都会被载入上下文。即使这些数据被缓存,上下文窗口的开销在每个回合中都是固定的,并且随着工具集的增长而增长。 **工具搜索。** 工具搜索通过让模型按需**加载工具定义**而非一次性全部加载来减少开销。一开始,模型只看到轻量级元数据(每个延迟加载工具的名称和描述),而较重的参数模式则保持在上下文之外,直到模型搜索工具并加载它。由于延迟加载的工具被添加到上下文窗口的末尾而非前缀中,缓存的提示前缀保持可重用,从而缓存增益能够在多个回合中持续生效。其回报是一个更精简的上下文窗口:模型在从未使用的工具上花费更少的令牌,从而为实际任务留出更多空间和预算。 ## OpenAI 模型的效率提升 对于 OpenAI 模型,我们近期的工作侧重于通过改进令牌效率来降低 Copilot 用户的使用成本和延迟。我们通过三项改动实现这一目标:延长缓存模型状态的保留时间、减少工具定义开销、以及用持久化 WebSocket 连接替代重复的 HTTP 请求。 ### 扩展提示缓存 OpenAI 模型会自动缓存提示前缀:提供商推断出可重用的前缀,并在多个请求间重用其模型状态。这种重用直接带来成本优势。对于大多数支持缓存输入定价的 OpenAI 模型,未缓存的输入令牌费用是**缓存输入令牌的 10 倍**。 前缀缓存会自动进行,但缓存的存活时间是我们可配置的。经过仔细评估后,我们为支持的模型通过 `prompt_cache_retention` 主体参数启用了扩展提示缓存。默认情况下,缓存位于快速的 GPU 内存中,并在大约 5-10 分钟无活动后(某些情况下可达一小时)被丢弃,以腾出空间给其他工作。设置 `"prompt_cache_retention": "24h"` 可将缓存移至较慢但容量更大的 GPU 本地存储,并保留长达 24 小时。 其好处显而易见。使用默认缓存时,若暂停超过几分钟,缓存将被丢弃,因此你的下一个请求必须以全价重新处理整个前缀。扩展保留则保持缓存有效,因此即使经过长时间暂停,继续之前的工作仍然快速且便宜。 在 VS Code 中为支持的 OpenAI 模型启用扩展提示缓存后,我们测量了缓存命中率的相对提升。这些是相对变化,而非百分点增加:例如 919% 的提升意味着缓存命中率是之前的 10.19 倍。 | 请求间隔时间 | GPT-5.2 | GPT-5.3-Codex | GPT-5.4 | |------------|---------|----------------|---------| | 10-20 分钟 | +13% | +32% | +10% | | 20-30 分钟 | +135% | +142% | +137% | | 30-40 分钟 | +301% | +203% | +679% | | 40-60 分钟 | +338% | +279% | +919% | 在请求间隔较长时提升最为显著,因为原本会过期的缓存模型状态现在仍可用于重用。实践中,这一提升意味着更多的提示部分按较低的缓存输入价格处理,从而降低了即使长时间暂停后的请求成本。 ### 工具搜索 为了避免每次请求时发送所有工具定义,工具搜索实现了按需加载。对于 GPT-5.4 及更新版本,OpenAI 原生工具搜索 (https://developers.openai.com/api/docs/guides/tools-tool-search) 通过 `defer_loading` 标志实现了这种延迟加载。 一开始,模型只看到轻量级元数据:每个延迟加载函数的名称和描述;或者当延迟加载函数被分组到命名空间时,仅看到命名空间的名称和描述。 在为期四天的 VS Code 实验中,使用 GPT-5.4 和 GPT-5.5 时,工具搜索减少了每回合的令牌使用量、首令牌时间以及完成时间: | 指标 | 模型 | 变化幅度 | |---------------------------|------------|--------------| | P50 每回合总令牌数 | GPT-5.4 | -9.81% | | P50 每回合总令牌数 | GPT-5.5 | -8.61% | | P50 首令牌时间 (TTFT) | GPT-5.4 | -6.88% | | P50 首令牌时间 (TTFT) | GPT-5.5 | -7.34% | | P50 完成时间 (TTC) | GPT-5.4 | -5.31% | | P50 完成时间 (TTC) | GPT-5.5 | -5.42% | 在整个会话中汇总,中位数 Copilot 用户的总令牌使用量在 GPT-5.4 上减少了 8.97%,在 GPT-5.5 上减少了 10.92%。 ### WebSockets 一个代理编码回合可能涉及向推理提供商发送多个顺序请求:模型每执行一个步骤(调用工具并朝向解决方案)都对应一步。即使底层 HTTP 连接被重用,每一步仍然是单独的 API 请求。 响应 API 的 WebSocket 模式 (https://developers.openai.com/api/docs/guides/websocket-mode) 保持持久连接开放,并为这些顺序请求提供低延迟的续行路径。在活跃连接上,OpenAI 还可以重用连接本地内存缓存中最新的响应状态,从而减少长工具调用链上的续行开销。 几个月前,OpenAI 宣布在响应 API 中支持 WebSocket。初始文档显示延迟有大幅改善,因此我们早期就开始试验,并在自己的 A/B 测试中观察到了一致的延迟降低。这是一个事后看来显而易见的主意:代理编码会话在长期交互中发出重复请求,这正是 WebSocket 设计要处理的情况。 在首次向 VS Code 稳定版推出 WebSocket 期间,A/B 实验中观察到的延迟收益在生产中得以保持。下表显示了该推出过程中 WebSocket 相对于 HTTP 的延迟收益。此后,堆栈其他部分的改进(包括改进的提示缓存)进一步降低了延迟和使用成本。每个指标越低越好: | 跟踪指标 | 百分位 | GPT-5.3-Codex | GPT-5.4 | |-------------------------------|--------|---------------|----------| | 首令牌时间 (TTFT) | p50 | -19.46% | -16.37% | | 首令牌时间 (TTFT) | p95 | -12.92% | -15.78% | | 完成时间(按回合) | p50 | -13.55% | -11.74% | | 完成时间(按回合) | p95 | -7.86% | -6.26% | 我们还观察到了用户参与度在统计上显著的相对提升。对于 GPT-5.3-Codex 和 GPT-5.4,活跃用户分别增加了 1.27% 和 2.17%,而两天留存率分别增加了 1.90% 和 3.14%。 这些收益促使我们将 WebSocket 设为 OpenAI 模型 GPT-5.2 及更新版本在包括 VS Code、Copilot CLI、GitHub 应用等 Copilot 产品中的默认传输方式。 ## Anthropic 模型的效率提升 对于 Anthropic 模型,我们近期的工作针对相同的两个重复成本:我们在缓存中保持温热的提示前缀,以及每个回合发送的工具载荷。我们通过两项改动实现目标:更精细地使用提示缓存断点,以及通过工具搜索延迟加载工具定义。 ### 更智能的提示缓存 Anthropic 的提示缓存与 OpenAI 模型使用的自动前缀缓存不同。提供商不会推断可重用的前缀,而是由调用方显式放置 `cache_control` 断点,API 会缓存每个标记之前的所有内容。 每个请求的断点预算有限且固定,因此断点放置的位置与是否使用它们同样重要。我们重新设计了对 Messages API 的缓存策略,将最多四个断点有策略地放置在提示中最稳定的边界处: - **工具定义的末尾**和**系统提示的末尾**——这些是回合间变化最少的部分。 - 一对**滚动锚点**,位于最近两个可缓存的消息上。 第二个较旧的锚点是一个安全网。如果最新的锚点未命中(例如,缓慢的工具调用导致其缓存失效,或内容稍有偏移),较旧的锚点仍能命中,覆盖其之前的所有内容。我们通常会牺牲一个回合的交换,而无需冷启动整个对话缓存。 这些改动使缓存命中率稳定提升了几个百分点。对于代理工作负载(前缀长且回合快速连续),命中率现在约为 94%,这意味着每个请求中只有一小部分输入需要重新计算,而非从缓存中提供。这同时降低了使用成本和首令牌时间。 ### 工具搜索 Anthropic 的工具搜索应用了相同的延迟加载思想。工具被标记为 `defer_loading: true`,在延迟加载的目录旁,我们保留了一个小型的核心工具集(读取和编辑文件、运行终端命令、搜索工作区)始终加载,这样最常见的操作无需额外步骤。 我们首先使用 Anthropic 服务器端的工具搜索推出了这一功能:模型在 Anthropic 端搜索延迟加载的目录,API 将匹配结果原地扩展为 `tool_reference` 块。在为期七天的 VS Code 实验中,延迟加载工具定义减少了提示令牌和总令牌的使用,并缩短了首块时间: | 指标 | 百分位/范围 | 变化幅度 | |----------------------------|-------------------|--------------| | 首块时间 | p50(按回合) | -2.45% | | 总提示令牌 | p50(按回合) | -11.30% | | 总提示令牌 | p95(按回合) | -8.85% | | 总提示令牌 | p50(按用户) | -18.32% | | 总令牌 | p50(按回合) | -11.09% | | 总令牌 | p95(按回合) | -8.74% | | 总令牌 | p50(按用户) | -18.03% | 对于中位数 Copilot 用户,整个会话中提示令牌和总令牌使用量均下降了约 18%。 在验证了方法有效后,我们将搜索本身移至客户端,并基于我们为 VS Code 精简工具集构建的同类工具分组系统进行支持。模型仍然调用 `tool_search` 工具,但不再由 Anthropic 匹配延迟加载的目录,而是由我们在本地执行搜索,并为最佳匹配结果返回 `tool_reference` 块。 本地搜索也更加智能。我们不再使用基于工具名称和描述的词汇匹配,而是使用**内部的 Copilot 嵌入模型** (https://github.blog/news-insights/product-news/copilot-new-embedding-model-vs-code/)——与驱动嵌入引导工具路由的模型相同——将查询与每个可用工具的向量表示进行比较。由于它匹配的是意图而非字面关键词,像“查找此符号的所有引用”这样的请求即使其名称和描述与查询没有共同词语,也能找到正确的工具。 关于这背后的分组和嵌入引导路由的深入介绍,请参阅:我们如何用更少的工具让 GitHub Copilot 更智能 (https://github.blog/ai-and-ml/github-copilot/how-were-making-github-copilot-smarter-with-fewer-tools/)。 将搜索移至客户端为我们带来了一些超出原始令牌节省的额外好处: - **响应速度:** 搜索在本地针对缓存的嵌入运行,因此发现工具不再依赖服务器端的搜索往返。 - **动态 MCP 工具发现:** 由于我们控制候选集,已连接 MCP 服务器在会话中添加或删除的工具会立即反映出来,无需等待固定的服务器端目录。 - **更高质量:** 嵌入引导的搜索更可能为给定查询露出正确的工具,从而减少用户错误并提高任务成功率,如下方指标所示。 这种响应速度直接体现在数字中。在为期两周的 VS Code 稳定版推出中,客户端工具搜索在延迟加载已带来的令牌节省基础上进一步降低了延迟。 | 指标 | 模型 | 变化幅度 | |----------------------------|--------------------|--------------| | 首令牌时间 (p50) | Claude Opus 4.6 | -1.91% | | 完成时间 (p50) | Claude Opus 4.6 | -1.97% | | 完成时间 (p95) | Claude Opus 4.6 | -2.57% | | 完成时间 (p50) | Claude Sonnet 4.6 | -1.30% | | 完成时间 (p95) | Claude Sonnet 4.6 | -3.35% | | 用户错误率 | Claude Sonnet 4.6 | -4.01% | 在两种变体中,延迟加载的工具都位于缓存的提示前缀之外,因此前缀永远不会被重写,上述缓存增益能够跨回合持续生效。并且一旦工具被发现,其在对话的剩余部分保持可用,因此模型无需为再次搜索而付费。 ## 下一步计划 上述工作使我们的代理 harness 更加精简:更高的缓存命中率、每次请求更少的工具定义、以及更低的传输开销。下一步是将整个工作类别从主代理中完全移出。我们正在构建专门的子代理,并探索定制训练的子代理,用于处理狭窄任务,例如搜索工作区、运行命令和总结结果。每个子代理运行在能够胜任该任务的最小、最便宜的模型上,而不是让主模型在自己的上下文中承担这些工作。结果是每个任务的总体成本更低。 此外,我们还在努力提升产品中关于令牌使用和缓存状态的透明度。这包括标记那些悄然推高成本的行为,例如在长时间暂停后恢复会话(缓存已过期),或在会话中间更改推理努力程度。这样你就可以在支付缓存冷启动的费用之前做出明智选择。 使代理 harness 更节约令牌是一项持续的工作,我们将继续投入,一次一个小的胜利。 祝编码愉快!💙

相似文章

GitHub Copilot App

Hacker News Top

GitHub Copilot 是一款 AI 驱动的代码补全工具,通过实时建议代码片段和函数来帮助开发者。