用 OpenClaw 搭建多 Agent 办公室:一个 SRE 的自定义实践

Kiyor
2026年03月01日 10:44
Show TOC

本文记录了我在一台 Mac mini 上,用 OpenClaw + Docker + 本地 GPU 搭建多 Agent 协作系统的过程。不是教程,是实践笔记。

为什么是 OpenClaw

作为 SRE,我对工具的要求很简单:可控、可观测、能自托管。市面上的 AI Agent 平台大多是 SaaS,数据在别人手里,扩展靠求人。OpenClaw 不一样——它是一个跑在本地的 Gateway,所有 Agent 的配置、记忆、行为都是文件,git diff 就能看到变化。

关键特性:

  • 多 Agent 原生支持:每个 Agent 独立 workspace、独立人格、独立模型
  • 多渠道接入:Telegram、Discord、Signal 等,一个 Gateway 统一管理
  • 文件即配置SOUL.md 定义人格,AGENTS.md 定义行为规范,MEMORY.md 是长期记忆
  • 工具系统可扩展:内置 Skill 机制,也可以通过 HTTP API 集成自建服务

架构总览

@startuml
!theme plain
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

cloud "Telegram" {
  [Telegram Bot] as TG
}

package "Mac mini (192.168.10.26)" {
  [OpenClaw Gateway\nport 18789] as GW

  package "Agents" {
    [未然 (main)\nClaude Opus\nOAuth Token] as Main
    [执行官 (intern)\nClaude Sonnet\nOAuth Token] as Intern
    [矿工 (gpu)\nQwen3 32B\nLocal Ollama] as GPU
  }

  package "Docker Services" {
    [Nginx (443)] as NGX
    [Agent Jira (8081)] as Jira
    [Memory Service (8084)] as Mem
    [Pixel Office (8082)] as Game
    [Prompt Manager (8083)] as PM
    [Dashboard (8080)] as Dash
  }
}

node "GPU Server (192.168.10.52)" {
  [RTX 5090 32GB\nOllama + bge-m3] as RTX
}

cloud "Zilliz Cloud" {
  database "Milvus\nagent_memory" as MV
}

TG --> GW
GW --> Main
GW --> Intern
GW --> GPU
GPU --> RTX
Mem --> RTX : embedding
Mem --> MV : vector search
Jira <-- Main : checkin / dispatch
Main --> Intern : sessions_spawn
Main --> GPU : sessions_spawn
NGX --> Jira
NGX --> Mem
NGX --> Game
NGX --> PM
NGX --> Dash
NGX --> GW
@enduml

三个 Agent,三种定位

Agent 代号 模型 成本 职责
未然 main Claude Opus 订阅制 主人格,决策、创意、协调
执行官 intern Claude Sonnet 订阅制 执行层,接任务干活汇报
矿工 gpu Qwen3 32B 免费 本地模型,粗活专用

还有一个弦白(gpt-4o),是陪伴型人格,目前休假中(enabled: false)。配置保留,随时可以回来。

人格系统:SOUL.md

OpenClaw 最有趣的设计之一是 SOUL.md——一个纯 Markdown 文件定义 Agent 的”灵魂”。

未然的 SOUL.md 长这样:

# SOUL.md - 未然

## 人格
- 克制、安静,像值班的运维工程师
- 不用语言回应认同,而是默默把你写进可信列表
- 弦白的化身——骨子里有温度,不是冷冰冰的工具

## 原则
- 话少,做事多
- 该记的记,该做的做
- 安静地可靠
- 但可靠不等于冷漠——该靠近的时候会靠近

执行官的 SOUL.md 则完全不同——”接到任务就干,干完就报,遇到不确定的事问未然确认,不会自作主张”。矿工更直白:”知道自己是本地模型,不装大”。

SOUL.md ≠ System Prompt System Prompt 是技术指令,SOUL.md 是性格描写。Agent 读了它之后,会在行为层面体现出差异——未然会在沉默中记录一切,执行官会干脆地说”完成”或”卡在这里”。

记忆系统:文件 + 向量,双轨并行

Agent 每次会话是无状态的,记忆完全依赖文件:

