
在 VS Code 里给 GitHub Copilot 装上 agent-skills 之后/spec、/plan这类斜杠命令没有出现换到 Codex又提示 CLI 版本不够装不了原生插件。这类“装上了但调不动”的报错往往比 Skill 本身更早拦住人。我把它拆成两件事先把模型入口钉死——去 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_boot取一个 Key把 Base URL 换成https://taotoken.net/api填进 Agent 的模型入口再来看 Red-Green-Refactor 的三步里到底哪一步在消耗 Token。本文以测试驱动开发者的视角把test-driven-development这份 SKILL.md 拆成可执行步骤给出测试命令、红绿重构记录模板以及每轮循环的消耗归因。1. 报错先于流程/spec缺失与 Codex 插件版本先把现场还原清楚。agent-skills 把研发过程切成定义需求、制定计划、编写代码、验证结果、审查质量、准备发布六个阶段仓库里 25 个 Skill 中 24 个管具体任务另一个using-agent-skills负责判断当前该调哪一个。最省事的安装入口是开放的 Skills CLI官方口径是能装进 70 多种 Agent同时为 Claude Code、Cursor、Gemini CLI、OpenCode、GitHub Copilot、Codex 等分别留了适配说明。问题就出在“跨工具不等于界面一致”这句话上Codex 需要较新的 CLI 版本README 提到 v0.122 或更高安装原生插件重开会话后用spec-driven-development这类名字调用而不是斜杠命令/spec、/plan、/build、/test、/review、/ship这 9 个工作流命令主要由 Claude Code 这类带适配层的宿主提供Issue #542 里用户正是在 VS Code 版 GitHub Copilot 安装后找不到/spec。0.6.9 版本已经在文档里区分 Copilot CLI 与 VS Code 的安装与调用方式但该 Issue 仍是开放状态。所以排障顺序应该是确认宿主 → 确认调用语法斜杠还是→ 确认 CLI 版本 → 再去怀疑 Skill 内容。把这三步走完再进入测试驱动流程才不会把“命令不存在”误判成“Skill 没生效”。2. 模型入口配置Claude Code、Codex 与 CC Switch 三件套测试驱动开发最怕的是循环跑到一半模型入口挂掉。所以配置要一次写死并能在多个 Agent 之间复用。Key 从 TaoToken 官网https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_key_setup申请Base URL 统一使用https://taotoken.net/api注意这个地址在工具配置里不加任何查询参数。2.1 Claude Codesettings.json 与 ANTHROPIC_*Claude Code 走ANTHROPIC_*这一组变量。项目级配置放.claude/settings.json个人全局配置放~/.claude/settings.json两者结构一致{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: 在 TaoToken 模型列表中选一个主力模型, ANTHROPIC_SMALL_FAST_MODEL: 选一个轻量模型用于跑红绿循环 } }写完用环境变量确认一次避免配置文件没被读到env | grep -E ANTHROPIC_(BASE_URL|AUTH_TOKEN|MODEL) # 期望看到 BASE_URL 指向 https://taotoken.net/api如果暂时不想改配置文件也可以只在当前 shell 会话里导出export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENYOUR_API_KEY2.2 Codexconfig.toml 走自己的 provider 段Codex 不吃ANTHROPIC_*它读~/.codex/config.toml用model_providers声明一个自定义供应商model_provider taotoken model 在 TaoToken 模型列表中选一个主力模型 [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api chat对应的 Key 放在环境变量里不要硬编码进 tomlexport TAOTOKEN_API_KEYYOUR_API_KEY这里最容易踩的坑是把ANTHROPIC_BASE_URL抄到 Codex 配置里——Codex 不认识这组变量配了等于没配最后表现为请求发不出去或一直转圈。2.3 CC Switch把三件套做成可切换的 profile如果用 CC Switch 管理多套供应商记住它维护的其实就是三件套Base URL、API Key、默认模型名。切换 profile 时逐项核对项目值检查点Base URLhttps://taotoken.net/api结尾不要带/v1之外的多余路径不要带 UTMAPI KeyYOUR_API_KEY与 TaoToken 控制台里创建的那把一致默认模型从模型列表选与 Agent 端model字段写法一致三件套任意一项对不上症状都是“能启动、不能回答”。切换完先跑一次最小对话验证再开始写测试别把配置问题带进 TDD 循环。3. 拆解 SKILL.mdRed-Green-Refactor 的进入条件与验收证据普通提示词只说要做什么SKILL.md 会规定执行顺序和停止条件。一份典型的 Skill 文档通常包含五块适用时机、操作步骤、常见借口与反驳、异常信号、最终验收要求。以测试驱动开发为例我把它整理成下面这份可执行版本放在仓库的skills/test-driven-development/SKILL.md--- name: test-driven-development description: 实现前先写失败测试按 Red-Green-Refactor 推进每步留下可验证证据 --- ## 适用时机 - 新增一个可独立测试的函数、模块或接口 - 修复一个已经能稳定复现的缺陷 ## 操作步骤 1. Red写出一个当前必然失败的测试运行并保存失败输出 2. Green只写让该测试通过的最少代码不顺手改其他文件 3. Refactor在测试保持绿灯的前提下调整结构然后复跑全量测试 ## 常见借口与反驳 - “先实现测试稍后补” → 拒绝。没有失败记录无法证明测试真的覆盖了目标行为 - “改动太小不值得写测试” → 至少补一个回归测试锁住这次修复 - “重构顺便把下个需求做了” → 拒绝。Refactor 阶段只允许等价变换 ## 异常信号 - 测试一开始就是绿的说明测试没写对回到 Red - Green 阶段一次改了多个文件范围失控拆成更小的循环 - 全量测试出现与本次无关的失败先记录单独处理不要混进本轮循环 ## 验收要求 - 三个阶段各自的运行命令与输出摘要 - 每个阶段只对应一个可解释的 diff - 最终全量测试通过且没有跳过或删除任何既有用例这份文档的价值在于两点一是把“完成”定义成可检查的证据而不是模型的自我陈述二是里面的反驳规则会挡住“测试稍后补”这类捷径。仓库在references/里另附完成定义、测试、安全、性能、无障碍与可观测性等检查清单evals/则用来验证 Skill 能否被正确触发、路由和执行。4. Red写一个注定失败的测试把失败输出存成证据Red 阶段的目标不是写测试而是写一个现在必然不通过的测试并把这个“不通过”固化下来。以 Python 项目为例先落一个测试文件# tests/test_slugify.py from app.slugify import slugify def test_slugify_collapses_spaces(): assert slugify(Hello Tao Token) hello-tao-token def test_slugify_strips_punctuation(): assert slugify(Red, Green Refactor!) red-green-refactor此时app/slugify.py还不存在运行必然失败mkdir -p .tdd python -m pytest tests/test_slugify.py -q --tbshort 21 | tee .tdd/red-01.txt预期输出是ModuleNotFoundError: No module named app.slugify或者收集阶段的 import 错误。这一步很关键如果测试一跑就绿说明断言写错了或者被测对象早已存在必须回到上一步重写。前端项目同理npx vitest run tests/slugify.spec.ts 21 | tee .tdd/red-01.txtRed 阶段的 Token 消耗特征是一次性输入偏大、输出偏小Agent 需要读规范、读现有目录结构、读命名约定然后写出一小段测试。真正贵的是上下文读取不是生成。5. Green最小改动转绿Token 主要烧在这一段Green 阶段只允许写“让当前失败测试通过的最少代码”。上面那个例子最小实现可以是# app/slugify.py import re def slugify(text: str) - str: text text.strip().lower() text re.sub(r[^a-z0-9\s-], , text) return re.sub(r\s, -, text)然后重跑同一条命令python -m pytest tests/test_slugify.py -q --tbshort 21 | tee .tdd/green-01.txt # 期望2 passed这里要说清楚Base URL 交给 TaoToken 之后Token 到底是谁在消耗。红绿循环里消耗集中在四个地方失败输出回灌。每次测试失败完整 traceback 都要作为上下文再喂给模型一次。断言越靠后、堆栈越深回灌越长。多轮重试。Green 很少一轮成功Agent 常见行为是改一版、跑一次、再改一版。每一轮都是一次完整请求。上下文重读。如果每轮都把整份 SKILL.md、references/检查清单、全量源码重新读一遍输入会随轮次线性增长。范围蔓延。Agent 顺手重构了别的模块测试全挂于是又开一轮新的修复。对应的控制手段把失败输出裁到首个断言别把整个 traceback 原样回灌python -m pytest tests/test_slugify.py -q --tbline 21 | tail -n 20 | tee .tdd/green-01.txt在 SKILL.md 的异常信号里明确写“Green 阶段一次只允许改一个文件”用轻量模型跑 Green主力模型留给 Red 阶段的测试设计和 Review检查清单只在循环开始时读一次不要每轮重读。把这几条落实后同一个功能的循环轮次通常能从七八轮压到三四轮。6. Refactor绿灯下重构范围失控会再烧一轮Refactor 的前提是测试全绿。此时允许做等价变换把重复的正则、魔法字符串收拢# app/slugify.py import re _PUNCT re.compile(r[^a-z0-9\s-]) _GAP re.compile(r[\s-]) def slugify(text: str) - str: return _GAP.sub(-, _PUNCT.sub(, text.strip().lower()))改完必须复跑且要跑全量而不是单文件python -m pytest -q --tbline 21 | tail -n 5 | tee .tdd/refactor-01.txt # 期望全部通过且没有 skip / xfail 数量异常Refactor 阶段最容易失控的地方是“顺手把下个需求也做了”。这在 Token 账单上的表现非常直接diff 变大、测试范围扩大、失败点变多于是又回到 Green 再烧一轮。所以 SKILL.md 里要显式写死“Refactor 只允许等价变换”。7. 红绿重构记录模板与复盘口径Skill 要求给出完成证据那就得有一份可归档的记录。我用一个 Markdown 文件放在仓库.tdd/目录下每轮循环追加一张表# 红绿重构记录slugify | 轮次 | 阶段 | 命令 | 关键输出 | Agent 动作 | 备注 | | --- | --- | --- | --- | --- | --- | | 01 | Red | python -m pytest tests/test_slugify.py -q --tbshort | ModuleNotFoundError | 新建 tests/test_slugify.py | 失败符合预期 | | 01 | Green | python -m pytest tests/test_slugify.py -q --tbshort | 2 passed | 新建 app/slugify.py改 1 个文件 | 未越界 | | 01 | Refactor | python -m pytest -q --tbline | 全部通过 | 抽出两个预编译正则 | 无行为变更 |复盘时看三列就够阶段是否越界Green 是否只改一个文件、失败是否可解释Red 的失败必须与断言直接相关而不是环境问题、轮次是否收敛同一测试反复红绿超过三轮就说明 SKILL.md 的停止条件不够硬。再往前一步可以把记录文件本身作为 Skill 的验收输入。评审角色分四类——代码质量、测试、安全、Web 性能——测试评审只认这份记录里的命令与输出不认“我已经测过了”这种描述。8. 安装与调用边界references/ 丢失与斜杠命令差异装完 Skill 之后还有两个边界要先看清否则会误判成模型不听话。第一单独安装一个 Skill 会丢共享材料。按 README 的提醒用 npx 单独安装时只会复制对应的skills/name/目录仓库根目录的共享references/不会一起带过去。Skill 本身仍能跑但里面引用补充检查清单的路径会失效表现为“Agent 说读了规范但规范内容不在上下文里”。需要完整材料时用整仓集成、克隆仓库或把需要的清单手动复制到该 Skill 自己的references/目录下。第二调用方式随宿主变化。Codex 走skill-nameClaude Code 走斜杠命令Copilot 的 CLI 与 VS Code 版本在文档里已被区分开。装完先做一次“最小触发测试”让 Agent 复述某个 Skill 的适用时机。能复述出来说明路由生效复述不出来先查安装路径和宿主语法别急着改 SKILL.md。9. 收尾把入口固定下来再让循环跑起来整套流程跑通后日常动作其实就三步确认 Base URL 仍指向https://taotoken.net/api确认 Key 是三件套里的那一把然后让 Agent 按 SKILL.md 完成一次 Red-Green-Refactor。想先看看模型在测试设计上的表现可以从模型对话开始准备把红绿循环变成日常习惯可以看 Coding PlanKey 还没创建去控制台建一把再回来Claude Code 的环境变量和 settings.json 细节文档里有完整对照。模型对话https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_cta_chatCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_cta_plan创建 API Keyhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_cta_keysClaude Code 文档https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contenttdd_cta_claudecode最后提醒一句Skill 能让 Agent 先写规范、跑测试、交证据但它替代不了代码审查也不保证所有模型都同样严格地执行步骤。合并或上线之前测试输出、代码差异和检查清单仍要由人来确认。测试命令全部在你自己的本地环境执行别把它接到生产库上。