GitHub 把 Agent CI 工作流的 Token 开销砍掉 62%——裁 MCP、换 CLI、日审计

2026-05-29 15 预计阅读时间:1 分钟
来源:infoq.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:11 分钟

Agent 跑 CI,Token 烧得比服务器还贵,这不是段子而是不少团队的日常。GitHub 最近公开了一组数据:通过裁剪无用 MCP 工具、把部分 MCP 调用换成 gh CLI、再配上每天自动跑的审计与优化 Agent,他们的 agentic CI 工作流 Token 开销最高降了 62%。做法并不玄学,拆开看每一步都是工程决策。

MCP 工具不是越多越好——裁掉不用的,Token 立刻省下来

MCP(Model Context Protocol)让 Agent 能调用外部工具,但问题在于:每次 Agent 拿到工具列表,这些工具的描述、参数 schema、示例都会作为上下文灌进 prompt。一个 20 个工具的 MCP server,光工具定义就可能吃掉几千 Token——哪怕 Agent 本次任务只用其中 1 个。

GitHub 的做法很直接:审计每个 MCP 工具的实际调用频率,把长期零调用的工具从配置里移除。这不是一次性动作,而是持续进行。工具列表精简后,Agent 每次请求的 system prompt 体积缩小,输入 Token 减少,输出也更聚焦——不会在无关工具上"犹豫"。

实际效果:某些工作流仅靠裁剪 MCP 工具,Token 开销就降了两位数百分比。

MCP 调用换成 gh CLI——更少的中间层,更少的 Token

MCP 的好处是标准化,但标准化本身有成本。一次 MCP 调用链路:Agent → MCP client → MCP server → GitHub API,中间每一层都有协议开销、错误处理、结果格式化——这些全要 Token 来"解释"和"理解"。

GitHub 发现,很多操作直接用 gh CLI 完成更划算。比如创建 PR、查看 CI 状态、合并分支,gh pr creategh run view 一行命令搞定,Agent 只需要读命令的 stdout,不需要经过 MCP 的 JSON-RPC 协议封装和解析。

关键判断标准:如果一个操作是高频的、结构简单的、CLI 已经覆盖的,优先用 CLI;只有需要复杂交互、多步编排、或 CLI 不支持的场景才走 MCP。这不是"去 MCP",而是让 MCP 只出现在它真正发挥价值的地方。

日审计 + 日优化——两个 Agent 把成本管控变成自动化流程

手动看 Token 账单发现问题,周期太长、反应太慢。GitHub 的方案是跑两个轻量 Agent:

  • Auditor Agent:每天扫描 Token 使用日志,按模型、按工作流、按工具维度汇总,找出异常飙升或回归。它输出的核心指标叫 Effective Tokens——不是原始 Token 数,而是扣掉冗余上下文后的"有效消耗",更真实地反映成本效率。
  • Optimizer Agent:拿到 Auditor 的报告后,自动生成优化建议:哪些 MCP 工具可以裁掉、哪些调用可以换成 CLI、哪些 prompt 模板可以精简。人工确认后落地。

两个 Agent 本身也消耗 Token,但因为只跑一次/天、任务单一,开销远小于它们省下来的量。

实操:搭一个最小化的 Token 审计流水线

下面给一个可以直接跑的示例——用 GitHub Actions 每天记录 Token 使用、计算 Effective Tokens、输出裁剪建议。你可以在此基础上扩展成自己的 Auditor + Optimizer。

1. 定义 token-usage.jsonl 的记录格式

每次 Agent 任务完成后,往 artifact 里追加一行 JSONL:

{"date":"2025-07-10","workflow":"pr-review","model":"gpt-4o","input_tokens":8200,"output_tokens":1200,"mcp_tools_available":18,"mcp_tools_called":2,"cli_calls":3,"task":"review-pr-1234"}
{"date":"2025-07-10","workflow":"pr-review","model":"gpt-4o","input_tokens":9100,"output_tokens":1500,"mcp_tools_available":18,"mcp_tools_called":1,"cli_calls":4,"task":"review-pr-1235"}

核心字段:mcp_tools_available vs mcp_tools_called 的差值,就是裁剪空间。

2. Auditor 脚本——扫描日志、计算 Effective Tokens、输出报告

#!/usr/bin/env python3
"""daily_token_auditor.py — 每日 Token 审计脚本"""

import json
import sys
from pathlib import Path
from collections import defaultdict

def load_records(path: str) -> list[dict]:
    records = []
    with open(path) as f:
        for line in f:
            line = line.strip()
            if line:
                records.append(json.loads(line))
    return records

def effective_tokens(rec: dict) -> int:
    """Effective Tokens = 实际输出 + 被调用的工具输入估算
    未被调用的 MCP 工具描述视为冗余上下文,不计入有效消耗"""
    # 假设每个可用 MCP 工具描述约 200 tokens
    TOOLS_DESC_TOKENS = 200
    redundant = (rec["mcp_tools_available"] - rec["mcp_tools_called"]) * TOOLS_DESC_TOKENS
    return rec["input_tokens"] - redundant + rec["output_tokens"]

