提升GitHub Agentic Workflows中的Token效率(12分钟阅读)

TLDR AI 工具

摘要

GitHub通过API代理记录Token使用并建立每日优化工作流,减少了未使用的MCP工具注册带来的开销,从而提升了其代理工作流的Token效率。

GitHub Agent Workflows显著提高了仓库的整洁度和质量,但成本正成为开发者日益担忧的问题。像代理工作流这样的AI任务会自动调度和触发,因此成本可能不知不觉地累积。上个月,GitHub开始系统性地优化许多工作流的Token使用。本文描述了团队的检测手段、应用的优化措施以及初步成果。
查看原文
查看缓存全文

缓存时间: 2026/05/08 18:27

# 提升 GitHub Agentic Workflows 中的 Token 效率 Source: https://github.blog/ai-and-ml/github-copilot/improving-token-efficiency-in-github-agentic-workflows/ GitHub Agentic Workflows 就像一支清洁小队,能够清理仓库中的各种小问题。这些工作流显著提升了仓库的卫生状况和质量,但与所有自动化工作一样,成本已成为开发人员日益关注的焦点。而且由于 CI 作业(如 agentic workflows)是自动调度和触发的,成本可能在不被察觉的情况下累积。 幸运的是,与交互式桌面会话相比,提高自动化的效率更容易。开发人员会话期间的工作很难预测,但 agentic workflows 的工作在 YAML 中完全指定,并且每次执行都重复相同的操作。 因为我们在自己的 GitHub 仓库中维护并使用 GitHub Agentic Workflows,所以我们与用户一样担心 token 效率。这就是为什么在 2026 年 4 月,我们开始系统地优化我们日常依赖的许多工作流的 token 使用。本文将介绍我们检测的内容、应用的优化以及初步结果。 ## 记录 Token 使用情况 我们在仓库中依赖数百个 agentic workflows 进行维护和 CI。所有工作流都以 GitHub Actions 的形式运行,并受到真实 API 速率限制。我们是在飞行中建造飞机,同时也在消耗喷气燃料。 在优化 token 消耗之前,我们需要了解 token 是如何被消耗的。我们面临的第一个挑战是,每个代理框架(Claude CLI、Copilot CLI、Codex CLI)都以不同的格式输出日志,而且历史运行的使用数据可能不完整。幸运的是,agentic-workflows 安全架构使用了一个 API 代理来防止代理直接访问身份验证凭据。这个代理为我们提供了一种方法,可以以统一的标准化格式捕获所有运行中的 token 使用情况,而不管使用哪个代理框架。 现在,每个工作流都会输出一个 `token-usage.jsonl` 制品,其中每条记录对应一次 API 调用,包含输入 token、输出 token、缓存读取 token、缓存写入 token、模型、提供者和时间戳。将这些数据与工作流的其余日志相结合,可以了解 token 通常是如何使用的,并使我们能够为未来的运行进行优化。 ## 工作流优化工作流 有了 token 数据,我们构建了两个每日优化工作流。 **每日 Token 使用审计器** 读取近期工作流运行的 token 使用制品,按工作流聚合消耗,并发布结构化的报告。它的任务是标记任何近期使用量显著增加的工作流,找出最昂贵的工作流,并记录异常运行(例如,一个通常只需要四轮 LLM 调用的工作流却用了 18 轮)。 当审计器标记出一个工作流时,**每日 Token 优化器** 会查看该工作流的源代码和近期日志,创建一个 GitHub Issue,描述具体的低效之处并提出具体的优化建议。优化器发现了许多我们本可能忽略的低效问题。 当然,审计器和优化器本身也是 agentic workflows,它们的 token 使用也会出现在每日报告中,形成一个小的良性循环。 根据我们最初的审计器和优化器结果,最常见的低效问题是未使用的 MCP 工具注册。 由于 LLM API 是无状态的,代理运行时通常会在每次请求中包含 MCP 工具函数名称和 JSON schema。实际上,这意味着完整的工具集可能成为每次调用上下文的一部分。对于一个包含 40 个工具的 GitHub MCP 服务器,每次轮次可能会增加 10–15 KB 的 schema。如果代理只使用两个工具,那么其余 38 个就是每次都添加的纯开销。 工作流作者自然开始时使用完整的工具集,因为这是阻力最小的路径,代理可以自行找出它需要的工具。但随着时间的推移,大多数工作流依赖于一个狭窄且稳定的工具集。优化器通过交叉引用工具清单与实际工具调用来识别这种模式,并建议从配置中修剪未使用的工具。 在我们的冒烟测试工作流中,从 MCP 配置中移除未使用的工具使每次调用的上下文大小减少了 8–12 KB,每次运行节省了几千个 token,且行为没有变化。 ## 用 GitHub CLI 替换 GitHub MCP 移除未使用的 MCP 工具是一个相对简单的胜利。一个更大的结构性机会是,将用于数据获取操作的 GitHub MCP 调用(例如获取拉取请求差异、文件内容和审查评论)替换为对 GitHub CLI 的调用。 这一改变不仅仅减少了未使用工具的开销,因为 MCP 工具调用除了数据检索外,还是一个推理步骤。代理必须决定调用工具、构造参数,并将输出作为上下文的一部分接收。这是一个完整的往返 LLM API 调用,消耗了工具使用 JSON schema、参数块和响应的 token。相比之下,调用 `gh pr diff` 是一个确定性的 HTTP 请求到 GitHub 的 REST API,不涉及 LLM。 我们使用了两种策略来进行这种迁移: **代理之前的预下载数据**。对于代理始终需要的数据,如拉取请求差异或变更文件列表,我们在工作流中添加了设置步骤,在代理启动之前运行 `gh` 命令并将结果写入工作区文件。代理读取这些文件而不是进行 MCP 调用。这消除了工具调用的开销,并允许代理利用其在 bash 脚本方面的广泛训练来高效地处理数据。 **代理内 CLI 代理替换**。在代理需要在运行时决定获取什么数据的情况下,预下载是不可能的。在这些情况下,我们使用一个轻量级的透明 HTTP 代理,将 CLI 流量路由到 GitHub 的 API 服务器,而不会向代理暴露身份验证 token。代理运行 `gh pr view –json` 并获取结构化数据,就像用户在终端中操作一样。这减少了 token 使用,同时不损害我们对代理的零密钥安全要求。 这些技术一起将大部分 GitHub 数据获取从 LLM 推理循环中移出。 ## 衡量效率提升并不容易 一旦我们开始优化工作流,我们遇到了一个更微妙的问题:你怎么知道一个改变是让事情变得更高效,还是只是让工作流做了更少(可能更差)的工作? 有三个混淆因素。 **并非所有的 token 都一样**。在 Claude Haiku 与 Claude Sonnet 上运行相同的工作流会产生相似的 token 数量,但成本差异很大。Haiku 每 token 的成本大约是 Sonnet 的 1/4,因此切换模型的工作流在原始 token 数量上看起来没有变化,但实际上代表了成本的大幅降低。为了解决这个问题,我们使用了一个**有效 Token (ET)** 指标,对每种 token 类型应用模型乘数: ``` ET = m × (1.0 × I + 0.1 × C + 4.0 × O) ``` 其中 `m` 是模型成本乘数(Haiku = 0.25×,Sonnet = 1.0×,Opus = 5.0×),`I` 是新处理的输入 token,`C` 是缓存读取 token,`O` 是输出 token。输出 token 具有 4 倍权重,因为它们在所有主要提供商中是最昂贵的 token 类型。缓存读取 token 仅具有 0.1 倍权重,因为它们是从缓存中以远低于新鲜输入的成本提供的。这个公式跨模型层级标准化了消耗,因此 10% 的 ET 减少意味着真正的 10% 成本降低,无论使用哪个模型。 **工作负载是一个实时仓库**。据我们所知,目前还没有一个 agentic-workflow 基准测试可以用来优化我们的 token 使用。当我们开始查看工作流的 token 使用情况时,我们发现一次运行中工作流可能处理一个五行修复,而下一次运行可能处理一个 200 行的拉取请求。第一次运行自然使用较少的 token,但差异并非由于效率的突然变化。原始 token 数量可能会将工作负载变化与效率波动混淆。我们尝试通过跟踪 LLM API 调用次数和 token 数量来归一化;每轮 LLM 调用次数恒定且每次调用的 token 数量下降,表明真正的效率提升。两者同时下降可能表明完成的工作量减少了。 **质量是否改变?** 理解输出质量是最困难的考虑。一个更轻量级的模型运行一个更受约束的工作流可能会产生更低质量的输出。我们查看了过程层面的信号,如每次 LLM 调用的输出 token、每轮运行次数和工具调用完成率,以近似质量。对于我们优化后的 Smoke Copilot 工作流,这三者在优化期间都保持稳定,即使 token 消耗下降了。该工作流每次运行大约完成五轮 LLM 调用,优化前后都是如此。当然,这些是过程信号,而非结果信号。我们无法直接观察质量是提高了、降低了还是保持不变,因为没有真相意义上的“正确性”。衡量每单位正确工作的 token 需要额外的检测和思考。 ## 初步结果 在 `gh-aw` 和 `gh-aw-firewall` 仓库中,我们在十几个生产工作流中部署了审计器和优化器后,我们下载了每个工作流优化前后的 token 使用制品,并计算了每次运行的 ET。12 个工作流中有 9 个接受了优化器建议的更改。我们只包含在优化前后至少各有八次运行的工作流的结果。这些是:Auto-Triage Issues、Daily Compiler Quality、Community Attribution、Security Guard 和 Smoke Claude。 图表显示了 Auto-Triage Issues、Daily Compiler Quality、Community Attribution、Security Guard 和 Smoke Claude 的 token 节省情况。 Auto-Triage Issues 在 109 次修复后的运行中显示出清晰且持续的 62% 的降低。Daily Compiler Quality 在 12 次修复后的运行中显示出 19% 的改进,而 Daily Community Attribution 在 8 次修复后的运行中显示出 37% 的改进。在 `gh-aw-firewall` 仓库中,Security Guard(审计每个拉取请求的安全敏感更改)和 Smoke Claude(一项测试防火墙的 Claude CLI 路径的集成测试)拥有最多的修复后运行次数,分别显示了 43% 和 59% 的改进。 运行频率与每次运行的节省同样重要。Auto-Triage Issues 会在每个新 Issue 上触发(平均每天 6.8 次,最高 15 次),而 Daily Compiler Quality 最多每天运行一次。62% 的节省和每天 6.8 次运行会迅速累积:在观察期内,假设优化前的速率,Auto-Triage 的优化节省了大约 780 万 ET。Security Guard 和 Smoke Claude 的运行频率更高。在决定哪些工作流优先优化时,运行频率与每次运行的消耗同样重要。 需要注意,并非代理推荐的每个优化都能转化为可衡量的 ET 节省,尤其是在实时仓库中观察窗口较短、工作负载每天变化的情况下。例如,Contribution Check 工作流的 ET 增加了 5%,我们将在下面更详细地讨论。 ## 经验教训 基于这些结果,我们强调三种模式。 **许多代理轮次是确定性的数据收集**。Auto-Triage Issues 在 `gh-aw` 中显示出最强的持续改进(62 次修复后运行中降低了 44%),因为优化消除了结构性低效:许多代理轮次用于不需要推理的读取操作,例如获取 Issue 元数据和扫描标签。在代理启动之前将这些读取操作移到预代理 CLI 步骤中,将其完全从 LLM 推理循环中移除。同样的模式导致了 Security Guard 在 `gh-aw-firewall` 中的 60% 降低:一个相关性门现在对那些不涉及安全敏感文件的拉取请求完全跳过 LLM。最便宜的 LLM 调用是你没有发出的那一次。 Contribution Check 说明了一个混淆因素:82–83% 的输入 token 是缓存读取(数据收集),但平均 ET 增加了 5%。这是由于工作负载的变化而非优化失败:在优化前时期,41% 的运行处理的是小拉取请求(ET < 100K),39% 处理的是大拉取请求(ET > 300K)。优化后时期恰逢开发活动激增,工作流处理了 9% 的小拉取请求和 65% 的大拉取请求。输出 token 在 ET 公式中具有 4 倍权重,随着代理审查更大的差异而增加了 14%。优化可能提高了每次轮次的效率,但向更重工作负载的转变在总体数字中掩盖了这一收益。 **未使用的工具代价高昂**。在被排除的 `gh-aw` 工作流中,Glossary Maintainer 是一个有启发性的案例。一个单一工具——search_repositories——在一次运行中被调用了 342 次,占所有工具调用的 58%,尽管对于一个只扫描本地文件更改的工作流来说完全不需要。将其从工具集中移除是优化器的建议。在 `gh-aw-firewall` 中,Smoke Claude 的 79% 降低部分归因于激进的 MCP 工具修剪,并结合了模型层级切换到 Haiku。Daily Community Attribution 工作流说明了这种方法的局限性:它配置了八个 GitHub MCP 工具,但在整个运行中没有调用其中任何一个,但移除它们并未减少 ET。工具清单只是该工作流整体上下文的一小部分。 **一条错误的配置规则可能导致失控循环**。同样在被排除的工作流中,Daily Syntax Error Quality 在优化前是项目中 ET 最高的工作流。根本原因是一行的错误配置:工作流将测试文件复制到 /tmp/ 然后调用 gh aw compile *,但沙箱的 bash 允许列表只允许相对路径的 glob 模式。每次编译尝试都被阻止。由于无法使用它需要的工具,代理陷入了一个 64 轮的回退循环,手动读取源代码来重建编译器会告诉它的内容。修复允许的 bash 模式消除了循环。我们没有足够的基线运行来精确量化改进,但问题很明显,修复也是明确的。 ## 下一步是什么? 我们用于优化工作流的工具,包括 API 级别的可观测性、自动化审计工作流、MCP 工具修剪和 CLI 替换,现在都可以在 GitHub Agentic Workflows 框架中使用。另一个即将到来的优化是将单体代理重构为使用更小、更便宜模型的子代理团队。 下一步是从工作流级别的优化转向系统级别的优化。工作流运行实际上不是一个扁平的 API 调用序列。它是一个剧集链:工作的短阶段,例如收集上下文、读取制品、失败后重试或综合最终答案。一旦你能够清晰地看到这些剧集,你就可以提出更好的问题。哪个剧集实际上导致了昂贵的运行?哪些剧集主要是重复工作、被阻塞的工作或失败的工作?哪些应该完全停止使用代理而变成确定性的预步骤? 同样的逻辑也适用于投资组合层面。仓库不会孤立地运行一个工作流。它们运行一组代理自动化,这些自动化通常在相同的事件上触发,检查相同的差异和日志,并产生相邻的判断。这意味着成本不仅是一个工作流的属性,也是跨投资组合重叠的属性。我们接下来想要的分析是投资组合级别的:哪些工作流重复读取数据,哪些工作流应该合并,以及哪些共享的中间制品应该被缓存而不是每次运行重新发现。 这些开放性问题确实很难。衡量良好的输出质量、将工作负载变化与效率变化分离开来,以及理解工作流间的重叠,都是持续的挑战。但初步结果表明了改进的空间,并使我们有信心继续推进。

相似文章

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

Lobsters Hottest

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

@tonygentilcore: https://x.com/tonygentilcore/status/2075234683202531403

X AI KOLs Timeline

Glean 的工程博客详细介绍了他们的新代理框架,该框架通过代码执行实现 100% 程序化工具调用,与标准工具调用相比,减少 24% 的 Token 使用量。该框架通过工具截断和沙箱文件系统管理上下文,适用于长时间运行的复杂工作流。