先说一个我这段时间被问得最多的问题:OpenClaw 部署的时候到底该用哪种 runtime?很多人把 runtime 理解成“安装方式”,选一个能跑就行。但等你真的把 agent 接入到不同设备、不同算力环境,就会发现 runtime 的选择直接影响工具权限、模型接法、skill 加载方式,甚至连日志都存在不同位置。这篇是“理解 Harness 系列”的收尾,上一期聊了 harness 的基本概念、agent 与工具集的边界,这一期专门把 OpenClaw Agent runtimes 的下半场讲透:桌面与服务器部署、Termux 移动端、Ollama 与 DeepSeek 算力接驳、skill 内网化部署,以及 ROSClaw 连接机器人的场景。
如果你正在做 agent 选型,或者已经照着仓库 README 装到一半被各种报错卡住,这篇文章应该能帮你把“为什么这么设计”和“实际该怎么配”一次性对齐。
1. Runtime 在 OpenClaw 架构中的真正定位
在聊具体部署之前,我想先把“runtime 到底管什么”这件事说清楚。因为只有理解了 runtime 在整个 harness 体系里的位置,你后面配置的时候才知道哪些参数是关键,哪些只是在抄作业。
1.1 Harness、Agent、Runtime 的分工
很多刚接触 agent 开发的人会把这三个词混着用,但它们其实是三个层次。
- Harness:承载 agent 逻辑的脚手架,负责把模型能力、工具调用、上下文窗口、记忆策略组织起来。你可以理解为“让模型会干活”的那套规则系统。
- Agent:基于 harness 跑出来的具体智能体,有身份、有工具集、有行为策略。
- Runtime:agent 程序实际运行的操作环境,决定进程怎么被拉起、网络怎么访问、文件系统怎么隔离、算力从哪里来。
用一个不那么严谨但很好记的类比:harness 是汽车的底盘和转向逻辑,agent 是坐在驾驶位上的司机,runtime 则是你把它开在高速、市区还是越野路面的那个“路况”。同一辆车、同一个司机,路况不同,跑法完全不同。
OpenClaw 把 runtimes 设计成多个入口,根本原因也在这里——同一个 agent 工程,既可以在服务器上做 7x24 常驻任务,也可以在手机上当作随身助手,甚至可以塞进机器人,通过 ROS 话题去控制机械臂。每一种场景对进程生命周期、网络策略、工具权限的要求都不一样,硬要用一种方式套所有场景,反而会把系统做得又重又危险。
1.2 进程视角看 Runtime 的差异
如果你从操作系统的角度看,runtime 之间的差异会非常直观。
在 Linux 服务器上,OpenClaw 通常以守护进程方式运行,由 systemd 管理,崩溃了自动重启,日志写到 journald,每次会话之间状态可以持久化。这种 runtime 适合做定时任务、知识库处理、邮件自动化这类需要长期驻守的工作。
在 Windows 桌面场景里,用户更习惯有界面、托盘图标、可视化配置入口。OpenClaw 的做法是拆出一个 Companion 进程,负责处理图形界面、剪贴板、系统通知这类“桌面能力”,而核心 agent 逻辑仍然通过本地服务接口与它通信。这样做的好处是,agent 的核心引擎可以保持跨平台一致,桌面相关能力被隔离在单独模块里,未来如果接入手机、平板,不需要重写核心。
到了 Termux 这类移动端 runtime,进程生命周期变得很被动。Android 系统随时可能因为内存紧张把后台进程杀掉,所以移动端 runtime 需要额外处理会话持久化、唤醒机制、断线重连。同样一套 agent 工具,在服务器上可以“放弃进程等重启”,在手机上就不能这么干。
1.3 你现在能用到的几类 Runtime
根据我实际接触到的配置情况,OpenClaw 相关的 runtime 可以大致分成四类:
| Runtime 类型 | 典型环境 | 适合场景 |
|---|---|---|
| 服务端 daemon | Linux / Docker | 常驻任务、自动化流程、团队共享 agent |
| 桌面端 Companion | Windows / macOS | 个人办公助手、GUI 集成、本地文件操作 |
| 移动端 runtime | Android + Termux | 随身查询、临时任务、边缘节点 |
| 机器人桥接运行时 | ROS2 + Gazebo | 机械臂控制、仿真验证、物理世界交互 |
这四类不是互斥的。实际项目中常见做法是:服务端跑一个核心 daemon,Windows 电脑上通过 Companion 接入,手机通过 Termux 作为远程客户端或独立节点,机器人场景再叠加 ROSClaw 桥接。后面我会逐个讲部署和配置要点。
2. OpenClaw 为什么坚持用 Rust 作为运行时底座
说完了 runtime 是什么,下一个绕不开的问题是:为什么 OpenClaw 选择用 Rust 而不是 Python、Go 或者 Node 来构建这些运行时?
这个问题在社区里争论很多。我的观点是,选 Rust 不是情怀,而是这套架构需求的必然结果。
2.1 性能与并发的硬要求
Agent 运行时和普通后端服务有个显著区别:它在单次任务里可能需要并发调度多个工具调用。比如一个“查资料并写周报”的任务,可能要同时发起搜索、读取文件、调用模型接口、写入本地数据库。Python 在这类场景里不是不能做,但 GIL 和进程模型会带来额外的调度成本。
Rust 的异步生态(tokio 为主)让每个工具调用可以以极轻量的 task 方式并发执行。实测下来,在同样配置的机器上,Rust 版本的运行时在高并发工具调用场景下延迟抖动明显更小。对于 agent 来说,每一次工具调用的延迟都会叠加到用户体感上,这个差异不能忽视。
2.2 单二进制分发的红利
另一个非常实际的原因是分发部署。
Rust 编译出来的产物是一个静态链接的二进制文件,不依赖目标机器上的 Python 版本、Node 环境、动态链接库。我在内网服务器上部署的时候,只需要把编译好的文件传上去,加一个执行权限,然后写好配置文件就能直接跑。对比 Python 项目常见的“虚拟环境 + requirements + 版本冲突”那一套,维护成本低非常多。
这里尤其要提一下交叉编译的价值。Rust 工具链可以很方便地从一台 x86 的构建机编译出 ARM64 版本,直接部署到树莓派、安卓 Termux 或者嵌入式设备上。如果你打算把 agent 部署到机器人或者边缘设备,这个能力几乎是刚需。
2.3 内存安全与被攻击面
Agent 运行时是要和外部工具、文件系统、网络频繁打交道的,安全优先级天然比普通 Web 服务高。Rust 的所有权机制在编译期就消除了大量空指针、野指针、缓冲区溢出这类问题,这意味着很多攻击路径在编译阶段就已经不存在了。
我不是说 Rust 写的程序绝对安全,但对比 C/C++ 这类需要手动管理内存的语言,Rust 能让你把更多精力放在业务逻辑和权限设计上,而不是在和内存 bug 搏斗。对于 agent 这种经常要执行外部命令、读取用户文件的系统,这个特性太重要了。
当然,Rust 也有它的代价。学习曲线陡、编译时间长、某些库生态不如 Python 成熟。但如果你是在做 agent 这种重工具、重并发的系统,我认为这些代价是值得付的。
3. 主流 Runtime 部署实操:Linux、Windows Companion 与 all-in-one 版本
理论知识补完之后,开始进实战。这一节先讲最常见的三类部署形态,如果你是从零开始,建议按顺序看完再动手。
3.1 Linux 服务端的标准部署路径
我在 Linux 服务器上部署 OpenClaw 的次数最多,流程也最稳定。大致分四步:
- 获取二进制或源码:你可以直接从发布页下载对应架构的编译产物,也可以 Git 克隆仓库后自行编译。生产环境我建议直接用发布产物,省时间。
- 初始化配置:第一次运行时会生成默认配置文件,里面包含模型 provider、工具启用列表、存储路径这些核心项。关键的环境变量包括模型接口地址、模型名称、允许的工具目录白名单。
- 配置 systemd 服务:让 agent 常驻后台,崩溃自动拉起。
[Unit] Description=OpenClaw Agent Daemon After=network-online.target [Service] User=openclaw ExecStart=/opt/openclaw/openclaw serve --config /etc/openclaw/config.toml Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target- 验证服务状态:启动后用
journalctl -u openclaw -f观察日志,确认能够正常拉取模型并响应指令。
这里有一个非常容易踩的坑:不要用 root 用户跑 agent 的服务进程。我之前为了省事直接用 root 运行,结果 agent 在执行文件工具时拥有整个文件系统的写权限,一旦 prompt 注入或者 skill 逻辑有漏洞,影响面会被放大到整台服务器。正确做法是单独建一个低权限用户,给 agent 一个专门的工作目录,只在这个目录里放开读写权限。
3.2 Windows Companion 的正确配置方式
Windows 桌面上跑 OpenClaw,官方推荐的方式是让核心引擎运行在本地服务端口,同时启用一个 Companion 进程来做图形界面和系统能力对接。
配置 Windows Companion 的时候,最核心的是理解它的端口和 Token 机制。Companion 和核心 daemon 之间通过本地 HTTP 通信,默认监听回环地址,Token 用于防止其他本地进程冒充客户端来调用 agent 能力。很多人卡在这一步,因为只配了端口没配 Token,结果一直报 401。
实际配置思路是这样:
- 核心 daemon 启动时,在配置里开启本地服务接口,记录下服务端口。
- 启动 Companion,填写或自动读取 daemon 地址与 Token。
- 在 Companion 界面里授权剪贴板、通知、屏幕捕获等能力。
- 测试时先跑一个简单任务,确认消息能到达 daemon 并返回结果。
桌面场景下,本地文件工具的权限设计要更小心。Windows 没有 Linux 那么细的用户隔离机制,agent 一旦获得权限,默认能读的范围非常大。我给的建议是,在配置文件中显式指定允许访问的目录,以及禁止执行的文件类型列表。比如可以允许读C:\Users\你的名字\Documents,但禁止读.ssh目录和浏览器保存的密码文件。
3.3 关于 all-in-one runtimes 2.5.0
最近社区里很多人问 all-in-one runtimes 2.5.0 到底是什么,这里统一解释一下。
简单说,这是一个把启动器、核心 daemon、skill 管理工具、Companion 打包在一起的集成发布包。目的很明确:让用户在安装的时候不需要分别处理各个模块的依赖,直接解压就能得到一个完整可用的 runtime 环境。
但请注意,all-in-one 不等于“只能单机运行”。它只是把各个模块在本地统一安装和管理。你完全可以在这套环境上配置本地模型端点,也可以把 skill 发布到内网服务器。all-in-one 解决的是“安装编排”问题,不限制你的算力来源和部署拓扑。
从我实际使用体验看,2.5.0 版本对新手最友好的一个改进是配置文件自带注释示例,默认情况下不需要太深的背景知识就能跑通第一个任务。但如果你需要做更精细的权限控制、多模型切换、离线部署,还是建议拆开理解每个模块的作用,不要把它当成一个黑盒。
4. 把 Agent 装进口袋:Termux 上运行 OpenClaw 的完整路径
手机跑 agent,听起来很极客,但实际用起来真香。通勤路上随手打开 Termux,让 agent 把今天的待办整理成表格、查一下某个服务的状态、或者在本地离线环境下完成一个文本处理任务,这些场景都成立。下面说操作。
4.1 为什么 Termux 能跑 Rust 编译的 Agent
Termux 是 Android 上的终端模拟器,它提供的用户空间里可以安装完整的编译工具链。因为 OpenClaw 是基于 Rust 的,而 Rust 可以交叉编译到 Android 支持的 ARM64 架构,所以理论上只要把编译好的二进制和依赖的动态库放进 Termux 环境,就能运行。
实际使用中需要注意,Termux 并不是完整的 Linux 发行版,缺少一些系统级服务,比如 systemd、用户管理。这意味着你不能用 Linux 那套“守护进程 + 自动重启”的模式来管理 agent,只能在前台启动或借助 Termux 的后台任务机制维持运行。
4.2 安装步骤要点
先给出一套我验证过的安装路径,然后逐个解释关键点。
# 1. 更新 Termux 软件源 pkg update && pkg upgrade -y # 2. 安装构建依赖 pkg install -y rust git binutils openssl pkg-config # 3. 克隆 OpenClaw 仓库 git clone [OpenClaw 仓库地址] # 4. 进入目录并编译 cargo build --release # 5. 初始化配置 ./target/release/openclaw init # 6. 启动 agent ./target/release/openclaw serve编译这一步在手机上会比较久,尤其老款机型。我自己的骁龙 870 机型编译 openclaw 核心工程,大概花了二十分钟左右。如果你不想在手机上编译,可以在电脑上交叉编译 ARM64 版本,然后通过adb push或网盘传到手机,再放进 Termux 目录并加执行权限。
有几个系统级的配置必须提前处理:
- 存储权限:Termux 默认只能访问自己的私有目录。如果你想让它读写手机的下载、文档这些公共目录,需要用
termux-setup-storage来授权。 - 后台保活:Android 系统为了省电,会把 Termux 的进程冻结或杀掉。你需要到系统设置里关闭电池优化,允许 Termux 在后台运行。这是手机端 runtime 能否长驻的关键。
- 唤醒锁:如果 agent 正在处理一个长任务,建议使用 Termux 的
termux-wake-lock命令,防止任务执行到一半屏幕熄灭后系统休眠。
4.3 手机运行时的性能与稳定性
性能方面,手机上跑模型推理不是完全不可能,但如果你用的是 7B 以上的模型,内存压力会非常大。我建议手机端 runtime 默认走“本地跑轻量模型或调用远程 API”的混合策略:日常文本任务用远程 API,遇到断网或者隐私数据场景,再切换成本地小模型。
稳定性上最大的敌人是系统杀进程。哪怕你已经关了电池优化,Android 在内存压力大的时候仍然可能回收后台进程。我的经验是给 Termux 进程加一个系统级的“可感知”机制——比如通过通知栏常驻提醒,让用户知道 agent 正在后台。另外,配置好 agent 的状态持久化,让进程重启后可以从最近的检查点继续,而不是从头再来。这样才能真正把手机变成 agent 的一个稳定运行节点。
5. 算力接驳:Ollama 本地推理与 DeepSeek API 的切换
评论区里一直有人问:OpenClaw 只能用接入 API 的方式使用算力吗?不是,这是一个流传很广的误解。OpenClaw 的算力接入层设计得比较开放,只要是兼容 OpenAI 协议的语言模型服务端点,都可以作为算力来源。
5.1 算力接驳的三种模式
我整理了三种最常见的算力模式,你可以看表格快速对照。
| 模式 | 模型服务地址 | 典型工具 | 适用场景 |
|---|---|---|---|
| 远程 API | 公网或云端 | DeepSeek API、OpenAI 兼容服务 | 追求模型效果、无需本地硬件 |
| 本地推理 | http://127.0.0.1:11434 | Ollama | 离线、隐私敏感、实验调试 |
| 内网模型服务 | http://内网IP:端口/v1 | vLLM、TGI、自建网关 | 企业内网、数据不出域 |
5.2 “只能用 API”这个误解是怎么来的
之所以有人觉得只能用 API,是因为很多配置教程顺着默认配置讲,默认指向的 provider 就是远程 API。如果你只需要填一个 API Key 就能跑通,根本不会去关注 base URL 这个字段。但实际上,模型接入的核心就两个参数:base URL 和 model name。你把 base URL 指向本地 Ollama 的地址,模型名改成你本地下好的模型,OpenClaw 就会走本地推理。
我自己在本地跑过一段时间,配置示例大概是这个样子:
llm: provider: openai-compatible base_url: "http://127.0.0.1:11434/v1" model: "qwen2.5:7b" api_key: "ollama" # Ollama 本地默认不校验 key,填任意占位字符串即可Ollama 的/v1端点就是为了兼容 OpenAI 协议而提供的,OpenClaw 通过标准协议调用时几乎不需要额外适配。你只需要确认 Ollama 已经拉取了对应模型并保持服务运行。
5.3 混合调度的实际配置思路
如果你既想用 DeepSeek API 做复杂推理,又想保留本地模型做简单任务,可以考虑在同一份配置里准备好两套参数,按需切换。更进阶的做法是,在 agent 的技能层面做调度——把不同难度、不同隐私等级的任务分流到不同模型。
举个例子,我有一个内网知识库问答 skill,数据本身敏感,我把它固定走本地 Ollama;而写代码、做总结这类对模型能力要求高的任务,我让它走 DeepSeek API。这样做的好处很明显:敏感数据永远不会出内网,同时复杂任务还能保持高质量。
需要特别提醒的是,切换模型 provider 之后,一定要检查工具描述和 prompt 是否兼容。不同模型对工具调用的指令遵循能力差异很大,有些 7B 模型在复杂工具选择上表现不稳定,任务失败率会明显上升。这属于模型能力的边界,不是运行时配置的问题。
6. 把 Skill 装在离线环境:DeepSeek Harness 附带 Skill 的内网部署
最近有人问“deepseek harness 附带 skill 怎么部署到内网服务器”,这个问题很典型。它涉及到两个关键点:一是 skill 的目录结构,二是模型算力的内网化。两者都做对了,你的内网 agent 才能真正跑起来。
6.1 Skill 到底是个什么东西
在 OpenClaw 这类 harness 架构里,skill 不是简单的“提示词文件”,它是一个自包含的模块单元,通常包含:
- 触发描述:说明什么情况下 agent 应该调用这个 skill。
- Prompt 模板:指导模型如何完成该任务的系统指令。
- 工具声明:说明需要调用哪些外部工具及参数格式。
- 脚本或资源文件:需要执行的 Python 脚本、参考文档、模板文件等。
Skill 的设计目标是把“某一类任务的处理方式”固化下来,让 agent 在遇到对应场景时能够按既定流程执行,而不是每次都从头推理。
6.2 内网部署的具体步骤
假设你已经在能上网的机器上拿到了 DeepSeek harness 附带的 skill 包,现在要把它部署到一台无法访问外网的内网服务器上,步骤可以拆成这样:
- 传递 skill 目录:把 skill 目录整体打包(注意包含隐藏文件),通过内部文件传输通道放到内网服务器指定位置。
- 导入并注册:在 OpenClaw 配置里指定 skill 的加载路径,重启服务。需要确认每个 skill 的资源文件路径不能被后续的权限沙箱屏蔽。
- 将模型端点指向内网服务:这是最关键的一步。编辑模型配置,把
base_url改成内网模型服务的地址。内网没有外网模型可用,必须确保模型服务本身可用,否则 agent 会陷入“有技能没脑子”的状态。 - 验证无外网依赖:检查 skill 里的脚本是否包含访问公网地址的逻辑。比如某些 skill 可能内置了请求外部 API 的代码,需要改成本地实现或删除该功能。
6.3 内网环境容易被忽略的权限边界
我遇到过好几次“部署成功后,agent 一调用 skill 就卡住”的情况。排查下来,很多时候不是 skill 逻辑错了,而是运行环境的权限或网络策略拦住了访问。
内网服务器的文件权限通常比个人电脑严格。比如 agent 进程如果是独立用户运行的,就要确认这个用户对 skill 目录里的脚本有“读 + 执行”权限,对需要临时生成的输出目录有“写”权限。这些权限如果没给对,表面上看一切正常,但调用时脚本会静默失败,非常消耗排查时间。
另外,skill 包里的密钥信息要格外小心。有些示例 skill 会自带一个config.example,里面可能有占位的 token。真正部署时要把密钥放到环境变量或单独的密钥管理服务里,不要明文写在 skill 文件里,尤其是内网会被多人访问的服务器。
7. 当 Agent 装上轮子:ROSClaw 与 ROS2 Humble、Gazebo 的集成
从纯数字世界走向物理世界,是 agent 最让人兴奋的方向之一。OpenClaw 在机器人场景的接入层叫 ROSClaw,它的目标非常明确:让 agent 能够通过 ROS2 的话题、服务、动作机制去感知和控制机器人。
7.1 ROSClaw 的定位与能力
ROSClaw 不是一个独立的 agent,它是 OpenClaw harness 与 ROS2 生态之间的桥接运行时。它负责做下面几件事:
- 把 ROS2 的话题数据转换成 agent 可理解的上下文。
- 把 agent 的工具调用转换成 ROS2 的服务请求或动作目标。
- 提供机器人状态反馈,让 agent 在任务执行过程中能够感知执行结果。
举例来说,你的 agent 可以订阅/camera/image_raw话题获取视觉数据,然后调用一个move_base服务让机器人导航到指定坐标,再通过/gripper/command发布夹取动作的指令。这一整套流程,本质上仍然是“模型 + 工具调用”,但工具的另一端是真实世界里的电机和传感器。
7.2 与 ROS2 Humble / Gazebo 的集成要点
我建议你在接触真实机器人之前,先在 Gazebo 仿真环境里把整套链路跑通。这样既不会撞坏设备,也方便调试参数。
安装配置上,ROSClaw 依赖你提前装好 ROS2 Humble。需要注意版本对齐,不同 ROS2 发行版之间的接口差异比较大,Humble 对应 Ubuntu 22.04,这是目前兼容性最稳的组合。
在launch层面,通常需要:
- 启动仿真环境:
gazebo.launch.py,加载你的机器人模型和传感器。 - 启动导航和运动控制节点:
nav2相关的 launch 文件。 - 启动 ROSClaw 桥接节点:把 agent 的工具层与 ROS 话题连通。
- 启动 OpenClaw 核心 daemon:agent 本体。
仿真联调时最常遇到的坑是时间同步。Gazebo 里的仿真时钟和真实系统的时钟如果不一致,agent 发布的导航指令可能被暂时丢弃。解决办法是让 ROSClaw 的桥接配置使用仿真时钟,并且在 agent 的超时设置里留足余量。
7.3 仿真里的安全策略
即使是在仿真环境里,我也强烈建议给 agent 托管机器人控制指令时加上一层“执行许可”机制。也就是 agent 生成的指令先进入一个审核队列,由策略节点确认目标位置、速度参数在安全范围内之后再放行。仿真环境验证这个机制,比实机上来就裸跑要稳妥得多。
说到底,让 agent 直接驱动真实电机,是自动化程度的进步,但同样也是责任边界的变化。把安全校验做成运行时的一部分,而不是等到出问题再补救,是我在机器人场景里最大的一个体会。
8. Agent 安全是 Runtime 设计的一部分,不是附加选项
最后单开一章聊安全,因为太多人把 agent 安全当成事后的防火墙,而不是运行时的一部分。这是不对的。一个能让模型调用工具的系统,它的安全边界在设计 runtime 的时候就必须想清楚。
8.1 命令执行是最大的风险敞口
Agent 最核心的能力是调用工具,而工具里最危险的就是命令执行类工具。一旦模型因为 prompt 注入或者推理偏差生成了一个恶意命令,在无约束的运行时环境里,损失可能是灾难性的。
我的建议是,任何命令执行类工具在运行时都必须经过一套强制检查,包括:
- 命令白名单:只允许执行预先批准的一批命令和参数,而不是整个 shell。
- 工作目录隔离:所有命令在指定工作目录下执行,禁止访问目录之外的资源。
- 超时控制:任何命令都不能无限期运行,必须有超时终止机制。
- 输出回传限制:命令输出的内容要经过过滤,避免内部敏感信息被不经思考地传给模型。
8.2 文件访问的最小权限原则
Agent 在处理本地文件时,天然需要读写能力。但请务必把这种能力限定在最小范围内。在配置文件中指定允许访问的目录白名单,而不是让它拥有整个文件系统的权限。
我自己现在的配置习惯是:一个独立用户、一个独立工作目录、所有文件工具只允许在这个目录内活动。如果需要访问外部数据,通过显式的副本或者导入流程完成,而不是直接放开读权限。这个习惯看起来繁琐,但当 agent 出现误操作时,它能帮你挡住绝大多数严重故障。
8.3 网络访问的收敛
Agent 的网络访问也需要收敛。内网部署时尤其明显,你肯定不希望 agent 既能访问内网敏感服务,又能绕过限制访问外网。建议在运行时层面配置网络白名单,明确允许连接的域名和 IP 段,其余一律拒绝。
另外,所有密钥类信息都应该通过环境变量或配置注入,不要直接写入到 skill 文件、日志文件或对话记录里。模型在处理上下文时,会把看到的敏感信息原样返回,这是很多人没意识到的泄密路径。做一次上下文内容审计,你会发现明文写在配置里的 token 有多危险。
如果你现在正在设计 agent 的运行时架构,我建议你拿出一张纸,把“工具的调用链路”完整画出来,从模型出参、工具解析、权限检查、命令执行、结果回传,到上下文记录,每一步都标出谁能访问、能访问什么。这张图就是你的安全基线。不要在 agent 跑起来之后再回来补安全,那时候付出的代价会高得多。