协作式多智能体操作系统

HiClaw 源码 × 部署 全景图

AgentScope 团队的开源 Multi-Agent OS,把 Higress AI 网关、Tuwunel Matrix 服务器、Element Web、MinIO 和 OpenClaw Agent 运行时**塞进单个 Manager 容器**,通过 docker.sock 动态拉起 Worker 容器,人类在 Matrix 房间里全程围观和介入。

4k+
GitHub stars
5
核心组件
19
安装状态机步骤
15
本文解析板块
本站不是官方文档 —— 是把 upstream 代码逐文件读完后写的解析,所有结论都附 file:line 引证。如果你只想看官方介绍去 higress.ai/hiclaw

01 这次怎么部的

用户的需求是部署到 VPS 但不能影响其他线上应用(同一台 VPS 跑着 Coolify + 10 个生产服务)。HiClaw 默认安装会挂载宿主 /var/run/docker.sock,等于宿主 root 权限 —— 直接装风险极大。

最终方案:LXC 系统容器隔离 + Coolify Traefik 反代 + nginx 路径改写

公网 https://hiclaw.kang-kang.com (Let's Encrypt)
        │
        ▼
┌─────────────────────────────────────────────────┐
│  VPS 76.13.31.179  Ubuntu 24.04 / 内核 6.8       │
│                                                  │
│  ┌──────────────────┐  ┌──────────────────┐    │
│  │  宿主 Docker      │  │  LXC 容器 hiclaw  │    │
│  │  (root)           │  │  (10.5.64.46)    │    │
│  │                   │  │  4 核 / 8GB      │    │
│  │ Coolify Traefik   │  │ nesting=true     │    │
│  │   ↓ labels        │  │                  │    │
│  │ hiclaw-traefik-   │  │ 内部 Docker 29.4 │    │
│  │   proxy (nginx)   │──┼─→ hiclaw-manager │    │
│  │                   │  │   (单镜像全家桶)  │    │
│  │ Gitea / SmartFile │  │   ├ Higress      │    │
│  │ Metabase / 等 9 个│  │   ├ Tuwunel      │    │
│  └──────────────────┘  │   ├ Element Web  │    │
│                         │   ├ MinIO        │    │
│                         │   └ OpenClaw     │    │
│                         │     ↓ docker.sock│    │
│                         │   worker-* (动态) │    │
│                         └──────────────────┘    │
└─────────────────────────────────────────────────┘
  

nginx 路径路由(让单域名同时承载 Element Web + Matrix Server)

HiClaw 的 Element Web config.json 把 homeserver 硬编码成 http://matrix-local.hiclaw.io:18080 —— 公网无法解析。我们用 nginx 在传输层"现场改写":

location = /config.json {
    proxy_pass http://10.5.64.46:18088;
    sub_filter_types application/json;
    sub_filter "http://matrix-local.hiclaw.io:18080"
               "https://hiclaw.kang-kang.com";
    sub_filter_once off;
}

# Matrix 服务器路径 -> Higress 网关(带原始 Host 头)
location ~ ^/(_matrix|_synapse) {
    proxy_pass http://10.5.64.46:18080;
    proxy_set_header Host matrix-local.hiclaw.io;
}

# .well-known matrix 服务发现 -> nginx 直接返回公网域名
location = /.well-known/matrix/client {
    return 200 '{"m.homeserver":{"base_url":"https://hiclaw.kang-kang.com"}}';
}

# 其他 -> Element Web
location / {
    proxy_pass http://10.5.64.46:18088;
}

关键:不需要新增 DNS 子域名,单 hiclaw.kang-kang.com 同时承载 Element Web 前端 + Matrix Server 后端 + Synapse 兼容路径 + 服务发现。

关键命令

# 1. 创建 LXC 容器(限资源 + 允许嵌套 Docker)
lxc launch ubuntu:24.04 hiclaw \
  -c security.nesting=true \
  -c limits.cpu=4 -c limits.memory=8GB

# 2. 容器内装 Docker
lxc exec hiclaw -- bash -c "curl -fsSL https://get.docker.com | sh"

# 3. 非交互式安装 HiClaw(必须强制 us-west-1 registry)
lxc exec hiclaw -- bash -c "
  HICLAW_NON_INTERACTIVE=1 \
  HICLAW_REGISTRY=higress-registry.us-west-1.cr.aliyuncs.com \
  HICLAW_LLM_PROVIDER=openai-compat \
  HICLAW_OPENAI_BASE_URL=https://api.poe.com/v1 \
  HICLAW_LLM_API_KEY=sk-poe-... \
  HICLAW_DEFAULT_MODEL=Claude-Sonnet-4.5 \
  HICLAW_LOCAL_ONLY=0 \
  bash hiclaw-install.sh manager
"

# 4. 立即打 clean-install 快照(随时回滚)
lxc snapshot hiclaw clean-install

# 5. 任何时候出问题,5 秒回滚
lxc restore hiclaw clean-install

02 安全模型 · 影响半径

为什么坚持 LXC 而不是直接装到宿主 Docker?因为 HiClaw 的 Worker 是动态创建的代码执行沙箱,Manager Agent 又是 LLM 驱动的 —— 一旦被 prompt 注入或 Worker 沙箱漏掉,挂载 docker.sock 等于把宿主 root 双手奉上。

受害对象裸装风险LXC 隔离后
Coolify 自身🔴 完全可控🟢 不可见
同机 9 个生产应用
Gitea / SmartFile / Metabase / Superset / DataEase / WiFi-Sense / AstrBot / Hermes / Open SWE
🔴 全部可炸🟢 不可见
宿主 root 文件系统🔴 可读写 /root/.ssh、/etc🟢 独立 rootfs
SSH / 网络配置🔴 可改🟢 命名空间隔离
CPU / 内存🟡 可耗光🟢 cgroup 限 4 核 8GB
LXC 内部 hiclaw + workers⚠️ 可炸(预期)

最坏情况下:LXC 内部全炸 → lxc restore hiclaw clean-install5 秒回滚到干净状态,VPS 上其他 9 个应用毫无察觉。

HiClaw 自己的安全设计(也不弱)

