clawdbot 跑米家 Agent 技能,Key 走 TaoToken
2026/9/20 15:55:47 网站建设 项目流程

clawdbot(也就是 openclaw)想当米家管家,真正的瓶颈往往不是那几个 Python 脚本,而是夹在中间的大模型调用。你说一句“我要睡觉了”,Agent 得在同一个长会话里完成设备枚举、siid/piid 匹配、多轮工具调用和敏感操作二次确认,这些全都走模型,Token 消耗和稳定性直接决定这套 AI Agent 智能家居方案能不能天天用。我现在的改法是先把模型层的 Key 统一交给 TaoToken,clawdbot 侧的 Base URL 填https://taotoken.net/api,米家的扫码登录和本地执行链路一行不改。这样长会话里的每一次工具调用都有稳定出口,出问题也能一眼定位是模型层还是设备层。

1. clawdbot 接米家,卡住的地方其实在模型层

1.1 一句“我要睡觉了”背后的完整链路

很多人第一次跑这套米家技能包,会以为难点在米家协议。实际把项目跑起来之后你会发现,扫码登录、设备枚举、属性读写这些都是确定性代码,跑通一次就不会再变。真正每天都在变的,是模型那一侧:同一个会话里,Agent 要反复读SKILL.md判断自己该不该触发技能,要读instructions.md确认操作顺序,要解析设备映射表把“客厅灯”翻译成具体的siid/piid,还要在关灯、拉窗帘、开净化器之间做任务编排。

我实测下来,一句“我要睡觉了”平均会触发 4 到 8 次模型往返。第一次是意图识别,第二次是调用list_devices.py拿设备清单,第三次是把自然语言房间名映射到did,第四次开始才是逐个设备下发控制。如果中间涉及门锁、摄像头这类敏感设备,还要多一轮“请确认是否执行”的对话。这些往返全部发生在同一个长上下文里,历史消息不会被清空。

1.2 长会话加多工具,会把 Key 的问题放大

短对话里 Key 填错最多报一次错,你改完就完事了。但 Agent/Harness 这种形态不一样:一个任务编排到一半失败,前面的工具调用结果全在上下文里,重试时模型会拿着旧的设备枚举结果继续往下走,很容易出现“设备 ID 对不上但模型硬编一个”的幻觉。

所以模型层需要的不是“能调通”,而是三件事:接口地址固定、鉴权方式单一、额度与并发可控。这也是我最终把 clawdbot 的模型出口统一收到的原因。它只负责给 clawdbot 供模型 Key,米家的控制逻辑、扫码登录、本地脚本执行全部留在本机,职责边界很清楚。

2. 把模型调用前置到 TaoToken

2.1 拿到 Key 与两个地址的区分

第一步不是打开编辑器,而是先去把 Key 准备好。打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册并进入控制台,在 API Keys 页面创建一个新 Key。创建时建议按用途命名,比如clawdbot-mijia,这样以后同时跑别的 Agent 项目时,能一眼看出哪个 Key 属于哪套流程,撤销也不会误伤。

这里有个必须分清的细节:官网地址和 API 地址是两个不同的东西。官网入口是给人看的,API 地址是给程序请求的。clawdbot 的模型 Base URL 要填的是https://taotoken.net/api,不要填官网地址,也不要在这个后面再拼/v1。填错的表现通常是 404,而不是 401,很多人会误以为是 Key 无效。

2.2 Base URL 为什么不带 /v1

不同 SDK 对路径的处理方式不一样。有的客户端会自动在 Base URL 后面补/v1/messages,有的会补/v1/chat/completions。如果你在 Base URL 里已经写了/v1,最终请求就会变成/api/v1/v1/messages,路径重复,直接 404。所以约定是:Base URL 只写到https://taotoken.net/api,版本段交给客户端或请求路径去拼。

TaoToken 在这里扮演的是统一 API 兼容通道,把不同客户端发出的请求格式对齐到同一个出口。对 clawdbot 来说,它感知不到这层差异,它只知道自己有一个能稳定返回工具调用结果的模型端点。

3. clawdbot 侧可复制的配置

3.1 环境变量方式

最省事的做法是把 Key 放进环境变量,避免写进仓库。Linux 或 macOS 下:

export TAOTOKEN_API_KEY="sk-你从控制台复制的Key" export TAOTOKEN_BASE_URL="https://taotoken.net/api" export TAOTOKEN_MODEL="以控制台模型列表里的实际 ID 为准"

Windows PowerShell 用:

