给 AI 员工搭个“牛马工作间”:我把 OpenClaw 搬进了像素办公室
最近我一直在折腾 OpenClaw。Agent 配好了,定时任务也跑起来了,飞书里偶尔还能收到它主动发来的消息。看起来一切都很自动化,但用久了以后,我总觉得少了点什么。
少的是一种“Agent到底在干什么”的确定感,以及资本家要看到 AI 员工有在干活的满足感!

任务发出去以后,Agent 是在思考,还是在调用工具?定时任务有没有按时执行?最近用了多少 token?如果同时养了几个 Agent,又该去哪里看它们各自的状态?
这些信息不是没有,Openclaw dashboard都能找到信息,但是散落在Chat、Session、日志和不同标签页里。每次想确认一下,都像领导突然想起某个需求,先在群里问一圈:“这个现在做到哪了?”
于是我做了一个小项目:**OpenNM,中文别名叫“牛马工作间”。**名字很赤裸,就是想看到Agent牛马干活,它想解决的问题也很具体:把 OpenClaw 里原本藏在后台的 Agent、Session、Cron、Usage 和执行状态,搬进一间看得见、点得动的像素办公室。
这篇文章主要聊四件事:
-
OpenNM 到底是什么; -
怎么在本地把它跑起来; -
目前可以用它做什么; -
后续还准备往哪里折腾。
一、OpenNM 是什么?
简单来说,OpenNM 是一个运行在本地的 OpenClaw 可视化工作间。
它不是另一个 AI Agent,也不打算替代 OpenClaw。OpenClaw 仍然负责 Agent、模型、Session、Cron 和工具调用,OpenNM 做的是在上面增加一层更直观的操作界面。
原本我们使用 OpenClaw,大致是这样的:
打开飞书或终端 → 找到某个 Agent → 发任务 → 等回复 → 再去别处翻 Session、Cron 或 Usage。
有了 OpenNM 以后,这条路径变成了:
打开办公室 → 看 Agent 状态 → 点击对应工位 → 发任务或查看历史信息。
图:OpenNM 当前选择某个Agent展开后的会话页面。

