ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

拆解Anthropic skill-creator:用TaoToken统一Key跑通代理技能测试、衡量与优化

拆解Anthropic skill-creator:用TaoToken统一Key跑通代理技能测试、衡量与优化

1. 为什么代理技能需要一套可复现的评估链路

很多人第一次接触 Anthropic skill-creator,会把它当成一个“帮你写 SKILL.md 的助手”。但真正用起来才发现,它解决的核心问题不是“写”,而是“写完到底有没有用”。代理技能(Agent Skills)本质上是给模型加一层行为约束:什么时候触发、触发后按什么流程走、输出要满足哪些标准。没有评估,你只能凭感觉说“好像变好了”,一旦模型版本更新,技能可能悄悄失效,而你完全不知道。

我见过最常见的翻车场景是这样的:团队里有人写了一个 NDA 审查技能,本地测了几条 prompt 都正常,就上线了。两周后模型小版本更新,技能触发率从 90% 掉到 40%,但没人发现,因为没有任何基准测试在跑。等到业务方反馈“最近审查结果不对”,已经积累了一批错误输出。这就是缺少评估链路的代价。

skill-creator 这次增强带来的关键能力,是把软件工程里的测试、基准测试、迭代改进引入到技能创作中。它把技能分成两类,这个分类直接决定了你该怎么测:

能力提升型技能,帮模型完成它原本做不好或做不稳的任务。比如 PDF 表单的坐标定位、复杂文档的结构化抽取。这类技能会随着模型变强而变得“不那么必要”,所以评估的重点是:模型不加载技能时能不能过?如果能过,说明技能的技术已经被模型内化了。

编码偏好型技能,记录的是团队工作流。模型本来就能完成每一步,技能只是把它们按你的流程串起来。比如按固定标准审查合同、从多个 MCP 拉数据起草周报。这类技能更持久,评估重点是:它是否忠实还原了你的实际流程。

这两类技能的测试目标不同,但都需要同一套东西:可复现的评估集、标准化的指标采集、以及优化前后的对比验证。而要让这套链路稳定跑起来,第一步是解决接入问题——测试环境里的模型调用必须走统一通道,否则每次换模型、换 Key、换端点,评估结果就没法横向对比。这也是我后面会用 TaoToken 统一 Key 和 API 通道的原因:评估链路要可复现,接入层就不能是变量。

下面我会按“先跑通接入,再搭评估,再做优化对比”的顺序,把每一步都写成可以直接复制的配置和脚本。你不需要是工程师,只要能改 JSON、能跑命令行,就能跟着做下来。

2. TaoToken 统一 Key 接入测试环境的前置准备

在搭评估链路之前,先把模型调用通道固定下来。原因很直接:skill-creator 的评估脚本会反复调用模型(跑 eval、跑 benchmark、跑 improve_description),如果每次调用走不同的 Key 或端点,你根本无法判断“这次通过率下降”是技能变差了,还是接入层抖动了。统一 Key 和 Base URL,是让评估可复现的前提。

TaoToken 在这里的角色是一个统一的 API 通道。你可以在官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 了解它的能力,实际调用走 API 端点 https://taotoken.net/api。它的价值在于:你只需要维护一套 Key,就能在评估脚本、Claude Code 插件、以及后续的 CI 里复用同一个通道,不用为每个环境单独配一套凭证。

前置准备分三步:拿 Key、确认模型 ID、把配置写进评估脚本能读到的地方。

第一步,登录后在控制台创建 API Key。地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。创建后立刻复制保存,页面刷新后不会再完整显示。建议按用途命名,比如skill-eval-local、skill-eval-ci,这样后面排查 401 时能快速定位是哪个 Key 失效。

第二步,确认你要用的模型 ID。skill-creator 的评估和优化会用到 Claude 系列模型,具体 ID 以你账号下可用列表为准。在模型对话页面可以先做一次连通性验证:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。这一步别跳过,因为后面配置里的 Model ID 必须和这里一致,写错了会直接报 model not found。

第三步,把 Base URL、Key、Model ID 这三件套写进环境变量或配置文件。我习惯用环境变量,因为评估脚本、Claude Code、CI 都能读同一份:

export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_API_KEY="sk-你的Key" export TAOTOKEN_MODEL_ID="你的模型ID"

如果你用的是 Claude Code 插件方式跑 skill-creator,配置要写进 settings 文件。路径和原文一致,通常是项目根目录下的.claude/settings.json:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的Key", "ANTHROPIC_MODEL": "你的模型ID" } }