03 LXC 隔离技术 · 为什么不是 Docker-in-Docker

HiClaw 需要 docker.sock 来动态创建 Worker 容器。如果直接装在宿主 Docker 上,一个被 prompt 注入的 Manager Agent 就能控制宿主全部容器(包括 Coolify / Gitea / Metabase 等 10 个生产应用)。我们选了 LXC 系统容器作为沙箱层 —— 这不是"换一种 Docker",而是一种完全不同的隔离模型。

LXC vs Docker:两种容器,根本区别

Docker(应用容器)LXC(系统容器)
隔离粒度单个进程整个 Linux 系统(有自己的 init/systemd/网络栈/用户空间)
典型用途跑一个 nginx / 一个 Node 应用跑一台"虚拟机"(但共享宿主内核,比 KVM 轻)
能否嵌套 Docker需要 --privileged(危险)security.nesting=true(安全,AppArmor 保护)
文件系统overlay fs,跟宿主共享内核 + 部分挂载独立 rootfs,看不到宿主文件
网络docker0 桥接,跟宿主 Docker 共网络独立 lxdbr0 网桥,跟宿主 Docker 网络隔离
资源限制cgroup(可选)cgroup v2 强制 + 可配磁盘配额
快照/回滚无原生支持lxc snapshot / lxc restore,5 秒回滚整个"机器"
性能开销~0~0(不是虚拟机,没有 hypervisor)

本次部署的 LXC 拓扑

VPS 宿主机 (Ubuntu 24.04, 内核 6.8, 8 核 31GB)
│
├── Docker daemon (root)
│   ├── coolify-proxy (Traefik)
│   ├── coolify / coolify-db / coolify-redis
│   ├── gitea / smartfile / metabase / superset / ...
│   └── hiclaw-traefik-proxy (nginx, 仅做反代)
│
└── LXD 5.21.4 LTS (snap)
    └── LXC 容器: hiclaw
        ├── 独立 IP: 10.5.64.46 (lxdbr0)
        ├── limits.cpu = 4
        ├── limits.memory = 8GB
        ├── security.nesting = true (允许内部跑 Docker)
        ├── AppArmor profile: 自动加载
        │
        └── 嵌套 Docker daemon
            ├── hiclaw-manager (Manager 全家桶)
            ├── hiclaw-docker-proxy (安全代理)
            └── hiclaw-worker-* (动态创建)
  

关键:宿主 Docker 和 LXC 内的 Docker 是两个完全独立的 Docker daemon。LXC 内的 docker.sock 只能看到/控制 LXC 内的容器,宿主 Docker 对它完全不可见。

