尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

第4章 Skill 开发入门与规范:用 TaoToken 统一 Key 打通 OpenClaw CLI 调试链路

第4章 Skill 开发入门与规范:用 TaoToken 统一 Key 打通 OpenClaw CLI 调试链路 1. 从零跑通第一个 OpenClaw Skill为什么统一 Key 是调试链路的关键如果你有 Node.js 或 TypeScript 背景第一次接触 OpenClaw Skill 开发最容易卡住的地方往往不是写业务逻辑而是调试链路本身。Skill 是一个独立的 Node.js 模块它需要被 OpenClaw CLI 动态加载、执行、输出日志而在这个过程中只要模型调用这一环的鉴权配置没打通你看到的就只会是401、local proxy failed或者干脆没有任何返回。所以这一章我不打算只讲概念而是带你从项目骨架开始一步步把 Skill 跑起来并且用 TaoToken 的统一 Key 把模型调用这条链路固定下来让后续每一次claw run都能稳定复现。先明确一下这一章适合谁你最好已经装好了 Node.js 22会用 npm能看懂 TypeScript 的 interface 和 class知道 CLI 是什么。如果你之前只写过前端或者纯脚本也没关系我会把每一步命令和配置都写全。Skill 本质上就是一个遵循 OpenClaw 规范的 Node.js 包它通过handleCommand接收命令和参数返回结构化结果。你可以把它理解成给智能体装的一个“技能包”每个包负责一类能力比如计算、文件处理、HTTP 请求。OpenClaw 负责调度Skill 负责执行。那为什么要在 Skill 开发里引入 TaoToken因为 Skill 在本地调试时经常需要调用大模型来做意图解析、参数补全或者结果润色。如果你每个 Skill 都单独配一套模型 Key调试时会非常混乱这个 Skill 用 A Key那个用 B Key日志里根本分不清是谁在请求。TaoToken 提供的是统一 Key 和统一 Base URL你只需要在 OpenClaw 的config.toml里配置一次所有 Skill 共享同一个入口。这样你在排查问题时只需要看一个地方的日志链路清晰很多。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 注意 API 地址后面不加 UTM 参数配置时直接写这个就行。我试过在多个 Skill 之间来回切换调试最痛苦的就是 Key 散落在各个.env文件里改一个忘一个。统一到 TaoToken 之后config.toml里只有一份api_key和base_urlSkill 代码里通过context.env读取既安全又方便。接下来我会先给你一个可复制的 Skill 项目骨架然后给出config.toml的完整片段最后用 CLI 命令验证请求是否真的打通。整个过程你都可以跟着做不需要额外申请一堆账号。2. TaoToken 前置准备统一 Key 与 config.toml 配置片段在开始写 Skill 之前先把 TaoToken 的 Key 准备好。打开 https://taotoken.net/api-keys 登录后创建一个 API Key。这个 Key 就是你后面所有 Skill 共用的凭证。创建时建议起一个能识别的名字比如openclaw-skill-dev方便以后在控制台里区分。拿到 Key 之后不要直接写进代码而是放进 OpenClaw 的配置文件里。OpenClaw CLI 默认会读取用户目录下的~/.openclaw/config.toml你也可以在项目目录里放一个config.toml做局部覆盖。下面是一个完整的配置片段你可以直接复制把sk-开头的那串换成你自己的 Key。# file: ~/.openclaw/config.toml # description: OpenClaw CLI 全局配置统一模型入口 [model] provider taotoken base_url https://taotoken.net/api api_key sk-你的TaoTokenKey default_model claude-sonnet-4-20250514 timeout_ms 60000 [model.fallback] enabled true models [gpt-4o-mini, claude-3-5-haiku-20241022] [skill] dev_mode true log_level debug hot_reload true [skill.sandbox] allow_network true allow_file_read [./data, ./assets] allow_file_write [./dist, ./logs]这里有几个点需要说明。base_url写https://taotoken.net/api不要在后面加斜杠或者多余路径OpenClaw 会自动拼接/v1/chat/completions这类端点。default_model我填的是 Claude 系列你也可以换成其他支持的模型 ID具体以模型对话页面里列出的为准。fallback是可选的当主模型超时或者返回错误时会自动切到备用模型这在调试阶段很有用避免因为单次网络抖动就中断整个 Skill 流程。配置写好后用一条命令验证 OpenClaw 能不能读到claw config get model.base_url # 期望输出https://taotoken.net/api claw config get model.api_key # 期望输出sk-****脱敏显示如果这两条命令能正常返回说明配置已经生效。接下来在 Skill 代码里你不需要再硬编码任何 Key直接通过context.env或者 OpenClaw 注入的模型客户端来调用。比如在SkillContext里context.env会包含TAOTOKEN_API_KEY和TAOTOKEN_BASE_URL这两个变量这是 OpenClaw 在加载 Skill 时自动注入的。你可以在代码里这样读取// file: src/utils/model.ts // description: 从上下文读取统一模型配置 import { SkillContext } from openclaw/types; export function getModelConfig(context: SkillContext) { const apiKey context.env.TAOTOKEN_API_KEY; const baseUrl context.env.TAOTOKEN_BASE_URL || https://taotoken.net/api; if (!apiKey) { throw new Error(TAOTOKEN_API_KEY 未注入请检查 config.toml 中的 model.api_key); } return { apiKey, baseUrl }; }这样写的好处是Skill 本身不关心 Key 从哪来只关心上下文里有没有。如果你以后要把 Skill 分享给别人别人只需要在自己的config.toml里填自己的 Key代码完全不用改。这就是统一 Key 的价值配置和代码解耦调试链路可复现。3. 可复制配置Skill 项目骨架与 package.json 完整片段现在开始搭项目骨架。你可以用 OpenClaw CLI 自带的模板生成也可以手动创建。我建议先用 CLI 生成再按自己的需求改这样不容易漏掉规范要求的字段。命令如下# 安装 OpenClaw CLI如果还没装 npm install -g openclaw/cli # 验证版本建议 2026.3.x 以上 claw --version # 创建 Skill 项目 claw create skill-demo # 交互式选择基础模板 - TypeScript - 需要示例代码 cd skill-demo npm install生成后的目录结构大致是这样skill-demo/ ├── src/ │ ├── index.ts # Skill 主入口 │ ├── types.ts # 类型定义 │ ├── utils/ │ │ └── model.ts # 模型调用封装 │ └── services/ │ └── demo.ts # 业务逻辑 ├── tests/ │ └── index.test.ts ├── docs/ │ └── README.md ├── assets/ │ └── icon.png ├── package.json ├── tsconfig.json ├── jest.config.js └── .clawignore重点看package.json里的openclaw字段这是 Skill 的元信息核心。下面是一个可以直接复制的完整片段我加上了模型调用相关的环境变量声明{ name: skill-demo, version: 1.0.0, description: OpenClaw Skill 开发调试示例, main: dist/index.js, types: dist/index.d.ts, files: [dist, assets], keywords: [openclaw-skill, demo, tool], author: Your Name, license: MIT, openclaw: { skillId: demo, skillName: 调试示例, version: 1.0.0, description: 用于验证 TaoToken 统一 Key 调用链路的示例 Skill, category: 开发类, icon: assets/icon.png, permissions: [network:access, file:read], env: [ { name: TAOTOKEN_API_KEY, description: TaoToken 统一 API Key, required: true, secret: true }, { name: TAOTOKEN_BASE_URL, description: TaoToken API 入口地址, required: false, default: https://taotoken.net/api } ], commands: [ { name: ask, description: 向模型发送一条消息并返回结果, parameters: [ { name: prompt, type: string, description: 用户输入的问题, required: true } ] } ] }, scripts: { build: tsc, dev: tsc --watch, test: jest, lint: eslint src/**/*.ts, package: claw package }, dependencies: { openclaw/types: ^2026.3.0, mathjs: ^13.0.0 }, devDependencies: { typescript: ^5.0.0, jest: ^29.0.0, ts-jest: ^29.0.0, types/jest: ^29.0.0, eslint: ^9.0.0 } }这里env数组里声明了TAOTOKEN_API_KEY和TAOTOKEN_BASE_URLOpenClaw 在加载 Skill 时会自动从全局config.toml里读取对应的值并注入。注意secret: true表示这个变量在日志里会被脱敏不会明文打印。permissions里我加了network:access因为要调用模型 APIfile:read是为了读取本地配置或数据文件。如果你不需要文件操作可以去掉。接下来写src/index.ts实现一个最小的ask命令把用户输入转发给 TaoToken 的模型接口并返回结果。代码里用fetch直接请求这样你能清楚看到请求链路// file: src/index.ts // description: 最小可调试 Skill验证 TaoToken 统一 Key 调用 import { Skill, SkillContext, CommandResult } from openclaw/types; class DemoSKill implements Skill { metadata { id: demo, name: 调试示例, version: 1.0.0, description: 验证 TaoToken 统一 Key 调用链路, }; async handleCommand( command: string, params: Recordstring, any, context: SkillContext ): PromiseCommandResult { switch (command) { case ask: return this.ask(params.prompt, context); default: return { success: false, error: 未知命令: ${command} }; } } private async ask(prompt: string, context: SkillContext): PromiseCommandResult { if (!prompt || typeof prompt ! string) { return { success: false, error: 请提供有效的 prompt 参数 }; } const apiKey context.env.TAOTOKEN_API_KEY; const baseUrl context.env.TAOTOKEN_BASE_URL || https://taotoken.net/api; if (!apiKey) { return { success: false, error: TAOTOKEN_API_KEY 未注入请检查 config.toml }; } try { const response await fetch(${baseUrl}/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey}, }, body: JSON.stringify({ model: claude-sonnet-4-20250514, messages: [{ role: user, content: prompt }], max_tokens: 512, }), }); if (!response.ok) { const errText await response.text(); context.logger.error(模型请求失败: ${response.status} ${errText}); return { success: false, error: 模型请求失败: ${response.status} }; } const data await response.json(); const content data.choices?.[0]?.message?.content ?? ; context.logger.info(模型返回: ${content.slice(0, 80)}...); return { success: true, data: { prompt, content }, message: content, }; } catch (error: any) { context.logger.error(请求异常: ${error.message}); return { success: false, error: 请求异常: ${error.message} }; } } } export default new DemoSKill();这段代码里context.env.TAOTOKEN_API_KEY就是 OpenClaw 从config.toml注入进来的。你不需要在 Skill 里写任何 Key也不需要.env文件。请求地址是${baseUrl}/v1/chat/completions其中baseUrl默认就是https://taotoken.net/api。如果你在config.toml里改了base_url这里会自动跟着变。4. 验证请求与成功结果CLI 调用与日志排查代码写完后先构建再安装到本地 OpenClawnpm run build claw install .安装成功后用claw list确认 Skill 已经被识别claw list # 期望输出中包含 # demo 调试示例 1.0.0 开发类 enabled然后运行ask命令claw run demo ask --prompt 用一句话解释什么是 OpenClaw Skill如果一切正常你会看到类似这样的输出[INFO] 模型返回: OpenClaw Skill 是一个可被智能体动态加载的 Node.js 模块... 计算结果OpenClaw Skill 是一个可被智能体动态加载的 Node.js 模块用于扩展智能体的能力。同时日志里会记录请求的完整链路。你可以用claw logs demo -f实时查看claw logs demo -f # 输出示例 # [2026-03-09 10:12:01] [INFO] Skill demo 加载完成 # [2026-03-09 10:12:03] [DEBUG] 请求 URL: https://taotoken.net/api/v1/chat/completions # [2026-03-09 10:12:03] [DEBUG] 使用模型: claude-sonnet-4-20250514 # [2026-03-09 10:12:05] [INFO] 模型返回: OpenClaw Skill 是一个...这里的关键验证点是日志里打印的请求 URL 必须是https://taotoken.net/api/v1/chat/completions而不是其他地址。如果 URL 不对说明config.toml里的base_url写错了。另外日志里不应该出现明文 Key因为secret: true已经做了脱敏。如果你看到sk-开头的完整字符串说明脱敏没生效需要检查env声明里的secret字段。再做一个异常验证故意把config.toml里的api_key改错然后重新运行claw run demo ask --prompt 测试错误 Key # 期望输出 # [ERROR] 模型请求失败: 401 {error:{message:Invalid API key}} # 返回模型请求失败: 401这个 401 是预期内的说明鉴权链路是通的只是 Key 不对。改回正确的 Key 后再次运行就能恢复正常。通过这种“先成功再失败再成功”的验证方式你可以确认整条链路是可观测、可复现的。如果你在日志里看到local proxy failed通常是因为 OpenClaw 在本地起了代理但没连上上游。这时候先检查config.toml里的base_url是否可达可以用curl直接测curl -X POST https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的Key \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:ping}],max_tokens:10}如果curl能返回正常 JSON说明网络和 Key 都没问题问题出在 OpenClaw 的配置加载上。这时候用claw config list看一下实际生效的配置确认model.base_url和model.api_key是不是你期望的值。5. 本篇常见错误排查401、local proxy failed、reading choices、OAuth在 Skill 调试过程中有几个报错几乎每个人都会遇到。我把它们整理成对照表方便你快速定位。报错信息常见原因排查动作401 Invalid API keyKey 错误、过期或未注入检查config.toml的model.api_key用claw config get model.api_key确认local proxy failedBase URL 不可达或代理配置冲突用curl直接测https://taotoken.net/api/v1/chat/completions检查base_url是否有多余路径Cannot read properties of undefined (reading choices)响应结构不符合预期通常是请求被拦截或返回了错误页打印完整响应体检查response.ok和response.status确认返回的是 JSON 而不是 HTMLOAuth token expired使用了 OAuth 方式鉴权但 token 过期改用 API Key 方式在config.toml里配置api_key而不是 OAuthSkill not foundSkill 未安装或未启用运行claw list确认状态用claw install .重新安装Command not found命令名拼写错误或未在package.json中声明检查openclaw.commands数组里的name字段重点说两个。第一个是reading choices这个报错的意思是代码里访问了data.choices[0]但data里没有choices字段。最常见的情况是请求返回了 401 或者 429但代码没有先判断response.ok就直接response.json()。所以我在上面的示例代码里先判断了response.ok如果不是 2xx 就直接返回错误避免继续解析。你如果自己写的时候漏了这一步就会看到这个报错。第二个是OAuth token expired。有些开发者习惯用 OAuth 登录 OpenClaw 开发平台但 Skill 运行时调用模型 API 用的是另一套鉴权。如果你在config.toml里没有显式配置api_keyOpenClaw 可能会尝试用 OAuth token 去请求模型接口而 TaoToken 的 API 入口需要的是 API Key。解决办法很简单确保config.toml的[model]段里有api_key字段并且值是以sk-开头的 Key。如果你同时配置了 OAuth 和 API KeyOpenClaw 会优先使用 API Key。还有一个容易忽略的点如果你在 Skill 代码里用了context.env.TAOTOKEN_API_KEY但package.json的openclaw.env数组里没有声明这个变量OpenClaw 就不会注入它。这时候context.env.TAOTOKEN_API_KEY会是undefined代码里如果没做判空就会直接抛错。所以每次新增环境变量都要同步更新package.json里的env声明。排查完之后如果你需要重新生成 Key 或者查看调用量可以去 https://taotoken.net/api-keys 管理。如果是要看模型列表和可用性去模型对话页面 https://taotoken.net/models 确认。这两个入口在调试阶段会经常用到。6. 语义一致 CTA把调试链路固定下来继续下一步走到这里你已经完成了一个可运行、可调试的 OpenClaw Skill项目骨架建好了config.toml里配了 TaoToken 统一 Keyask命令能正常请求模型并返回结果日志里能看到完整的请求 URL 和模型返回。更重要的是你知道 401、local proxy failed、reading choices 这些报错分别对应哪一层的问题下次再遇到就不会卡住。接下来你可以做两件事。第一把这个 Skill 扩展成真正有用的工具比如加一个summarize命令读取本地文件并调用模型做摘要或者加一个translate命令做中英互译。每次扩展都复用同一套config.toml和context.env不需要重新配 Key。第二如果你打算长期做 Skill 开发建议把 Coding Plan 用起来它适合需要持续调用模型、跑 Agent 流程的场景入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。如果你只是想先验证模型调用是否稳定可以到模型对话页面直接测试 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 。需要管理 Key 和查看用量就去 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有更完整的参数说明和示例。最后留一个实用技巧在config.toml里把log_level设成debug然后在 Skill 代码里用context.logger.debug打印关键变量比如请求 URL、模型 ID、响应状态码。这样当你换模型或者换环境时一眼就能看出是哪一层变了。调试链路一旦固定下来后面写再多 Skill 都只是在这个基础上叠加业务逻辑不会再被鉴权和配置问题打断。
返回列表