$env:TAOTOKEN_API_KEY="sk-你从控制台复制的Key" $env:TAOTOKEN_BASE_URL="https://taotoken.net/api" $env:TAOTOKEN_MODEL="以控制台模型列表里的实际 ID 为准"

模型 ID 不要凭记忆写,去控制台的模型列表或者模型对话页面确认一下当前可用的名称,填错会直接返回 model not found。

3.2 项目配置文件

如果你希望配置跟着项目走,可以在 clawdbot 的配置目录放一份 JSON。下面这份是按通用结构写的示例,键名请对齐你本机 clawdbot 实际的配置规范:

{ "model": { "baseUrl": "https://taotoken.net/api", "apiKeyEnv": "TAOTOKEN_API_KEY", "modelId": "以控制台模型列表里的实际 ID 为准", "timeoutMs": 120000 }, "agent": { "maxTurns": 24, "trimKeepTurns": 12, "confirmRequired": ["lock", "camera", "curtain"] } }

maxTurns控制单个任务最多允许多少轮工具往返,防止模型在“设备找不到”时无限循环。trimKeepTurns是长会话裁剪的保留轮数,后面第 5 节会展开。confirmRequired列出必须二次确认的设备类型,这条逻辑放在配置里而不是提示词里,模型绕不过去。

3.3 技能包里的模型调用封装

米家技能包本身不需要改执行逻辑,只需要让它读取上面这些变量。如果你在scripts/下有自己的模型调用封装,可以统一成下面这种形式,避免 Key 散落在多个文件里:

import os BASE_URL = os.environ.get("TAOTOKEN_BASE_URL", "https://taotoken.net/api").rstrip("/") API_KEY = os.environ["TAOTOKEN_API_KEY"] MODEL_ID = os.environ["TAOTOKEN_MODEL"] def chat(messages, tools=None, max_tokens=1024): payload = { "model": MODEL_ID, "max_tokens": max_tokens, "messages": messages, } if tools: payload["tools"] = tools # 具体请求实现按你使用的客户端 SDK 填写, # 关键是 endpoint = BASE_URL + "/v1/messages" return payload, BASE_URL, API_KEY

注意rstrip("/")这一步。很多人从别处复制地址时末尾带了斜杠,再拼/v1/messages就变成双斜杠,部分网关会直接拒绝。

3.4 instructions.md 里的长会话编排约束

模型层配置好之后,还要在instructions.md里加两条约束,否则长会话跑十几个设备时,模型容易跳步。第一条是强制先枚举后控制:任何控制动作之前,必须先调用list_devices.py确认设备存在。第二条是设备 ID 只能来自工具返回结果,不允许模型自行推断或复用上一轮的记忆。

## 控制流程 1. 收到自然语言指令后,先调用 list_devices.py 获取设备清单。 2. 从工具返回的 did / siid / piid 中选目标,禁止自行编造。 3. 敏感设备(lock / camera)必须先向用户确认,得到明确同意再执行。 4. 单个设备控制失败时,停止后续编排并回报失败原因。

第 4 条很关键。米家设备离线时control_device.py会返回非零状态码,如果模型继续往下关灯拉窗帘,最后你会收到一句“都搞定了”,但实际只成功了一半。

4. 验证请求:从连通性到“我要睡觉了”全链路

4.1 第一步:纯模型连通性

先不要碰米家,只验证模型端。用 curl 打一次最小请求:

curl -sS https://taotoken.net/api/v1/messages \ -H "x-api-key: $TAOTOKEN_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "'"$TAOTOKEN_MODEL"'", "max_tokens": 32, "messages": [{"role": "user", "content": "只回复 ok 两个字母"}] }'

返回里能看到content数组和正常的stop_reason,就说明 Key、Base URL、模型 ID 三者对齐了。如果这一步就失败,先看第 5 节,不要急着去改米家脚本。

4.2 第二步:设备枚举,先不下发控制

模型通了之后,验证设备层。这一步只读不写:

python scripts/list_devices.py --room 客厅 --json

期望返回结构类似:

[ {"did": "888001", "name": "客厅吸顶灯", "model": "yeelink.light.ceiling1", "siid": 2, "piid": 1, "on": true}, {"did": "888002", "name": "客厅窗帘", "model": "lumi.curtain.hagl04", "siid": 2, "piid": 1, "position": 100}, {"did": "888003", "name": "空气净化器", "model": "zhimi.airpurifier.mb3", "siid": 2, "piid": 1, "mode": 0} ]

