这个系列的第一篇我写了怎么把 OpenClaw 这个 AI 核心在家庭环境里跑起来,模型用的 DeepSeek,基础对话已经没问题了。但说实话,跑通归跑通,家里没人愿意打开那个网页去聊天。直到我把飞书机器人接进 OpenClaw,这事儿才真正从“我自己的玩具”变成了“家里人愿意用”的工具。现在我在飞书里跟它聊天气、查日程、让它调接口干活,老婆在群里 @ 它也能正常响应。这篇文章就把从飞书开放平台创建应用、到 OpenClaw 配置飞书通道、再到写 Skill 扩展能力的完整过程都拆开讲一遍,顺带把部署期间那几个高频报错(比如 Control UI did not start、node runtime not found)一并说清楚。
1. 为什么最后选飞书当家庭 AI 的对话入口
1.1 不是微信接不起,而是飞书更省心
我最早想的是接入微信,毕竟全家人都用微信,习惯成本为零。但实际调研下来发现,微信个人号协议接入这类机器人,本质上是在走非官方接口,有挺大的风控风险。轻则消息发不出去,重则账号被限制。公众号倒是正规,但订阅号/服务号的接口权限、认证流程、消息模板,对家庭内部这种小规模场景来说太重了,而且也不支持那种“像真人一样聊天”的连续对话体验。
飞书不一样。飞书开放平台提供了官方机器人能力,个人可以创建一个只有几个人的企业,在内部自建应用,然后启用机器人,这套流程完全免费,也不要求企业认证。更关键的是,飞书的事件订阅支持长连接模式,也就是说不需要公网 IP、不需要配置回调 URL,OpenClaw 在家里跑着,通过长连接就能实时收到飞书消息。对家庭内网环境来说,这一条直接解决了最大的网络配置难题。
1.2 飞书机器人对于家庭场景的几个比较优势
拿我实际体验来说,飞书作为入口有几个优点不是纸面参数,而是日常用出来的:
- 多端齐全:手机、电脑、网页都有客户端,长辈用手机,我自己在电脑上也能顺手打开同一个会话。
- 单聊群聊都支持:既能和机器人单独聊天,也能把机器人拉进家庭群,所有人共享一个助手。
- 消息卡片能力:飞书机器人可以发复杂卡片消息,后面做日程提醒、待办列表的时候,展示效果比纯文本好太多。
- 权限模型的颗粒度合适:开放平台里可以精确控制这个应用能读什么、不能读什么,把最小权限给了,心里踏实。
- OpenClaw 社区对飞书通道的打磨已经比较成熟:基本就是填上 App ID 和 App Secret 就能跑,下一步扩展接口也有现成路子。
当然,这不是说飞书完美。飞书机器人在国内使用时,偶尔会碰到开放平台控制台打开慢、应用审核需要管理员同意这类小摩擦。但相比微信那种“能不能用看运气”的状态,飞书是正规军路线,更适合一个想要长期稳定运行的家庭基础设施。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先让 OpenClaw 跑起来:环境、模型与三个启动报错
2.1 家庭部署的环境选型与安装流程
OpenClaw 的部署门槛不算高,Node.js 环境就能跑。我建议用家里长期开机的设备,比如 Mac mini、老旧笔记本,或者一块跑着 Linux 的小主机。我自己用的是一台 Mac mini,功耗低,放客厅角落也没声音。
安装流程大致是这样:
- 先装 Node.js,务必选 LTS 版本,我用的 18.x,后面会解释为什么不建议用最新版本。
- 通过 npm 全局安装 OpenClaw CLI 工具(具体包名以你安装时的官方文档为准):
bash复制npm install -g @openclaw/cli
- 初始化项目目录:
bash复制openclaw init my-home-ai
cd my-home-ai
- 启动:
bash复制openclaw start
第一次启动会引导你配置模型。我自己用的是 DeepSeek 的 API,配置里需要填 API Key,模型名填 deepseek-chat。如果你不想依赖外部 API,也可以用 Ollama 跑本地模型,OpenClaw 对本地模型的支持还可以。不过本地模型对硬件要求比较高,还要自己处理模型文件,如果只是求一个稳定能用的家庭助手,直接调云端的 DeepSeek 更省事,成本也不高。
2.2 启动阶段最容易踩的三个坑及排查思路
这里把我在部署过程中遇到的高频报错整理成了一张表,每个都附上根因和解决办法:
| 报错信息 | 根因分析 | 解决办法 |
|---|---|---|
oneclaw node runtime not found |
OpenClaw 没找到可用的 Node 运行时,通常是 PATH 没刷新,或安装的 Node 版本太老 | 卸载后装 Node 18 LTS,然后完全退出终端重新打开;检查 node -v 能正常输出版本 |
Control UI did not start |
Control UI 是独立进程,启动失败一般是端口被占用,或者浏览器环境不兼容 | 查看日志里监听的端口,改用 OPENCLAW_UI_PORT=18080 这类环境变量换个端口;不用管 UI 也能正常用,功能上不影响飞书接入 |
unknown model: deepsee |
配置文件里的模型名写错了,DeepSeek 官方接口认的是 deepseek-chat,明显是你少打了个 k |
打开配置文件,把 model 字段改成正确的标识;这个报错在 OpenClaw 社区里出现频率极高,基本都是手误 |
还有一个小提示:项目目录不要放在中文路径下。Windows 下尤其容易出问题,node 生态里某些工具对非 ASCII 路径处理不好,OpenClaw 也不例外。我在 Windows 机器上试过一次,放在 D:\文档\AI助手 目录下,启动的时候各种玄学报错,后来把所有东西挪到 D:\openclaw\ 下面,世界就清净了。
3. 在飞书开放平台把机器人“造”出来:应用、权限与发布
3.1 创建企业自建应用的全过程
飞书机器人不是直接在客户端里添加的,需要先到飞书开放平台去创建一个应用。这里有个关键认知:个人也可以拥有一个企业,飞书允许一个人创建一个只有自己的企业组织,这对家庭场景完全够用。
操作流程是这样的:
- 打开飞书开放平台,用你的飞书账号登录。如果还没有企业,先创建一个企业(一个人也能建),建好之后顺手把家人拉进来,后面就可以在群里测试。
- 进入开发者后台,点击“创建应用”,选择“企业自建应用”。
- 填写应用名称和描述。我填的是“家庭 AI 助手”,描述写“由 OpenClaw 驱动的家庭智能助手,负责查询天气、日程提醒、问答”。
- 创建完成后,进入应用的“凭证与基础信息”页面,这里能看到两个关键值:App ID 和 App Secret。这两个值就是后面 OpenClaw 连接飞书要用的钥匙,App Secret 千万别泄露,建议直接复制到本地的环境变量文件里,别提交到任何公开仓库。
这一步本身不复杂,但很容易把 App ID 和 App Secret 搞混。可以这样记:App ID 相当于你的应用身份证号,相对不那么敏感;App Secret 相当于密码,必须保密。OpenClaw 配置时两个都要填对,填反了不会报错,但就是收不到消息。
3.2 启用机器人能力、申请权限、订阅事件
应用建好后,要做的不是直接写代码,而是把飞书侧的能力开关一一打开。顺序错了会浪费不少排查时间,按照下面这个顺序来基本上不会漏:
-
添加机器人能力:在“应用能力”页面添加“机器人”。这是必须的,不加的话这个应用根本没有发消息的入口。
-
配置权限:在“权限管理”页面里搜索并开通以下权限:
im:message相关权限(阅读单聊和群聊消息、以机器人身份发消息)im:chat相关权限(获取群组信息,方便机器人拉进群后知道自己在哪个群)contact:user.base:readonly(读取用户基本信息,用于识别发消息的人是谁)
牢记最小权限原则,不要一个权限列表全勾上。OpenClaw 只需要收发消息和识别用户身份,这四五个权限足够了。
-
订阅事件:在“事件与回调”页面选择“使用长连接接收事件”,然后订阅
im.message.receive_v1(接收消息事件)。这一步是整个方案能不能落地的最核心配置。 -
发布版本:在“版本管理与发布”里创建一个新版本,填上版本号和更新说明,提交发布。如果是自己创建的企业,通常马上就过审了。
-
设置可用范围:发布后,在“可用范围”里把这个应用设置为对某些成员可用,至少包含你自己。如果这一步漏了,你发消息给机器人它收不到,因为它根本不在你的飞书环境里。
飞书这边配置完成后,你会拥有四样东西:App ID、App Secret、事件订阅的长连接状态、以及一个发布成功的应用版本。前两个给 OpenClaw,后两个是检查用的。
4. 把飞书通道接进 OpenClaw:关键配置和长连接调试
4.1 配置文件里的关键参数与最小示例
OpenClaw 的配置结构比较简洁,飞书通道只需要在配置文件里增加一个 channels 段落。我的配置文件大概长这样:
json复制{
"model": {
"provider": "deepseek",
"name": "deepseek-chat",
"apiKey": "sk-你自己的key"
},
"channels": {
"feishu": {
"appId": "cli_xxxxxxxx",
"appSecret": "你的AppSecret",
"longConnection": true
}
},
"skillsPath": "./skills"
}
这里需要解释几个容易含糊的点:
apiKey是模型服务的 API 密钥,不是飞书的,别和 App Secret 搞混。appId填飞书开放平台里的 App ID,开头通常是cli_。appSecret填对应的 App Secret。longConnection就是前面说的长连接开关,必须设成true,这样 OpenClaw 会主动跟飞书维持一个 websocket 长连接,不需要任何公网回调地址。skillsPath指向你存放 Skill 的目录,下一节会讲。
配置好后重启 OpenClaw,启动日志里如果能看到类似 “feishu channel connected” 的提示,说明应用凭证和事件订阅都通过了。如果没看到,按顺序检查三件事:App Secret 是否复制完整、长连接开关是否打开、飞书那边的应用版本是否真的发布成功了。
4.2 长连接模式为什么更适合家庭网络,以及调试组合拳
很多机器人接入教程默认你有公网服务器和备案域名,因为事件订阅通常回调到你的服务器上。但家庭场景里,OpenClaw 跑在客厅的 Mac mini 上,没有公网 IP,也不想搞内网穿透,所以长连接模式就是最省事的选择。它的原理是 OpenClaw 发起一条到飞书服务器的长连接,飞书有新消息时主动推过来,连接一直保持。即使家庭宽带没有公网 IP,连接也完全不受影响。
调试的时候,我习惯用一套固定的组合拳:
- 先看 OpenClaw 日志,确认长连接已经建立。
- 在飞书里给机器人发一条私聊消息,内容随便写个“你好”。
- 回到终端看有没有对应的消息日志。如果有,说明链路已经通了大半;如果没有,多半是权限/可用范围没配置对。
- 如果收到了消息但 OpenClaw 没回复,往下看模型服务的调用日志,确认 API Key、模型名、余额都没问题。
另外,如果 OpenClaw 本身有 Control UI,可以顺便看一眼消息是否在 UI 的监控面板里出现。不过哪怕 UI 没启动,也不影响飞书消息的收发,单纯一个入口故障而已,不用紧张。
5. 给机器人装“工具箱”:Skill 的编写与两个家庭场景示例
5.1 Skill 是什么,怎么组织
OpenClaw 接上飞书后,它只是一个聊天窗口。真正让它从“能聊”变成“能干”的,是 Skill 机制。你可以把 Skill 理解成手机里的 App:OpenClaw 内核负责推理和规划,具体的动作(查天气、写文件、调 API、读日历)都封装在独立的 Skill 里。
一个典型 Skill 的目录结构是这样的:
code复制skills/
weather/
SKILL.md
main.py
family_schedule/
SKILL.md
main.js
SKILL.md 是这个 Skill 的说明书,OpenClaw 通过它来判断什么情况下该调用这个 Skill。这里有一点非常关键:name 和 description 要写得足够清晰准确,因为模型是靠 description 里的文字来决定何时调用的。比如天气 Skill 的 description 如果只写“提供天气服务”,模型可能不知道该在什么场景触发;写成“当用户询问今天或未来的天气、气温、降雨情况时使用,支持城市名查询”,触发率就会高很多。
Skill 脚本本身遵循一个简单的输入输出协议:从标准输入读 JSON 格式的请求,输出 JSON 格式的结果。这样无论你用 Python、Node.js 还是 Shell 写,OpenClaw 都能统一调度。
5.2 示例:天气查询 Skill 的完整编写过程
写一个天气 Skill 最直接的方案,是调公共天气 API。这里我用一个稍微简化的版本做示例,重点是展示结构。
先写 SKILL.md:
markdown复制---
name: weather
description: 查询天气情况。当用户询问今天、明天、本周的天气,包括气温、下雨概率、空气质量时,使用此工具。参数 city 为城市名称。
---
然后 main.py:
python复制#!/usr/bin/env python3
import sys
import json
import urllib.request
def query_weather(city):
url = f"https://api.example.com/weather?city={urllib.parse.quote(city)}"
# 这里替换成你实际使用的天气 API
with urllib.request.urlopen(url) as resp:
data = json.loads(resp.read())
# 模拟返回结果
return {
"city": city,
"condition": "多云",
"temperature": "22~28℃",
"humidity": "65%"
}
def main():
req = json.load(sys.stdin)
city = req.get("city", "上海")
result = query_weather(city)
print(json.dumps(result, ensure_ascii=False))
if __name__ == "__main__":
main()
用的时候,在飞书里对机器人说“今天上海天气怎么样”,OpenClaw 的推理层看到“天气”这个意图,读到 SKILL.md 的 description,就会自动拉起这个 Skill,把 {"city": "上海"} 传进去,再把返回结果整理成自然语言回复。
常见问题是进程权限。有的系统上 Skill 脚本没有执行权限,导致 OpenClaw 调度失败。解决办法是给脚本加上可执行权限,或者确认 OpenClaw 的配置里脚本运行方式是 python3 main.py 这类显式命令。
5.3 示例:家庭日程 Skill 的轻量实现
家庭日程是另一个非常高频的需求。我的实现思路很简单,用本地一个 JSON 文件存日程,Skill 负责读文件并返回当天安排。这样既不需要数据库,也不需要额外服务。
SKILL.md 的 description 写法:
markdown复制---
name: family_schedule
description: 读取家庭日程。当用户询问今天有什么安排、明天要做什么、家庭日程时使用。参数 date 为 YYYY-MM-DD 格式日期,缺省为今天。
---
主脚本负责读文件,按日期筛选,返回格式化好的文本。数据文件长这样:
json复制{
"2025-03-20": [
{"time": "09:30", "event": "开周会"},
{"time": "18:00", "event": "接孩子放学"}
],
"2025-03-21": [
{"time": "19:30", "event": "家庭聚餐"}
]
}
这样实现的巧妙之处在于,数据和逻辑分离。以后天气、提醒之类的 Skill 多了,都能用同一套“读 JSON + 格式化输出”的模式。真要做复杂提醒,可以把存储换成飞书多维表格,然后 Skill 走飞书开放 API 读写多维表格,这也是很自然的扩展路径。
6. 实际用了一周的体会:哪些设计值得坚持,哪些可以砍掉
6.1 日常使用场景里的真实表现
接入飞书后,我的第一周测试大概覆盖了这些场景:
- 早上在家庭群里 @ 机器人:“今天上海天气怎么样”,大约 2-3 秒后返回天气情况。
- 问“明天有什么安排”,OpenClaw 调用家庭日程 Skill 返回当天的安排列表。
- 临时设一个简单的“帮我记一下,周末买牛奶”,我让它写入日程文件的
2025-03-22下面,再过一天问它也能想起来。 - 让它在群里做简单的问答和计算,比如“一家四口,每个人需要 2 个鸡蛋,一共几个”,这属于模型本身的能力。
整体体验是:飞书的即时性和消息记录直观可见,比开网页、看终端舒服太多了。延迟上,DeepSeek API 大概 2-5 秒,属可接受范围。如果换成本地模型,我猜响应会更快,但前提是本地跑得动。
也有让我吐槽的地方。比如 Skill 的触发不稳定,同样一句“今天天气怎么样”,有时候它直接靠模型内部知识回答,没有调用 Skill,导致数据不准。这时候就得回头改 SKILL.md 里的 description,把触发条件写得更紧,比如明确写“必须调用 weather skill 获取实时信息,不要自己编造天气”。
6.2 我总结下来的几条个人判断
用了一周之后,有几点很个人的判断,可能对你有参考价值:
- 先单聊,后群聊:一开始别着急把机器人拉进家庭群测试,先在私聊里把通道、Skill、回复格式都调顺了,再拉群。群里人多嘴杂,出错了也不好定位。
- 建一个固定的“家庭频道”:把机器人和家人都加到同一个群,在群公告里写清楚它能干什么,这种仪式感会让人更容易接受和尝试。
- 别急着接微信:热词里也有“OpenClaw 接入微信”,但我还是建议先把飞书这条链路跑稳。一个入口稳定后,再考虑其他通道,否则同时维护多个通道,调试成本翻倍。
- Skill 不要一上来搞太多:第一个 Skill 做天气,第二个做日程就足够了。Skill 越多,模型选择错误的概率越高。先让它精通几个技能,再逐步扩展。
最后分享一个小技巧。飞书机器人默认名字就是应用名称,你可以在开放平台里改成“小飞”“小助手”之类的名字。我还把它的系统提示词调了一下,让它在回复开头不要总说“作为 AI 助手”这类废话,直接给结论。这样一来,家庭群里跟它对话的感觉,跟跟真人说话已经非常接近了。工具能落地,靠的不是技术指标多高,而是每个家庭成员真的愿意用它。