注意这里的三件套是成对出现的:Base URL 指向 TaoToken 的 API 端点,Key 用你刚创建的,Model ID 用验证过的那个。少任何一个,评估脚本都会在调用阶段失败。如果你用的是 Codex 风格的auth.json,结构类似,把 base_url、api_key、model 三个字段填全即可。

配完之后先别急着跑评估,做一次最小连通性测试。用 curl 打一次模型对话接口,确认返回正常:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "'"$TAOTOKEN_MODEL_ID"'", "max_tokens": 64, "messages": [{"role": "user", "content": "reply with ok"}] }'

返回里能看到正常内容,说明接入层通了。这一步的意义在于:把“接入问题”和“技能问题”提前隔离开。后面评估通过率异常时,你可以确定不是 Key 或端点的问题。更多接入细节和参数说明在文档里:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

3. 可复制的技能评估配置与指标采集脚本

接入通了之后,进入核心部分:搭评估集、跑评估、采指标。skill-creator 的评估逻辑和软件测试很像——定义测试 prompt,描述“良好表现”的标准,然后让它告诉你技能是否达标。区别在于,这里的“达标”包含触发判断和输出质量两层。

先看评估集的结构。它是一个 JSON 文件,每个条目包含一条查询语句和期望是否触发。我建议按 should_trigger 分层,正负样本都要有,否则你测不出误触发。一个最小可用的评估集长这样:

{ "skill_name": "nda-review", "evals": [ { "query": "帮我审查这份保密协议,重点看违约责任条款", "should_trigger": true, "files": ["samples/nda_a.txt"] }, { "query": "这份 NDA 的保密期限是多久", "should_trigger": true, "files": ["samples/nda_b.txt"] }, { "query": "帮我写一封请假邮件", "should_trigger": false }, { "query": "总结一下这份季度财报", "should_trigger": false, "files": ["samples/report_q3.txt"] } ] }

正样本是“应该触发技能”的查询,负样本是“不该触发”的查询。负样本特别重要,因为描述写得太宽泛时,技能会在无关查询上误触发,而这类问题在只看正样本时完全暴露不出来。

接下来是评估执行。skill-creator 的run_eval会对每条查询重复运行多次(--runs-per-query),用进程池并行调用,然后在子进程 stdout 上逐行读 JSON 事件判断是否触发。触发判断有两种方式:看事件里是否出现技能调用,或者看输出里是否包含技能标识。每条查询算出触发率(触发次数/运行次数),再和期望值比较:正例触发率 ≥ 0.5 算通过,负例触发率 < 0.5 算通过。

你可以直接调用这个评估脚本,参数按你的环境填:

python -m scripts.run_eval \ --eval-set evals/nda_review.json \ --skill-dir skills/nda-review \ --runs-per-query 5 \ --model "$TAOTOKEN_MODEL_ID" \ --base-url "$TAOTOKEN_BASE_URL" \ --api-key "$TAOTOKEN_API_KEY" \ --output results/eval_run_001.json

跑完之后,结果 JSON 里会有每条查询的详细数据和总体统计。但单次评估不够,你需要的是基准测试模式,也就是在模型更新后或技能迭代后重复跑,对比通过率、耗时、令牌数三个核心指标。

指标采集脚本我建议单独写一个,把多次运行的结果聚合成均值、标准差、最小值、最大值。核心逻辑是:通过率从grading.json的summary.pass_rate取;运行时间优先从grading.json的timing.total_duration_seconds取,没有就读同目录timing.json;令牌数优先从timing.json的total_tokens取,没有就用grading.json里execution_metrics.output_chars近似。

import json, glob, statistics def collect_metrics(result_dir): pass_rates, times, tokens = [], [], [] for f in glob.glob(f"{result_dir}/**/grading.json", recursive=True): g = json.load(open(f)) pass_rates.append(g["summary"]["pass_rate"]) t = g.get("timing", {}).get("total_duration_seconds") if t is None: tj = f.replace("grading.json", "timing.json") t = json.load(open(tj)).get("total_duration_seconds", 0) times.append(t) tk = None tj = f.replace("grading.json", "timing.json") try: tk = json.load(open(tj)).get("total_tokens") except FileNotFoundError: tk = g.get("execution_metrics", {}).get("output_chars", 0) tokens.append(tk) def stat(xs): return { "mean": round(statistics.mean(xs), 4), "std": round(statistics.pstdev(xs), 4), "min": min(xs), "max": max(xs) } return { "pass_rate": stat(pass_rates), "time_seconds": stat(times), "tokens": stat(tokens) } if __name__ == "__main__": print(json.dumps(collect_metrics("results"), indent=2, ensure_ascii=False))