页面里的每个 Agent 都有自己的工位、角色和模型信息。空闲时,它们会在办公室里发呆、伸懒腰、喝咖啡,甚至去洗手间;收到任务后,再走回工位开始工作。
这部分看起来像在做小游戏,但它并不只是装饰。
对我来说,像素小人的价值在于把抽象状态翻译成了人能一眼理解的行为:
idle
:暂时没活,可能在办公室闲逛; thinking
:收到任务,正在理解和规划; running_tool
:正在调用工具; executing_command
:正在执行命令; waiting_user
:卡在某一步,等待用户补充; completed
:任务完成; error
:执行出错; offline
:Agent 当前不可用。
换个说法,过去我们是在读日志,现在是在“看人干活”。虽然它们并不是真的人,但管理牛马的仪式感,算是先有了不是?
为什么要在本地加一层 BFF?
OpenNM 的结构并不复杂:
浏览器↓本地 OpenNM BFF↓OpenClaw CLI / Gateway↓远端 Agent、Session、Cron、Usage
这里的 BFF,可以理解成浏览器和 OpenClaw 之间的本地中转站。
它主要做三件事:
-
复用本机已经认证过的 OpenClaw CLI,不把 Gateway 凭证交给浏览器; -
把不同来源的数据整理成前端容易展示的格式; -
统一处理输入校验、敏感内容脱敏和实时事件推送。
所以,OpenNM 默认只监听 127.0.0.1。它首先是一个个人本地工具,而不是开箱即用的公网管理后台。
这点很重要:如果以后要把它暴露到局域网或互联网,必须先补认证,不能直接把端口一开就宣布“数字化转型成功”。
二、基础环境怎么搭?
OpenNM 目前更适合已经有 OpenClaw 环境的人使用。如果你还没接触过 OpenClaw,也可以先把这一段当成判断清单:它并不是下载完就能独立聊天的桌面应用。
1. 准备环境
本地需要具备:
-
Node.js 22 或更高版本; -
已安装 OpenClaw CLI; -
CLI 版本与远端 Gateway 版本匹配; -
本机已经完成远端 profile 的认证; -
当前设备至少拥有 operator.read和operator.write权限; -
本机能够访问远端 OpenClaw Gateway。
我自己的环境是 macOS 本地开发,远端运行 OpenClaw,再通过 Tailscale 访问。你也可以使用其他私网方案,关键不是一定要有 Tailscale,而是本机确实能够连上 Gateway。
2. 先验证 OpenClaw
在安装 OpenNM 之前,先执行:
openclaw gateway call statusopenclaw gateway call agents.list --json
第一条用于确认 Gateway 可访问,第二条用于确认当前 profile 能够读取 Agent。
为什么要先做这一步?
因为如果这里已经失败,OpenNM 再怎么刷新也只会显示 Gateway OFFLINE。先确认上游,再排查界面,能少走不少弯路。
3. 安装并启动 OpenNM
进入项目目录后执行:
npm installnpm run dev
然后打开:
http://127.0.0.1:5173
开发模式下,Vite 负责前端页面,本地 BFF 运行在 127.0.0.1:8787,前端会把 /api 请求代理过去。
如果只是日常使用,不需要热更新,可以采用更稳定的生产启动方式:
npm run checknpm run buildnpm start
然后访问:
http://127.0.0.1:8787
停止前台服务可以使用 Ctrl+C。如果服务在另一个终端运行,也可以执行:
npm stop
4. 可选配置
默认情况下,不配置环境变量也能运行。需要调整时,可以参考 .env.example:
|
|
|
|
|---|---|---|
OPENCLAW_BIN |
openclaw |
|
BFF_HOST |
127.0.0.1 |
|
BFF_PORT |
8787 |
|
OPENCLAW_TIMEOUT_MS |
600000 |
|
COMMAND_OUTPUT_MAX_CHARS |
12000 |
|
如果启动时遇到 EMFILE: too many open files, watch,通常是系统文件监听数量不足。这个问题影响开发模式的文件监听,不代表项目构建失败。可以先使用:
npm run buildnpm start
绕开 watcher,等真正需要开发调试时再处理系统监听上限。
三、它现在能做什么?
OpenNM 当前还是 MVP,但已经可以完成一条比较完整的使用链路:
发现 Agent → 查看状态 → 下发任务 → 观察执行 → 回看 Session → 检查 Cron 和 Usage。
下面分别来看。
1. 在办公室里查看 Agent 状态
主界面会从远端读取真实 Agent,并把它们映射到对应工位。
每个工位会展示:
-
Agent 名称和角色; -
当前使用的模型; -
当前任务状态; -
最近一个 Cron 的时间角标; -
电脑开关和执行状态; -
Agent 的空闲或工作动作。
页面通过 SSE 接收状态和活动更新,所以 Agent 开始思考、调用工具或执行命令时,不需要手动刷新整页。
我比较喜欢这个设计的一点是:状态不再只是一串英文,而是同时影响人物动作、电脑状态和气泡。
例如 Agent 收到任务后,会先返回自己的工位,再进入敲键盘状态;空闲一段时间后,又可能去休闲区喝咖啡。办公室因此不只是一个静态看板,而是会随着真实任务变化。
2. 直接对 Agent 下发任务
点击任意 Agent,可以打开右侧抽屉。里面目前有五个 Tab:
Chat
:发送任务并查看消息; Sessions
:查看和切换历史 Session; Cron
:查看定时任务; Usage
:查看 token 使用情况; Activity
:查看当前 Agent 的执行活动。
页面底部还提供了一个 Quick Channel。它更像快捷工作台,可以不打开完整抽屉,直接选择 Agent、查看最近消息或发送任务。
如果 Agent 已经绑定飞书 Session,Web 与飞书消息会进行同步。也就是说,你可以在飞书里发起任务,再回到 OpenNM 观察状态;也可以从 OpenNM 发送,再到飞书里继续对话。
这解决的是一个很现实的问题:入口可以很多,但任务状态最好只有一份。
3. 回看 Session 与工具执行
Sessions 面板会展示某个 Agent 的历史会话、来源渠道、模型、更新时间和 token 数。点击 Session 后,Chat 会切换并加载对应历史消息。
工具调用不会全部摊成一大段日志,而是折叠成卡片。需要排查时,再展开查看:
-
工具名称; -
输入摘要; -
输出摘要; -
执行耗时; -
成功或失败状态。
Activity 则更偏向“现在正在发生什么”,适合观察 Agent 当前调用的是文件、终端还是其他工具。
这里我刻意没有把所有原始输出直接扔到页面上。日志当然越全越方便排查,但个人工作台首先要能读,不能每打开一个 Agent,都像误入了 CI 控制台。
4. 查看 Cron 任务
图:Cron 面板会展示计划、时区、下一次运行时间与最近状态。

