简介:OpenClaw(曾用名 Clawdbot、Moltbot)是2026年初在GitHub快速走红、主打本地优先架构的开源个人AI助手平台,这份手册正适合希望掌握其部署与深度使用的开发者、运维及进阶用户。内容覆盖核心特性、通讯平台接入、文件处理、浏览器自动化、终端命令执行、技能插件系统与持久化记忆等玩法,并给出国内网络环境下的模型选择、常见问题与本地部署指南。资源为单份PDF电子手册,整包3.48MB,便于按目录检索和离线查阅。目前已有189人浏览学习;借助手册,读者可按Windows、macOS、Linux、Docker或云服务器路径完成部署,也可结合附录的常用命令、配置参考与故障排除指南,快速上手从对话问答到自动化执行的OpenClaw。
1. OpenClaw 是什么:一个常驻在消息平台里的 AI 智能体,为什么值得花一晚部署它
OpenClaw 是一套可以完全自托管的 AI 智能体框架,跑起来之后,它会以常驻进程的方式住在你自己的服务器上,通过 Telegram、Microsoft Teams、Discord 这类消息平台和你对话、执行任务、调用工具、读写记忆。我第一次部署它是在找“能自己跑、不上云、还能接 Teams 的智能体”时,结果折腾了两个晚上才把链路摸顺,回头看最大的坑根本不在安装,而在会话锁、webhook 回调这些消息平台层面的细节。这份笔记按 202602v1 版的使用习惯来写,适合独立开发者、小团队和自动化爱好者:你不需要先懂分布式,只要有一台 Ubuntu 机器和一个能收到消息的群,就能把 OpenClaw 变成你的常驻助理。它解决的核心问题很简单:让 AI 不再躺在网页对话框里,而是站在你每天已经在用的聊天窗口里。
2. 部署 OpenClaw:Ubuntu 服务器从零到常驻的 Docker 方案,解决“每次重启都要手动拉起”的问题
2.1 为什么选 Ubuntu 22.04 + Docker Compose:隔离依赖,也隔离翻车的风险
OpenClaw 的部署方式无非两种:直接跑二进制,或者跑容器。我两边都试过,如果你的服务器以后还要跑 Ollama、Nginx、别的服务,Docker Compose 是更省心的选择,它把运行环境、配置目录、日志输出都框在一个 compose 文件里,换机器时只要把数据目录和配置一起带走就行。Ubuntu 22.04 是目前兼容性最好的宿主系统,OpenClaw 的运行时依赖在 22.04 上基本不会碰到“缺 libc 版本”这种问题。
硬件上 2C4G 起步,如果只用云上的模型 API,这个配置跑 OpenClaw 本体绰绰有余;如果你还想在同一个机器上跑 Ollama 本地模型,建议至少 4C8G。手头只有一台临时云主机的话,也可以先用试用实例把链路跑通,再决定是否扩容,OpenClaw 对单机部署非常友好,不需要额外买数据库。
提示:数据目录一定要放在本地磁盘,不要放 NFS 或网络盘。OpenClaw 的会话文件依赖文件锁,网络文件系统的锁语义在低版本实现上有坑,后面避坑章节会专门讲。
2.2 最小部署命令:docker compose 起一个能跑的服务
我习惯把 OpenClaw 的数据统一放在/opt/openclaw下面,这样备份和迁移都方便。先准备目录:
# 1. 准备数据目录,sessions 放会话文件,memory 放长期记忆 sudo mkdir -p /opt/openclaw/data/sessions sudo mkdir -p /opt/openclaw/data/memory sudo chown -R $USER:$USER /opt/openclaw目录建好后,在/opt/openclaw下新建docker-compose.yml:
services: openclaw: image: openclaw:202602v1 # 镜像名按 Release 页实际提供的 tag 替换 container_name: openclaw restart: unless-stopped ports: - "127.0.0.1:8080:8080" environment: OPENCLAW_HOME: /data volumes: - /opt/openclaw/data:/data command: ["openclaw", "serve"]这份配置里有两个关键点。第一,端口只绑在127.0.0.1:8080,而不是0.0.0.0:8080,原因是 OpenClaw 的 HTTP 服务默认没有鉴权,暴露到公网等于裸奔;后面接 Teams 或 webhook 时,我会用 Nginx 做一层地址转发,把公网流量转发到本机这个端口。第二,OPENCLAW_HOME=/data表示所有状态都写进挂载目录,容器重建后你的会话和记忆都还在。
启动并观察日志:
cd /opt/openclaw docker compose up -d docker compose logs --tail 50第一次启动如果看到类似listening on 127.0.0.1:8080的日志,说明服务已经起来了。此时你可以先不改任何配置,用默认模型配置跑一条测试消息,确认 agent 能正常回话,再开始接消息平台。这一步的意义是先把“服务本身”和“消息平台接入”两个变量分开,避免后面出了问题不知道是部署的问题还是 webhook 的问题。
2.3 用 systemd 托管容器:重启策略与开机自启
restart: unless-stopped已经覆盖了大多数崩溃场景,但如果你用了二进制方式部署,或者在容器里改了网络模式,我建议直接用 systemd 托管,这样日志会统一进 journald,排查时不用 docker logs 一条条翻。下面是一个最小 unit 文件,按二进制放在/opt/openclaw/openclaw的情况写:
[Unit] Description=OpenClaw agent service After=network-online.target Wants=network-online.target [Service] WorkingDirectory=/opt/openclaw ExecStart=/opt/openclaw/openclaw serve --port 8080 Restart=on-failure RestartSec=10 Environment=OPENCLAW_HOME=/opt/openclaw/data [Install] WantedBy=multi-user.target然后执行:
sudo systemctl daemon-reload sudo systemctl enable --now openclaw sudo systemctl status openclaw注意Restart=on-failure只会在进程异常退出时拉起,如果你手动 stop,systemd 不会跟你对着干。RestartSec=10是我习惯的间隔,太短会在 OOM 时陷入崩溃循环,太长又会让空窗期变大。如果你的 OpenClaw 用 Docker 方式跑,就没必要再包一层 systemd,restart: unless-stopped加systemctl enable docker已经等价,不要叠床架屋。
3. 把 OpenClaw 接入 Microsoft Teams 与 Telegram:webhook 回调和会话隔离的落地配置
3.1 消息平台接入原理:从“主动去拉”到“平台推给你”
在接平台之前,先理解 OpenClaw 的两种消息获取模式。第一种是 polling,OpenClaw 定期向平台服务器问“有没有新消息”,实现简单,内网部署也能用,Telegram 的 bot 走这种模式最省事。第二种是 webhook,平台服务器收到用户消息后,主动向你的 OpenClaw 地址发一个 HTTP POST,OpenClaw 再回复,优点是实时性好,缺点是要求你的服务器有一个公网可达的 HTTPS 地址。
Microsoft Teams 走的是 webhook 这条路,而且要求比较苛刻:它要求回调地址必须是公网 HTTPS,证书有效,并且在收到消息后十几秒内返回 200,否则会判定回调失败并重试。这个“十几秒内返回 200”是后面很多问题的根源,很多人部署完发现自己接入失败了,其实不是 OpenClaw 配置错了,而是 Nginx 那层没有把 POST 请求正确转发进去。
3.2 接入 Microsoft Teams:Bot Framework 回调与常见静默失败
Teams 的正确接入方式是通过 Bot Framework,而不是往频道里扔一个 Incoming Webhook。Incoming Webhook 只能“发出去”、不能“收回来”,收用户消息必须有一个 bot 身份。你在 Azure 门户创建一个 Bot 资源后,会拿到两个关键值:Application ID 和客户端密钥。把这两个值填进 OpenClaw 的消息配置块:
{ "messaging": { "teams": { "enabled": true, "app_id": "你的 Bot Framework Application ID", "app_password": "你的 Bot 客户端密钥", "endpoint": "https://你的域名/api/teams" } } }endpoint是 Teams 回调你的地址,具体路径以你启动 OpenClaw 后日志里打印的“Bot endpoint”为准,我这里是按/api/teams写的,不同版本可能不同。填完后,用 Nginx 把这个公网路径转发到127.0.0.1:8080,然后自测一下回调链路:
curl -i -X POST "https://你的域名/api/teams" \ -H "Content-Type: application/json" \ -d '{"type":"message","from":{"id":"probe"},"conversation":{"id":"probe"},"text":"探活"}'如果返回 200,说明链路通了;如果返回 404,说明路径没对上;如果超时,说明 Nginx 没转发过去。这一步能帮你把“OpenClaw 配置”和“外部链路”分开排查。Teams 接入最容易翻车的地方是:你改了 Azure 里的 bot 配置,但 Teams 客户端和 bot 服务之间有缓存,改完要等几分钟再测,否则会看到“已读但没回复”的假象。
3.3 接入 Telegram:BotFather 拿 token 和 polling 模式
Telegram 简单很多。找 BotFather 创建一个 bot,拿到 token,填进配置:
{ "messaging": { "telegram": { "enabled": true, "bot_token": "123456:ABC-DEF...", "allowed_chat_ids": [123456789], "mode": "polling" } } }mode选polling可以省掉公网 HTTPS 的依赖,适合放在内网或临时机器上验证。allowed_chat_ids是白名单,只允许指定的 chat_id 跟你对话,防止 bot 被陌生人扫到后用你的模型额度发消息。这个字段建议一上来就配上,空数组等于放行所有人,我第一次部署时没配,一天被骚扰了二十多次,血泪教训。
3.4 同一套服务跑多平台:会话文件命名带来的冲突
当同一个 OpenClaw 实例同时接 Teams 和 Telegram 时,会话隔离就成了真问题。OpenClaw 的会话是按“平台 + 聊天 ID”来分文件的,Telegram 的 chat_id 是一串数字,干净;Teams 的 conversation id 是一长串带特殊字符的字符串,如果直接拿来做文件名,你会看到两个后果:一是文件名超长,二是同一个群里如果既有 Teams 又有别的入口,会话文件可能在同一个会话 ID 下被两个请求同时写。
我的做法是不同平台接不同的 agent 配置,而不是全都挤在一个默认 agent 里。Teams 走/api/teams,Telegram 走 polling,它们各自的会话目录通过OPENCLAW_HOME或配置里的session_dir分开。这样即使两个平台同时有人说话,底层也不会争抢同一个文件锁,后面第 5 章要讲的 session file locked 就少了一大半诱因。
4. OpenClaw 的会话、记忆与模型路由:把“能聊天”调成“能干活”的核心参数
4.1 session 生命周期:为什么 agent 忽然“失忆”
OpenClaw 里一次对话就是一个 session,它对应 sessions 目录下的一个文件,里面按顺序记录每一轮的输入输出。session 的打开和关闭由两个参数控制:session_timeout_min和max_turns。前者表示多少分钟没新消息就判定会话结束,后者表示一个会话最多能聊多少轮。这两个参数直接影响你感受到的“记忆长度”。
{ "agent": { "persona": "你是一个后端助手,回答保持简短,优先给可执行命令", "session_timeout_min": 60, "max_turns": 20 } }session_timeout_min设小了,你会发现过一会儿再发消息,agent 完全不记得刚才聊了什么,这不是它蠢,是会话已经被回收了;设大了,又会带来一个副作用:长时间挂着的会话占用内存,多聊几轮后输入的上下文越来越长。我一般默认 60 分钟,max_turns控制在 20 轮以内,超过就强制开新会话。这样既不经常“失忆”,又不会让单次请求的 token 消耗失控。
你还要理解一个反直觉点:重启 OpenClaw 之后,agent 依旧不记得你是谁,不是因为会话文件没了,而是进程重启后活跃会话列表被清空,需要对方再发一条消息才会把旧会话文件重新加载进来。所以重启服务后第一句“你还记得我吗”得到否定回答,别慌,那是正常的。
4.2 记忆机制:memory 的存储、召回与清理边界
session 是短期对话上下文,memory 才是长期记忆。OpenClaw 的长期记忆默认也是落盘文件,backend设为file,指定一个目录存记忆条目。配置里有两个关键项:
{ "memory": { "backend": "file", "dir": "/data/memory", "recall_days": 30 } }dir是记忆存放目录,recall_days是召回窗口,意思是 agent 思考时只会把最近 30 天内的记忆条目纳入上下文。这里藏着一个常见的性能误区:有人把recall_days拉到 365,以为记忆越多越聪明,结果每次请求都带上大量记忆,既费 token 又拖慢响应。记忆不是上下文,它是检索候选池,候选池越大,挑错信息的概率也越大。
我见过一个做法是把dir直接指向 Obsidian vault 下的某个文件夹,这样喂给 OpenClaw 的外部资料和它自己沉淀的记忆都落在同一个目录里,你能直接用 Obsidian 打开看它到底记住了什么,相当于是给记忆文件加了一层可视化。这个做法适合自己折腾,不一定要学。
4.3 模型路由:OpenAI、Ollama 与超时参数怎么配合
OpenClaw 的 provider 配置决定 agent 用哪个模型答题。如果你接的是 OpenAI 类 API,最常见的最小配置是:
{ "provider": { "openai": { "api_key": "sk-...", "model": "gpt-4o-mini", "temperature": 0.7 } } }temperature不是越高越好,做工具调用和命令生成时,我习惯调到 0.2 到 0.4,减少随机性。如果你想让 agent 执行具体操作(读写文件、跑命令),温度太高容易生成不存在的参数,翻车概率直线上升。
本地模型走 Ollama 时配置不一样:
{ "provider": { "ollama": { "base_url": "http://127.0.0.1:11434", "model": "qwen2.5:7b", "keep_alive": "5m" } } }base_url指向 Ollama 的端口,keep_alive表示模型在内存里驻留 5 分钟。这个参数很关键:如果设成 0,每轮请求都要重新加载模型,第一次响应能慢到 30 秒以上,用户体验极差;设成 5m,至少在连续对话时模型是热着的。本地模型首问慢的问题,我习惯在部署完后手动预热一次:
curl -s http://127.0.0.1:11434/api/generate \ -d '{"model":"qwen2.5:7b","keep_alive":"5m","prompt":"hi"}' >/dev/null把模型先拉进内存,再让 OpenClaw 接流量,能避开“以为服务挂了、其实在加载模型”的误会。
4.4 工具白名单和配置模板:用一套配置管多个 agent
OpenClaw 的 agent 不只是聊天,它能调用工具:搜索网页、发 HTTP 请求、读写文件、执行命令。工具是把双刃剑,我在配置里一定会做白名单,没列进去的工具一律禁用。比如允许它读写/tmp下的临时文件,但不允许碰系统目录;允许它调用 http 请求访问内部服务,但不允许外发数据。
配多个 agent 的常见做法是准备一个基础配置模板,然后每个 agent 只改persona和session_dir。比如一个叫ops-agent,persona 偏向回答运维问题;一个叫writer-agent,persona 偏向写文档。两者共享同一套模型和记忆策略,但会话目录隔开,互不干扰。
顺带回应一个常见纠结:“OpenClaw 和 WorkBuddy 哪个好”。我的判断是:如果你只需要一个定时任务型、日历型轻量助手,WorkBuddy 那类工具开箱即用;如果你要的是“住在消息平台里、能接 Teams、有记忆和工具调用”的常驻智能体,OpenClaw 的灵活度明显更高。两者不是替代关系,是定位不同,选之前先想清楚你要的是定时脚本还是一个能对话的协作对象。
5. OpenClaw 避坑指南:会话文件锁超时、Teams 静默失败与本地模型首问慢的排查顺序
5.1 session file locked (timeout 60000ms):并发写入撞上单文件锁
现象:用户发消息后,agent 一直不回复,日志里出现agent failed before reply: session file locked (timeout 60000ms) openclaw,然后整条请求在等锁等了 60 秒后失败。
原因:这个错误是多个请求同时针对同一个会话文件加锁导致的。最常见的有三种场景:两条不同平台的消息几乎同时到达同一个会话;前一个请求还在处理中(比如模型调用慢或工具执行卡住),新消息进来又试图写同一个会话文件;会话目录落在网络盘上,文件锁语义不对。60 秒是默认锁等待上限,超过就放弃。
解决:先把现象和进程状态分开确认,再动手。如果日志里能同时看到两三条请求都在等同一个会话,说明是并发冲突,优先从架构上拆:不同平台分 session 目录,同一个会话的请求串行化处理。如果是历史遗留的锁文件卡住,可以使用下面的命令清理超过 10 分钟的锁文件:
# 先查看,再确认没有活跃请求后删除 find /opt/openclaw/data/sessions -name '*.lock' -mmin +10 -print find /opt/openclaw/data/sessions -name '*.lock' -mmin +10 -delete-mmin +10是只处理修改时间超过 10 分钟的锁文件,避免误删正在被使用的锁。清理完观察几分钟,如果还会继续出现锁超时,就不是锁文件残留,而是并发设计问题,要去调整会话目录划分。
5.2 Teams 已读但 agent 不回话:回调 URL 与 HTTPS 证书的问题
现象:用户在 Teams 里发消息,消息状态显示已读,但 agent 没有任何回复。OpenClaw 日志里干干净净,连请求记录都没有。
原因:Teams 的 Bot Framework 在回调失败时会自动重试,而且客户端会先标记“已读”,所以用户看到的是“发出去了、也读了、就是没结果”。真正的原因大多在两个地方:一是 endpoint 填的 URL 公网不可达或路径不对,二是 HTTPS 证书校验失败。还有一种情况是你改了 endpoint 配置,但 Teams 服务端那边有延迟,旧地址还在被调用。
解决:先用外部视角测一下你的回调地址是否真的能通。直接用浏览器或 curl 访问https://你的域名/api/teams,如果返回 404,说明路径不对,去日志里看启动时打印的 endpoint;如果返回 502 或超时,说明 Nginx 转发层有问题,重点查证书链。确认外部链路通了之后,再改 Teams 配置,改完等三到五分钟再测。这个“等几分钟”很关键,很多 Teams 接入失败其实是你改对了,但旧配置还没过期,多试两次就过了。
5.3 容器 OOM 被 kill:OpenClaw 沉默之前的征兆
现象:容器跑得好好的,突然谁发消息都没反应,docker logs openclaw的最后几行是Killed,或者宿主机的journalctl里有 oom-kill 记录。
原因:OpenClaw 进程被系统 OOM killer 杀掉了。常见诱因是会话数量太多、每个会话的上下文又长,或者某一个会话在工具调用里反复执行了占用内存的操作。观察到的特征通常是:容器还在但进程没了,docker ps显示容器是 running,但 OpenClaw 进程已经被杀,只是容器还在等待重启。
解决:给容器加内存上限,让 OOM 发生时系统优先杀其他进程。另一个兜底是把max_turns调小,限制单会话上下文膨胀。我的经验是 4G 内存跑 OpenClaw + 外部模型 API 足够,但如果你同时跑了 Ollama 加载 7B 参数模型,内存直接吃紧,建议这种组合上 8G。每次 OOM 后我都会检查会话文件个数:
find /opt/openclaw/data/sessions -type f -mtime +7 -print超过一周的旧会话文件会被我定期清理,防止目录里堆着几万个文件拖慢列表操作。
5.4 本地模型首问要几十秒:不是卡死,是在等模型加载
现象:Ollama 模式下,第一句话发出去后 agent 半天没反应,日志显示响应耗时 30 秒以上,但后续对话又恢复正常。
原因:这大概率不是服务问题,是模型还没进内存。keep_alive设为 0 或时间太短时,每次空闲间隔后模型都会被从内存卸掉,下一条消息要先把模型权重重新加载,7B 模型的加载时间在磁盘性能一般时能到几十秒。这部分体验问题,配置参数解决不了,只能靠预热脚本兜住。
解决:在每日巡检或部署脚本里加一步预热请求,确保 OpenClaw 上线的同时模型已经在内存里。具体做法就是 4.3 节那条 curl,把keep_alive设成"5m"或更长。如果你发现预热之后还是慢,看两处:一是 Ollama 日志有没有反复出现加载模型的记录,二是系统监控里内存有没有被模型占满导致换页。这个现象经常被误报成 bug,其实是本地模型的调度特性,理解了就不慌。
5.5 推荐排查顺序:从日志级别到出网再到 provider 状态
遇到 OpenClaw 不回话,我习惯按下面这个顺序排查,能少走很多弯路。
先看服务状态和最近日志:
docker logs --tail 80 openclaw docker logs --since 10m openclaw | grep -iE "error|lock|teams|timeout"二进制部署的话把 docker logs 换成journalctl -u openclaw -n 80 --no-pager。日志能告诉你 80% 的问题:如果是 lock 超时,按 5.1 节处理;如果有401或403,大概率是模型 API key 失效或消息平台凭据过期;如果是context deadline exceeded,就要看下游超时了,是模型接口慢还是 webhook 回调慢。
日志里没东西时,再查消息平台侧。Teams 优先查 endpoint 公网可达性和证书,Telegram 优先查 token 是否有效、白名单是否包含了当前 chat_id。最后才去看模型 provider 的接口面板,确认余额和限流状态。这个顺序能帮你快速区分“OpenClaw 的锅”“平台的锅”和“模型的锅”,而不是在三个黑匣子里同时乱找。
6. 让 OpenClaw 长期不掉线:健康检查脚本与三个每日验证命令
6.1 一个可用的健康检查脚本
我每台跑 OpenClaw 的机器上都放一个探活脚本,定时任务每分钟跑一次,真正出事时能第一时间在系统日志里留下痕迹:
#!/usr/bin/env bash # 探活:进程、HTTP、锁文件三个维度 if ! pgrep -f "openclaw serve" >/dev/null; then echo "[alert] openclaw process not found" | systemd-cat -t openclaw-health exit 1 fi curl -sf http://127.0.0.1:8080/health >/dev/null \ || echo "[alert] openclaw http check fail" | systemd-cat -t openclaw-health stale=$(find /opt/openclaw/data/sessions -name '*.lock' -mmin +10 2>/dev/null | wc -l) [ "$stale" -gt 3 ] && echo "[alert] stale locks=$stale" | systemd-cat -t openclaw-health/health路径如果在你版本里不存在,替换成日志里显示的探活路径。锁文件数量超过 3 个才告警,是为了避免偶发锁残留误报。用systemd-cat的好处是告警统一进 journald,你后续接监控工具时直接过滤openclaw-health标签就行。
6.2 三个每日验证命令
我每天只跑三个命令确认它活着。第一条看容器状态,第二条看最近有没有记忆写入,第三条看有没有新会话创建:
docker ps --filter name=openclaw --format '{{.Status}}' find /opt/openclaw/data/memory -mmin -10 -type f | wc -l docker logs --since 30m openclaw | grep -c "session created"如果第二条长期是 0,说明 agent 根本没在记东西,可能是记忆目录配错或权限有问题;如果第三条很高,说明有人在跟它对话,但如果你没主动发消息,那就要查是不是 bot 被外面扫描到了。这三条命令覆盖了“活着没、在记没、有人理没”三个维度,比盯着聊天窗口等回复可靠得多。
我现在的习惯是每天中午花一分钟跑这三个命令,顺手看一眼锁文件数量,这套习惯救了我至少三次:有一次 Teams 回调异常,就是锁文件数量先冒头,我才赶在用户发现之前把 endpoint 修正过来。OpenClaw 是个好工具,但它不会主动告诉你它快撑不住了,给会话目录和日志留点关注,比事后翻黑匣子轻松得多。希望帮到你。
本文还有配套的精品资源,点击获取