都在用 OpenClaw 跑 Skill,但你写的“技能”为什么总让 AI 频繁罢工?——从 config.toml 骨架到 Skill Engineering 的排错清单

发布时间:2026/9/30 19:30:53
都在用 OpenClaw 跑 Skill,但你写的“技能”为什么总让 AI 频繁罢工?——从 config.toml 骨架到 Skill Engineering 的排错清单
1. 为什么你的 OpenClaw Skill 总在关键时刻罢工你大概也遇到过这种场景明明在SKILL.md里把步骤写得清清楚楚Agent 却在执行到第三步时突然“失忆”转头去调用一个完全无关的工具或者更气人的是它压根就不触发你写的 Skill自顾自地用通用能力瞎猜一通。你盯着日志里那句tool not found或者skill not triggered开始怀疑是不是 OpenClaw 本身有 bug。先别急着甩锅给框架。我实测下来九成以上的“罢工”都不是 OpenClaw 的锅而是 Skill Engineering 层面的设计缺陷。OpenClaw 作为一个 Agent 运行时它做的事情其实很纯粹读取config.toml里的模型与工具声明加载 Skill 目录下的SKILL.md然后把用户输入、Skill 描述、可用工具列表一起塞进上下文让模型自己决定“要不要用这个 Skill、用哪个工具、传什么参数”。问题就出在这个“让模型自己决定”上——你的 Skill 描述如果写得像一份晦涩的 API 文档模型在长上下文里根本抓不住重点触发率自然惨不忍睹。更隐蔽的坑在于config.toml的骨架配置。很多人从社区抄了一份配置改了个模型名就直接跑结果base_url指向了一个不支持 function calling 的端点或者model_id写的是对话模型却指望它做工具编排。这种配置层面的错配表现出来就是 Agent 频繁“罢工”要么请求直接 401要么返回的choices里根本没有tool_calls字段OpenClaw 解析不到工具调用只能干瞪眼。所以这篇排错清单的思路很明确先别动 Skill 的逻辑先把config.toml骨架和最小验证动作跑通确认“配置链路”没问题再去排查“Skill Engineering”的设计问题。顺序反了你会在错误的地方浪费大量时间。2. TaoToken 前置把模型接入这层先理清楚在深入config.toml之前得先把模型接入这层理清楚。OpenClaw 本身不绑定任何模型供应商它通过 OpenAI 兼容的 API 协议去调用后端模型。这意味着你需要一个稳定的、支持 function calling 的 API 端点。我目前用的是 TaoToken 的 API 服务它的接口地址是https://taotoken.net/api完全兼容 OpenAI 的/v1/chat/completions格式OpenClaw 可以直接对接。为什么强调“支持 function calling”因为 Skill 的本质就是让模型输出结构化的工具调用指令。如果后端模型不支持这个能力或者 API 网关在转发时把tools字段吞掉了OpenClaw 收到的响应里就不会有tool_callsAgent 自然无法执行 Skill。TaoToken 这边我实测下来Claude 系列和 GPT 系列的工具调用都能正常透传响应结构里的finish_reason会正确返回tool_calls这是跑通 Skill 的前提。你需要准备的东西很简单一个 TaoToken 的 API Key以及确认你要用的模型 ID。模型 ID 的命名规则跟官方保持一致比如claude-sonnet-4-20250514或者gpt-4o这类。拿到 Key 之后先别急着写 Skill用一条 curl 命令验证一下工具调用是否正常。这一步能帮你排除掉“API 端点不支持工具调用”这个最底层的坑。如果你还没有 Key可以去 TaoToken 的 API Keys 页面创建一个。创建时注意权限范围如果你只是本地开发调试给一个默认的读写权限就够了。Key 拿到后先存到环境变量里别硬编码进config.toml后面我会讲怎么在配置里引用环境变量。3. 可复制的 config.toml 骨架与 Skill 目录结构OpenClaw 的配置核心是config.toml它决定了模型怎么连、Skill 从哪加载、工具怎么注册。很多人罢工的根因就藏在这个文件的细节里。下面这份骨架是我踩过坑之后稳定下来的版本你可以直接复制修改。# ~/.openclaw/config.toml [model] provider openai-compatible base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model_id claude-sonnet-4-20250514 max_tokens 4096 temperature 0.2 [agent] name my-openclaw-agent system_prompt_file ./prompts/system.md max_iterations 15 tool_choice auto [skills] enabled true skill_dirs [./skills] auto_reload true [tools] enabled [read_file, write_file, run_shell, http_request]几个关键点需要展开说。base_url这里填https://taotoken.net/api注意不要在后面多加/v1OpenClaw 内部会自动拼接路径。api_key_env指向环境变量名你在 shell 里export TAOTOKEN_API_KEYsk-xxx就行这样配置文件可以安全地提交到 git。model_id必须选支持工具调用的模型如果你填了一个纯对话模型Agent 会在需要调用工具时返回纯文本OpenClaw 解析不到tool_calls就会报no tool calls found in response。max_iterations这个参数很关键。它限制的是 Agent 在一次任务里最多进行多少轮“思考-调用工具-观察结果”的循环。设得太小复杂 Skill 跑到一半就被截断设得太大一旦 Skill 逻辑有死循环你会看到 Agent 疯狂调用同一个工具直到烧完 token。我一般设 15 到 20 之间配合后面要讲的 Skill 边界设计基本不会出问题。Skill 的目录结构也有讲究。OpenClaw 默认会扫描skill_dirs下的每个子目录每个子目录里必须有一个SKILL.md开头是 YAML front matter声明name、description和可选的tools。一个最小可用的 Skill 长这样--- name: fetch-weather description: 当用户询问某个城市的天气时调用此技能获取实时天气数据。适用于“今天天气怎么样”“明天要下雨吗”这类问题。 tools: - http_request --- ## 步骤 1. 从用户输入中提取城市名称。 2. 调用 http_request 工具请求天气 API。 3. 将返回的 JSON 中的温度、天气状况整理成自然语言回复。注意description的写法。它不是给你看的说明书而是给模型看的“触发提示”。模型在决定是否调用这个 Skill 时主要依据就是这段描述。如果你写得太泛比如“处理天气相关任务”模型在长上下文里可能根本注意不到它如果你写得太窄比如“查询北京市朝阳区天气”换个城市就不触发了。我后面会专门讲怎么调这个描述。4. 验证请求用最小 Skill 确认链路通畅配置写完之后别急着上复杂 Skill。先做一个最小验证建一个只做加法运算的 Skill确认 OpenClaw 能正确触发、调用工具、拿到结果。这一步能帮你把“配置问题”和“Skill 设计问题”彻底分开。先建目录和文件mkdir -p ~/.openclaw/skills/calc-test cat ~/.openclaw/skills/calc-test/SKILL.md EOF --- name: calc-test description: 当用户要求做两个数字的加法运算时使用此技能。例如“帮我算一下 3 加 5 等于多少”。 tools: - run_shell --- ## 步骤 1. 从用户输入中提取两个加数。 2. 调用 run_shell 工具执行 echo $((a b))。 3. 将计算结果返回给用户。 EOF然后启动 OpenClaw 并发送一条测试消息export TAOTOKEN_API_KEYsk-your-key-here openclaw chat --config ~/.openclaw/config.toml在交互界面里输入“帮我算一下 3 加 5 等于多少”。如果链路正常你会看到 Agent 先输出一段思考然后触发run_shell工具最后返回“8”。日志里应该能看到类似这样的结构{ finish_reason: tool_calls, tool_calls: [ { name: run_shell, arguments: {\command\: \echo $((3 5))\} } ] }如果这一步跑通了说明config.toml的模型接入、API Key、工具注册、Skill 加载全部正常。接下来如果复杂 Skill 还是罢工问题就出在 Skill Engineering 层面而不是配置。如果这一步就失败了对照下一节的报错清单逐条排查。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth排错的时候报错信息是最诚实的线索。下面这几个是我在 OpenClaw 社区里看到频率最高的基本覆盖了 90% 的罢工场景。401 Unauthorized这个最直接API Key 没传对。检查三件事环境变量TAOTOKEN_API_KEY是否真的 export 了用echo $TAOTOKEN_API_KEY确认config.toml里的api_key_env拼写是否和实际环境变量名一致Key 本身是否过期或被禁用。注意不要在config.toml里直接写api_key sk-xxx然后又设了api_key_env两者同时存在时 OpenClaw 的行为可能不符合预期统一用环境变量最稳。local proxy failed / connection refused这个报错通常出现在你本地配了 HTTP 代理但代理进程没启动或者端口不对。OpenClaw 底层用的是标准 HTTP 客户端会读取HTTP_PROXY和HTTPS_PROXY环境变量。如果你之前为了调试设过这些变量记得unset掉。另外检查base_url是否写成了https://taotoken.net/api/带尾斜杠某些版本的 OpenClaw 在拼接路径时会产生双斜杠导致 404表现上也可能被误报为连接失败。reading choices 相关报错典型信息是failed to read choices from response或者index out of range。这说明 API 返回的 JSON 结构里没有choices数组或者数组为空。根因通常是model_id填错了比如填了一个不存在的模型名API 返回了错误对象而不是正常的 completion 结构。另一个可能是base_url指向了一个非 OpenAI 兼容的端点。用 curl 直接打一次 API 确认返回结构curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:hi}]} | jq .choices[0].message.content如果这条命令能正常返回内容说明 API 侧没问题问题在 OpenClaw 的配置解析。OAuth 相关报错如果你用的是 Claude Code 或者某些需要 OAuth 流程的客户端可能会遇到OAuth token expired或invalid_grant。这类报错跟 OpenClaw 本身无关是上游认证层的问题。解决办法是重新走一遍授权流程或者改用 API Key 方式接入。TaoToken 的 API 接入不需要 OAuth直接用 Key 就行省掉这层麻烦。排查的时候有个技巧把 OpenClaw 的日志级别调到 debug能看到完整的请求体和响应体。请求体里重点看tools字段有没有被正确序列化响应体里重点看finish_reason是不是tool_calls。这两个信息一对照问题基本就定位了。6. 从配置到 Skill Engineering让 Agent 稳定干活的几个心法配置链路跑通之后剩下的就是 Skill 本身的设计。这部分才是真正拉开差距的地方。我总结了几条实战心法每一条都对应着一种常见的“罢工”模式。Description 要抢注意力不要写说明书。模型在长上下文里对信息的注意力是有限的。你的 Skill 描述如果淹没在一堆工具声明和系统提示里触发率就会暴跌。写法上把最核心的触发场景放在第一句用具体的用户问法举例。比如不要写“此技能用于处理文件相关操作”而是写“当用户说‘帮我读一下这个文件’‘看看 xxx.log 里有什么’时使用此技能”。具体的例子比抽象的描述更能激活模型的模式匹配。用“讲道理”代替 MUST/NEVER。传统编程思维喜欢用强制命令但在大模型这里大写的 MUST 反而可能引发逻辑短路。更好的方式是在 Skill 里解释“为什么”要这么做。比如不要写“MUST call read_file before write_file”而是写“在写入之前先读取原文件内容这样可以避免覆盖掉用户已有的修改”。模型理解了意图执行起来会更灵活也更稳定。LLM 管控制流脚本管数据流。这是最核心的一条。如果你让模型自己去解析 JSON、做字符串拼接、算数值它迟早会出错。正确的做法是把确定性的计算逻辑封装成脚本Skill 里只负责决定“什么时候调用这个脚本、传什么参数”。OpenClaw 的run_shell工具就是干这个的。模型负责判断和编排脚本负责精确执行各司其职。渐进式披露别一次塞太多。一个 Skill 如果步骤超过 7 步模型在中途“失忆”的概率会显著上升。解决办法是把大 Skill 拆成多个小 Skill每个只做一件事通过description里的触发条件让模型按需加载。OpenClaw 支持auto_reload你改完SKILL.md不用重启就能生效调试起来很方便。最后说一个我踩过的坑Skill 的name字段不要用中文也不要用空格。用短横线连接的英文小写比如fetch-weather、parse-log。某些版本的 OpenClaw 在解析 YAML front matter 时对非 ASCII 字符处理不一致可能导致 Skill 加载失败但又不报错表现就是“Skill 明明存在但 Agent 就是不用”。改成纯英文名之后这个问题再没出现过。如果你在排障过程中需要对照 API 的返回结构可以直接用 TaoToken 的模型对话页面发一条带 tools 的请求看看原始响应长什么样。接入文档里也有完整的请求示例对着调比盲猜快得多。长期跑编码类 Agent 的话Coding Plan 的额度比按量计费更划算适合把 OpenClaw 挂在后台持续干活。