我最早接触 OpenClaw,起因其实特别朴素:我想让团队的飞书群里有个真正的 AI 助手,不是在网页对话框里点来点去那种,而是我@它一句,它就能查资料、总结文档、写回复草稿。后来又想在自己维护的 Discord 服务器里放一个能随时对话的机器人。试了几套方案之后,我把 OpenClaw 作为主力框架稳定跑了下来,整个过程最大的心得是:能不能把体验做好,GPU 占了七成原因。
这篇教程把我完整的部署过程写出来,从 GPU 环境准备讲起,到 OpenClaw 核心服务的安装初始化,再分别走通飞书和 Discord 两条接入链路。最后一部分是我实际跑服务时踩过的一些坑,以及怎么一步步定位和解决。内容偏实操,涉及的命令和配置我都贴出来了,照着做基本能复现。如果你也打算在自己的设备上部署一个类似的多平台 AI 助手,这篇文章应该能帮你少走不少弯路。
1. OpenClaw是什么:它解决的不只是"把模型接进聊天软件"
1.1 一个把大模型"装进"各类聊天软件的运行时
OpenClaw 本质上是一个 Agent 运行时,不是单纯把大模型 API 包装成一个聊天机器人。它做的是三件事:消息通道层负责接收和发送各个平台的消息,比如飞书、Discord、微信、Slack;Agent 调度层负责管理会话状态、调用工具、处理多轮对话;模型推理层负责跟本地或远端的大模型通信。三层拆开之后,你换来的是非常清晰的扩展性——要加一个新平台,不需要动 Agent 逻辑和模型逻辑,只需要写一个适配器。
我用一个例子说明它跟普通机器人框架的差别。普通的聊天机器人框架,一般是"收到消息 -> 请求模型 -> 返回结果"这样一条直线。但真实场景里,你可能希望 AI 先分析用户发的文档链接,再调用某个搜索引擎查资料,最后把两者结合起来生成回复。这种多工具、多步骤的任务,需要框架层有工具调度的能力。OpenClaw 的 Agent 层做的就是这个事情。所以它适合的不只是个人玩家,也适合小团队做内部自动化助手,甚至有的开发者拿它当基础骨架,改造出垂直领域的客服机器人。
1.2 为什么坚持上 GPU:CPU 跑不动的不只是速度
很多人一开始会想:我的机器也不差,CPU 跑个模型能行吗?如果追求"能出结果就行",CPU 确实可以跑,但如果你要接入飞书或者 Discord,体验完全不一样。我最早拿一台 8 核 CPU 的机器试过 7B 模型,生成一个 token 要几百毫秒,一句话十来个字要等十几二十秒,群里等回复的人基本都失去耐心了。GPU 的核心价值在于并行计算,同样一个模型,消费级显卡能把单 token 延迟压到几十毫秒,首 token 延迟也能控制在几秒内,这还没算并发能力上的巨大差异。
显存大小决定了你能用多大规模的模型,这个是部署前必须想清楚的。我整理了一张粗略的对照表,适用于常见的开源对话模型:
| 模型规模 | 量化方式 | 权重显存占用 | 最低建议显存 |
|---|---|---|---|
| 7B | INT4 | 约 4-5 GB | 6 GB,建议 8 GB |
| 7B | FP16 | 约 14 GB | 16 GB |
| 14B | INT4 | 约 9-10 GB | 12 GB |
| 14B | FP16 | 约 28 GB | 32 GB |
| 32B | INT4 | 约 20 GB | 24 GB |
这个表只是权重的占用,实际跑起来还要算上 KV Cache、临时激活值和并发请求的额外开销。我自己用下来,12GB 显存是一个比较舒服的起步线,能流畅跑 7B 甚至 14B 量化模型。如果你手里只有 6GB 或 8GB 显存,也不用灰心,INT4 量化的 7B 模型也能跑得动,只是并发上要压一压。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. GPU 环境准备:部署前的自查与选型
2.1 nvidia-smi 输出怎么看:驱动、CUDA 和显存确认
不管你是 Linux 裸机、Windows + WSL2 还是 Docker 容器,第一步永远是确认 GPU 驱动能被系统正常识别。打开终端跑一下:
bash复制nvidia-smi
这个命令会输出几行关键信息:驱动版本、CUDA 版本、GPU 型号、显存总量和当前使用量。我见过不少人在这一步卡住,最常见的情况是驱动没装好,或者系统装了两套驱动导致冲突。如果你跑完 nvidia-smi 报错说找不到命令,先确认驱动是否安装;如果报错信息跟什么 "NVML" 有关,通常是驱动状态异常,需要重新安装匹配的驱动。
确认 GPU 型号用:
bash复制nvidia-smi -L
这一步的作用是让你心里有数,后面选模型规模、量化方式、并发配置,全部要回到这张"底牌"上。另外,如果你在 WSL2 里跑,只要 Windows 侧驱动正常,WSL2 里面通常也能直接看到 GPU,不需要在 Linux 里重新装驱动,这是个常见误区。
2.2 容器化部署还是裸机部署:我为什么推荐 Docker
部署 OpenClaw 有两条主流路径:一条是在虚拟环境里裸机部署,另一条是用 Docker 跑容器。两条我都试过,最后稳定使用的是 Docker Compose 方案。原因是容器化把环境依赖全部隔离在镜像里,换机器、升级版本、回滚都方便很多,不会出现"昨天还能跑,今天 brew 更新之后依赖崩了"这种糟心事。
Linux 下使用 Docker 跑 GPU 需要额外装一个组件,叫 NVIDIA Container Toolkit。安装步骤大致是:
bash复制sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
装完之后,可以用下面这个命令验证容器能否访问 GPU:
bash复制docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
如果能看到 GPU 信息,说明容器运行时已经正确接入了 GPU。这一步是后面所有工作的地基,建议不要跳过。至于 Windows 用户,我的建议是直接用 Docker Desktop 的 WSL2 后端,在 WSL2 的 Linux 发行版里执行同样的命令,体验和 Linux 原生几乎一致。
2.3 Python 环境与 PyTorch GPU 版本对齐
如果你不想用容器,那就绕不开 Python 环境的配置。OpenClaw 这类框架通常依赖 PyTorch,而 PyTorch 的 GPU 版本必须和你的 CUDA 版本匹配。我先说一个通用操作:创建一个干净的虚拟环境,然后根据你的 CUDA 版本安装对应的 PyTorch。
bash复制python3 -m venv openclaw-env
source openclaw-env/bin/activate
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
这里 cu124 代表 CUDA 12.4,具体用哪个版本,建议先去 PyTorch 官网查一下当前推荐版本。装完之后,跑一段 Python 验证 GPU 是否真实可用:
python复制import torch
print(torch.__version__)
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))
如果 torch.cuda.is_available() 返回 False,大概率是 PyTorch 版本跟你机器上的 CUDA 驱动不匹配,或者你安装的是 CPU 版本。这一节很重要,因为 OpenClaw 本身只是一个调度框架,真正干活的是底层的 PyTorch 或推理引擎,底层没吃上 GPU,上层再折腾也是白搭。
3. 安装并初始化 OpenClaw:跑通第一个 Agent
3.1 获取项目与启动核心服务
OpenClaw 的获取方式在不同版本里略有差异,最常见的是直接从官方仓库克隆代码,或者拉取预构建的 Docker 镜像。我个人更推荐 Docker 镜像方式,因为省去了依赖安装的环节,尤其适合新手。
拉取镜像并启动服务的逻辑大致是这样:把配置目录挂载到宿主机,把端口映射出来,然后通过环境变量传入模型后端和渠道密钥。一个常见的 Docker Compose 配置长这样:
yaml复制version: "3.8"
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./config:/app/config
- ./logs:/app/logs
environment:
- OPENCLAW_MODEL_BACKEND=ollama
- OPENCLAW_OLLAMA_BASE_URL=http://host.docker.internal:11434
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
这个 YAML 里有几个地方值得解释一下。host.docker.internal 是 Docker 提供的特殊域名,指向宿主机,这样容器里的 OpenClaw 可以去访问跑在宿主机上的 Ollama 服务。deploy.resources 这段是把 GPU 显式分配给容器,没有这一段,容器里即使装了工具包也拿不到 GPU。
3.2 模型后端接入:Ollama、vLLM 与 NIM 的取舍
OpenClaw 本身不绑定某个特定模型后端,这点设计得比较聪明。实际部署时,你有几个选择:Ollama、vLLM、NVIDIA NIM,甚至直接接 OpenAI 兼容的云端 API。我用过的三个方案,区别还是挺明显的:
- Ollama:上手最快,一条命令就能把模型拉下来,内存和显存管理做得比较省心,适合个人使用。缺点是高并发下吞吐不如专门优化的推理引擎。
- vLLM:吞吐量很高,支持 PagedAttention,显存利用率更好,适合多用户并发场景。但配置相对复杂,启动参数也多,新手需要花点时间。
- NVIDIA NIM:如果你用的是 NVIDIA 专业卡,NIM 提供了预优化的容器方案,性能很强,但生态相对封闭,而且显存占用比较高。
我自己的主力方案是 Ollama,因为团队规模不大,单卡 12GB 的负载下 Ollama 完全够用。部署完 Ollama 之后,拉一个基础的对话模型:
bash复制ollama pull qwen2.5:7b-instruct
ollama serve
然后在 OpenClaw 的配置里指定模型后端和默认模型名。如果你选的是 vLLM 或者 NIM,配置文件里对应的地址和模型字段不一样,但整体接入思路是一致的——OpenClaw 只关心你要调用的服务地址是什么,以及用什么模型名。
3.3 第一个验证节点:Control UI 启动
OpenClaw 自带一个网页控制面板,通常叫 Control UI。这个面板的作用是让你在接入飞书和 Discord 之前,先确认核心服务是否正常。启动服务后,在浏览器里访问映射出来的端口,比如 http://localhost:8080,进入面板之后查看模型状态,试着直接在面板里发一条对话消息。
我第一次启动的时候,面板一直打不开,后来查日志发现是端口被占用了。这个排查过程后面专门写一节。这里想强调的是,不要跳过这一步直接去配飞书。先确认模型能在面板里正常回复,再去做渠道接入,这样出了问题你才能明确知道是哪一层的事。否则就会出现"飞书消息发出去没反应"这种问题,你分不清是模型挂了还是飞书配置挂了。
4. 飞书接入:让机器人进入你的工作群
4.1 飞书开放平台应用创建与权限配置
飞书接入的第一步,是在飞书开放平台里创建一个企业自建应用。这个流程在飞书开发者后台完成,你需要在"开发者后台"里面新建应用,类型选"企业自建应用"。创建完成之后,你会拿到两个关键凭证:App ID 和 App Secret,这两个值后面要填进 OpenClaw 的配置里。
创建完应用之后,需要在"应用能力"里添加"机器人"能力。这一步很关键,没添加机器人能力的话,你的应用只能在后台调 API,不能以机器人身份出现在群里。添加机器人之后,还需要配置权限。飞书的权限控制比较细,至少需要这几个:
im:message:读取用户发给机器人的消息im:message:send_as_bot:以机器人身份发送消息im:chat:读取群组信息,用于定位消息来自哪个群
配置好权限之后,进入"版本管理与发布",创建一个版本并提交发布。这里要注意,飞书对自建应用有审核机制,如果你在"测试企业"里调试,可以把自己加为测试成员,不需要走完整审核。我第一次就卡在这里,权限配了一堆但版本没发布,导致机器人一直不生效。这个细节看起来不起眼,却是新人最常踩的坑。
4.2 事件订阅 URL 的回调验证原理
飞书的工作方式不是"轮询"消息,而是"事件回调":飞书服务器把消息事件推送到你配置的回调地址。因此你需要一个公网可以访问的 URL。如果你部署的机器没有公网 IP,可以用内网穿透工具,比如 ngrok、frp、cpolar,把本地端口映射到一个公网地址。
这里有一个很重要的原理要理解。当你把回调 URL 填进飞书后台并点击"验证"时,飞书会向你的 URL 发送一个请求,请求里带一个 challenge 字段和一个 token 字段。你的服务需要校验 token 是否正确,然后把 challenge 原样返回,飞书才会认为这个回调地址有效。OpenClaw 对飞书的支持封装好了这套逻辑,但前提是你在配置里正确填入了三样东西:
- 回调地址 URL
- Verification Token(在飞书后台"事件与回调"页面获取)
- Encrypt Key(可选,用于加密消息内容)
我在这个环节出过一次问题:Encrypt Key 填错了,导致飞书回调验证一直失败。排查的时候,OpenClaw 日志里会显示解密失败的错误,但是飞书后台只给你一个笼统的"验证失败"提示,如果不看日志,根本不知道问题出在哪。所以当你遇到回调校验失败,第一件事永远是去看服务日志。
4.3 channel 配置与消息闭环测试
飞书后台的事情都做完了,回到 OpenClaw 这边,把飞书渠道的配置加进去。不同的部署方式配置路径不一样,但你需要设置的字段基本是这些:
yaml复制channels:
feishu:
enabled: true
app_id: "cli_xxxxxxxxxxxx"
app_secret: "xxxxxxxxxxxxxxxxxxxxxxxx"
verification_token: "xxxxxxxxxxxxxxxx"
encrypt_key: "xxxxxxxxxxxxxxxx"
填好之后重启服务。然后去飞书群里 @ 机器人,发一句"你好"。正常情况下的链路是:飞书服务器收到消息,推送到你的回调地址,OpenClaw 解析事件,调用模型生成回复,再通过飞书 API 把消息发回群里。如果这一轮通了,恭喜你,飞书接入就算完成了。
如果消息发出去没有反应,我的排查顺序是:先看飞书后台的"事件投递"记录,确认事件有没有推送到你的地址;再看 OpenClaw 日志,确认有没有收到事件;最后看模型日志,确认是不是模型调用超时。用这个顺序,基本上能在几分钟内定位到问题到底出在哪一段。
5. Discord 接入:把 Bot 拉进你的服务器
5.1 Discord 开发者后台创建 Bot
Discord 的接入逻辑和飞书略有不同。飞书走的是"事件回调",而 Discord 用的是网关(Gateway)长连接。这意味着你的服务需要主动跟 Discord 服务器建立一个 WebSocket 连接,保持在线状态。OpenClaw 封装好了这一层,你要做的只是在 Discord Developer Portal 里创建应用并拿到 Bot Token。
进入 Discord 开发者后台,点击 New Application,起个名字,然后在左侧菜单找到 Bot,创建一个 Bot。创建之后你会看到一个 Token,这个 Token 就是机器人的"登录凭证",OpenClaw 靠它连接 Discord。Token 的敏感程度等同于密码,千万不要硬编码到会提交到 Git 仓库的配置文件里,也不要截图发给别人。我见过不止一个开发者因为 Token 泄露,机器人被恶意控制,最后只能重新生成 Token。
5.2 三个 Intents 权限的坑:Message Content Intent
在 Bot 页面往下滚,会看到一个叫 Privileged Gateway Intents 的区域,里面有三个开关:
- Presence Intent:获取在线状态
- Server Members Intent:获取服务器成员信息
- Message Content Intent:读取消息内容
其中 Message Content Intent 是最容易被忽略、也最容易导致"机器人明明在线却回不了话"的坑。Discord 的网关设计里,如果这个 Intent 没有开启,你的机器人虽然能收到"有消息来了"这个事件,但是消息的 content 字段是空的。OpenClaw 接到的是一封"空信",自然不会触发回复逻辑。
所以接入 Discord 时,第一件事就是把这个 Message Content Intent 打开。另外两个 Intent 看你的实际需求,如果只是让机器人在频道里对话,Presence Intent 和 Server Members Intent 不开启也没关系。打开 Intent 之后,保存修改,Discord 可能会提示你重新确认授权,按提示操作就好。
5.3 邀请 Bot 到服务器并配置 OpenClaw
拿到 Token 之后,下一步是把 Bot 邀请进你的服务器。在 Developer Portal 左侧菜单找到 OAuth2 -> URL Generator,这里需要勾选 bot scope,然后在下方的 Bot Permissions 里勾选需要的权限,一般选择"发送消息"、"读取消息历史"和"阅读消息"这几个就够了。生成邀请链接后,在浏览器打开,选择目标服务器,确认授权。
邀请成功之后,Bot 会出现在你的服务器成员列表里。此时把 Token 填进 OpenClaw 配置:
yaml复制channels:
discord:
enabled: true
bot_token: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
重启服务,观察日志,你会看到类似"Connected to gateway"的信息,表示 WebSocket 连接已经建立。然后去服务器的某个频道发一条消息,正常的话 Bot 会在几秒内回复。如果没回复,先回去确认 Message Content Intent 有没有开启;如果确认开启了,再看日志,看有没有报错信息。
这里还有一个细节:Discord 的频道权限是层级式的,如果某个频道的"机器人角色权限"里把发送消息的权限关掉了,即使 Bot 整体有权限,在那个频道里也发不了消息。我在调试的时候经常用"普通成员视角"去检查权限设置,能省下不少排查时间。
6. 实际部署中的报错排查:我踩过的几个坑
6.1 显存不足(CUDA OOM)时的处理思路
显存不足是我在部署和使用 OpenClaw 过程中遇到频率最高的问题。现象很直接:日志里出现 CUDA out of memory,轻则当前请求失败,重则整个推理进程崩溃。尤其是接入社交软件之后,群里几个人同时@机器人,并发一上来,OOM 的概率直线上升。
我的处理办法分三步。第一步,降低模型显存占用,换量化程度更高的模型。Ollama 里可以指定量化版本,比如 qwen2.5:7b-instruct-q4_K_M,实测下来效果损失不大,显存占用直接减半。第二步,限制并发。如果你用的是 vLLM,可以设置 --max-num-seqs 来控制最大并发数;如果用的是 Ollama,可以通过环境变量控制请求排队数量。第三步,给推理进程设置显存上限。vLLM 里可以用 --gpu-memory-utilization 0.8,告诉它最多用 80% 的显存,给系统留出一点余量,避免总内存和 CUDA 显存竞争导致崩溃。
6.2 飞书回调 URL 校验失败的定位过程
前面提到过,飞书回调验证失败是我早期遇到的一个难题。当时我的排查顺序是这样的:先在 OpenClaw 日志里找线索,发现日志里有一条"request body verification failed"的错误;然后把日志级别调成 debug,重新点了一次"验证",发现是 Encrypt Key 解密失败。后来去飞书后台重新拷贝了一遍 Encrypt Key,回填之后问题解决。
除了密钥问题,回调 URL 校验失败还有几个常见原因,按出现频率排序:
| 现象 | 可能原因 | 排查方式 |
|---|---|---|
| 请求根本没到你的服务 | URL 不可达、端口未放通 | 用 curl 手动请求回调地址看是否返回数据 |
| 请求到了但验证失败 | Verification Token 不匹配 | 对比飞书后台和配置文件中的 Token |
| 解密失败 | Encrypt Key 不一致 | 检查是否包含多余空格或换行符 |
| 返回格式不对 | 回调逻辑没有正确返回 challenge | 看日志,看是否报"challenge not found"错误 |
有一个技巧可以帮助你快速定位:在配置 OpenClaw 的飞书回调时,可以在飞书后台的事件列表里查"事件投递记录",它会显示每次请求的响应码和响应体。通过这个记录,你能立刻判断是你的服务没收到请求,还是收到了但处理失败。
6.3 Discord 机器人收不到消息的完整排查链路
Discord Bot 在线,但发消息没反应,这个问题我在帮助另一位朋友排查时遇到过。他从 Developer Portal 创建 Bot、拿到 Token、配置 OpenClaw,全部步骤看起来都正确,但机器人就是不回消息。我远程看了半天,最后发现问题出在 Message Content Intent 没有开启。
完整的排查链路应该是这样:先确认 Bot 在线,如果在 Discord 服务器里能看到 Bot 在成员列表里是绿色的,说明网关连接正常。接着去 OpenClaw 日志里按 discord 关键字过滤,看看有没有收到消息事件。如果日志里连消息事件都没有,说明网关连接层面就有问题,检查 Token 和 Intent。如果日志里有消息事件但内容为空,那就是 Message Content Intent 的问题。如果事件和内容都正常,还是没有回复,那就要检查消息处理链路了,比如模型后端是否正常、是否有敏感词过滤规则挡掉了消息。
6.4 Control UI 启动失败与端口占用
Control UI 启动失败,我遇到两次,一次是端口被占用,一次是配置里的静态资源路径不对。端口占用的定位方法很简单,Linux 下用:
bash复制ss -tlnp | grep 8080
或者:
bash复制lsof -i :8080
找到占用端口的进程,要么把它停掉,要么改 OpenClaw 的端口映射。改端口的时候要注意,Docker Compose 里改了 ports 映射,配置文件里的回调地址也可能需要同步更新,尤其是飞书那边,回调地址一旦变了,需要回飞书后台修改。
至于静态资源路径错误,一般是因为挂载配置目录的方式不对。OpenClaw 的 Control UI 页面文件在容器里的固定路径,如果你把宿主机的某个空目录挂载到了那个路径上,就会导致页面资源文件缺失,面板打不开。这种情况的解决办法是去掉多余的数据卷挂载,或者把宿主机目录里的内容补全。
7. 性能优化与进阶玩法:把资源用到位
7.1 并发与延迟如何平衡
接入社交软件之后,并发问题会逐渐显现。我的经验是,在单 GPU 的环境下,模型推理本身是"串行"的,多个请求同时进来时,只能排队逐个处理。你可以通过限制并发和调低请求超时时间,让体验保持在一个可控范围。
一个简单的并发估算公式是这样的:单请求显存占用(权重 + KV Cache)乘以最大并发数,加上模型权重占用的显存,不能超过你 GPU 的总显存。举个例子:一个 7B INT4 模型,权重约 5GB,每个并发请求的 KV Cache 大约 1GB,如果你的显卡是 12GB 显存,最多也就能同时跑 7 个左右的并发请求。超过这个数,就可能 OOM。所以在配置里限制最大并发数,宁可让用户多等一会儿,也不要让整个服务崩掉。
7.2 本地模型与云端模型的混合路由
OpenClaw 这样的 Agent 框架普遍支持按场景指定不同模型。我现在的配置是"本地为主、云端兜底":日常闲聊、内容总结这类任务走本地 Ollama 模型,因为响应快、没有额外成本;遇到复杂推理、代码生成这类高难度任务,则路由到云端 API。这样既保证了速度和稳定性,又不会让云端成本失控。
如果你也打算走混合路由,建议先在配置里把模型路由规则设计好,比如按消息来源的群组、按消息前缀、按关键词触发来分流。在配置阶段就要把这些规则想清楚,否则上线之后再改,用户已经习惯了你的机器人行为,调整成本很高。
7.3 日志监控与异常恢复
服务跑起来之后,日志和监控就是你的第二双眼睛。我用的是最简单的方案:Docker 的 restart: unless-stopped 策略保证服务崩溃后自动拉起,日志通过 docker logs -f openclaw 实时查看。如果要更正式的监控,可以在容器外面再挂一个 Uptime Kuma,定时探测 OpenClaw 的健康检查接口,如果服务挂了,它会通过飞书或 Discord 反向通知你。
还有一点是我自己反复踩过的坑:升级 OpenClaw 或者更新模型版本之后,一定要在低峰期操作,并且先备份配置目录。这个框架的配置文件是 YAML 格式的,升级前后字段可能会有增删,直接替换可能造成配置不兼容。备份旧配置,至少能让你在出问题时快速回滚到可用状态。
从整体来看,把 OpenClaw 跑通并不难,难的是让它长期稳定地在飞书和 Discord 里为你提供价值。选择多大的模型、怎么控制并发、如何设计监控告警,这些决策才是真正影响使用体验的部分。我个人始终建议先用小规模模型把链路整体跑通,再逐步升级模型和优化配置,这样每改动一个变量,你都能知道它带来的影响是什么。