LXC 的 5 层安全边界

  1. Linux Namespaces(命名空间):LXC 容器有独立的 PID / Mount / Network / User / UTS / IPC namespace。容器内 ps -ef 看不到宿主进程,ip addr 看不到宿主网卡,ls / 看不到宿主文件系统。
  2. cgroup v2 资源隔离:硬限 CPU 4 核 / 内存 8GB。即使 HiClaw 起了 100 个 Worker,也不能超这个上限。宿主的 Coolify / Gitea 等不受影响。
    # 验证
    lxc config get hiclaw limits.cpu     # 输出: 4
    lxc config get hiclaw limits.memory  # 输出: 8GB
  3. AppArmor MAC(强制访问控制):LXD 自动为每个 LXC 容器生成 AppArmor profile,限制系统调用范围。即使容器内 root,也不能 mount 宿主文件系统、加载内核模块、修改 /proc/sys
  4. 独立网络栈(lxdbr0 NAT):LXC 容器通过 lxdbr0 桥接网络(10.5.64.0/24)上网,对外 NAT。它不在 Coolify 的 coolify Docker 网络里。宿主 Traefik 通过 IP 直连 LXC(nginx 反代 proxy_pass http://10.5.64.46:18088),但 LXC 无法反向访问宿主 Docker 网络内的容器。
  5. 快照回滚(灾难恢复):LXC 支持即时快照,当前有 3 个:
    快照名时间说明
    clean-install2026-04-09 15:47首次 install 后(域名未对)
    clean-fresh-2026-04-092026-04-09 17:47域名修正后(LLM 不通)
    working-gemini-2026-04-102026-04-10 04:18✅ Poe + Gemini 2.5 Pro,已验证可对话
    # 出事了?5 秒回到正常状态
    lxc restore hiclaw working-gemini-2026-04-10
    # 想从零重来?
    lxc restore hiclaw clean-install

为什么不用其他隔离方案

方案优点为什么没选
裸装宿主 Docker Coolify UI 能管 HiClaw 拿 docker.sock = root 权限,炸了拖累 10 个生产应用
Docker-in-Docker (DinD) 概念简单 需要 --privileged 才能跑 DinD,privileged 容器有已知逃逸漏洞,安全性不如 LXC
Rootless Docker(独立用户) 不需 LXC 文件系统不完全隔离,init/systemd 跟宿主混在一起,排查困难;无快照回滚
KVM 嵌套虚拟机 最强隔离(独立内核) 需要 VPS 开嵌套虚拟化,500MB+ 内存常驻,LXC 已经够安全
Sysbox(Nestybox) 无 privileged 的 DinD 需要额外安装 sysbox-runc,Ubuntu 24.04 兼容性不稳定

security.nesting=true 不危险吗?

这是最常被问的问题。security.nesting=true 允许 LXC 容器内跑 Docker,但它不等于 privileged:

Canonical/Ubuntu 官方文档明确表示:security.nesting=true 是 LXD 的标准功能,设计用途就是在 LXC 内安全地跑 Docker,不需要降低安全等级。

实测验证(本次部署的实际隔离效果)

# 从 LXC 内部能看到宿主 Coolify 容器吗?
$ lxc exec hiclaw -- docker ps
CONTAINER ID  IMAGE                  NAMES
9e2766a715b0  higress/hiclaw-manager hiclaw-manager
a1b2c3d4e5f6  higress/docker-proxy   hiclaw-docker-proxy
# 只看到 HiClaw 自己的容器 ✅

# 从宿主能看到 LXC 内的 Docker 容器吗?
$ docker ps | grep hiclaw
# 空 ✅ (宿主 Docker 看不到 LXC 内的)

# LXC 内能访问宿主的 Coolify 数据库吗?
$ lxc exec hiclaw -- curl -s http://172.17.0.1:8000/api/health
# 超时/拒绝 ✅ (网络隔离)

# LXC 内能读宿主的 /root/.ssh/ 吗?
$ lxc exec hiclaw -- ls /root/.ssh/
# 只有 LXC 自己的 .ssh ✅ (独立 rootfs)

LXC 运维要点(给未来自己看)

操作命令
查看容器状态lxc list
进入容器 shelllxc exec hiclaw -- bash
查看资源限制lxc config show hiclaw | grep limits
改 CPU 限制lxc config set hiclaw limits.cpu 6
改内存限制lxc config set hiclaw limits.memory 12GB
打快照lxc snapshot hiclaw <名字>
列出快照lxc info hiclaw | grep -A20 Snapshots
回滚快照lxc restore hiclaw <名字>
删除快照lxc delete hiclaw/<名字>
重启容器lxc restart hiclaw
停止容器lxc stop hiclaw
删除容器(慎!)lxc delete hiclaw --force
从主机传文件进去lxc file push <本地文件> hiclaw/<远程路径>
从容器拷文件出来lxc file pull hiclaw/<远程路径> <本地文件>
添加端口代理(主机→LXC)lxc config device add hiclaw myproxy proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:8080

04 ⚠ 调试实录:为什么 LLM 死活连不上

这是本次部署最痛的一段。表面看 HiClaw 装好了、Element Web 能登录、Manager Agent 在线 —— 但每次发消息,Manager 都返回一段 403 Forbidden HTML 给你,LLM 完全不工作。**根因排查花了 6 次尝试,前 5 次都修错了方向**。下面把整个过程写出来,供任何要在中国 VPS / 海外 VPS 部署 HiClaw 的人避坑。

结论先放:HiClaw 自带的 Higress AI 网关转发到任何 Cloudflare 防护的 LLM API(Poe / OpenRouter / Anthropic 等)时会被 Cloudflare 的 bot fight mode 拦截 —— **跟你的 IP / API key / User-Agent 都无关,被识别的是 Envoy 代理的 TLS JA3 指纹**。

Round 1:Manager 回了 403 cloudflare 给我

登录 Element Web 进 manager DM,发"你好" —— Manager 回:

403 <html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>cloudflare</center>
</body>
</html>

这个 HTML 不是 Manager 写的 —— 是 Manager 调用 LLM API 时收到的响应,被原样回显到聊天框里。注意 <hr><center>cloudflare</center> 这一行,**典型 Cloudflare 拦截页面**。

Round 2:误以为是 DM 白名单,发现根本没调到 LLM

查 OpenClaw 日志,看到这条:

matrix: blocked dm sender @admin:hiclaw.kang-kang.com
  (dmPolicy=allowlist, matchKey=none matchSource=none)

Manager 的 dmPolicy=allowlist 把我屏蔽了 —— 因为之前的安装用的是 matrix-local.hiclaw.io:18080 域名,白名单缓存了那个老 user_id,我重装到 hiclaw.kang-kang.com 后,新 user_id 不在允许列表里。

原因:HiClaw 的 manager-workspace 是主机挂载的目录(~/hiclaw-manager → /root/manager-workspace),重装 HiClaw 镜像不会清这个目录,白名单文件 openclaw.json 仍是老的。

修法:Python 读 openclaw.json,把 channels.matrix.dm.allowFromgroupAllowFrom 都改成新 user_id,然后重启 manager-agent。

d["channels"]["matrix"]["dm"]["allowFrom"] = ["@admin:hiclaw.kang-kang.com"]
d["channels"]["matrix"]["groupAllowFrom"] = ["@admin:hiclaw.kang-kang.com"]

白名单修好了,Manager 真的开始处理我的消息 —— **然后我看到了真正的 403**(上面 Round 1 那个),原来之前根本没走到 LLM 那一步。

Round 3:猜是 User-Agent 被 Cloudflare 拦了

查源码 manager/scripts/init/setup-higress.sh,发现 Higress AI 网关在转发 LLM 请求时强制注入了 User-Agent: HiClaw/v1.0.9 header:

# setup-higress.sh:278
. + {"headerControl":{
    "enabled": true,
    "request": {
        "add": [{"key":"user-agent","value":"HiClaw/${HICLAW_VERSION}"}]
    }
}}

"HiClaw/v1.0.9" 这种字符串典型机器人 UA,Cloudflare bot fight 必拦。我登录 Higress 控制台 API,把 UA 改成 Chrome:

curl -X PUT http://127.0.0.1:8001/v1/ai/routes/default-ai-route \
  --data '{"headerControl":{"request":{"add":[
    {"key":"user-agent","value":"Mozilla/5.0 (Macintosh; ...) Chrome/120.0.0.0 Safari/537.36"}
  ]}}}'

重测 —— **403 变成 421**!HTTP 状态变了,说明 UA 改对了一半。但 421 是什么?

Round 4:421 Misdirected Request → SNI 没设

421 Misdirected Request 是 Cloudflare 在 TLS SNI 跟 HTTP Host 头不匹配时返回的。意思是:"你跟我握手时说要去 A 服务器,但 HTTP 请求里写的是 B 服务器,我送错门了"。

查 Higress 的 service source 配置,发现 openai-compat 服务源:

{
  "name": "openai-compat",
  "type": "dns",
  "domain": "openrouter.ai",
  "port": 443,
  "protocol": "https",
  "sni": null  ← 问题!
}

SNI 是空的!Envoy 不知道 TLS 握手时该用什么 SNI,默认会用上游 IP,Cloudflare 收到 SNI=IP 而 Host=openrouter.ai → 421。

修法:PUT service source 把 sni 设成 openrouter.ai

Round 5:SNI 修好了,**又回到 403**

这次连 421 都没了,直接 403。但 UA 是 Chrome,SNI 是对的,IP 还是同一个 VPS —— 为什么直 curl 同样的 endpoint HTTP 200,经 Higress 转发就 403?