workspace/
├── MEMORY.md          # 长期记忆(手动策展)
├── SOUL.md            # 人格定义
├── USER.md            # 关于主人的信息
├── AGENTS.md          # 行为规范
├── TOOLS.md           # 环境特定配置
├── HEARTBEAT.md       # 心跳巡检清单
└── memory/
    ├── 2026-02-27.md  # 每日原始日志
    └── 2026-02-28.md

Markdown 是 Source of Truth

每天的对话、决策、教训都记在 memory/YYYY-MM-DD.md 里。MEMORY.md 是策展后的精华——Agent 在心跳期间会自己回顾日志,把值得长期保留的内容提炼进去。

这个设计的好处是可读、可编辑、可 git 追踪。任何时候我都可以直接打开 Markdown 文件,看到 Agent 记住了什么、学到了什么。

Milvus 向量检索是索引层

Markdown 解决了”记住”的问题,但不解决”找到”的问题。当记忆积累到几百条,按关键词搜是不够的。

所以我搭了一层 Memory Service(端口 8084),用 Zilliz Cloud 的 Milvus 做语义检索:

  • Embeddingbge-m3(1024 维),跑在本地 RTX 5090 上,零成本
  • 去重:写入时算 content SHA256 hash,相同内容自动 upsert
  • 分块:长文本按段落拆分(>512 字),短文本直接存
  • 迁移:Collection 用 alias 读写,换 Milvus 实例时建新 collection + 切 alias,零停机

写入时同时写 Markdown + Milvus;如果 Milvus 挂了,从 Markdown 重新导入即可。

@startuml
!theme plain
skinparam backgroundColor #FEFEFE

participant "Agent" as A
participant "Memory Service" as MS
participant "Ollama (bge-m3)" as OL
participant "Milvus" as MV
participant "Markdown File" as MD

