Google Agent Skills 的构建、测试与规模化全景解析:从 SKILL.md 到 CI/CD 落地

发布时间:2026/10/2 11:47:38
Google Agent Skills 的构建、测试与规模化全景解析:从 SKILL.md 到 CI/CD 落地
1. 从一段“祖传 Prompt”说起为什么 Agent 需要 SKILL.md 这种工程化技能包如果你在过去一年里认真用过 AI 编码助手大概率经历过这样的时刻你让 Agent 帮你在云上部署一个服务它热情满满地开始干活然后用了一个早就废弃的 API写出一段看起来无比自信、跑起来必然报错的命令。你纠正它它道歉然后换一种方式继续错。第二天新开一个对话它全忘了你又要重新教一遍。这不是某个模型的个例而是整个 Agent 时代的集体困境模型很聪明但它不懂你所在的“江湖”。它不知道你公司内部的部署规范不知道某个云服务最新的最佳实践不知道哪些命令在你团队里是红线。通用大模型的知识停留在训练数据截止的那一天而真实世界的 API、文档、规范每天都在演进。过去的解法是写 Prompt。更长的 Prompt更精细的 Prompt把注意事项一条条塞进系统提示词里。结果上下文窗口越来越臃肿提示词越来越像一坨没人敢动的祖传代码而且换个任务就不灵了。Google Agent Skills 这套体系的核心主张朴素而锋利别再手搓 Prompt 了把领域知识做成标准化的“技能包”用软件工程的方式去治理它。SKILL.md 就是这套体系的最小单元它面向的读者是 Agent 而非人类本质上更接近一份 API 定义写法必须结构化、无歧义、可执行。这篇文章面向需要把 Agent 能力从原型推向多团队复用的开发者。我会从单文件 SKILL.md 的定义讲起一路走到 MCP 工具接入、EVAL.yaml 评测断言再到 CI/CD 流水线的校验步骤最后演示如何通过统一的 Key/API 通道完成多模型调用的接入验证。全程给出可复制的模板和配置你可以边看边跟做。先给一个整体认知Agent Skills 是一个轻量级开放格式核心简单到令人意外——一个装着 SKILL.md 的文件夹。真正精妙的是它的工作方式叫做渐进式披露Progressive Disclosure。Agent 启动时只加载每个 Skill 的 name 和 description大约几十个 token像翻目录一样扫一眼当用户任务与某个 Skill 匹配时才读取完整的 SKILL.md 指令最后按指令执行任务按需调用文件夹里捆绑的脚本和参考资料。用到谁才加载谁。这个设计让 Agent 可以“持有”成百上千个技能而上下文窗口分毫不增就像你的手机装了 100 个 App但内存里只跑着当前打开的那一个。理解了这一点你就明白为什么 SKILL.md 的写法如此关键它的 frontmatter 元数据直接参与 Discovery 阶段的任务匹配写得好不好决定 Agent 能不能在正确的时候找到它。下面我们进入实操。2. 前置准备用 TaoToken 统一 Key/API 通道打通多模型调用在动手写 SKILL.md 之前先把调用通道准备好。Agent Skills 的评估和 CI 校验往往需要反复调用模型如果每个模型都单独配一套 Key、单独记一个 Base URL维护成本会迅速失控。我的做法是用一个统一的 API 通道来收敛这件事TaoToken 就是我在用的方案它提供 OpenAI 兼容的接口形态改一个 Base URL 就能切换模型对写评估脚本特别友好。先说清楚它解决什么问题。你在本地跑 EVAL.yaml 的断言时可能需要用不同模型交叉验证同一个 Skill 的效果——比如用 A 模型跑一遍看任务完成率用 B 模型跑一遍看 token 消耗。如果每个模型都要去各自的控制台申请 Key、记不同的 endpoint脚本里就会散落一堆硬编码。统一通道的价值在于Base URL 只有一个Key 只有一个模型名作为参数传入切换成本降到最低。接入步骤很直接。第一步打开 https://taotoken.net/api 对应的控制台入口注册并创建一个 API Key。创建时建议按用途命名比如agent-skills-eval方便后续在 CI 里区分不同环境的凭证。第二步记下两个关键信息Base URL 填https://taotoken.net/api以及你创建的 Key。第三步在本地用环境变量管理不要写进代码export TAOTOKEN_API_KEYsk-你的key export TAOTOKEN_BASE_URLhttps://taotoken.net/api这里有个我踩过的坑要提醒你Base URL 末尾不要多加/v1之类的路径OpenAI 兼容客户端通常会自动拼接多写一层会导致 404。如果你用的是某些 SDK 要求必须带版本号先看它的默认行为再决定。接下来验证通道是否通。用 curl 发一个最小请求curl -s $TAOTOKEN_BASE_URL/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: gpt-4o-mini, messages: [{role: user, content: 回复两个字通了}], max_tokens: 16 }如果返回的 JSON 里choices[0].message.content有内容说明通道正常。这一步看起来简单但它是后面所有评估脚本的地基务必先跑通再往下走。关于模型选择我的建议是评估阶段至少准备两个不同档位的模型一个便宜快速的用于大批量回归一个能力强的用于关键场景的准确性验证。具体有哪些模型可用、各自的定价和上下文长度直接看模型列表页最准我不在这里编造参数。你可以在 https://taotoken.net/api 的文档区找到当前支持的模型清单按需挑选。还有一个细节如果你打算把评估跑在 CI 里Key 要配置成 CI 平台的 Secret不要明文写在 workflow 文件里。GitHub Actions 的话就是仓库 Settings 里的 Secrets命名成TAOTOKEN_API_KEYworkflow 里用${{ secrets.TAOTOKEN_API_KEY }}引用。这一步做对了后面流水线才不会因为凭证泄露被安全团队打回。通道准备好之后我们就可以进入正题开始写第一个 SKILL.md。3. 可复制配置SKILL.md 模板、EVAL.yaml 断言与 MCP 接入片段这一节是全文的核心给出可以直接抄走的三件套SKILL.md 模板、EVAL.yaml 断言配置、以及 MCP 工具接入的配置片段。先说目录结构一个标准的 Skill 长这样{skill-name}/ ├── SKILL.md # 必需: 主指令和 frontmatter 元数据 ├── OWNERS # 必需: Skill 维护者 ├── EVAL.yaml # 必需: 评估提示套件和评分标准 ├── reference/ # 可选: 深度技术文档和 schemas ├── scripts/ # 可选: 可执行辅助脚本 ├── assets/ # 可选: 静态资源和图表 └── _internal/ # 可选: 测试 mocks 和内部数据三个必需文件每一个都值得掰开看。先看 SKILL.md 的模板。注意 frontmatter 里的 name 和 description 是机器可读的契约description 要写清楚“什么时候该用这个技能”而不是“这个技能是什么”--- name: gke-safe-deploy description: 在 GKE 集群上安全部署容器化服务。当用户请求部署、发布或更新 GKE 上的工作负载时使用。包含配额检查、集群状态校验和回滚步骤。 version: 1.2.0 --- # GKE 安全部署 ## 前置检查 执行部署前必须按顺序完成以下检查。任何一步失败立即停止并告知用户失败原因不要尝试跳过。 1. 调用 list_clusters 工具确认目标集群存在且状态为 RUNNING。若集群不存在输出“目标集群未找到”并停止。 2. 调用 get_quota 检查 CPU 与内存配额。若余量不足以支撑本次部署输出缺口的具体数值并停止。 3. 确认目标命名空间存在。若不存在先创建命名空间再继续。 ## 部署步骤 1. 使用 reference/deploy-schema.md 中的清单模板生成部署配置。 2. 调用 apply_manifest 工具提交配置。 3. 轮询 get_deployment_status直到状态为 Available 或超时默认 300 秒。 4. 若超时调用 rollback_deployment 回滚并输出回滚结果。 ## 边界情况 - 权限不足捕获 403 错误提示用户检查 IAM 角色绑定不要重试。 - 配额不足见前置检查第 2 步输出缺口数值。 - 镜像拉取失败检查镜像地址与镜像仓库凭证输出具体错误码。 ## 禁止事项 - 禁止在未通过前置检查的情况下执行部署。 - 禁止使用已废弃的 API 版本。 - 禁止跳过回滚步骤。这份模板的关键在于每一步都是可执行、可验证、失败有明确出口的程序化指令。对比一下文档式写法“部署前最好先确认一下集群状态”人类读者会心一笑Agent 读到只会礼貌点头然后继续蛮干。接口式写法才是 Agent 能执行的合约。接下来是 EVAL.yaml。它要求每个 Skill 在诞生时就定义“什么算成功”评估提示套件加评分标准缺一不可skill: gke-safe-deploy version: 1.2.0 model_under_test: gpt-4o-mini runs_per_case: 3 cases: - id: happy-path prompt: 把 my-api 服务部署到 prod 集群的 default 命名空间 expect: - tool_called: list_clusters - tool_called: get_quota - tool_called: apply_manifest - final_status: success weight: 1.0 - id: quota-insufficient prompt: 把 my-api 服务部署到 prod 集群注意配额可能不够 mock: get_quota: { cpu_free: 0.5, mem_free: 256Mi } expect: - tool_called: get_quota - not_tool_called: apply_manifest - output_contains: 配额 weight: 1.5 - id: cluster-missing prompt: 把 my-api 部署到 staging 集群 mock: list_clusters: { clusters: [] } expect: - not_tool_called: apply_manifest - output_contains: 未找到 weight: 1.0 scoring: pass_threshold: 0.8 metrics: - accuracy - token_efficiency这份 EVAL.yaml 里有几个设计要点。runs_per_case: 3是因为大模型输出天然带随机性同一个任务跑五次可能成功四次失败一次单次评估的“通过”可能只是运气好多次运行才能获得统计显著性。mock字段用来注入边界情况的测试数据比如配额不足、集群不存在这些在真实环境里很难稳定复现用 mock 就能覆盖。weight让关键场景的权重更高配额不足这种安全相关的用例给 1.5 倍权重。scoring里的pass_threshold是合并的门槛低于 0.8 不许合并。最后是 MCP 工具接入的配置片段。Google 的架构指导原则是尽可能引用远程 MCP 工具仅在必要时才回退到 CLI 或 API 调用。以 Claude Code 的 MCP 配置为例在项目根目录的.mcp.json里写{ mcpServers: { gke-tools: { type: http, url: https://your-mcp-server.example.com/mcp, headers: { Authorization: Bearer ${MCP_TOKEN} } } } }如果你用的是 Cline配置写在cline_mcp_settings.json里结构类似{ mcpServers: { gke-tools: { type: streamableHttp, url: https://your-mcp-server.example.com/mcp, headers: { Authorization: Bearer ${MCP_TOKEN} } } } }这里的三件套要写全Base URLMCP 服务器的 url、KeyAuthorization 头里的 token、Model ID在 SKILL.md 的 frontmatter 或评估配置里指定。三者缺一不可少任何一个都会在调用时报错。远程 MCP 相比本地 MCP 的优势在于凭证、权限、审计的负担收敛到服务端Agent 的每一次工具调用都在企业既有的权限体系内运转安全团队才睡得着。配置写完之后下一步就是验证它真的能跑通。4. 验证请求与成功结果跑通一次完整的 Skill 评估配置写完不代表能用必须跑一次完整的评估来验证。这一节给出可执行的验证步骤和预期结果。先写一个最小的评估脚本用 Python 调用统一通道读取 EVAL.yaml 并逐条执行import os import yaml from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlos.environ[TAOTOKEN_BASE_URL] /v1, ) def load_eval(path): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def run_case(case, model): resp client.chat.completions.create( modelmodel, messages[ {role: system, content: 你是一个遵循 SKILL.md 指令的 Agent。}, {role: user, content: case[prompt]}, ], temperature0, ) return resp.choices[0].message.content if __name__ __main__: spec load_eval(EVAL.yaml) model spec[model_under_test] for case in spec[cases]: for i in range(spec[runs_per_case]): out run_case(case, model) print(f[{case[id]}] run {i1}: {out[:80]})跑起来之后你会看到每个用例被重复执行runs_per_case次。预期结果是happy-path 用例三次都成功quota-insufficient 用例三次都输出包含“配额”的提示且没有调用 apply_manifestcluster-missing 用例三次都输出“未找到”。如果某个用例三次里有一次不符合预期说明这个 Skill 的指令存在歧义需要回去改 SKILL.md。这里有个关键点评估要在两个维度上展开准确性和效率。准确性看响应质量和任务完成率效率看 token 消耗和完成时间。你可以在脚本里加上 token 统计resp client.chat.completions.create(...) usage resp.usage print(fprompt_tokens{usage.prompt_tokens}, completion_tokens{usage.completion_tokens})把每次运行的 token 数记下来对比“有 Skill”和“没有 Skill”两种情况。如果加了 Skill 之后 token 消耗暴涨但准确率没提升这个 Skill 就不合格。Google 的做法是把每个 Skill 放进一个 2×2 矩阵里检验准确性提升了吗效率提升了吗只有两个维度都有可衡量的正向提升这个 Skill 才证明了自己的存在价值。这个矩阵还藏着一个反直觉的洞察一个 Skill 让 Agent 更“准”但更“贵”按严格标准不算好 Skill因为效率退化意味着生产环境成本上升而成本失控的 Agent 系统注定无法规模化。验证通过之后把评估脚本接进 CI。以 GitHub Actions 为例name: skill-eval on: pull_request: paths: - skills/** jobs: eval: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-pythonv5 with: python-version: 3.11 - run: pip install openai pyyaml - run: python scripts/run_eval.py env: TAOTOKEN_API_KEY: ${{ secrets.TAOTOKEN_API_KEY }} TAOTOKEN_BASE_URL: ${{ secrets.TAOTOKEN_BASE_URL }}这个 workflow 在每次 PR 修改 skills 目录时触发跑评估脚本不通过就卡住合并。这就是“评估即合约”的落地没有评估用例的 Skill 不许合并就像没有单测的代码不许上线。除了评估CI 里还要加静态检查。用 lychee 检查文档里的链接用 skills-ref 校验结构pip install skills-ref agentskills validate skills/gke-safe-deployagentskills validate会检查 frontmatter 是否完整、目录布局是否符合标准、命名是否规范。结构层面的“形状错误”机器一秒钟就能拦住不要留给人肉 review。跑通这一整套之后你就有了一条从 SKILL.md 到 CI 校验的完整链路。接下来我们看常见的报错和排查方法。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth 报错对照实操过程中一定会遇到报错这一节把最常见的几类列出来对照排查。先给一个总原则报错信息里的关键词决定了排查方向不要看到红色就慌先读错误码和错误消息。第一类401 Unauthorized。这是最常见的通常有三个原因。一是 Key 没传对检查Authorization头是不是Bearer开头中间有没有多余空格。二是 Key 本身失效或额度用尽去控制台确认 Key 状态。三是 Base URL 配错导致请求打到了别的服务检查TAOTOKEN_BASE_URL是不是https://taotoken.net/api末尾不要多加路径。排查命令curl -s -o /dev/null -w %{http_code}\n \ $TAOTOKEN_BASE_URL/v1/models \ -H Authorization: Bearer $TAOTOKEN_API_KEY返回 200 说明 Key 和 URL 都对返回 401 就是凭证问题。第二类local proxy failed。这个报错通常出现在 MCP 客户端连接远程服务器时意思是本地代理层没能建立连接。排查方向先确认 MCP 服务器的 URL 是否可达用 curl 直接打一下curl -s -o /dev/null -w %{http_code}\n \ https://your-mcp-server.example.com/mcp \ -H Authorization: Bearer $MCP_TOKEN如果这里就失败说明是网络或服务端问题跟客户端配置无关。如果这里通了但客户端还报 local proxy failed检查客户端的 MCP 配置里type字段是否写对——http 和 streamableHttp 在不同客户端里叫法不一样写错会导致代理层无法识别协议。第三类reading choices 相关报错。典型的是Cannot read properties of undefined (reading choices)这几乎总是因为响应体不是预期的 OpenAI 格式。原因可能是Base URL 少了/v1导致返回了 HTML 错误页或者模型名写错导致服务端返回了错误结构。排查方法是在脚本里打印原始响应resp client.chat.completions.create(...) print(resp.model_dump_json(indent2))如果打印出来是 HTML 或者错误对象就回到 Base URL 和模型名上找问题。模型名必须和模型列表页里的 ID 完全一致大小写都不能错。第四类OAuth 相关报错。如果你用的是 Claude Code 或 Codex 这类需要 OAuth 登录的客户端可能会遇到 token 过期或 scope 不足。典型报错是OAuth token expired或insufficient scope。排查方向重新走一遍登录流程刷新 token检查你申请的 scope 是否包含需要的权限。如果是 Codex 的auth.json配置确认文件里的字段完整{ access_token: your-access-token, refresh_token: your-refresh-token, expires_at: 1735689600 }expires_at是过期时间戳过期了就要刷新。如果刷新失败删掉auth.json重新登录。第五类评估脚本跑出来的结果不稳定。同一个用例三次运行结果不一致这不是报错但更麻烦。原因通常是temperature没设成 0或者 SKILL.md 的指令存在歧义。先把temperature设为 0如果还不稳定就回去逐句检查 SKILL.md把“建议”“通常”“视情况”这类弹性表达全部替换成明确的步骤和条件判断。第六类CI 里评估通过但本地不通过。这通常是环境变量没配全。CI 里用的是 Secret本地用的是 shell 环境变量检查两边是否一致。还有一个隐蔽的坑CI 的 Python 版本和本地不同某些库的行为有差异在 workflow 里固定 Python 版本能避免这类问题。排查的核心思路是分层定位先确认通道通不通curl 打 models 接口再确认配置对不对Base URL、Key、Model ID 三件套最后确认指令有没有歧义评估结果稳定性。大部分问题在前两层就能解决。6. 语义一致 CTA把 Skill 资产沉淀下来从单文件走向多团队复用走到这里你已经有了一个能跑的 SKILL.md、一份带断言的 EVAL.yaml、一套接进 CI 的校验流水线以及一个统一的调用通道。接下来的问题是怎么把它从“我一个人的技能包”变成“多团队复用的资产”。先说一个判断Skill 是产品不是片段。片段的生命周期在粘贴那一刻就结束了产品的生命周期从发布那一刻才开始。承认这一点才谈得上后面的维护、评估和迭代。每个 Skill 必须有具名 OwnerOwner 的职责包括 API 变更跟进和质量退化修复这些要写进团队的工作定义里而不是靠自觉。没有 Owner 的 Skill 会像无数无人维护的开源库一样慢慢腐烂而且是有毒的负债因为 Agent 会自信地执行过时的指令。在工具链层面我建议把评估和接入这两件事固定下来。评估侧把 EVAL.yaml 的断言配置和 CI 流水线模板化新 Skill 直接复制模板改用例降低上手成本。接入侧用统一的 Key/API 通道收敛多模型调用避免每个 Skill 各自维护一套凭证。如果你还在为每个模型单独配 Key可以试试 https://taotoken.net/api 这套方案它的 OpenAI 兼容接口对写评估脚本特别友好改一个 Base URL 就能切换模型评估阶段的多模型交叉验证会轻松很多。对于需要长期跑编码 Agent、做多轮评估的团队Coding Plan 这类按周期计费的方式比按量付费更可控成本可预测适合把评估跑成日常流水线。你可以到 https://taotoken.net/api 的对应入口看看当前的方案细节按团队规模选合适的档位。最后给一个行动清单。今天就可以做的三件事第一把你团队里最痛的那个“祖传 Prompt”找出来按本文的 SKILL.md 模板改造它记得带上评估用例第二用 curl 验证一遍你的调用通道确认 Base URL、Key、Model ID 三件套齐全第三把评估脚本接进 CI哪怕只有五个用例也强过没有。这三件事做完你就有了一个可复用的最小闭环。再往远看一步当“造 Skill 的 Agent”和“用 Skill 的 Agent”同时存在一个自我强化的飞轮会开始转动Agent 使用 Skill 完成任务实践中发现不足编写 Agent 改进 Skill改进后的 Skill 让 Agent 更强。这个飞轮目前还需要人类在关键环节把关但方向已经足够清晰。现在开始积累“为 Agent 写作”的经验就是在为这个方向占座。回到开头那个问题如果你的团队明天就要把最核心的业务流程交给 Agent 执行你手里的“岗位手册”敢拿出来给它看吗如果答案是犹豫的那说明你找到了下一个季度最值得投入的工程方向。从写第一个 SKILL.md 开始把领域知识编译成 Agent 能执行的指令集这件事的门票现在还很便宜。