Cron 面板目前以查看为主,会展示:
-
任务名称; -
Cron 表达式; -
时区; -
下一次运行时间; -
最近一次执行结果。
办公室工位上的时间角标,则用于提示最近要运行的任务。
当前版本没有直接在页面里修改或删除 Cron。我认为这个边界暂时是合理的:读取状态风险低,修改计划则可能直接影响真实自动化任务。先把“看清楚”做稳,再考虑“从页面操作”,顺序更重要。
5. 查看 Usage 消耗
图:Usage 支持 Today、7D 和 30D 三个时间范围。

Usage 面板支持 Today、7D 和 30D 三种范围,可以看到:
-
Session 数量; -
Input token; -
Output token; -
Context / Total token。
页面只展示 Gateway 返回的真实数据。拿不到成本时,就不强行估一个看起来很专业的数字。
这一点看起来保守,但我觉得比“为了完整而编个费用”更实用。Usage 的价值不是制造精确幻觉,而是帮助我们判断:哪个 Agent 用得最多、上下文是否膨胀、某类自动任务是否正在悄悄吞 token。
6. 加载、空态和错误反馈
除了功能本身,OpenNM 也补了几种容易被忽略的状态:
-
数据加载中的骨架和提示; -
没有 Session、Cron 或 Activity 时的空态; -
Gateway 或面板请求失败时的错误提示; -
面板内的重试入口; -
切换 Agent 或 Session 时,避免旧数据覆盖新数据。
这些细节不会出现在功能清单的第一行,却决定了这个工具到底是“能演示”,还是“能日常使用”。
四、后续还想怎么优化?
做到这里,OpenNM 已经能跑,也能完成基本任务,但距离我想象中的“AI 工作间”还有不少空间。
我暂时把后续方向分成三层。
1. 先把个人使用体验做顺
近期更值得做的是:
-
增加演示 / 隐私模式,一键隐藏真实消息、Session ID 和 Usage; -
允许配置 Agent 皮肤、工位和办公室装饰; -
继续丰富动作与状态衔接,让等待、报错和完成更容易区分; -
增加全局 Activity 时间线,方便同时观察多个 Agent; -
增加 Usage 预算提醒,而不只是展示历史数字。
这些功能不算“架构升级”,但会直接影响每天愿不愿意打开它。
2. 从状态查看走向任务复盘
再往后,可以考虑:
-
Session 回放; -
工具调用耗时统计; -
Cron 成功率与失败趋势; -
Agent 间协作关系; -
任务从发起到完成的完整时间线; -
飞书、Slack、Telegram 等渠道的统一通知。
如果说当前版本解决的是“它现在在干什么”,那么这一层想解决的是“它过去做得怎么样”。
3. 再考虑远程和多人
多用户登录、权限管理、移动端适配、远程部署、本地事件持久化,这些都可以做,但不应该抢在前面。
原因也很简单:一旦从个人本地工具变成多人远程系统,认证、权限、数据隔离、审计和部署成本都会一起出现。到那时,它就不再只是一个有趣的像素办公室,而是一套真正的管理后台。
我希望先确认个人场景足够有价值,再决定要不要背上这套复杂度。
最后
OpenNM 的出发点,其实不是“把 AI 做得更像人”。
它更像是在解决一个产品问题:当 Agent 开始长期运行、主动执行任务,并同时存在多个角色以后,我们需要一个比聊天框更完整、又比原始日志更容易理解的界面。
像素办公室只是表达方式,可交互、可观察、可追溯才是核心。
如果你只是偶尔问 AI 两句话,OpenNM 可能有点重;但如果你已经在使用 OpenClaw,配置了多个 Agent、Cron 和长期 Session,又经常想知道“我的 AI 员工现在到底在干什么”,那么它值得试一试。
至于“牛马工作间”这个名字会不会太直白?没关系。人已经上了一天班,至少让 AI 把这个称号接过去一会儿。
夜雨聆风