每份 SKILL.md 的 Red-Green-Refactor,Base URL 交给 TaoToken 后谁耗 Token
2026/9/18 13:50:33 网站建设 项目流程

在 VS Code 里给 GitHub Copilot 装上 agent-skills 之后,/spec/plan这类斜杠命令没有出现;换到 Codex,又提示 CLI 版本不够,装不了原生插件。这类“装上了但调不动”的报错,往往比 Skill 本身更早拦住人。我把它拆成两件事:先把模型入口钉死——去 TaoToken 官网(https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=tdd_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_source=taotoken_aicg_blog_end&utm_content=tdd_key_setup)申请,Base URL 统一使用https://taotoken.net/api,注意这个地址在工具配置里不加任何查询参数。

2.1 Claude Code:settings.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_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY"

2.2 Codex:config.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 放在环境变量里,不要硬编码进 toml:

export TAOTOKEN_API_KEY="YOUR_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之外的多余路径,不要带 UTM
API KeyYOUR_API_KEY与 TaoToken 控制台里创建的那把一致
默认模型从模型列表选与 Agent 端model字段写法一致

三件套任意一项对不上,症状都是“能启动、不能回答”。切换完先跑一次最小对话验证,再开始写测试,别把配置问题带进 TDD 循环。

3. 拆解 SKILL.md:Red-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 --tb=short 2>&1 | tee .tdd/red-01.txt

预期输出是ModuleNotFoundError: No module named 'app.slugify',或者收集阶段的 import 错误。这一步很关键:如果测试一跑就绿,说明断言写错了,或者被测对象早已存在,必须回到上一步重写。前端项目同理:

npx vitest run tests/slugify.spec.ts 2>&1 | tee .tdd/red-01.txt

Red 阶段的 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 --tb=short 2>&1 | tee .tdd/green-01.txt # 期望:2 passed

这里要说清楚Base URL 交给 TaoToken 之后,Token 到底是谁在消耗。红绿循环里,消耗集中在四个地方:

  1. 失败输出回灌。每次测试失败,完整 traceback 都要作为上下文再喂给模型一次。断言越靠后、堆栈越深,回灌越长。
  2. 多轮重试。Green 很少一轮成功,Agent 常见行为是改一版、跑一次、再改一版。每一轮都是一次完整请求。
  3. 上下文重读。如果每轮都把整份 SKILL.md、references/检查清单、全量源码重新读一遍,输入会随轮次线性增长。
  4. 范围蔓延。Agent 顺手重构了别的模块,测试全挂,于是又开一轮新的修复。

对应的控制手段:

  • 把失败输出裁到首个断言,别把整个 traceback 原样回灌:
python -m pytest tests/test_slugify.py -q --tb=line 2>&1 | 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 --tb=line 2>&1 | 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 --tb=short | ModuleNotFoundError | 新建 tests/test_slugify.py | 失败符合预期 | | 01 | Green | python -m pytest tests/test_slugify.py -q --tb=short | 2 passed | 新建 app/slugify.py,改 1 个文件 | 未越界 | | 01 | Refactor | python -m pytest -q --tb=line | 全部通过 | 抽出两个预编译正则 | 无行为变更 |

复盘时看三列就够:阶段是否越界(Green 是否只改一个文件)、失败是否可解释(Red 的失败必须与断言直接相关,而不是环境问题)、轮次是否收敛(同一测试反复红绿超过三轮,就说明 SKILL.md 的停止条件不够硬)。

再往前一步,可以把记录文件本身作为 Skill 的验收输入。评审角色分四类——代码质量、测试、安全、Web 性能——测试评审只认这份记录里的命令与输出,不认“我已经测过了”这种描述。

8. 安装与调用边界:references/ 丢失与斜杠命令差异

装完 Skill 之后还有两个边界要先看清,否则会误判成模型不听话。

第一,单独安装一个 Skill 会丢共享材料。按 README 的提醒,用 npx 单独安装时,只会复制对应的skills/<name>/目录,仓库根目录的共享references/不会一起带过去。Skill 本身仍能跑,但里面引用补充检查清单的路径会失效,表现为“Agent 说读了规范,但规范内容不在上下文里”。需要完整材料时,用整仓集成、克隆仓库,或把需要的清单手动复制到该 Skill 自己的references/目录下。

第二,调用方式随宿主变化。Codex 走@skill-name,Claude Code 走斜杠命令,Copilot 的 CLI 与 VS Code 版本在文档里已被区分开。装完先做一次“最小触发测试”:让 Agent 复述某个 Skill 的适用时机。能复述出来,说明路由生效;复述不出来,先查安装路径和宿主语法,别急着改 SKILL.md。

9. 收尾:把入口固定下来,再让循环跑起来

整套流程跑通后,日常动作其实就三步:确认 Base URL 仍指向https://taotoken.net/api,确认 Key 是三件套里的那一把,然后让 Agent 按 SKILL.md 完成一次 Red-Green-Refactor。想先看看模型在测试设计上的表现,可以从模型对话开始;准备把红绿循环变成日常习惯,可以看 Coding Plan;Key 还没创建,去控制台建一把再回来;Claude Code 的环境变量和 settings.json 细节,文档里有完整对照。

  • 模型对话:https://taotoken.net/models/detail/chat?utm_source=taotoken_aicg_blog_end&utm_content=tdd_cta_chat
  • Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=tdd_cta_plan
  • 创建 API Key:https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=tdd_cta_keys
  • Claude Code 文档:https://taotoken.net/doc/ClaudeCodeAnthropic?utm_source=taotoken_aicg_blog_end&utm_content=tdd_cta_claudecode

最后提醒一句:Skill 能让 Agent 先写规范、跑测试、交证据,但它替代不了代码审查,也不保证所有模型都同样严格地执行步骤。合并或上线之前,测试输出、代码差异和检查清单仍要由人来确认。测试命令全部在你自己的本地环境执行,别把它接到生产库上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询