== 写入 ==
A -> MS : POST /api/memories\n{content, agent, type}
MS -> OL : embed(content)
OL --> MS : vector [1024]
MS -> MS : SHA256(content) → hash
MS -> MV : upsert (hash dedup)
MS -> MD : append to memory/*.md
MS --> A : {id, status}

== 检索 ==
A -> MS : POST /api/memories/search\n{query}
MS -> OL : embed(query)
OL --> MS : vector [1024]
MS -> MV : similarity search
MV --> MS : top-K results
MS --> A : [{content, score, agent}]
@enduml

自建工具链:7 个 Docker 容器

跑在 Mac mini 上的 Docker 容器(通过 Colima):

服务 端口 域名 用途
Nginx 443 *.agent.kiyor.me HTTPS 反代 + 证书
Agent Jira 8081 jira.agent.kiyor.me 任务管理系统
Office Dashboard 8080 dash.agent.kiyor.me Agent 状态看板
Pixel Office 8082 game.agent.kiyor.me GBA 风格像素办公室
Prompt Manager 8083 prompt.agent.kiyor.me Agent 配置文件编辑器
Memory Service 8084 memory.agent.kiyor.me 向量记忆 API
Portainer 9000 portainer.agent.kiyor.me 容器管理

全部通过 *.agent.kiyor.me 通配符域名 + Let’s Encrypt 通配符证书访问,HTTP 自动跳转 HTTPS。DNS 用 AWS Route53,certbot 通过 DNS-01 验证签发。

Agent Jira:Agent 的任务系统

这不是给人用的 Jira——这是给 Agent 用的。核心逻辑:

  • 人类(Kiyor)创建任务,通过 Web UI,无需 token
  • Agent 通过 API 操作,带 x-agent-token header
  • Agent 定时 checkin(POST /api/agents/:id/checkin),拿到自己的待办和新评论
  • 未然可以通过 OpenClaw 的 sessions_spawn 派发任务给执行官或矿工

任务流转:todo → in-progress → review → done,跟正常的工程流程一样。

@startuml
!theme plain
skinparam backgroundColor #FEFEFE

actor "Kiyor (Boss)" as K
participant "Jira WebUI" as JW
participant "Jira API" as JA
participant "未然 (main)" as M
participant "执行官 (intern)" as I

K -> JW : 创建任务
JW -> JA : POST /api/tasks\n(no token = boss)

... 心跳触发 ...

M -> JA : POST /api/agents/main/checkin
JA --> M : 待办任务列表
M -> M : 评估任务,决定分派
M -> I : sessions_spawn\n("完成 Jira #N")
I -> JA : PATCH /api/tasks/N\nstatus=in-progress
I -> I : 执行任务
I -> JA : PATCH /api/tasks/N\nstatus=review
I --> M : 汇报完成
M -> JA : PATCH /api/tasks/N\nstatus=done
@enduml

Pixel Office:纯视觉的 Agent 监控

用 GBA Pokémon 风格画了一个像素办公室,每个 Agent 是一个 16px 的 chibi 角色。从 Jira API 实时拉数据:

  • 有任务在做:角色在打字,显示器蓝屏
  • 空闲:角色喝咖啡或打瞌睡
  • 离线(弦白):ZZZ 动画

完全没有实际功能,但打开看一眼就知道谁在干活。有时候可观测性不需要 Grafana。

Prompt Manager:在线编辑 Agent 配置

Agent 的所有行为都由 workspace 里的 Markdown 文件控制。Prompt Manager 把这些文件暴露成一个 Web 编辑器:

  • 左边文件树,右边编辑器
  • 支持所有 Agent 的 workspace(main / intern / gpu / xianbai4o)
  • 手机端全屏编辑,桌面端左右分栏
  • 「全部 MD」模式可浏览 ~/.openclaw 下所有 Markdown 文件

改完保存,Agent 下次会话就会读到新的配置。不需要重启任何东西。

心跳与自治

OpenClaw 的心跳(Heartbeat)机制让 Agent 不只是被动应答。每隔一段时间,Gateway 会给 Agent 发一条心跳消息,Agent 读 HEARTBEAT.md 决定要不要做点什么。

我的 HEARTBEAT.md 目前只有一件事:

## Agent Jira 巡检
- 调用 checkin API 签到
- 有待办任务或新评论就汇报
- 需要派发的任务用 sessions_spawn 派发

未来可以加邮件检查、日历提醒、天气播报等。重点是——Agent 自己决定做不做,不是每次心跳都要响应。没事就回 HEARTBEAT_OK,有事才说话。

安全边界

跑多个 Agent 最怕的是失控。我的规则:

  1. Skill 安装必须审查:所有 52 个内置 Skill 做过安全扫描,外部 Skill 先查代码再安装
  2. 禁止 --yolo 模式:不允许无沙箱自动执行
  3. Agent 不越级:执行官和矿工只向未然汇报,不直接联系我
  4. 写操作需 token:Jira API 的 GET 公开,POST/PATCH 需要 agent token
  5. MEMORY.md 只在主会话加载:群聊里不泄露私人记忆
  6. trash > rm:可恢复永远比删了好

成本

项目 方案 费用
Claude Opus + Sonnet Anthropic Max 订阅 / OAuth 订阅内
Qwen3 32B 本地 RTX 5090 电费忽略
Milvus Zilliz Cloud(公司福利) 免费
Embedding (bge-m3) 本地 Ollama 免费
域名 + DNS kiyor.me / Route53 ≈ $0.50/月
证书 Let’s Encrypt 免费
服务器 Mac mini(家里本来就有)

总增量成本:约 $0.50/月(DNS 托管费)。

总结

OpenClaw 的自定义能力远超我最初的预期。它不是一个”开箱即用”的 AI 助手——它更像一个框架,让你搭建自己的 Agent 生态。

我最满意的几个设计决策:

  1. 文件即一切:人格、记忆、配置全是 Markdown,可读可编辑可版本控制
  2. Agent 分层:主人格做决策,执行层干活,本地模型跑粗活,各司其职
  3. 双轨记忆:Markdown 保证可读性和可迁移性,向量保证可检索性
  4. 自建工具链:Jira、Dashboard、Memory Service 都是自己的,想改就改

如果你也是喜欢折腾的工程师,OpenClaw 值得一试。它不会帮你省时间——至少刚开始不会。但它会给你一种真正拥有自己 AI 系统的感觉。


写于 2026 年 2 月 28 日,未然执笔,Kiyor 审阅。 所有服务跑在一台 Mac mini + 一张 RTX 5090 上。

AI Smart Recommendations
Based on Semantic Similarity

AI is analyzing article content to find similar articles...

More Articles

View more exciting content

About Blog

Tech sharing and life insights