拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Hello Claw 学习笔记:用 Datawhale OpenClaw 教程跑通第一个 ReAct AI 助理 Skill

Hello Claw 学习笔记:用 Datawhale OpenClaw 教程跑通第一个 ReAct AI 助理 Skill

1. 从零跑通 ReAct 助理:为什么我盯上了 OpenClaw 的 Skill 机制

OpenClaw 是一个命令行 AI 助理系统,核心能力是让模型在 ReAct 循环里自主决定「先想什么、再调哪个工具、拿到结果后怎么继续」。Datawhale 出品的 Hello Claw 教程把它拆成领养龙虾、龙虾大学、构建龙虾三块,其中「构建龙虾」第 13 章专门讲 Skill 编写,这也是我决定动手跑第一个 ReAct 助理的入口。

如果你之前只玩过单轮对话,可能会觉得「助理」和「聊天机器人」差不多。差别在于:聊天机器人拿到问题直接生成答案,而 ReAct 助理会先判断需不需要外部信息,需要就调用工具,把工具返回塞回上下文,再决定下一步。这个「思考—行动—观察」的循环,才是 OpenClaw 里 Skill 真正跑起来的样子。

我这次的目标很具体:写一个能查本地时间并做时区换算的 Skill,让助理在收到「现在东京几点」这类问题时,自动触发工具调用,而不是靠模型瞎猜。整条链路涉及 Skill 目录结构、frontmatter 声明、工具函数注册、以及一次完整的触发验证。下面按可跟做的顺序展开,配置片段都能直接复制。

适合谁看:已经装好 OpenClaw、想理解 ReAct 循环怎么落地的人;或者想给助理加自定义能力、但卡在 Skill 怎么写的人。零基础也能跟,因为我会把每个文件放哪、命令敲什么写清楚。

2. TaoToken 前置:给 OpenClaw 配一个稳定的模型入口

OpenClaw 本身不绑定模型,它通过 provider 配置去调外部 API。ReAct 循环对模型的要求比普通对话高:模型要能稳定输出结构化的工具调用意图,还要在多轮里保持上下文不崩。所以第一步是把模型入口配好,再谈 Skill。

我用的方式是 TaoToken 的聚合入口。它的 API 地址是https://taotoken.net/api,兼容 OpenAI 风格的调用格式,OpenClaw 的 Custom Provider 可以直接填。先去控制台建一个 API Key,路径在console下的api-keys页面,建完复制出来,后面写进配置文件。

这里有个容易踩的点:OpenClaw 的模型配置分两层,一层是 provider 定义(base URL、key),一层是 agent 绑定哪个模型。很多人只改了 provider 没改 agent,结果助理还是走默认模型,Skill 触发行为对不上。所以下面配置里两层都会写。

关于模型选择,ReAct 场景建议用指令跟随能力强的型号,工具调用格式不容易跑偏。TaoToken 的模型对话页面可以先把候选模型拉出来试一轮,确认它能正确返回 tool call 结构,再写进 OpenClaw。如果你打算长期跑编码类或 Agent 类任务,Coding Plan 的额度模型更适合高频循环调用,普通体验用按量就行。

配好之后先别急着写 Skill,用一条最简请求确认 provider 通。命令我在下一节给,连同 Skill 配置一起。

3. 可复制配置:Skill 目录、frontmatter 与 openclaw.json

OpenClaw 的 Skill 放在工作区的skills/目录下,每个 Skill 一个子目录,里面至少有一个SKILL.md和一个入口脚本。我先建目录:

mkdir -p ~/.openclaw/workspace/skills/timezone-helper cd ~/.openclaw/workspace/skills/timezone-helper

然后写SKILL.md。frontmatter 是 Skill 的声明区,name 和 description 决定模型什么时候会想到调用它,description 要写清楚「什么情况下用」,这是 ReAct 里模型做工具选择的主要依据:

--- name: timezone-helper description: 当用户询问某个城市当前时间、或需要做时区换算时使用。输入城市名或时区标识,返回该地当前时间与 UTC 偏移。 version: 0.1.0 entry: index.js tools: - name: get_city_time description: 查询指定城市的当前本地时间 parameters: type: object properties: city: type: string description: 城市名,如 Tokyo、Shanghai required: - city --- # timezone-helper 查询城市当前时间,支持常见 IANA 时区映射。

入口脚本index.js用 Node 写,导出一个工具函数。注意参数校验要做,模型偶尔会传空值:

const tzMap = { Tokyo: 'Asia/Tokyo', Shanghai: 'Asia/Shanghai', London: 'Europe/London', 'New York': 'America/New_York', }; function get_city_time({ city }) { if (!city || !tzMap[city]) { return { error: `unsupported city: ${city}` }; } const now = new Date(); const local = now.toLocaleString('en-US', { timeZone: tzMap[city] }); const offset = -now.getTimezoneOffset() / 60; return { city, local_time: local, utc_offset_hours: offset }; } module.exports = { get_city_time };

接着改~/.openclaw/openclaw.json,把 provider 和 agent 都指向 TaoToken,并让 agent 加载这个 Skill 目录:

