上个月我把 OpenClaw 从笔记本迁到了云服务器,前后折腾了差不多两天。起因倒不复杂:本地跑一个主控 Agent 加三个工具 Agent 的时候,只要同时丢进去两个复杂任务,内存直接飙到 12G,笔记本风扇像直升机起飞。更要命的是任务跑到一半,笔记本一合盖,整个 Agent 集群就全断了。后来我重新梳理了部署方式——先解决本地稳定性,再打包镜像上云,最后用守护进程托管。整个过程让我意识到,多 Agent 系统的部署难点根本不在框架本身,而在于环境一致、进程守护和 Agent 通信这三块。
这篇就围绕 OpenClaw 的阿里云 / 本地部署展开,把从零开始的每一步完整写下来。适合两类人看:一类是刚接触多 Agent,想在本地先跑通;另一类是已经跑通本地,准备迁到云主机上长期稳定运行。我不打算讲特别深奥的内部原理,只讲实际部署时你一定会碰到的步骤、参数和坑。
1. 本地跑得好好的,为什么非要多部署一份到云上
多 Agent 系统有个很容易被忽视的特点:它不是单进程,而是多个独立进程的协作。每个 Agent 都带着模型连接、工具执行器、记忆存储,就算单纯闲置,也比普通 Web 服务多占不少内存。
1.1 多 Agent 的资源争夺比你想的严重
我最早在本地只跑一个 Agent,内存占用大概 1.5G 左右,CPU 也不高。后来加到四个 Agent,内存直接翻了好几倍。原因不复杂:OpenClaw 里每个 Agent 都可以有自己的工作线程、工具加载器和会话上下文,同时并发执行时,模型接口的响应也会在内存里缓存。
这里有一个经验公式:单 Agent 基础内存约 1.2G 到 1.5G,每增加一个 Agent 再加约 0.8G。如果你给 Agent 挂了重量级工具(比如图表生成、文档解析),单个 Agent 的内存峰值会到 2G 以上。所以本地笔记本跑四个 Agent,一旦任务并发,内存翻车是必然的。
1.2 本地与云端部署的本质差异
本地部署的最大好处是调试方便,日志直接看,代码改了立刻生效。但坏处也很明显:笔记本会休眠、合盖断网、网络不稳定导致模型接口超时。我之前遇到过任务跑到一半,电脑进入睡眠状态,所有 Agent 的待处理消息全部卡死。
云服务器部署解决的正是“持续在线”和“稳定资源”两个问题。只要机器不关机,Agent 集群就能一直跑;而且云主机的网络质量和带宽通常比家庭宽带更稳,调用模型接口的延迟也会低一些。
不过云部署也会带来新问题:环境不一致、镜像构建麻烦、进程退出后没人拉起、端口暴露不安全。这些是后几章要重点处理的内容。
1.3 部署方案选型:一台大机器搞定一切
一开始我考虑过把不同 Agent 拆到多台云主机上,比如主控一台、写作一台、数据分析一台。后来实际测下来发现,对于不超过十个 Agent 的规模,单机部署是最划算的。理由很简单:同机部署时 Agent 之间的消息走内存队列,基本没有延迟;跨机部署要走网络,不仅要处理网络分区,还要额外维护消息队列。
如果 Agent 数量在 5 个以内,云主机选 2 核 4G 基本够用;5 到 10 个,建议直接上 4 核 8G。再往上的话,再考虑拆机。我的建议是:先单机跑通,再考虑扩容。
2. 本地部署 OpenClaw:先让单机场景稳定下来
本地部署是整个迁移过程的第一步。没有稳定的本地实例,后面做镜像、上云都是空中楼阁。
2.1 环境依赖清单
OpenClaw 的依赖不算多,但有几个容易忽略。先把清单列出来:
- 操作系统:Ubuntu 22.04、Debian 12 或者 macOS 13 以上都可以;Windows 上跑问题较多,不建议。
- Python 版本:3.10 或更高。我用的 3.10.12,太老的版本会有依赖编译问题。
- 编译工具:
build-essential,因为某些依赖需要本地编译,不装会直接报错。 - 模型接口:OpenClaw 需要通过一个兼容的模型服务地址来调用大模型,本地部署时可以直接访问远程模型 API,也可以先连一个本地模型服务。
- 内存:至少 8G,如果要跑四个以上 Agent,建议 16G。
2.2 创建虚拟环境并安装 OpenClaw
我习惯把所有项目都装在虚拟环境里,避免和系统 Python 打架。步骤很简单:
python3 -m venv ~/openclaw-env source ~/openclaw-env/bin/activate pip install --upgrade pip pip install openclaw==0.9.4 openclaw --version第一次装的时候我踩了一个坑:直接用了系统的 Python 3.8,结果某个依赖要求最低 3.10,编译报错。所以版本检查很重要。装完后先跑openclaw --version,如果能看到版本号,说明基础安装没问题。
2.3 初始化工作目录并跑通单 Agent
我通常习惯把 Agent 的工作目录和代码目录分开,目录结构这样搭:
mkdir -p ~/openclaw-demo/{agents,storage,logs} cd ~/openclaw-demo openclaw init --name demo openclaw doctor openclaw start --config config.yaml openclaw status每条命令的用途解释一下:
openclaw init会生成一个默认的config.yaml,以及基础的 Agent 目录结构。openclaw doctor会检查环境依赖、模型接口连通性、目录权限,等于帮我们做一次体检。openclaw start --config config.yaml是正式启动。openclaw status查看所有 Agent 的运行状态。
在本地跑单 Agent 时,如果openclaw status能看到一个 Agent 处于READY状态,就说明基础链路已经通了。
2.4 为什么要先在本地跑通
很多人喜欢直接上云,但我不推荐。本地的最大优势是排查方便:模型调用失败时,你能直接看完整日志;依赖缺失时,你可以快速安装,不用在云端反复提交镜像。我先在本地把整个 Agent 流程跑通,包括模型连通、工具调用、结果返回,再考虑打包上云。
本地跑通还有一个隐性收益:能直观感受每个 Agent 的内存和 CPU 占用。这为后面买云主机选配置提供了真实依据。
3. 上云前准备:把 OpenClaw 实例做成可分发镜像
本地环境跑得好,不代表放到云主机上也能跑。最大的问题就是“环境不一致”。我见过很多人在本地能跑、上云就报缺依赖,原因就是没有把环境固化下来。
3.1 依赖锁定,让镜像可复现
在虚拟环境里生成一份完整的依赖清单,是上云前最重要的动作之一。不要只记录顶层依赖,要把所有传递依赖也固定下来。
pip freeze > requirements.lock注意requirements.lock和普通的requirements.txt不太一样。requirements.lock是精确到版本的,目的是保证云端和本地安装的依赖完全一致。我还会顺带把pip本身也锁住,避免不同版本的 pip 解析依赖结果不同。
3.2 把配置外置,密钥不写进代码
上云后,端口、模型接口地址、密钥这些东西应该通过环境变量注入,而不是写死在配置里。我的做法是维护一个.env文件,放在云主机的/opt/openclaw/下面,不进镜像。
OPENCLAW_PORT=8080 OPENCLAW_MODEL_ENDPOINT=http://172.17.0.1:8000/v1 OPENCLAW_MODEL_KEY=your-model-api-key AGENT_WORKER_COUNT=4这样做的原因很简单:镜像会被分发和备份,一旦包含密钥,就等于把凭据扩散到所有地方。把密钥留在云主机本地,只通过启动参数注入,能大幅降低泄露风险。
3.3 用容器封装 OpenClaw
为了让本地和云端的环境尽可能一致,我强烈建议用容器封装。以 Docker 这套为例,下面的 Dockerfile 基本够用:
FROM python:3.11-slim ENV PYTHONUNBUFFERED=1 WORKDIR /srv/openclaw COPY requirements.lock . RUN pip install --no-cache-dir -r requirements.lock && \ useradd -r -u 1001 openclaw COPY --chown=openclaw:openclaw . . USER openclaw EXPOSE 8080 CMD ["openclaw", "start", "--config", "config.yaml", "--env-file", "/etc/openclaw/.env"]几个细节:
- 不要把
.env文件COPY进镜像,而是在运行时通过--env-file挂载。 - 不需要以 root 运行,创建一个低权限用户更稳妥。
PYTHONUNBUFFERED=1能让日志实时输出,方便排查问题。
3.4 镜像的导出与导入
本地构建好镜像后,如果不想走镜像仓库,可以直接把镜像文件传到云主机:
docker build -t openclaw-demo:0.1 . docker save -o openclaw-demo.tar openclaw-demo:0.1 scp openclaw-demo.tar your-cloud-user@your-host:/opt/openclaw/然后在云主机上导入:
docker load -i openclaw-demo.tar这一套操作非常简单,适合小团队或个人使用。如果你有专门的镜像仓库,当然也可以走推送和拉取的方式,但核心思路都是一样的:保证云主机上运行的镜像是本地验证过的那一个。
4. 云服务器部署:从购买机器到 systemd 守护进程
上云的实操步骤会直接决定后面运行的稳定性。不要以为把镜像拉起来就算部署完成,进程守护、开机自启、异常重启这些才是真正保证“长期在线”的关键。
4.1 云主机选型思路
选云主机时,我不是先选配置,而是先看 Agent 数量。下面这张表是我自己的经验参考:
| Agent 数量 | CPU 核数 | 内存 | 云盘大小 | 带宽 |
|---|---|---|---|---|
| 1 - 3 | 2 核 | 4G | 40G | 5Mbps |
| 4 - 8 | 4 核 | 8G | 80G | 10Mbps |
| 9 - 15 | 8 核 | 16G | 160G | 20Mbps |
如果跑的是分析类 Agent,需要频繁读写中间结果,云盘建议用固态盘。带宽不用太大,Agent 之间的内部消息不占带宽,主要流量是模型接口调用和日志上传。
系统镜像我推荐 Ubuntu 22.04,稳定且社区文档多。第一次用云主机时,我选了默认的最小镜像,结果发现连curl、git都没有,还得手动装,浪费时间。
4.2 安全组与防火墙配置
云主机一般靠安全组来控制外部访问。我的原则是只开放必须的端口:
- SSH 端口(默认 22,也可以改到非标准端口)
- OpenClaw 控制端口(比如 8080)
- 模型接口如果也在本机,不要对公网开放,只监听内网或回环地址
安全组里不要直接对0.0.0.0/0开放所有端口,尤其不要把调试端口暴露出去。我之前为了让本地调试方便,临时放过一个端口,结果第二天日志里全是被扫描的记录。
4.3 导入镜像并启动
云主机初始化完成后,进入项目目录:
cd /opt/openclaw docker load -i openclaw-demo.tar docker run -d --name openclaw-demo \ --env-file .env \ -p 8080:8080 \ -v /opt/openclaw/storage:/srv/openclaw/storage \ openclaw-demo:0.1这里我特意把/opt/openclaw/storage挂载出来,用来保存 Agent 运行时的持久化数据。这一步很重要:如果不挂载,容器一旦重建,所有历史数据都会消失。
启动后用docker ps看容器状态,再用curl http://127.0.0.1:8080/health探活。如果能返回OK,说明容器内部启动成功。
4.4 用 systemd 守护 OpenClaw
docker run -d只能保证容器在后台运行,但没法保证云主机重启后容器自动启动,也没法在容器异常退出后自动拉起。所以我把容器托管给 systemd。
新建一个 service 文件:
[Unit] Description=OpenClaw Agent Cluster After=network-online.target Wants=network-online.target [Service] User=openclaw Group=openclaw WorkingDirectory=/opt/openclaw ExecStartPre=/usr/bin/docker load -i /opt/openclaw/openclaw-demo.tar ExecStart=/usr/bin/docker run --rm --name openclaw-demo \ --env-file /opt/openclaw/.env \ -p 8080:8080 \ -v /opt/openclaw/storage:/srv/openclaw/storage \ openclaw-demo:0.1 ExecStop=/usr/bin/docker stop openclaw-demo Restart=always RestartSec=10 [Install] WantedBy=multi-user.target然后启用:
sudo systemctl daemon-reload sudo systemctl enable --now openclaw有几个小细节值得注意:
Restart=always表示无论容器怎么退出,systemd 都会重新拉起。RestartSec=10避免频繁重启导致日志刷屏。ExecStartPre里执行docker load,是为了保证镜像文件还在,如果镜像缺失会自动导入。
加了 systemd 之后,我就再也不用担心云主机重启导致 Agent 集群全部断线了。
5. 多 Agent 编排:配置文件里的角色、工具与通信
部署只是把地基打好,真正决定多 Agent 系统好用不好用的,是编排配置。OpenClaw 的所有 Agent 定义都在一个config.yaml里,结构清晰,但字段不少。
5.1 Agent 的角色定义
下面是我实际使用的一份简化配置:
version: 3 bus: type: memory max_queue: 2048 agents: - name: coordinator role: 主控 model: openclaw-coder-4 system_prompt: "你是任务分配员,负责拆解任务并汇总结果。" tools: [task_split, result_merge] - name: writer role: 写作Agent model: openclaw-text-4 system_prompt: "你负责生成文案,输出 Markdown。" tools: [doc_writer, seo_checker] - name: analyst role: 数据分析Agent model: openclaw-data-1 system_prompt: "你负责清洗数据和生成图表。" tools: [pandas_runner, chart_builder]每个 Agent 的核心字段是name、role、model和system_prompt。我建议给每个 Agent 设置明确的角色,不要共用同一个system_prompt。否则多个 Agent 会“互相抢活”,任务分配混乱。
5.2 工具挂载原则
tools字段决定了这个 Agent 能调用哪些能力。我踩过一个坑:为了让 Agent 功能强大,一开始把工具全部挂给每个 Agent,结果一个简单的写作任务也会触发数据分析工具,白白消耗了额外资源。
后来我遵循一个原则:最小权限挂载。主控 Agent 只挂任务拆分和结果汇总工具,文本 Agent 只挂写作相关工具,数据分析 Agent 只挂数据处理工具。这样不仅资源占用更少,各 Agent 的行为也更可预期。
5.3 Agent 间通信
同机部署时,bus.type: memory是最合适的选择。消息格式非常简单,OpenClaw 内部就是传递结构化消息:
{ "task_id": "t-20240612-001", "from_agent": "coordinator", "to_agent": "writer", "payload": "请生成一篇关于多Agent部署的实践总结", "timeout": 120 }如果你把 Agent 拆到多台机器上,那就需要把bus.type改成外部消息队列,但说实话,小型团队没必要一上来就搞这么复杂。先单机跑通,再考虑跨机扩展。
5.4 并发、超时与重试参数
下面是运行时参数示例:
runtime: task_timeout: 300 max_concurrency: 8 retry_times: 3task_timeout是单个任务的超时时间,单位秒。设置太短会导致复杂任务被误杀,太长会导致卡死任务占住资源。max_concurrency是全局并发数。我的经验是先从 CPU 核数 ×2 开始,观察内存和模型接口延迟再调整。retry_times是任务失败后的重试次数。重试不是越多越好,因为模型接口超时需要排查根因,单纯重试会放大压力。
这些参数一定要在本地压测后再固化到配置文件里。上云之后,模型接口的延迟可能和本地不同,参数要跟着调整。
6. 上线后的验证清单与故障排查记录
不要以为镜像启动了、systemd 配置好了就万事大吉。上线后的第一件事,是完整验证整条链路。
6.1 探活与健康检查
我习惯在部署完成后依次执行这几步:
openclaw status curl http://127.0.0.1:8080/health curl http://127.0.0.1:8080/metricshealth接口确认服务存活,metrics接口查看 Agent 数量、队列堆积、任务成功率。不要把这两步省略,很多问题在启动早期并不会暴露,但指标已经出现异常。
另外一个细节是检查日志。OpenClaw 默认会把日志输出到容器标准输出,用journalctl -u openclaw -f可以实时跟踪。如果日志能连续输出完整的任务流转记录,说明 Agent 通信链路是通的。
6.2 常见故障排查思路
这里把我在部署过程中遇到的几个高频问题整理成一张表:
| 现象 | 可能原因 | 处理思路 |
|---|---|---|
| 容器一直重启 | 启动命令参数错误或依赖缺失 | 先看journalctl -u openclaw -f,再手动运行容器排查 |
| 端口被占用 | 8080 被其他服务占用 | 换端口,或在 systemd 单元里调整-p参数 |
| 模型接口超时 | 网络不通或模型服务过载 | 在云主机上curl模型接口地址,确认连通性 |
| Agent 间消息丢失 | 队列大小不足或超时过短 | 调大max_queue,增加task_timeout |
| 内存持续上涨 | Agent 缓存积累过多 | 检查是否有长会话上下文常驻,定期重启 Agents |
我最想提醒的是:不要一上来就怀疑 OpenClaw 本身。大多数问题出在网络、端口、依赖、内存这些基础项上。先用openclaw doctor做一次全量自检,能排除 80% 的环境问题。
6.3 更新流程:新版本上线不中断
多 Agent 系统上线后,更新是绕不开的。我现在的更新流程固定为四步:
- 在本地更新代码和依赖,重新构建镜像并验证。
docker save导出新镜像,传到云主机。- 备份
/opt/openclaw/storage目录。 - 停掉 systemd 服务,重新 load 镜像再启动。
sudo systemctl stop openclaw sudo docker load -i openclaw-demo-0.2.tar sudo systemctl start openclaw这里要强调备份。Agent 的会话历史、记忆数据都在storage目录里,一旦丢失,整个系统等于失忆。我在一次更新时忘了备份,结果所有 Agent 的上下文历史全部清空,后续任务少了上下文,输出质量明显下降。
最后的实际操作体会
把 OpenClaw 从本地迁到云主机之后,我再也不用担心合盖断线、任务中断这类问题。整套流程走下来,最值得分享的心得是:不要急着上云,先把本地环境、依赖锁、配置外置这些基本功做扎实;上云后也别忘了用 systemd 把进程托管起来,否则一个重启就会让所有 Agent 回归起点。
另外一个小技巧:每次改动配置后,先在本地开一份一模一样的配置,连跑通三个任务再上云。我在云端踩过的坑,几乎都能在本地提前发现。多 Agent 系统部署不是一个“启动完就结束”的过程,它更像是在不断调整环境、参数和工具边界的过程中,逐步找到一套稳定运行的组合。有了这套组合,后面无论是扩容还是加 Agent,都只是改配置加机器的问题。