这个脚本输出的就是 benchmark 报告的核心。benchmark.json里的runs数组还会保留每次运行的原始数据,包括 passed/failed/total、tool_calls、errors、expectations、notes,这些在你排查“为什么这次通过率掉了”时非常有用。

配置层面还有一个关键点:数据分割。split_eval_set会把评估集按 should_trigger 分层随机分割成训练集和测试集,保持正负样本比例,固定种子保证可重复。这意味着你在优化描述时,只能用训练集的结果去调,测试集留着做最终验证。如果你拿测试集去调描述,就是在过拟合,评估结果会虚高。这一点和机器学习里的 train/test split 是一个道理,别省这一步。

4. 验证请求与成功结果:从触发率到优化前后对比

配置和脚本都就位后,跑一次完整链路,确认每一步都有可观测的结果。我按实际执行顺序拆成四个验证动作。

第一个动作,验证触发判断是否正常。先跑一次小规模评估,--runs-per-query 3,看输出里每条查询的触发率。正样本触发率应该在 0.5 以上,负样本在 0.5 以下。如果正样本触发率普遍很低,说明技能描述太窄,模型根本没意识到该调用;如果负样本触发率很高,说明描述太宽泛,误触发严重。这两种问题的修法完全不同,所以先看触发率再动描述。

第二个动作,验证指标采集。跑完评估后执行上面的采集脚本,确认三个指标都有值。通过率的均值应该在 0 到 1 之间,运行时间单位是秒,令牌数是整数。如果某个指标是 0 或缺失,检查对应的 JSON 文件路径是否匹配——grading.json和timing.json通常在同一目录下,采集脚本的路径替换逻辑要对得上。

第三个动作,跑优化模块。improve_description会基于当前评估结果和历史记录生成改进的技能描述。它的输入是评估结果文件、技能目录、可选的历史记录文件、模型名称。执行命令:

python -m scripts.improve_description \ --eval-results results/eval_run_001.json \ --skill-dir skills/nda-review \ --history results/desc_history.json \ --model "$TAOTOKEN_MODEL_ID" \ --base-url "$TAOTOKEN_BASE_URL" \ --api-key "$TAOTOKEN_API_KEY" \ --log-dir logs/improve_001 \ --output results/improved_desc_001.json

它内部会做几件事:从评估结果里分离出“应该触发但没触发”和“不该触发却触发”的查询示例,计算训练集得分,把当前描述、评分摘要、历史尝试、技能内容组合成优化 prompt,调用模型生成新描述,从<new_description>标签里解析出来。如果新描述超过 1024 字符,会自动再调一次模型做缩短。最终输出包含新描述和更新后的历史记录。

第四个动作,做优化前后对比。这是最关键的一步,也是很多人漏掉的。你不能只看“新描述看起来更好”,要用同一套评估集重新跑一遍,对比通过率、耗时、令牌数。更严谨的做法是用比较智能体做 A/B:两个技能版本,或者技能 vs. 无技能,在不知道哪个是哪个的情况下判断输出。这样你才能确定改动是否真的有帮助,而不是被自己的预期带偏。

对比结果我建议用表格记录,每次迭代一行:

版本通过率均值通过率标准差耗时均值(s)令牌均值备注
v1 原始0.720.0812.41840基线
v2 优化描述0.860.0511.81790负样本误触发减少
v3 模型更新后0.810.0610.91620能力提升型技能,部分被模型内化

这张表能告诉你三件事:优化是否有效(通过率上升)、稳定性是否改善(标准差下降)、成本是否可控(令牌数变化)。如果 v3 的通过率下降但耗时和令牌也下降,很可能是模型变强后技能变得不那么必要了——这正是能力提升型技能的正常生命周期。

还有一个容易被忽略的验证点:技能在正确时机触发。评估衡量输出质量,但只有技能该触发时触发才有意义。skill-creator 的描述调整功能会分析样本 prompt,建议编辑来减少误报和漏报。官方在自己的文档创作技能上跑过这个功能,6 项公开技能中有 5 项的触发得到了改进。你可以用同样的方式,先跑触发分析,再跑输出质量评估,两个维度都达标才算真正可用。

5. 本篇常见错误排查:401、local proxy failed、reading choices、OAuth

评估链路跑不起来,八成是接入层的问题。我把实际踩过的几类报错和对应排查方法列出来,你按报错信息对号入座。