def audit(records: list[dict]) -> dict:
    report = defaultdict(lambda: {"total_input": 0, "total_output": 0,
                                   "total_effective": 0, "total_raw": 0,
                                   "tools_available": 0, "tools_called": 0,
                                   "count": 0})
    for rec in records:
        key = (rec["workflow"], rec["model"])
        r = report[key]
        r["total_input"] += rec["input_tokens"]
        r["total_output"] += rec["output_tokens"]
        r["total_effective"] += effective_tokens(rec)
        r["total_raw"] += rec["input_tokens"] + rec["output_tokens"]
        r["tools_available"] += rec["mcp_tools_available"]
        r["tools_called"] += rec["mcp_tools_called"]
        r["count"] += 1

    # 生成裁剪建议
    suggestions = []
    for (wf, model), r in report.items():
        waste_ratio = 1 - r["total_effective"] / r["total_raw"] if r["total_raw"] else 0
        avg_unused = (r["tools_available"] - r["tools_called"]) / r["count"]
        if waste_ratio > 0.15:
            suggestions.append(
                f"[裁剪建议] {wf}/{model}: 冗余率 {waste_ratio:.1%}, "
                f"平均每次任务有 {avg_unused:.0f} 个 MCP 工具未被调用,建议移除"
            )
        if r["tools_called"] < r["count"] * 1.5 and avg_unused > 3:
            suggestions.append(
                f"[换CLI建议] {wf}/{model}: MCP 调用频率低(均 {r['tools_called']/r['count']:.1f} 次/任务),"
                f"检查是否可用 gh CLI 替代"
            )
    return {"per_workflow_model": dict(report), "suggestions": suggestions}

if __name__ == "__main__":
    records = load_records(sys.argv[1] if len(sys.argv) > 1 else "token-usage.jsonl")
    result = audit(records)
    print(json.dumps(result, indent=2, ensure_ascii=False))
    # 保存报告供后续 Optimizer Agent 读取
    Path("audit-report.json").write_text(json.dumps(result, indent=2, ensure_ascii=False))

运行方式:

python3 daily_token_auditor.py token-usage.jsonl

输出示例:

{
  "per_workflow_model": {
    "('pr-review', 'gpt-4o')": {
      "total_input": 17300,
      "total_output": 2700,
      "total_effective": 9900,
      "total_raw": 20000,
      "tools_available": 36,
      "tools_called": 3,
      "count": 2
    }
  },
  "suggestions": [
    "[裁剪建议] pr-review/gpt-4o: 冗余率 50.5%, 平均每次任务有 16 个 MCP 工具未被调用,建议移除",
    "[换CLI建议] pr-review/gpt-4o: MCP 调用频率低(均 1.5 次/任务),检查是否可用 gh CLI 替代"
  ]
}

3. GitHub Actions 每日定时跑审计

name: Daily Token Audit
on:
  schedule:
    - cron: '0 6 * * *'   # 每天 UTC 6:00
  workflow_dispatch:        # 也支持手动触发

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Download yesterday's token-usage artifact
        uses: actions/download-artifact@v4
        with:
          name: token-usage-jsonl
          path: ./data

      - name: Run auditor
        run: |
          python3 daily_token_auditor.py ./data/token-usage.jsonl

      - name: Upload audit report
        uses: actions/upload-artifact@v4
        with:
          name: audit-report
          path: audit-report.json

      - name: Post suggestions to Slack (optional)
        if: always()
        run: |
          SUGGESTIONS=$(python3 -c "
          import json; r=json.load(open('audit-report.json'));
          print('\n'.join(r['suggestions']) if r['suggestions'] else '今日无裁剪建议')
          ")
          # 替换为你的通知方式
          echo "::notice::${SUGGESTIONS}"

这个流水线每天自动跑,你只需要看 suggestions 就知道该裁哪个 MCP 工具、该换哪个 CLI。

落地前想清楚的三件事

  1. 裁剪粒度按工作流来,不是一刀切。PR review 用到的 MCP 工具和 issue triage 完全不同,分别审计、分别裁剪。全局裁掉某个工具可能误伤其他工作流。

  2. Effective Tokens 是内部指标,不是计费指标。你的账单还是按原始 Token 算。Effective Tokens 的价值在于横向对比——同一工作流换模型后效率是否下降、裁剪后冗余率是否回升。它帮你做决策,不帮你砍账单数字。

  3. Optimizer Agent 的建议要人工确认。自动建议可以省时间,但"把某个 MCP 工具移除"这个动作一旦落地,Agent 就真的不能再调用它了。确认环节不可省略,否则可能裁掉低频但关键的工具。


GitHub 这套做法的核心逻辑并不复杂:测量 → 发现冗余 → 裁剪 → 换更轻的路径 → 每天重复。复杂的是坚持做。Token 成本在 agentic 工作流里是持续变量,今天最优的配置下个月可能就过时——只有把审计变成日常流程,62% 的降幅才不是一次性的运气,而是可维持的工程结果。


相关推荐