关键测试:

# 直 curl,UA 写成 HiClaw/v1.0.9 都行
$ curl https://openrouter.ai/api/v1/chat/completions \
    -H "User-Agent: HiClaw/v1.0.9" \
    -H "Authorization: Bearer sk-or-v1-..." \
    -d '{"model":"anthropic/claude-sonnet-4.5",...}'
HTTP 200 ✅ "Hello! How can I help you today?"

# 经 Higress 转发,UA 改成 Chrome 都不行
$ curl http://127.0.0.1:8080/v1/chat/completions \
    -H "Host: aigw-local.hiclaw.io" \
    -H "Authorization: Bearer ${GATEWAY_KEY}" \
    -d '{"model":"anthropic/claude-sonnet-4.5",...}'
HTTP 403 ❌ Cloudflare

同一台机器、同一个 IP、同一个 Cloudflare endpoint —— 唯一区别是请求的 TCP/TLS 客户端是 curl 还是 Envoy。

Round 6:真因 = TLS JA3 指纹

Cloudflare bot fight mode 的检测信号有 4 层,User-Agent 只是最弱的一层:

信号怎么伪装
L1User-Agent 字符串容易,改 header 就行
L2HTTP header 顺序 / 大小写中等,要劫持 HTTP 库
L3TLS ClientHello JA3/JA4 指纹极难,要 patch TLS 库
L4HTTP/2 帧顺序、SETTINGS 值更难,要 patch HTTP/2 实现

JA3 是 TLS 握手时 ClientHello 包的指纹(支持的 cipher suites 列表 + extensions 顺序 + supported groups 等的哈希)。**每个 TLS 库都有自己独特的 JA3** —— Chrome 的、curl 的、Go 的、Envoy 的、Java 的全都不一样。

Cloudflare 维护着一个常见 bot 的 JA3 黑名单。**Envoy/Istio 用的 BoringSSL 配置生成的 JA3 在黑名单里**(它跟 Istio 服务网格的标志性指纹太像了)。OpenRouter 和 Poe 都是 Cloudflare 客户,默认开了 bot fight,看到这个 JA3 直接 403。

所以无论你怎么改 User-Agent、Host、SNI,只要请求是 Envoy 发的,就会被打。

最终修法:Manager Agent 直连 LLM,绕过 Higress

HiClaw 的 OpenClaw 运行时是 Node.js 写的,它通过 fetch()(用 undici)调用 LLM。Node.js 的 TLS 是 OpenSSL,JA3 跟 Chrome 接近,Cloudflare 不拦。

