ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用 TaoToken 统一 Key 跑通模拟 Claude Code Skills 机制的 demo 代码

用 TaoToken 统一 Key 跑通模拟 Claude Code Skills 机制的 demo 代码 1. 为什么我要用一份 demo 复刻 Claude Code 的 Skills 机制Claude Code 的 Skills 机制简单说就是把「一类任务怎么做」写成一份可被运行时读取的描述文件模型在收到用户输入后先判断该不该用某个技能再按技能里写好的执行方式去跑脚本或调工具。它解决的核心问题是——不用把几十个工具函数硬编码进主流程而是让技能以文件形式独立存在按需加载、按需触发。这套机制适合谁适合正在做 Agent 工具编排、想让本地脚本被大模型「自动挑出来执行」的开发者也适合想理解 Claude Code 内部路由逻辑、但不想一上来就啃源码的人。我这次的做法是用一份本地 Node/Python 可跑的 demo把「技能描述文件 → 关键词路由 → 执行 → Trace 记录」这条链路完整走一遍并且用 TaoToken 统一 Key 来接管模型调用这样本地脚本和线上模型走的是同一套凭证不用在多个平台之间来回切。热词里提到的 Clade Code、Skills、demo、代码本质都指向同一件事把技能定义和执行解耦。下面我会先给目录结构再给技能 JSON 配置然后是可复制的运行命令最后演示新增一个技能后怎么验证它被正确触发。全程你都可以跟着敲。2. TaoToken 前置准备统一 Key 与模型接入在跑 demo 之前先把模型调用这条线理顺。TaoToken 在这里扮演的角色是「统一入口」你只需要一个 Key就能在本地脚本里调用模型对话能力不用为每个模型单独配一套鉴权。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。第一步拿到 Key。进入控制台的 API Keys 页面创建https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制那串以 sk- 开头的字符串后面所有配置都用它。第二步确认你要用的模型 ID。demo 里我会用一个通用对话模型来做意图路由判断你可以在模型对话页面先试一下https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。把模型 ID 记下来比如常见的对话模型 ID填到后面的配置里。第三步理解 Base URL 的写法。TaoToken 的 API 根地址是 https://taotoken.net/api 在 OpenAI 兼容的 SDK 里通常需要写成 https://taotoken.net/api/v1 这种形式具体以接入文档为准。接入文档在这里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你用的是 Claude Code 这类工具配置方式略有不同可以参考 ClaudeCodeAnthropic 的接入说明https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 。这里有个关键点demo 里的「技能路由」有两种实现方式。一种是纯关键词匹配不依赖模型跑起来最快另一种是让模型读技能描述判断该用哪个技能。我建议先用关键词版跑通再切模型版。模型版就需要上面这套 Key 和 Base URL。如果你打算长期跑编码类 Agent 任务可以考虑 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它更适合高频调用场景demo 阶段用按量 Key 就够了。3. 可复制配置目录结构、技能 JSON 与运行命令这一节是全文最核心的部分所有片段都可以直接复制。先给目录结构mini_skills_runtime/ ├── skills_runtime/ │ ├── __init__.py │ ├── models.py # 数据模型 │ ├── loader.py # 技能加载器 │ ├── router.py # 技能路由器 │ ├── executor.py # 技能执行器 │ ├── trace.py # Trace 管理器 │ └── metrics.py # 指标聚合 ├── skills/ │ ├── dir_filetype_stats/ │ │ ├── SKILL.md │ │ └── scripts/ │ │ └── count_filetypes.sh │ └── add_filename_prefix/ │ ├── SKILL.md │ └── scripts/ │ └── add_prefix.py ├── demo.py ├── requirements.txt └── .env技能描述文件我用 JSON 和 Markdown 两种形式都支持。先看 JSON 版放在 skills/dir_filetype_stats/skill.json{ name: dir_filetype_stats, description: 统计指定目录下各类型文件的数量, when_to_use: 用户要求统计目录文件类型分布时, when_not_to_use: 用户只是询问单个文件信息时, keywords: [统计, 文件类型, 目录, filetype, stats], inputs: { dir: { type: string, required: true, description: 目标目录路径 } }, outputs: { result: { type: string, description: 各类型文件数量统计 } }, execution: { type: shell, entry: scripts/count_filetypes.sh }, safety: { side_effects: none, requires_confirmation: false } }对应的 SKILL.md 版本两者选一即可loader 会优先读 JSON# Skill: dir_filetype_stats ## Description 统计指定目录下各类型文件的数量 ## When to Use 用户要求统计目录文件类型分布时 ## When NOT to Use 用户只是询问单个文件信息时 ## Inputs - dir: 目标目录路径 ## Outputs - result: 各类型文件数量统计 ## Execution - type: shell - entry: scripts/count_filetypes.sh ## Safety - side_effects: none - requires_confirmation: falseShell 脚本 scripts/count_filetypes.sh#!/usr/bin/env bash set -euo pipefail TARGET_DIR${1:-.} find $TARGET_DIR -type f | sed s/.*\.// | sort | uniq -c | sort -rnPython 技能 add_filename_prefix 的 skill.json{ name: add_filename_prefix, description: 给目录下所有文件添加统一前缀, keywords: [前缀, 重命名, prefix, rename], inputs: { dir: { type: string, required: true }, prefix: { type: string, required: true } }, execution: { type: python, entry: scripts/add_prefix.py }, safety: { side_effects: filesystem, requires_confirmation: true } }.env 文件把 Key 和 Base URL 放进去TAOTOKEN_API_KEYsk-你的Key TAOTOKEN_BASE_URLhttps://taotoken.net/api/v1 TAOTOKEN_MODEL你的模型IDrequirements.txtopenai1.0.0 python-dotenv1.0.0安装依赖并运行pip install -r requirements.txt python demo.py --input 帮我统计当前目录的文件类型运行后你会看到loader 扫描 skills 目录router 根据关键词命中 dir_filetype_statsexecutor 调用 shell 脚本trace 记录每一步状态metrics 输出延迟和成功率。4. 验证请求与成功结果新增技能如何被正确触发跑通基础 demo 后重点来了新增一个技能验证它是否被正确路由。我加一个「统计代码行数」的技能目录结构skills/count_lines/ ├── skill.json └── scripts/ └── count_lines.pyskill.json{ name: count_lines, description: 统计目录下代码文件的总行数, keywords: [行数, 代码行, lines, loc], inputs: { dir: { type: string, required: true } }, execution: { type: python, entry: scripts/count_lines.py }, safety: { side_effects: none, requires_confirmation: false } }count_lines.pyimport sys from pathlib import Path target Path(sys.argv[1] if len(sys.argv) 1 else .) exts {.py, .js, .ts, .go, .java} total 0 for f in target.rglob(*): if f.suffix in exts and f.is_file(): total sum(1 for _ in f.open(encodingutf-8, errorsignore)) print(ftotal lines: {total})重新运行python demo.py --input 统计一下这个项目的代码行数预期输出里应该出现routed to: count_lines然后打印总行数。如果路由没命中检查 keywords 是否和输入有交集。我实测下来关键词匹配对中文分词比较敏感建议把「行数」「代码行」都写进 keywords。如果你想用模型来做路由判断把 demo.py 里的 router 换成 LLM 版from openai import OpenAI import os client OpenAI( api_keyos.getenv(TAOTOKEN_API_KEY), base_urlos.getenv(TAOTOKEN_BASE_URL), ) def llm_route(user_input, skills): desc \n.join(f- {s[name]}: {s[description]} for s in skills) resp client.chat.completions.create( modelos.getenv(TAOTOKEN_MODEL), messages[ {role: system, content: f根据用户输入选择最合适的技能只返回技能名。\n{desc}}, {role: user, content: user_input}, ], ) return resp.choices[0].message.content.strip()这段代码里resp.choices[0]就是模型返回结果如果报reading choices相关错误通常是返回体结构不对检查 base_url 是否带了 /v1。5. 本篇常见错排查401、local proxy failed 与 OAuth跑 demo 时最容易撞上的几类报错我按真实遇到的顺序列一下。第一类401 Unauthorized。原因通常是 Key 没读到或者 .env 没被加载。检查两点一是python-dotenv是否在代码开头调用了load_dotenv()二是 Key 有没有多余空格。如果你用的是 Claude Code 类工具401 也可能是 OAuth 凭证过期需要重新走一遍授权流程参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecodeutm_campaignrewrite 里的说明。第二类local proxy failed。这个报错一般出现在你本地配了某个转发层但转发层没起来或者端口对不上。demo 里如果直接用 TaoToken 的 Base URL是不需要本地转发的把配置里多余的 proxy 字段删掉即可。第三类reading choices或Cannot read properties of undefined。这是返回体解析问题多半是 base_url 写成了https://taotoken.net/api而没加/v1导致请求打到了非兼容端点。改成https://taotoken.net/api/v1再试。第四类技能没被触发。先看 loader 有没有把新技能加载进来打印一下skills.keys()。如果技能在但路由没命中就是 keywords 覆盖不够。如果技能不在检查 skill.json 是否放在技能目录根下文件名是否拼错。第五类shell 脚本权限问题。count_filetypes.sh需要可执行权限跑chmod x scripts/count_filetypes.sh。Windows 下建议直接用 Python 版技能避免 shell 兼容问题。第六类模型返回空。检查模型 ID 是否填对以及该模型是否在你的账号权限范围内。可以在模型对话页面先手动发一条消息验证https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。排障时建议把 trace 级别调到 DEBUG这样每一步的状态转换、输入参数、返回摘要都会打出来定位问题比看最终报错快得多。6. 把 demo 用起来从验证到长期编码demo 跑通之后你可以做三件事让它真正有用。第一把技能目录挂到你的实际项目里让 loader 扫描真实脚本这样模型就能调用你已有的工具。第二把关键词路由逐步替换成模型路由命中率会明显提升尤其是用户输入比较口语化的时候。第三把 trace 和 metrics 接到你的日志系统长期观察哪些技能被调用最多、哪些经常失败。如果你打算把这套机制用在日常编码或 Agent 任务上Coding Plan 会比按量 Key 更省心https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它适合高频、长时间的调用场景。最后给一个实用技巧技能描述里的when_not_to_use别偷懒写清楚反而能减少误触发。我试过把「不要用于单个文件」写进去之后路由准确率提升很明显。另外新增技能后不用重启整个 runtimeloader 支持运行时重新扫描改完 skill.json 直接再跑一次输入就行。
返回列表