siid是服务 ID,piid是属性 ID,不同厂商型号这两个值差别很大,这也是reference/device_catalogs.md存在的意义。枚举结果对了,说明扫码登录的会话还有效。

4.3 第三步:全链路跑一次“我要睡觉了”

前两步都通过后,在编辑器里打开项目文件夹,对 clawdbot 说“我要睡觉了”。正常日志应该长这样:

[env-check] python 3.11.6 ok [mijia] session valid [agent] turn 1 -> tool list_devices(room=客厅) [tool] 3 devices matched [agent] turn 2 -> tool list_devices(room=卧室) [tool] 2 devices matched [agent] turn 3 -> plan: 关灯 x2 / 窗帘 position=0 / 净化器 mode=1 [agent] turn 4 -> control_device(888001, siid=2, piid=1, on=false) [tool] code=0 [agent] turn 5 -> control_device(888002, siid=2, piid=1, position=0) [tool] code=0 [agent] turn 6 -> control_device(888003, siid=2, piid=1, mode=1) [tool] code=0 [agent] done: 已关闭客厅与卧室灯光,窗帘已拉上,净化器切到睡眠模式

整个过程中,模型在 Taotoken 那一侧完成理解和编排,control_device.py在本机执行真实的米家控制。中途如果出现401,说明是模型层的事;如果出现code非 0,那是设备层的事,两者不要混在一起排查。

5. 常见报错排查

5.1 401 与 403

401基本就是 Key 本身的问题:没复制全、前后有空格、环境变量没生效。可以在终端里echo ${TAOTOKEN_API_KEY:0:8}看一下前几位是否符合预期,注意别把完整 Key 打到日志里。403通常是 Key 被撤销或权限范围不匹配,去 API Keys 页面确认状态即可。

5.2 404 与 model not found

404有九成是 Base URL 写错了。常见两种:填成了官网地址,或者在https://taotoken.net/api后面又加了/v1。后者会让请求路径变成/api/v1/v1/messagesmodel not found则是模型 ID 写错,去控制台模型列表核对,注意区分大小写和版本后缀。

5.3 上下文超限与工具调用解析失败

长会话跑到二十轮以上,最容易撞上下文上限。我的做法是在每次请求前做裁剪,保留 system 消息、首轮用户意图和最近若干轮:

def trim(messages, keep=12): if len(messages) <= keep + 1: return messages return [messages[0]] + messages[-keep:]

工具调用解析失败则通常是模型输出里夹带了自然语言解释。解决办法是在instructions.md里明确要求“需要调用工具时只输出工具调用,不要输出解释文字”,并把max_tokens压低一点,减少模型自由发挥的空间。

5.4 siid/piid 匹配失败与登录会话过期

如果日志里出现设备找到了但控制返回参数错误,多半是device_catalogs.md里该型号的siid/piid没收录或者写错了。对照设备枚举返回的真实值补一条映射就行。另一种情况是扫码登录的会话过期,表现为枚举直接报鉴权失败,重新跑一次扫码登录即可,这部分链路完全在本地,和模型层无关。

现象大概率原因处理方向
401Key 无效或未生效检查环境变量与 Key 状态
404Base URL 填错改回https://taotoken.net/api
model not found模型 ID 写错核对控制台模型列表
上下文超限长会话未裁剪保留首轮加最近 12 轮
code 非 0设备离线或 siid 错误查映射表与设备状态

6. 长期跑 Agent,出口要提前想清楚

clawdbot 这套米家技能的日常使用频率其实很高,早晚各一次场景编排,中间还有零散的“看看客厅温湿度”这类查询。按任务数算,每天几十次模型往返很正常。所以模型出口的稳定性和额度管理,比第一跑通更重要。

如果你只是偶尔试试,先按第 3 节把环境变量配好,跑通第 4 节的三步验证就够了,遇到鉴权或地址类问题可以从 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=api-keys 重新生成 Key,路径和参数写法在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=doc 里有对照说明。想先确认某个模型 ID 能不能稳定返回工具调用,可以直接在 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=chat 里手动发一轮带工具的请求,比改代码快得多。

如果你打算让 clawdbot 长期挂在家里当管家,甚至同时跑几个 Agent 技能包,那更适合走 Coding Plan,把并发和额度一次规划好,省掉每天盯着用量调整的麻烦:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=coding-plan 。我自己是先把trimKeepTurns固定在 12,再观察一周日志里每轮工具调用的实际次数,确认稳定之后才把并发调上去,这样比一上来就放开更不容易踩坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询