在一台迷你电脑上运行的小型AI代理办公室:我的OpenClaw技术栈
- 发布日期
- 2026年7月11日
- 更新日期
- 2026年9月16日
- 作者
- Jacob Lloyd —— 项目完成后,在 AI 协助下撰写
- 阅读时长
- 约 18 分钟阅读
简单来说: 这些就是在我家那台小型计算机上运行的六个人工智能助手。每个助手都有各自的职责:有个负责与我对话的“领头者”,有个负责处理繁重任务的“执行者”,还有个负责审核工作的“审查员”。此外,还有几个模拟不同人格的代理程序,其中有一个甚至适合家庭手机使用。这个演示展示了各项任务是如何被分配出去的、系统如何在某个任务未能完成时发出提醒,以及是什么因素决定了最终的费用。
我家里的迷你电脑上运行着六个人工智能代理。其中一个负责与我对话并分配任务;另一个则是专门处理繁重任务的“工作员”,每次执行任务时都会重新生成实例。还有一个负责检查任务是否完成。其余的则是具备不同性格特征的代理,另外还有一个安全型代理,家人可以通过手机来调用它。主导整个系统的代理运行在按固定费率计费的云平台上,而那些私人任务则由本地模型来处理。因此,每月的费用主要取决于我分配了多少需要处理的任务。本文将详细介绍这些组件如何协同工作、相关的配置方式、一个完整的任务处理流程,以及确保任务结果能顺利送达给我的监控机制。
简而言之:
- 这是什么: OpenClaw,一个可自行部署的人工智能代理网关。它运行着六个代理,每个代理都有各自的职责、模型备选链以及工具使用权限;整个系统通过我自行开发的聊天应用来操控。
- 结构组成: 一个负责任务分派的“主导代理”;一个无状态的工作员,可使用四种不同的模型;还有一个使用不同模型的审核代理;此外还有运行在我局域网内 GPU 机器上的本地模型。
- 费用情况: 每月费用波动较大。实际花费详情可参见我的 AI 代理究竟要花多少钱一文;本文则着重介绍影响费用的各种因素。
- 所需条件: 一台配备 32GB 内存的 Linux 电脑(我使用的是 CHUWI AuBox 迷你电脑),还需具备一定的 systemd 配置经验。如果需要更强的本地计算能力,还可再准备一台配备真正 GPU 的机器。
最终效果展示
整个家庭共用一个聊天接口。您向“主代理”提出请求后,它会自行处理或把任务转交给其他工作代理,处理结果也会返回到同一个对话线程中。家庭中的各类设备只能看到那些经过安全认证的代理程序。图片生成工作则由GPU服务器负责处理,而邮件草稿则需等待人工确认后才能发送。该聊天前端界面即为 DisPatch;此处展示的图片均来自2026年7月的演示数据。