本来 OpenClaw 的 baseUrl 指向 Higress(http://aigw-local.hiclaw.io:8080/v1),Higress 再转发到真 LLM。如果让 OpenClaw 的 baseUrl 直接指向 https://openrouter.ai/api/v1,Higress 就不参与了,Cloudflare 认得 Node.js 的握手,放行。

问题是 HiClaw 的启动脚本 start-manager-agent.sh 在每次启动时会用 jq 重写 openclaw.json,把 apiKey 强制设回 Higress gateway key,把 baseUrl 留在 Higress URL。我手动 patch 一次,下次重启就被覆盖。

**永久修法**:在容器内 patch start-manager-agent.sh 的 jq 重写逻辑。原本是:

# 原始
jq --arg key "${HICLAW_MANAGER_GATEWAY_KEY}" '
  ...
  | .channels.matrix.accessToken = $token
  | .models.providers["hiclaw-gateway"].apiKey = $key
'

改成:

# patched
jq --arg key "${HICLAW_LLM_API_KEY}" '
  ...
  | .channels.matrix.accessToken = $token
  | .models.providers["hiclaw-gateway"].apiKey = $key
  | .models.providers["hiclaw-gateway"].baseUrl =
      (env.HICLAW_OPENAI_BASE_URL // .models.providers["hiclaw-gateway"].baseUrl)
'

两点改动:

  1. --arg key 从 Higress gateway key 改成真实的 LLM API key(HICLAW_LLM_API_KEY)—— 这样 Manager 调用 OpenRouter 时直接带正确凭证
  2. 新增一行 baseUrl = env.HICLAW_OPENAI_BASE_URL —— 让 baseUrl 指向真实 LLM 服务而不是 Higress 内部域名

重启 Manager,验证 openclaw.json:

$ docker exec hiclaw-manager python3 -c '
import json
d = json.load(open("/root/manager-workspace/openclaw.json"))
p = d["models"]["providers"]["hiclaw-gateway"]
print("baseUrl:", p["baseUrl"])
print("apiKey :", p["apiKey"][:30])
'
baseUrl: https://openrouter.ai/api/v1
apiKey : sk-or-v1-f93aa03f77794c37fbeed

然后浏览器发"你好",Manager 真实回了:

我已上线,随时可以帮你创建 Worker、分配任务、管理项目 — 试试给我一个任务?🚀

Claude Sonnet 4.5 自然中文,带 emoji,**完整 LLM 输出**。✅

跳过 Higress 的代价(诚实地讲)

失去影响
Higress AI Gateway 的 rate limiting个人用无所谓;团队用要靠 OpenRouter 自身 rate limit
多 provider 路由(自动 failover、模型映射)切模型现在要改 env + 重启,不能在 Higress 控制台里点
key 隔离(每个 Worker 一个 consumer)所有 Worker 共享同一个 OpenRouter key,账单看不出谁花的
请求日志(Higress 控制台)要在 OpenRouter dashboard 看

对单人用 / 实验场景,这些都可以接受。多租户生产环境就别这么干了 —— 那种情况下应该自建一个 LLM 代理网关(LiteLLM ProxyOne API)替代 Higress AI Gateway,这两个产品的 TLS 握手是 Python/Go 标准库,不被 Cloudflare 拦。

避坑 checklist(给后人)

  1. 用海外 VPS 装 HiClaw,务必加 HICLAW_REGISTRY=higress-registry.us-west-1.cr.aliyuncs.com(默认按时区会选 cn-hangzhou,被阿里云防火墙阻断)
  2. 装完后第一次发消息前先看 OpenClaw 日志的 dmPolicy,确认 admin 在 allowFrom 里(尤其重装过的)
  3. 不要用 Poe API / OpenRouter / 任何 Cloudflare 防护的 LLM —— 通过 Higress AI Gateway 一定会被拦,跟 IP/UA/key 都无关
  4. 能用的 LLM provider:Anthropic 直接 API、OpenAI 直接 API、DeepSeek 直接 API、阿里云 Bailian、自建 LLM
  5. 非要用 Cloudflare 防护的 → 必须 patch start-manager-agent.sh 让 Manager 直连(代价见上表)
  6. Higress AI Gateway 在国内有 LLM 服务的场景下是个好东西(多模型路由 + key 管理),但出了国就是定时炸弹

修复时间线

时刻事件状态
2026-04-09 15:36 UTC第 1 次 install,默认域名 matrix-local.hiclaw.io✅ Manager 起来,但只能本机访问
17:24重装,改 HICLAW_MATRIX_DOMAIN=hiclaw.kang-kang.com✅ 公网域名 user_id
17:32浏览器发"你好",Manager 回 403 Cloudflare❌ LLM 不工作
17:40定位到 dmPolicy 白名单老缓存,patch 修好⏩ Manager 真的开始处理消息
17:52切到 OpenRouter(因为 Poe 也被拦),还是 403
18:13读 setup-higress.sh,发现 User-Agent 注入🔍 找到伪嫌疑
18:33改 UA 为 Mozilla/Chrome → 421 Misdirected⏩ 进一步
18:35service source 设 sni=openrouter.ai → 又 403🤯 矛盾
18:38对比直 curl(200)vs 经 Higress(403),定位 TLS JA3💡 找到真因
18:45patch start-manager-agent.sh 跳过 Higress,Manager 直连 OpenRouter✅ 成功
18:50Matrix 发消息,Manager Claude Sonnet 4.5 正常回复✅✅✅

总耗时:从发现问题到修好约 75 分钟。其中大约 40 分钟花在错误方向(改 UA、改 SNI、查路由配置),后 35 分钟读源码 + 直连测试 + patch。**真正能加速这种调试的只有一句话:出现奇怪的 403 / 421 时,先做"直 curl vs 经代理"的对比测试,把代理隔离出来**。

05 install.sh · 19 步状态机

官方安装脚本 install/hiclaw-install.sh 2819 行,核心是个 19 步状态机,支持按 b 回退到上一步。每一步既收集配置又即时验证。

#step 函数关键变量作用
1step_langHICLAW_LANGUAGEen / zh / ja
2step_modeHICLAW_MODElocal / aliyun(SAE 云)
3step_versionHICLAW_VERSION固定版本或 latest
4step_existing检测已有配置,询问覆盖/升级
5step_llmHICLAW_LLM_PROVIDER
HICLAW_DEFAULT_MODEL
HICLAW_LLM_API_KEY
qwen 或 openai-compat,本次我们选 openai-compat 接 Poe API
6step_adminHICLAW_ADMIN_USER
HICLAW_ADMIN_PASSWORD
admin 账户(默认自动生成 16 位密码)
7step_network检测 DNS / 公网
8step_portsHICLAW_PORT_GATEWAY/CONSOLE/ELEMENT_WEB暴露端口 18080/18001/18088
9step_domainsHICLAW_MATRIX_DOMAIN
HICLAW_MATRIX_CLIENT_DOMAIN
HICLAW_AI_GATEWAY_DOMAIN
HICLAW_FS_DOMAIN
HICLAW_CONSOLE_DOMAIN
5 个内部域名(默认 *-local.hiclaw.io,公网部署需替换)
10step_githubHICLAW_GITHUB_TOKEN可选,用于 Worker MCP 调用 GitHub
11step_skillsHICLAW_SKILLS_API_URL技能市场(Nacos)
12step_volumeHICLAW_DATA_DIR持久化 docker volume
13step_workspaceHICLAW_WORKSPACE_DIR主机挂载的 Manager 工作区(默认 ~/hiclaw-manager)
14step_manager_runtimeHICLAW_MANAGER_RUNTIMEopenclaw(Node.js,500MB)或 copaw(Python,150MB)
15step_runtimeHICLAW_DEFAULT_WORKER_RUNTIME同上,但是 Worker 默认
16step_e2eeHICLAW_MATRIX_E2EEMatrix 端到端加密(默认关)
17step_docker_proxyHICLAW_DOCKER_PROXY
HICLAW_PROXY_ALLOWED_REGISTRIES
启用 docker-proxy 安全层(默认开)
18step_idleHICLAW_WORKER_IDLE_TIMEOUTWorker 空闲超时(默认 720 分钟)
19step_hostshareHICLAW_HOST_SHARE_DIR主机文件共享目录(挂载到容器 /host-share)

非交互模式 HICLAW_NON_INTERACTIVE=1 下,所有 step 跳过询问直接用 env 变量,适合 CI / 自动化部署。install/hiclaw-install.sh:2071-2167

06 整体架构

HiClaw 由 5 个核心组件构成,Manager 是单镜像全家桶(由 supervisord 编排 5 类进程),Workers 是动态拉起的轻量沙箱。

        ┌───── 人类(Element Web)
        │
        ▼ Matrix 协议
┌────────────────────────────────────────────────────┐
│  Manager 容器(单镜像,supervisord 编排)              │
│                                                     │
│  ┌──基础设施层────┐  ┌──网关层────────┐            │
│  │ Tuwunel :6167 │  │ Higress :8080  │ ◀─── LLM 出站│
│  │ MinIO :9000   │  │ apiserver :8001│             │
│  └────────────────┘  │ controller    │             │
│         ▲             │ pilot         │             │
│         │             │ console       │             │
│  ┌──应用层───────┐  └────────────────┘            │
│  │ Element Web   │         ▲                       │
│  │   :8088       │         │                       │
│  │ mc-mirror     │  ┌────────────┐                 │
│  │ hiclaw-       │  │ OpenClaw / │                 │
│  │   controller  │  │ CoPaw      │                 │
│  └────────────────┘  │ Agent      │                 │
│                      └────────────┘                 │
│                            │ docker.sock           │
└────────────────────────────┼───────────────────────┘
                             │ via docker-proxy
                             ▼
        ┌────────────┐  ┌────────────┐  ┌────────────┐
        │ worker-    │  │ worker-bob │  │ worker-... │
        │ alice      │  │            │  │            │
        │ (无状态)    │  │            │  │            │
        └────────────┘  └────────────┘  └────────────┘
                ▲               ▲
                │ MinIO mc mirror(双向)
                ▼
        ┌──────────────────────────┐
        │ MinIO bucket: hiclaw-fs/ │
        │  agents//...       │
        │  shared/tasks/...        │
        │  shared/projects/...     │
        └──────────────────────────┘
  

1. Manager 容器(全家桶)

OpenClaw/CoPaw Agent + Higress 网关 + Tuwunel Matrix + Element Web + MinIO,supervisord 按 priority 50→800 启动 5 个层次

2. Worker 容器(无状态)

启动时从 MinIO 拉所有配置,运行时双向同步,容器随时可销毁重建,状态零丢失

3. hiclaw-controller

Go 写的 K8s 风格 operator,用嵌入式 kine + kube-apiserver,通过 YAML 声明式管理 Worker/Team/Human 三个 CRD

4. docker-proxy

Go 写的 docker.sock 代理,镜像白名单 + 容器策略 + 能力检查,Manager 不直接碰 docker.sock

5. install.sh

2819 行 Bash 状态机,19 个 step,支持本地 / 阿里云 SAE 双模式,非交互可 CI

07 Manager 一体化容器

看见"Manager 容器内同时跑 Higress + Tuwunel + Element Web + MinIO + Agent"第一反应:这违反 Docker "一个容器一个进程"原则。但 HiClaw 选择这么做有道理:对单机部署用户来说,这是开箱即用 vs 编排 5 个 service的取舍。

supervisord 编排 5 个层次

boot 顺序由 priority 字段控制 manager/supervisord.conf:1-143:

Priority进程端口
50基础设施MinIO9000 / 9001
100Tuwunel(Matrix)6167(内部)
200Higress 网关apiserver8001 内部
300controller
400pilot
500gateway8080 主入口
600console8001 Web UI
650应用Element Web(nginx)8088
700mc-mirror(MinIO 同步)
750hiclaw-controller6443 内部
800manager-agent(OpenClaw/CoPaw)

对外只暴露 4 个端口:18080(网关)、18001(控制台)、18088(Element Web)、18888(Manager 控制台,本地),通过 install.sh 的 step_ports 配置 install/hiclaw-install.sh:2491-2514

OpenClaw 镜像构建(关键源码)

# openclaw-base/Dockerfile:54-67
RUN git clone --depth 1 -b hiclaw-v1 \
    https://github.com/johnlanni/openclaw.git /opt/openclaw && \
    cd /opt/openclaw && \
    pnpm install && pnpm build && \
    # 验证 matrix-sdk-crypto 原生模块
    test -f packages/clawdbot/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/matrix-sdk-crypto.linux-x64.node

OpenClaw 是 HiClaw 的 fork(johnlanni/openclaw#hiclaw-v1),不是原版。HiClaw 通过 shell skill 框架扩展其能力,避免了 fork 维护负担。

08 OpenClaw vs CoPaw · 双运行时

HiClaw 支持两种 Agent 运行时,功能和资源各有取舍 manager/scripts/init/start-manager-agent.sh:1-150:

OpenClaw 默认

  • 语言:Node.js
  • 体积:~500MB
  • Matrix:原生支持(@matrix-org/matrix-sdk-crypto-nodejs 含 E2EE)
  • 编译来源:johnlanni/openclaw#hiclaw-v1 commit 86dad13
  • 启动器:验证 matrix-sdk-crypto.linux-x64.node 原生模块存在 openclaw-base/Dockerfile:54-80
  • 适用:生产 / 完整功能

CoPaw 轻量

  • 语言:Python(基于 AgentScope)
  • 体积:~150MB
  • Matrix:无原生支持,通过 matrix-nio[e2e] + 自定义 channel copaw/src/copaw_worker/matrix_channel.py
  • 依赖:copaw==0.0.5, matrix-nio[e2e], markdown-it-py copaw/pyproject.toml:12-17
  • 配置桥接:启动时自动 bridge_openclaw_to_copaw(),把 openclaw.json 转 CoPaw 的 config.json + providers.json
  • 适用:边缘 / 资源受限场景(树莓派等)

09 hiclaw-controller · K8s 风格声明式

这是 HiClaw 最有意思的组件之一:把整个 Kubernetes 控制平面塞进单个 Go 二进制,然后用它来 watch YAML 文件管理 Worker。

架构

3 个 CRD

// hiclaw-controller/api/v1beta1/types.go:15-75
type Worker struct {
    Spec WorkerSpec  // model, runtime, image, skills, mcp-servers, expose ports
    Status WorkerStatus  // phase, matrix-user-id, room-id, container-state
}
type Team struct {
    Leader string
    Members []string
    TeamAdmin string
    ChannelPolicy ChannelPolicy
}
type Human struct {
    MatrixID string
    Level int  // L1: DM 权限, L2: group room 权限
}

工作流

  1. 用户在 /root/hiclaw-fs/hiclaw-config/workers/alice.yaml 写 YAML
  2. file watcher 检测变化 → 解析 → import 到嵌入式 etcd
  3. controller-runtime reconcile loop 触发
  4. 调用 shell executor(本质是 create-worker.sh 等技能脚本)
  5. 结果写回 Worker.status

这相当于把 GitOps 工作流压缩到单容器内 —— 你可以用 kubectl get workers.hiclaw.io 操作 hiclaw-controller,完全跟操作真 K8s 集群一样。hiclaw-controller/cmd/controller/main.go:25-140

10 docker-proxy · 安全隔离层

Manager Agent 是 LLM 驱动的,理论上可被 prompt 注入。如果它直接 docker.sock,等于"恶意 prompt → 任意宿主命令"。docker-proxy 是 Go 写的 Docker API 中间层,做白名单和策略检查。

POST/DELETE 白名单 docker-proxy/main.go:18-25

镜像白名单 docker-proxy/security.go:1-100

isHigressRegistry(image)  // higress-registry-*.cr.aliyuncs.com/*
isLocalImage(image)       // hiclaw/*, hiclaw:latest
isLocalhostImage(image)   // localhost/*, 127.0.0.1/*
HICLAW_PROXY_ALLOWED_REGISTRIES // 用户自定义额外白名单

容器策略

设计哲学:既不信任 Manager Agent(可能被 prompt 注入),也不暴露完整 Docker API。安全验证在代理层,不依赖 Agent 的"诚实"。

11 Worker 生命周期 · 全程拆解

Worker 是完全无状态的容器,所有配置和记忆存在 MinIO,启动时拉取,运行时同步。这让 Worker 可以随时被销毁、重建、跨机迁移,代价是启动慢一点(要 mc mirror)。

worker-entrypoint.sh 6 步启动 worker/scripts/worker-entrypoint.sh:1-150

  1. 设置时区(从 TZ env 读)
  2. 配置 mc 别名:本地模式直接 mc alias set,云模式调用 ensure_mc_credentials 刷新阿里云 STS 临时凭证
  3. 拉取 Worker 配置(重试 6 次,每次 5s):
    mc mirror "${HICLAW_STORAGE_PREFIX}/agents/${WORKER_NAME}/" \
              "${WORKSPACE}/" \
              --exclude ".openclaw/matrix/**" \
              --exclude ".openclaw/canvas/**"
  4. 符号链接:把 workspace 目录链接成 HOME,让 OpenClaw 读 ~/.openclaw/openclaw.json
  5. 启动 file-sync 后台进程:周期性双向 mc cp(增量)
  6. 启动 OpenClaw / CoPaw

MinIO 文件架构

HICLAW_STORAGE_PREFIX/
├── agents/<WORKER_NAME>/
│   ├── openclaw.json        ← Manager 写,Worker 读
│   ├── SOUL.md              ← Worker 身份
│   ├── AGENTS.md            ← 行为指导
│   ├── skills/              ← 双向同步
│   ├── memory/YYYY-MM-DD.md ← Worker 写日记
│   ├── .openclaw/           ← session 状态(不同步)
│   └── credentials/         ← 凭证(不同步)
└── shared/
    ├── tasks/<id>/          ← Manager 和 worker 共享
    ├── knowledge/           ← 知识库
    └── projects/<id>/       ← 项目状态(plan.md 等)

12 Matrix 集成

HiClaw 用 Tuwunel(conduwuit fork,Rust 写的 Matrix 服务器)而不是 Synapse —— 性能更好、单二进制、无 Python 依赖。Manager 容器内嵌一个 Tuwunel 实例,所有 Agent 都注册在这里。

账户和房间

OpenClaw 的 Matrix 集成

来自 @matrix-org/matrix-sdk-crypto-nodejs 原生模块(支持 E2EE)。openclaw-base 镜像构建时验证原生模块存在 openclaw-base/Dockerfile:54-67。OpenClaw 内置 Matrix channel,自动同步加入房间、接收 @mention 消息触发 agent loop。

CoPaw 的 Matrix 集成(替代实现)

CoPaw 没有原生 Matrix 支持,通过自定义 channel 类继承 BaseChannel,使用 matrix-nio[e2e]copaw/src/copaw_worker/matrix_channel.py:1-100。支持 markdown → HTML 转换、斜杠命令(/message /history /new /clear)。

设计洞察:用 Matrix 协议而不是自建 IM 协议,极大降低维护成本 —— Element Web 直接用,移动端可用 FluffyChat / Element Mobile,联邦/E2EE 全免费。

13 LLM 调用全链路

用户在 Element Web 输入 → Manager 回复,中间 LLM 调用走的是 Higress AI Gateway(不是直接 OpenAI API)。

10 步调用链 manager/scripts/lib/gateway-api.sh:166-200

  1. 用户 Element Web 输入消息 → POST /_matrix/client/v3/sync
  2. Tuwunel 把消息广播到 Manager 所在 room
  3. OpenClaw 在 sync() 轮询里检测到 @manager mention
  4. 触发 agent loop:读 SOUL.md 构造 system prompt
  5. POST http://127.0.0.1:8080/v1/chat/completions
    Header:Authorization: Bearer ${HICLAW_MANAGER_GATEWAY_KEY}
  6. Higress 网关拦截 → 验证 key-auth → 查询 consumer → 检查路由权限
  7. 转发到配置的后端(Qwen/OpenAI/Anthropic/Poe...)
  8. 响应流式返回给 OpenClaw
  9. Agent 解析响应,可能调用 skill 脚本(如 create-worker.sh)
  10. 把结果作为新消息发回 Matrix room

多 provider 路由

# manager/scripts/lib/gateway-api.sh:129-147
# 列出所有 AI 路由
curl http://127.0.0.1:8001/v1/ai/routes -b ${HIGRESS_COOKIE_FILE}

# 给每个路由的 allowedConsumers 加白名单
curl -X PUT http://127.0.0.1:8001/v1/ai/routes/{route} \
  -d '{"authConfig": {"allowedConsumers": ["worker-alice", ...]}}'

关键:LLM provider 可以在不改 Agent 代码的前提下动态切换 —— 通过 Higress 控制台改路由配置即可。本次部署我们选 openai-compat + https://api.poe.com/v1,model = Claude-Sonnet-4.5,Higress 把 OpenAI 协议透传给 Poe,工作得很好。

14 MinIO · 单一数据源(SSOT)

HiClaw 把 MinIO 当成整个集群的唯一真相。Manager 和 Worker 之间不直接共享文件,全部通过 MinIO 中转,这是 Worker 无状态的前提。

同步策略

跨容器/跨机部署的关键

因为 MinIO 是唯一真相,理论上你可以把 Manager 跑在一台机器,Workers 跑在另外几台,只要它们都能访问同一个 MinIO 端点 —— 这是 HiClaw 支持云模式(SAE/Aliyun)的基础。本地模式下 MinIO 直接跑在 Manager 容器内。

15 技能系统 · 19 个 shell 技能

HiClaw Agent 的"工具"不是 LLM function calling 那种,而是一堆 shell 脚本。每个技能一个目录,带 SKILL.md(给 Agent 看)和 scripts/(给 shell 跑)。

典型技能目录

skills/worker-management/
├── SKILL.md              # 给 Agent 看:何时调用、参数、陷阱
├── skill.json            # 元数据(名称、描述、参数 schema)
├── scripts/
│   ├── create-worker.sh     # 创建 worker 全流程
│   ├── lifecycle-worker.sh  # 启停/空闲检测
│   └── push-worker-skills.sh
└── references/              # 长篇文档
    ├── create-worker.md
    └── lifecycle.md

核心 19 个技能 manager/agent/skills/

worker-management
创建/启停 worker
task-management
分配/记录任务
task-coordination
processing marker 防冲突
project-management
plan.md 维护
team-management
Team Leader
human-management
授权用户
channel-management
Room 权限
model-switch
切 Manager LLM
worker-model-switch
切 Worker LLM
mcp-server-management
MCP 服务器配置
hiclaw-find-worker
Nacos 市场搜索
git-delegation-management
git 委派
matrix-server-management
Tuwunel 管理
file-sync-management
MinIO 同步
mcporter
MCP tool 调用器
service-publishing
发布端口到 Higress

为什么是 shell 而不是 TypeScript/Python?
降低运维门槛 —— 任何会写 bash 的人都能加技能,不需要碰 Node.js 包管理器。SKILL.md 文档化 API 和陷阱,Agent 通过自然语言匹配 description 字段决定调用哪个技能。

16 心跳 · 自动停启 Worker

Manager 定期跑心跳检查 manager/agent/HEARTBEAT.md:1-195,7 步流程,核心是检测空闲 Worker 并自动停止以省内存,任务来时自动重启。

7 步心跳

  1. 初始化 state.json — 读 active_tasks 列表
  2. 检查 finite tasks — 对每个有限任务,lifecycle-worker.sh --action ensure-ready,Worker 没起就拉起,起好后 @mention 询问进度
  3. 检查 infinite tasks — 定时执行类(如"每小时检查邮件"),按 next_scheduled_at 触发
  4. 项目进度监控 — 遍历 plan.md,找出标 [~](进行中)的任务,Worker 没动就跟进
  5. 容量评估 — 计数 finite 任务数,识别空 Worker,建议 admin 创建新 Worker
  6. 容器生命周期 — 同步 Docker 状态到 lifecycle.json,空闲超时 → 自动 stop
  7. 汇总报告 — 把所有发现 DM 给 admin

空闲检测核心代码 manager/agent/skills/worker-management/scripts/lifecycle-worker.sh:200-300

_worker_has_finite_tasks() {
    # 查询 state.json,计 .active_tasks[] 中 assigned_to=worker 的有限任务数
}

# 无任务则记 idle_since,超时停止
if [ $idle_duration -gt $idle_timeout_minutes ]; then
    worker_backend_stop "$worker"
    _set_worker_field "$worker" "container_status" "stopped"
    _set_worker_field "$worker" "auto_stopped_at" "$(_ts)"
fi

空闲超时由 HICLAW_WORKER_IDLE_TIMEOUT 控制,默认 720 分钟(12 小时)。下次任务分配时,ensure-ready 会先 docker start 把停掉的 worker 拉回来,对用户透明。

17 凭证 · 入口 · 管理命令

主入口https://hiclaw.kang-kang.com
登录admin / admina1947bbdaac8
LLMPoe API → Claude-Sonnet-4.5(可在 Higress 控制台改)
VPS76.13.31.179(Ubuntu 24.04 / 8 核 31GB)
LXC 容器hiclaw · IP 10.5.64.46 · 限 4 核 8GB
反代容器hiclaw-traefik-proxy(nginx:alpine,joins coolify network)
nginx 配置/opt/hiclaw-proxy/nginx.conf
HiClaw 数据卷LXC 内 docker volume hiclaw-data
Manager workspaceLXC 内 /root/hiclaw-manager
快照clean-install(2026-04-09 15:47 UTC)

常用运维命令

# SSH 进 VPS
ssh root@76.13.31.179

# 进 LXC
lxc exec hiclaw -- bash

# 看 HiClaw 内部容器状态
lxc exec hiclaw -- docker ps

# 看 Manager 日志
lxc exec hiclaw -- docker logs -f hiclaw-manager

# 重启 LXC(包括内部所有 HiClaw 容器)
lxc restart hiclaw

# 改 nginx 反代配置后必须 down/up(bind mount inode 问题)
cd /opt/hiclaw-proxy && docker compose down && docker compose up -d

# 一键回滚到干净状态
lxc restore hiclaw clean-install

18 源码地图

所有引证都对应 github.com/agentscope-ai/HiClaw 仓库。

install/hiclaw-install.sh2819 行,19 步状态机安装器
manager/DockerfileManager 全家桶镜像构建
manager/supervisord.conf5 层进程编排
manager/agent/SOUL.mdManager 身份和行为规范
manager/agent/HEARTBEAT.md7 步心跳流程
manager/agent/skills/*/19 个核心技能(shell)
manager/scripts/init/start-*.sh各服务启动脚本
manager/scripts/lib/gateway-api.shHigress 网关 API 调用
manager/scripts/lib/container-api.shdocker.sock / docker-proxy 调用
worker/DockerfileWorker 镜像(基于 openclaw-base + mc)
worker/scripts/worker-entrypoint.shWorker 6 步启动
openclaw-base/DockerfileOpenClaw 编译基础镜像
copaw/src/copaw_worker/Python 替代运行时
copaw/src/copaw_worker/matrix_channel.pymatrix-nio 自定义 channel
hiclaw-controller/cmd/controller/main.go嵌入式 K8s 控制平面
hiclaw-controller/api/v1beta1/types.goWorker/Team/Human CRD 定义
docker-proxy/main.godocker.sock HTTP 代理
docker-proxy/security.go镜像白名单 + 容器策略