1. 问题现场Skill 注册成功模型却装聋作哑你按着 OpenClaw 的 Java Skill 教程一路写下来Skill、SkillFunction、SkillParameter三个注解都贴好了WebCrawlerSkill里的fetchSinglePage和batchFetch也写完了单元测试跑得绿油油。启动 Spring Boot控制台打印出“WebCrawler Skill 已启动等待 OpenClaw 连接”OpenClaw 的 Web 界面里也能看到你的 Skill 挂在能力列表上。然后你在对话框里敲下“用 WebCrawler 抓取 https://example.com”。模型回你一句“好的我可以帮你抓取网页内容请提供更多信息。”或者干脆答非所问开始跟你聊网页抓取的原理。你盯着屏幕心里想的是我 Skill 都注册上去了你怎么就不调用呢这个场景我太熟了。问题几乎不在你的 Java 代码而在模型通道的配置。OpenClaw 的 Skill 系统负责“告诉模型有哪些能力可用”但模型本身要能正常发请求、收响应才能完成“判断该不该调用 Skill”这一步。如果模型通道没配 Key、Base URL 填错模型请求根本走不通它自然没法调用你的 Skill。具体到这篇的场景你的application.yml里写了openclaw.skill.server-url: http://localhost:6123和server.port: 8080这两个是 Skill 服务和 OpenClaw 核心服务之间的通信地址不是模型通道的地址。很多人第一次配的时候会把 TaoToken 的地址填到这两个位置结果 Skill 注册正常模型调用全挂。正确的做法是Skill 服务地址保持原样模型通道单独配置。你需要一个能稳定访问的模型 API 通道把 Base URL 和 Key 填对模型才能正常发起请求进而判断“用户让我抓网页我有 WebCrawlerSkill 可以用”。下面我把整个排查和修复过程拆开讲从确认问题现象到配置模型通道再到重新联调验证每一步都能跟着做。2. 前置动作先把模型通道的 Key 和 Base URL 准备好在改 OpenClaw 配置之前你需要先有一个可用的模型 API 通道。这里用 TaoToken 来演示因为它对 Java 开发者比较友好Base URL 格式统一不需要额外处理路径拼接。打开 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 注册账号进入控制台后创建一个 API Key。创建完先复制保存后面填到 OpenClaw 的模型通道配置里。这里有个细节要注意TaoToken 的 Base URL 是https://taotoken.net/api不要在后面加/v1也不要带任何查询参数。很多模型客户端默认会帮你拼/v1/chat/completions如果你 Base URL 写成https://taotoken.net/api/v1最终请求路径就变成/api/v1/v1/chat/completions直接 404。这个坑我踩过排查了半天才发现是路径重复。Key 的权限方面创建时如果看到模型范围选项选你实际要用的模型即可。OpenClaw 的 Skill 调用场景通常需要模型具备 function calling 或 tool use 能力选支持这类能力的模型。创建完成后Key 只显示一次记得存好。如果你还没有 OpenClaw 的模型通道配置入口一般在 OpenClaw Web 界面的设置里或者核心服务的配置文件里。不同版本的 OpenClaw 配置位置可能略有差异但核心参数就两个Base URL 和 API Key。找到对应位置把https://taotoken.net/api和刚创建的 Key 填进去。填完之后不要急着启动 Skill 服务先确认模型通道本身是通的。你可以在 OpenClaw 的模型对话界面里发一条普通消息比如“你好”看模型能不能正常回复。如果这一步就不通说明模型通道配置有问题先解决这个再去看 Skill 调用。3. 可复制配置OpenClaw 模型通道与 Skill 服务分开填这一节把配置拆成两块一块是 OpenClaw 的模型通道一块是你 Java Skill 服务的application.yml。两块不要混。3.1 OpenClaw 模型通道配置在 OpenClaw 的模型通道设置里按下面填配置项填写值说明Base URLhttps://taotoken.net/api不带/v1不带 UTM 参数API Key你创建的 Key从 TaoToken 控制台复制模型名称按你实际使用的模型填需支持 function calling请求格式OpenAI 兼容TaoToken 接口兼容 OpenAI 格式如果你是通过 OpenClaw 核心服务的配置文件来设置模型通道通常是一个 YAML 或 JSON 文件找到model或llm相关的配置段把base_url和api_key替换成上面的值。注意不要动openclaw.skill.server-url那是 Skill 注册用的。3.2 Java Skill 服务的 application.yml你的application.yml保持这样不要往里填 TaoToken 的地址openclaw: skill: name: web-crawler-skill server-url: http://localhost:6123 # OpenClaw 核心服务地址不是模型通道 auto-register: true heartbeat-interval: 30 server: port: 8080 # 你的 Skill 服务端口别和 OpenClaw 冲突这里server-url指向的是 OpenClaw 核心服务你的 Skill 启动后会向这个地址注册自己的能力清单。模型通道的 Base URL 和 Key 不在这里配它们在 OpenClaw 那一侧。如果你之前把 TaoToken 的地址填到了openclaw.skill.server-url现在改回http://localhost:6123。改完重启 Skill 服务确认注册日志正常。3.3 确认模型通道请求路径TaoToken 的接口路径是https://taotoken.net/api加上具体的端点。OpenClaw 或你使用的模型客户端在发起请求时通常会拼接/chat/completions。最终请求地址类似https://taotoken.net/api/chat/completions如果你在 Base URL 后面多写了/v1就会变成/api/v1/chat/completions而 TaoToken 的接口不需要这个/v1前缀。这一点在配置时反复确认能省掉很多 404 排查时间。配置完成后重启 OpenClaw 核心服务和你的 Skill 服务。启动顺序建议先起 OpenClaw 核心再起 Skill 服务这样 Skill 注册时能直接连上。4. 验证请求让模型真正调用 fetchSinglePage配置改完接下来做一次完整的联调验证。这一步的目标是在 OpenClaw Web 界面输入抓取指令观察模型是否调用你的fetchSinglePage并检查返回结果里有没有filePath。4.1 确认 Skill 注册状态启动 Skill 服务后看控制台日志。正常情况会看到类似WebCrawler Skill 已启动等待 OpenClaw 连接... Skill registered: WebCrawler, functions: [fetchSinglePage, batchFetch]如果只看到启动日志没有注册成功日志检查openclaw.skill.server-url是否指向正确的 OpenClaw 核心服务地址以及 OpenClaw 核心服务是否在运行。4.2 在 OpenClaw Web 界面发起调用打开 OpenClaw 的 Web 界面在对话框输入用 WebCrawler 抓取 https://example.com发送后观察界面上的工具调用提示。如果模型通道配置正确模型会判断出需要调用WebCrawlerSkill.fetchSinglePage并生成参数 JSON类似{ url: https://example.com, outputDir: ./downloads }OpenClaw 收到这个调用请求后会通过 Skill 注册时建立的通道反射调用你 Java 服务里的fetchSinglePage方法。4.3 检查返回结果你的fetchSinglePage方法执行成功后返回的SkillResult里包含filePath、title、wordCount三个数据字段。在 OpenClaw Web 界面上模型会收到这个结果并可能回复你抓取成功已保存至: /path/to/downloads/20250101_120000_Example.md 标题: Example Domain 字数: 1234同时你可以在 Skill 服务的控制台看到方法被调用的日志。如果日志里出现了fetchSinglePage的调用记录并且返回了filePath说明模型请求已经走通了 TaoToken 通道Skill 调用链路完整。4.4 用 batchFetch 做二次验证为了确认不是偶然再试一次批量抓取用 WebCrawler 批量抓取 https://example.com,https://httpbin.org/html观察batchFetch是否被调用返回的successCount和totalCount是否符合预期。如果两次调用都正常模型通道配置就没问题了。这里有个小技巧你可以在fetchSinglePage里加一行日志打印当前线程和请求来源方便确认调用确实来自 OpenClaw 而不是你的单元测试。日志用 SLF4J 写别用System.out.println避免污染返回给模型的消息内容。5. 本篇常见错排查即使按上面步骤配了还是可能遇到一些报错。这一节把常见问题和排查方法列出来。5.1 模型不调用 Skill但模型对话正常现象在 OpenClaw 里发普通消息模型能正常回复但发抓取指令模型不调用 Skill只是用文字回复。排查方向模型通道配置正确但模型可能不支持 function calling或者 OpenClaw 没有把 Skill 的能力清单正确传给模型。检查 OpenClaw 核心服务的日志看它是否把WebCrawler的能力描述包含在了模型请求的 tools 参数里。如果 tools 列表为空说明 Skill 注册信息没有同步到模型通道。另一个可能你的SkillFunction方法参数里用了基础类型int delaySeconds而模型没有传这个参数时OpenClaw 反射调用会抛 NPE。改成包装类型Integer并在方法内部做默认值处理。5.2 报错 401 或 403现象OpenClaw 日志里出现 401 Unauthorized 或 403 Forbidden。排查方向Key 填错、Key 过期、或者 Key 没有对应模型的权限。重新在 TaoToken 控制台创建一个 Key确认复制完整没有多余空格。填到 OpenClaw 模型通道后重启服务。5.3 报错 404 Not Found现象模型请求返回 404。排查方向Base URL 路径拼错。确认填的是https://taotoken.net/api没有多写/v1没有末尾斜杠。如果你用的模型客户端会自动拼接/v1/chat/completions那 Base URL 就应该是https://taotoken.net/api最终路径由客户端拼接。5.4 Skill 注册成功但调用超时现象OpenClaw 显示 Skill 已注册但模型调用时超时。排查方向你的 Skill 服务端口 8080 是否被防火墙拦截OpenClaw 核心服务能否访问到http://localhost:8080。如果 OpenClaw 和 Skill 服务不在同一台机器localhost要改成实际 IP。另外检查fetchSinglePage里的网络请求超时设置Jsoup 默认超时可能太短设成 10000 毫秒比较稳妥。5.5 返回结果里没有 filePath现象模型调用成功但返回的数据里没有filePath字段。排查方向检查SkillResult.success().withData(filePath, ...)这行代码是否执行到。如果Files.writeString抛了 IOException会走到 catch 分支返回 failure自然没有 filePath。在 catch 里打印完整堆栈确认是目录权限问题还是路径问题。Windows 和 Linux 的路径分隔符不同建议用Paths.get(outputDir, filename)来拼接不要手动拼字符串。6. 配好通道后继续把 Skill 用起来模型通道配通之后你的WebCrawlerSkill就能在 OpenClaw 里正常调用了。回到第 6.1 节的联调流程在 Web 界面多试几条指令观察fetchSinglePage和batchFetch的返回结果。如果filePath正常返回说明整条链路已经打通。后续如果你要长期跑编码任务或者 Agent 场景可以了解 TaoToken 的 Coding Plan它针对代码生成和工具调用场景做了优化适合 OpenClaw 这类需要频繁 function calling 的场景。模型对话调试可以在模型对话页面直接测试接入文档里有详细的接口说明和参数示例。接入相关的配置和 Key 管理在 API Keys 页面可以随时创建和轮换。如果你用的是 Claude Code 或 Anthropic 风格的接口文档里也有对应的配置说明。把模型通道和 Skill 服务分开配置是 OpenClaw 联调里最容易踩的坑之一。记住openclaw.skill.server-url填 OpenClaw 核心服务地址模型通道的 Base URL 填https://taotoken.net/apiKey 填 TaoToken 创建的 Key。配完之后先验证模型对话再验证 Skill 调用一步步来问题就好定位了。