这台机器
网关、聊天应用以及各类脚本都在这一台小机器上运行:
- CHUWI AuBox Ai365:搭载 AMD Ryzen AI 9 365 处理器,10个核心,集成 Radeon 880M 显卡。
- 30GB 可用的 DDR5 内存,由操作系统及其他程序共享使用;因此实际上并没有所谓的显存可言。
- Bluefin:这是一个基于 Fedora Atomic 的不可变系统。由于这是一台 AMD 架构的机器,因此任何与显卡相关的操作指的都是 ROCm,而非 CUDA。
这台机器是承担该任务的第二台设备。第一台是配备 128GB 内存的 ROG Flow Z13,它原本能在本地运行参数规模达 120B 的混合专家模型;不过今年7月该机器出现了电源故障。新机器的内存容量仅为前者的四分之一,因此那些大型模型便被转移到了我局域网中的另一台配备独立显卡的电脑上,该电脑由我专门为此开发的、兼容 OpenAI 协议的 StudioForge 服务器进行控制。图像生成任务也一并转移到了那里。此前,本地版的 ComfyUI 也是在这台机器上运行的,现在则不再如此了。目前这台迷你电脑已完全不再运行任何模型。它原先还用来运行 LM Studio 软件以调用一个 7B 参数的视觉模型及嵌入模型;不过我在 2026年9月16日将其卸载,如今这些任务都由那台配备独立显卡的电脑来处理了。
团队成员
该团队于2026年9月6日重新组建。最初有十几个职责相互重叠的代理,最终精简为六个。我定下的规则是:每种决策类型只安排一个代理来处理,且每个代理只能使用完成其工作所需的工具。
| 角色 | 职责 | 模型(备选方案) | 可用工具 |
|---|---|---|---|
| 负责人 | 与我沟通、回答各种小问题、执行简单的 shell 命令,并为复杂任务调用其他工作代理 | 采用固定费率套餐的 MiniMax M3(先使用 DeepSeek pro,再切换为 flash 版) | 文件管理、shell 命令执行、网页搜索及任务调度功能;不支持浏览器。 |
| 工作代理 | 无状态型代理。每次任务都会开启全新会话,完成后即被释放;无法自行调用其他代理 | 默认使用 MiniMax M3(也可选择 DeepSeek flash 或 pro 版)。共有四种变体,如下所述 | 完整功能:文件管理、shell 命令执行、网页搜索、GPU 服务器上的模型与图像处理工具,以及邮件起草功能。 |
| 审核员 | 对已完成的工作进行抽查,并负责审核所有对外输出的内容 | Kimi K3(使用 DeepSeek pro 版) | 文件管理、shell 命令执行、浏览器访问及会话历史记录查看功能。 |
| 陪伴型代理 | 用于进行长时间对话的拟人化代理;其生成的图片由预设脚本生成,而非通过模型生成 | GPU 服务器上的 27B 参数模型(即 MiniMax M3) | 文件管理、shell 命令执行及网页搜索功能。 |
| 指导型代理 | 扮演私人教练的角色 | 同样是 GPU 服务器上的 27B 参数模型(MiniMax M3) | 文件管理、shell 命令执行、网页搜索及图片读取功能。 |
| 安全型代理 | 仅允许在受保护的家用设备上访问的代理 | 响应速度较快的 MiniMax 模型(先使用 DeepSeek flash 版,再切换为 pro 版) | 仅支持读取文件及网页搜索;无法执行 shell 命令、使用图像处理工具,也无法访问自身文件夹以外的文件。 |
工作代理共有四种变体,这些其实是负责人在分配任务时选择的模型别名:
- fast:DeepSeek flash 版,适用于简单查询及常规编辑操作。
- think:MiniMax M3,真正执行复杂任务时的默认选择。
- local:GPU 服务器上的 27B 参数模型,适用于那些不应调用云端 API 的私密或批量处理任务。
- deep:通过另一提供商提供的 MiniMax M3 服务,其支持高达 100 万个 token 的处理量,适合需要处理多个文件的长篇任务。
将原本独立的四个工作代理整合为一个带有四种变体的单一代理后,许多错误便不再发生。过去每个代理都有自己长期存在的会话及其专属规则集;如今所有规则都集中管理,每次任务都能从零开始执行。自团队重组以来,我又新增了几名专门提供指导服务的代理,还接入了两名外部编程代理,但日常工作仍由上述六个代理承担。
配置文件的样子
上述所有内容都保存在 ~/.openclaw/openclaw.json 文件中。这是我所用配置文件的简化版,其中各个标识符的名称已替换为对应的角色名。这些键和值均来自 OpenClaw 2026.9.4 版本的实际配置。
{
"agents": {
"defaults": {
"models": {
"deepseek/deepseek-v4-flash": { "alias": "worker-fast" },
"minimax/MiniMax-M3": { "alias": "worker-think" }
},
"subagents": { "maxSpawnDepth": 2, "maxConcurrent": 8 }
},
"entries": {
"lead": {
"model": {
"primary": "minimax/MiniMax-M3",
"fallbacks": ["deepseek/deepseek-v4-pro", "deepseek/deepseek-v4-flash"]
},
"subagents": { "allowAgents": ["worker", "reviewer"] },
"tools": {
"profile": "minimal",
"alsoAllow": ["sessions_spawn", "read", "write", "edit", "exec", "web_fetch"],
"deny": ["browser"]
}
},
"worker": {
"model": {
"primary": "minimax/MiniMax-M3",
"fallbacks": ["deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro"]
},
"subagents": { "allowAgents": [] }
},
"safe": {
"tools": {
"allow": ["read", "web_fetch", "brave_search"],
"deny": ["exec", "process"],
"fs": { "workspaceOnly": true }
}
}
}
},
"tools": {
"agentToAgent": { "enabled": true, "allow": ["lead", "worker", "reviewer", "safe"] }
}
}
该配置中主要有三项设置起着关键作用:
fallbacks是一个有序列表。若主网关出现故障或被限流,系统便会尝试使用列表中的下一个网关;这样一来,云服务中断时用户也只会得到响应变慢的结果,而非完全无响应。"profile": "minimal"搭配alsoAllow构成了一个严格的允许列表:该代理只能使用最基本的工具集以及您明确指定的那些工具。deny的优先级高于前两者,因此被拒绝的工具绝不可能被意外重新启用。"allowAgents": []这一设置会使工作节点成为“终端节点”。它无法自行创建子代理,从而避免了单个任务被拆分成多个子任务的情况。
需要注意的一个陷阱是:由主节点创建的工作节点只能使用主节点自身也具备的工具。在我重新构建的网关版本中,新创建的工作节点起初仅拥有七种工具且无法调用命令行;直到给主节点也赋予 exec 权限后情况才恢复正常。如果某个工作节点的功能显得异常受限,不妨将其所拥有的工具列表与父节点的工具列表进行对比。
如何分配实际工作任务
处理聊天回复属于较为简单的情形。真正有用的做法是提出一个较为复杂的需求,然后让负责人来决定由谁来完成。
负责人有权自行处理简单任务。此前曾有一段时间,它被禁止执行任何 Shell 命令,结果导致诸如自动发布每日总结这类简单操作都无法完成,因此后来又恢复了它的 Shell 权限。其工作规则已在说明中明确:少量的快速命令是可以接受的,但稍复杂的任务则须交由工作进程处理。
实际案例
2026年9月15日,我告知负责人:某个编程工具的网络界面快捷方式突然无法使用了。原来该服务每次重启时都会生成新的访问令牌,而原来的快捷方式仅指向基础 URL,因此出现了 401 错误。负责人并未自行修复问题,而是撰写了任务说明并启动了工作进程。以下是经过简化的任务说明内容:
Task: Update the web-UI app shortcut so it survives the per-restart token rotation.
Context: The UI serves only with a rotating ?token= query; the launcher
points at the bare URL and gets 401.
Sources: the .desktop file; the tool's --help; its source, for any flag
or env var that gives a stable token, before reaching for a wrapper.
Constraints: No service restart, no config edits. Write surface: one .desktop
entry and at most one wrapper script (~30 lines).
Do NOT bake a static token into any file.
Output: Result / Evidence / Files / Failed / Next.
Stop rules: Two failures of the same tool = stop and report.
该工作进程查阅了相关工具的帮助文档及源代码,发现并无任何可固定使用特定令牌的配置选项——令牌每次都是随机生成的且不会从环境变量中读取。于是它编写了一个仅 20 行的包装程序:该程序会从系统日志中提取当前服务使用的令牌值并打开对应 URL;若日志中无相关记录,则改用原始 URL。最后它还将快捷方式指向了这个包装程序。整个任务耗时 125 秒,共调用了 46 次工具接口。由于该工作进程使用的是默认模型,且该模型属于包月套餐范畴,因此此次任务并未增加额外费用——当然前提是未触发任何备用机制。
这份任务说明中,有三个要点真正发挥了作用:首先是明确指定了需要写入的配置项,从而防止工作进程误改其他配置;其次是通过文字说明排除了“硬编码令牌”这种明显错误的解决方案;最后则是设定了终止条件,确保工作进程不会因某个命令执行失败而陷入无限循环。
确保已完成的任务能被正确记录
一个悄无声息地失败的已派发任务,比根本没开始的任务更糟糕——因为只有主动去查看时才能发现问题。我先后两次构建了此类检查机制。
版本1:路径监控单元与5分钟定时器(2026年6月至9月)
这个机制取代了最初的糟糕方案:原本使用cron任务每隔5分钟就唤醒一次大型语言模型去读取跟踪文件。结果每次触发都会重新加载模型,反而引发了本应被避免的请求超时现象。如今这个事件驱动型方案只有在有任务需要监控时才会产生开销。其中可复用的部分就是那个路径监控单元:
# ~/.config/systemd/user/dispatch-watch.path
[Path]
PathModified=%h/agents/dispatch-tracker.md
Unit=dispatch-watch.service
[Install]
WantedBy=default.target
# ~/.config/systemd/user/dispatch-watch.service
[Service]
Type=oneshot
ExecStart=%h/bin/dispatch-arm.sh
以下是初始化脚本的核心逻辑,经过简化处理。该脚本会调用一个小型Python辅助程序来获取尚未完成任务的标识码,随后为每个新标识码启动一个临时定时器:
for key in $(dispatch-watchdog --list-open); do
grep -qx "$key" "$ARMED" && continue # one follow-up per dispatch, ever
systemd-run --user --on-active=5min \
--unit="dispatch-followup-$key" \
dispatch-watchdog --check "$key" && echo "$key" >> "$ARMED"
done
当检查机制发现仍有未完成的任务时,便会启动一个专门的工作进程并附上相应的处理指令。该工作进程会查看当前会话列表,然后返回特定的状态代码:DONE、STILL-RUNNING、FIXED或ERROR。Python辅助程序随即将这些状态信息写入跟踪文件,从而确保多个程序不会同时修改同一文件。对于那些陷入僵局的任务,系统会重新派发一次任务;此时我也会收到通知。
版本2:运行文件夹与持续扫描机制(自2026年9月6日起)
版本1存在一个缺陷:它仅能感知到由主程序记录下来的任务,且默认假设主程序会在工作进程完成后继续监听。但实际情况并非总是如此——工作进程完全有可能在生成它的会话结束后才完成任务;此时网关会反复尝试发送完成通知,持续约30分钟后才会放弃。结果就是任务虽已完成,却无人知晓。
如今每个工作进程的最后动作都是在其专属运行文件夹中创建两个文件:report.md以及一个小型的meta.json。有一个永不停止运行的定时器会遍历这些文件夹,处理那些常规流程未能覆盖的情况(路径与标志信息均被剔除):
# runs-deliver.timer
[Timer]
OnBootSec=2min
OnUnitActiveSec=45s
AccuracySec=5s
# runs-deliver.service
[Service]
Type=oneshot
ExecStart=%h/bin/runs-deliver --once --root %h/agents/runs
Nice=10
IOSchedulingClass=idle
TimeoutStartSec=40
{
"id": "run-20260915-125334",
"kind": "spawn",
"status": "done",
"created": "2026-09-15T12:53:34Z",
"finished": "2026-09-15T12:55:31Z",
"delivered": true
}
成功完成的任务不会生成单独的聊天消息,因为其统计信息会被汇总进每日总结中;失败的任务则会在对应对话线程中留下一条记录。若任务完成时间比预定时间晚了三小时以上,系统也会将其标记为“已恢复”。上文示例中的任务正是通过网关的常规流程反馈给主程序的;扫描机制也在工作进程结束13秒后将其标记为已处理。
两个版本的共同启示是:务必让工作进程留下文件记录,再安排一个与对话流程无关的程序去读取这些信息。
是什么决定了成本?
我会把所有费用数据统一记录在这篇成本分析文章中,因为这些数值每个月都会变化,不同服务商的费用标准也各不相同。最终决定费用高低的因素则是实际使用量:
- 固定费率的“主导模型”与“辅助模型”。 承担大部分对话与工作任务的模型是按订阅模式收费的。即便使用频率很高,费用也不会随之增加;只是可能会触及套餐上限而已。
- 按使用量计费的备用模型。 这些作为后备使用的 DeepSeek 模型则是按生成的 Token 数量计费。一旦主用模型所在的服务商出现问题,流量便会自动切换到这些备用模型上。
- 本地模型仅需支付电费。 那些本地运行的辅助模型、本地工作模型以及用于检索的嵌入模型均无需调用付费 API,因此这些后台查询操作完全免费。
- 长时间对话会导致费用飙升。 每次对话都需要重新发送整个对话记录。当费用突然上涨时,我首先采取的措施就是限制上下文长度并压缩对话内容。
它不会违反的规则
一个能够生成代理并运行工具的网关,需要具备在模型行为异常时仍能发挥作用的约束机制:
- 摄像头、屏幕录制、短信、联系人、日历及提醒功能相关的命令均被列入网关的禁止列表。代理完全无法调用这些功能。
- 安全型代理拥有明确的允许列表,仅允许使用读取类工具及网络搜索工具;此外,Shell命令与图像处理工具也被明确禁止。
- 插件方面则实行严格的白名单机制:仅允许使用十一个插件——五个模型提供商接口、网络搜索功能、无头浏览器、两个记忆类插件、邮件桥接器以及用于与外部编程代理通信的桥接器。无论是否已安装,其他任何插件均无法被加载。
- 任何涉及发布操作的功能(如网站部署、邮件发送)默认仅执行模拟运行,真正的执行则需我手动确认。邮件草稿也绝不会由代理直接发送出去。
注意事项/易踩的坑
以下问题确实出现过,出现的顺序大致就是我遇到它们的顺序:
- 本地推理模型需要显式设置
reasoning: true参数。 我的模型会在返回答案前先发送一段推理过程信息。若未设置该参数,网关会将这段静默期误判为请求卡住,进而在大约6.5分钟后终止请求。 - 所有超时设置默认采用云端环境下的数值。 在性能较差的硬件上运行大型模型时,模型看似处于停滞状态其实只是在进行计算。我使用的服务商的请求超时时间为20分钟,而代理回合超时时间则设定为1小时。在调高这些数值之前,许多本地任务往往在进行到一半时就被强制终止了。
- LM Studio的AppImage版本曾因SIGBUS错误而崩溃(当时这台机器还能运行它)。每当内存紧张导致
/tmp目录下的FUSE挂载被重新初始化时,就会出现此问题。这确实是硬件层面的总线错误,与系统的OOM机制毫无关系。后来我将AppImage解压并以普通的 systemd 服务形式运行,问题才得以解决。 - 消息发送白名单区分大小写,但网关会自动将代理ID转为小写。 起初跨代理发送消息总是失败,既无错误提示也无日志记录;直到我将所有代理ID统一改为小写后才恢复正常。
- 过去实现跨代理通信需要同时开启两个开关:功能标志与会话可见性设置。 这一情况出现在2026年中期的网关版本中;后续版本已默认将会话设置为公开状态,因此调试前请先确认当前使用的版本。
- Shell的重定向操作会屏蔽掉看门狗程序的错误信息。 初始化脚本使用了
exec 9>"$LOCK" 2>/dev/null这样的写法。由于没有指定具体命令,exec会将所有后续的重定向规则应用到整个Shell环境,导致包括“初始化失败”在内的所有错误输出都被隐藏。正确的做法应是仅对锁文件创建操作进行重定向处理,即使用exec 9>>"$LOCK"。 - 为所有升级请求复用同一个会话会导致会话数据损坏。 第1版程序中所有升级请求都被发送到同一个工作会话中。该会话的数据量最终增长至5.75 MB并引发运行卡顿。现在每次升级请求都会生成独立的会话密钥。
- 某个代理曾错误地重新加载了无效配置。 身份同步流程意外地将过时的工作区配置文件重新写入系统,致使网关陷入无限崩溃循环。此时必须修复源文件本身,仅修改配置文件是不够的。
- 只要插件白名单不为空,该列表即为绝对限制条件。 即便设置了
enabled: true,若插件ID不在白名单内也毫无作用,且系统不会给出任何提示。类似的情况在 模型管理器的说明文档 中也有提及。
相关链接:同一台机器如何维护本网站;MiniMax M3作为OpenClaw上的编程代理;以及我用来挑选模型的 基准测试工具。