401 Unauthorized。这是最常见的。原因通常是 Key 没配、Key 失效、或者 Key 和 Base URL 不匹配。排查顺序:先确认环境变量TAOTOKEN_API_KEY在当前 shell 里能 echo 出来;再确认请求头用的是x-api-key而不是Authorization: Bearer(Anthropic 风格接口用前者);最后确认 Base URL 是https://taotoken.net/api,没有多余斜杠或路径。如果是在 Claude Code 插件里报 401,检查.claude/settings.json里的ANTHROPIC_API_KEY是否被系统环境变量覆盖了——有时候 shell 里有个旧的 Key,插件读的是那个。

local proxy failed。这个报错通常出现在你本地配了某种转发,但转发目标不可达。排查时先确认没有多余的本地代理配置干扰,直接让请求走 TaoToken 的 API 端点。检查HTTP_PROXY、HTTPS_PROXY、ALL_PROXY这几个环境变量是否被设置,如果有就 unset 掉再试。另外确认ANTHROPIC_BASE_URL没有被写成http://localhost:xxxx之类的本地地址。

reading choices 相关报错。这类错误一般出现在解析模型响应时,脚本期望某种结构但实际返回了别的。常见原因是 Model ID 写错,导致返回的不是预期格式;或者评估脚本的响应解析逻辑和实际返回结构不匹配。排查时先把原始响应打出来看,确认choices或content字段是否存在。如果是 skill-creator 的评估脚本报这个,检查--model参数是否和你在模型对话页面验证过的一致。

OAuth 相关报错。如果你用的是需要 OAuth 的客户端,报错通常和 token 过期或 scope 不足有关。排查时确认 OAuth 流程是否走完,token 是否还在有效期内。如果同时配了 API Key 和 OAuth,确认客户端优先用哪个——有些客户端会优先走 OAuth,导致 API Key 配置被忽略。这种情况下,要么统一用 API Key,要么确认 OAuth token 有效。

除了接入层,评估本身也有几个高频坑:

评估集正负样本比例失衡。如果负样本太少,你测不出误触发;如果正样本太少,触发率统计不可靠。建议正负样本至少各占 30%。

--runs-per-query设得太小。跑 1 次就下结论,随机性太大。建议至少 3 次,重要评估跑 5 次。

用测试集调描述。前面说过,split_eval_set分出来的测试集只能用于最终验证,不能拿来调描述。如果你发现优化后训练集通过率很高但测试集很低,就是过拟合了。

指标采集路径写错。grading.json和timing.json的目录结构因脚本版本而异,采集脚本里的路径替换逻辑要按实际输出调整。跑之前先find results -name "*.json"看一眼实际结构。

如果你在排查过程中需要确认模型是否可用,可以直接在模型对话页面发一条测试消息:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。接入配置的完整参数说明在文档里:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。Key 管理在控制台:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。

6. 把评估链路固定下来:从一次性测试到持续基准

跑通一次评估不难,难的是让它持续跑下去。skill-creator 的评估结果由你自己保管,可以存本地、接仪表盘、或者接入 CI。我的建议是至少做到“模型更新后自动跑一次基准测试”,因为模型演进是技能失效的主要外部原因。

具体做法:把评估集、采集脚本、对比逻辑打包成一个可重复执行的命令,在 CI 里配置成模型版本变更时触发。每次跑完把结果追加到历史记录里,形成时间序列。这样你能看到通过率随模型版本的变化趋势,提前发现退化。

对于能力提升型技能,重点监控“无技能时通过率”。如果基础模型不加载技能就能通过你的评估,说明技能的技术已被内化,可以考虑归档。对于编码偏好型技能,重点监控“流程忠实度”,也就是输出是否严格按团队标准走。这类技能不会因为模型变强而失效,但会因为流程变更而需要更新。

如果你需要长期跑编码类或 Agent 类任务,Coding Plan 提供了更适合持续调用的通道:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。Claude Code 用户接入 Anthropic 风格接口的说明在这里:https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite 。API Key 管理入口:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。

最后说一个我自己的习惯:每次改完技能描述,先跑触发分析,再跑输出质量评估,两个都过了才提交。触发分析看的是“该不该调用”,输出质量看的是“调用后做得好不好”。这两个维度分开测,问题定位会快很多。评估集不要一次写太大,从 10 到 20 条开始,覆盖主要场景和典型负样本,跑顺了再扩。基准测试的价值不在于一次跑多全,而在于每次改动后都能跑、都能对比。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进