{ "providers": { "taotoken": { "type": "openai-compatible", "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的Key", "models": ["你的模型ID"] } }, "agents": { "default": { "provider": "taotoken", "model": "你的模型ID", "workspace": "~/.openclaw/workspace", "skillsDir": "~/.openclaw/workspace/skills" } } }

三件套对齐检查:Base URL 是https://taotoken.net/api,Key 是控制台建的那串,Model ID 要和 provider.models 里写的一致。改完重启 OpenClaw 让配置生效:

openclaw gateway restart openclaw skill list

skill list里能看到timezone-helper就说明加载成功。如果没出现,八成是 skillsDir 路径写错或 frontmatter 格式有问题,下一节排障会讲。

4. 验证请求:触发一次完整的 ReAct 循环

配置就绪后,用一条自然语言请求验证。启动交互模式:

openclaw chat

然后输入:

现在东京几点?顺便告诉我伦敦时间。

预期行为是:模型先「思考」需要调用get_city_time,传入Tokyo,拿到结果后再调一次传London,最后把两个结果组织成回答。你会在终端看到类似这样的循环日志:

[think] 用户问东京和伦敦时间,需要调用 get_city_time [act] get_city_time({ city: "Tokyo" }) [observe] { city: "Tokyo", local_time: "3/21/2025, 11:42:00 AM", utc_offset_hours: 9 } [think] 东京结果已拿到,继续查伦敦 [act] get_city_time({ city: "London" }) [observe] { city: "London", local_time: "3/21/2025, 2:42:00 AM", utc_offset_hours: 0 } [final] 东京现在是 11:42,伦敦是 2:42。

看到[act]和[observe]交替出现,就说明 ReAct 循环真的跑起来了,不是模型直接编答案。这一步是整个学习笔记里最关键的验证点:工具被调用、结果被回灌、模型基于观察继续推理。

如果只想知道模型入口通不通,可以先跑一条不带工具的请求:

curl https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer sk-你的Key" \ -H "Content-Type: application/json" \ -d '{"model":"你的模型ID","messages":[{"role":"user","content":"ping"}]}'

返回里有choices字段就说明 provider 正常。这一步和 Skill 验证分开做,能快速定位问题出在模型侧还是 Skill 侧。

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

跑 ReAct 助理最容易卡在几个固定报错上,我按实际遇到的顺序列。

401 Unauthorized:Key 没填对或没生效。检查openclaw.json里apiKey是不是完整复制,有没有多余空格。改完必须openclaw gateway restart,热更新对 provider 段不一定生效。如果 curl 也 401,那就是 Key 本身问题,回控制台重新建一个。

local proxy failed:OpenClaw 网关没起来,或者端口被占。先openclaw gateway status看状态,再openclaw gateway restart。如果还报,检查 baseUrl 是不是写成了带路径的完整地址,provider 段只填到/api这一层。

reading 'choices' of undefined:模型返回体里没有 choices,通常是模型 ID 写错,或者 provider 返回了错误结构但被当成正常响应解析。先用第 4 节的 curl 确认模型 ID 能返回标准结构,再回填配置。这个错在 ReAct 多轮里更隐蔽,因为第一轮可能正常,第二轮上下文超长被截断后返回异常。

Skill 不触发:模型压根没调工具。原因一般是SKILL.md的 description 写得太泛,模型判断不出该用。把触发条件写具体,比如「当用户询问某城市当前时间时使用」,而不是「时间相关」。另外确认skill list里能看到它。

OAuth 相关报错:如果你用的是需要 OAuth 的 provider,token 过期会报这个。TaoToken 走 API Key 不涉及,但如果你混用了其他 provider,检查对应凭证是否刷新。

排查顺序建议:先 curl 验模型,再skill list验加载,最后 chat 验循环。三层分开,问题不会混在一起。

6. 继续往下走:把 Skill 接进长期工作流

第一个 ReAct Skill 跑通后,你会发现真正的价值在组合。比如把timezone-helper和日程类 Skill 放一起,助理就能处理「帮我约东京同事明天上午十点」这种跨时区任务,它会先算时区再写日程。Hello Claw 的龙虾大学里有 11 个场景案例,邮箱助手、早间简报、CI/CD 助手都是这个思路的延伸。

如果你打算长期跑这类 Agent 任务,模型调用频率会比普通对话高很多,这时候 Coding Plan 的额度模型更划算,适合把 ReAct 循环当日常工具用。想先试模型行为,模型对话页面可以直接拉起来对比不同型号的工具调用稳定性。接入文档里有 provider 配置的完整字段说明,遇到 openclaw.json 参数不确定时对着查。

我自己的习惯是每写一个新 Skill,先用一条最小请求验证工具被调用,再叠到复杂工作流里。这样出问题时能立刻定位是 Skill 本身还是组合逻辑。你可以从改timezone-helper的 tzMap 开始,加一个你常打交道的城市,重新openclaw gateway restart,再问一次时间,看循环日志里是不是多了你新加的那条[act]。

返回列表