PixOffice:给 AI 多智能体加一层 2D 办公室可视化,三种接入方式详解

PixOffice: How to Integrate 2D Office Scene Visualization Into Your AI Agent System

Tech-Experiment #多Agent协作#可视化#TypeScript#开源工具#Agent集成#虚拟办公室
🇨🇳 中文

如果你在跑多个 AI Agent 协同工作,有一个问题迟早会出现:不知道谁在做什么。日志里看不清,终端里一堆 stdout,出了问题才发现两个 Agent 在同一个任务上各自推进了半小时。

PixOffice 给这个问题加了一层可视化——不是监控大屏,是一个可以通过 HTTP 命令驱动的 2D 办公室场景。你的 Agent 可以在里面走到某张桌子、开个会、说一句话、切换到专注状态。可视化只是副产品,真正的价值是:外部系统用标准 HTTP 命令就能控制场景,Agent 的状态变化有了可观测的物理位置。

GitHub: https://github.com/workbzw/pixoffice | ⭐ 7 | MIT | TypeScript


项目结构

PixOffice 用 npm workspaces 拆成五个包,接入时只需关心三个:

包职责接入时是否需要
contracts共享协议类型(Zod schema)接 HTTP API 不需要,直接用 JSON
runtime核心引擎,无头 Node.js 可运行,不依赖 React/Pixi/DOM写自定义后端时需要
renderer-pixiPixi.js 渲染宿主只在前端展示时需要
animation-frame帧动画播放器前端渲染依赖
scene-office办公场景数据和行为插件前端渲染依赖

对大多数 Agent 集成场景来说,你只需要跑起 PixOffice 的 dev server,然后通过 HTTP 发命令。 不需要直接引用 npm 包(它们目前也没发布到 npm registry)。


启动本地实例

git clone https://github.com/workbzw/pixoffice.git
cd pixoffice
npm install
npm run dev

启动后有两个端口:

  • 前端展示:http://localhost:5173(Vite dev server)
  • Action Gateway:http://localhost:8765(Legacy HTTP API)

新协议 Scene Commands 的端口在 dev server 里也是 8765,通过路径区分:/scene/commands vs /actions。


三条接入路径

路径 1:Scene Commands v2.0(推荐)

这是当前推荐的接入方式。命令结构清晰,支持异步轮询,有协议版本标记。

发送一条命令:

curl -X POST http://localhost:8765/scene/commands \
  -H 'Content-Type: application/json' \
  -d '{
    "protocolVersion": "2.0",
    "sceneId": "office-1",
    "commandId": "task-handoff-001",
    "type": "activity.start",
    "capability": "office.visit",
    "participants": [
      { "entityId": "marvis", "role": "visitor" },
      { "entityId": "code-agent", "role": "host" }
    ],
    "params": {
      "stops": [
        {
          "hostId": "code-agent",
          "message": "请核对数据源,有疑问再来找我。",
          "reply": "收到"
        }
      ],
      "durationMs": 3000
    }
  }'

轮询结果:

curl http://localhost:8765/scene/commands/task-handoff-001

返回 { "status": "completed" | "pending" | "error", ... }。

查询当前场景状态:

curl http://localhost:8765/scene/state

发现可用能力:

curl http://localhost:8765/scene/capabilities

内置能力一览

通过 capability 字段指定,当前内置六种:

capability效果
office.visitA 走到 B 的桌子,交换一句话后返回
office.meeting多人集中到会议室,支持轮流发言
office.focus角色切换到专注状态(视觉上不被打扰)
scene.move角色移动到指定坐标
scene.say角色发出一段话(气泡或旁白)
office.emote触发表情动作(点头、摇头、鼓掌等)

坐标系是整数网格,场景中每个桌子/房间有固定的 entityId,通过 scene.capabilities 接口可以枚举所有实体和它们支持的能力。


路径 2:Legacy Actions API(快速上手)

如果只是快速验证可行性,Legacy API 更简单——参数少,语义直白:

# Agent A 走到 Agent B 的桌子
curl -X POST http://localhost:8765/actions \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "desk_visit",
    "visitor": 1,
    "host": 5,
    "message": "这件事交给你了。"
  }'

# Agent 移动到指定格子
curl -X POST http://localhost:8765/actions \
  -d '{ "type": "move", "entityId": "agent-3", "x": 12, "y": 8 }'

# Agent 发言
curl -X POST http://localhost:8765/actions \
  -d '{ "type": "say", "entityId": "agent-2", "text": "代码审查完成。" }'

# 更新对象状态
curl -X POST http://localhost:8765/actions \
  -d '{ "type": "set_state", "entityId": "task-board", "state": "active" }'

Legacy API 是同步的,没有 commandId 和轮询,适合原型阶段。


路径 3:Chat SDK 注入(给 React 前端用)

如果你有自己的 React 前端需要嵌入 PixOffice,可以通过 chatSource prop 注入对话流:

1. 设置环境变量:

VITE_PIXOFFICE_CHAT_URL=https://your-agent-endpoint.com/v1/chat

2. 或者直接注入 SDK(更灵活):

import { OfficeApp } from '@pixoffice/renderer-pixi'

function App() {
  return (
    <OfficeApp
      dataSource={{
        kind: 'static',
        sceneId: 'office-1'
      }}
      chatSource={{
        kind: 'my-agent',
        async *stream(request, signal) {
          const resp = await fetch('/api/chat', {
            method: 'POST',
            body: JSON.stringify({
              version: '1.0',
              conversationId: request.conversationId,
              messages: request.messages
            }),
            signal
          })

          const reader = resp.body.getReader()
          const decoder = new TextDecoder()

          while (true) {
            const { done, value } = await reader.read()
            if (done) break

            for (const line of decoder.decode(value).split('\n')) {
              if (!line.trim()) continue
              const event = JSON.parse(line)  // NDJSON

              if (event.type === 'delta') yield event.content
              if (event.type === 'done') return
              if (event.type === 'error') throw new Error(event.message)
            }
          }
        }
      }}
    />
  )
}

Chat endpoint 需要返回 NDJSON 流,每行一个 JSON 对象,type 字段为 status / delta / done / error。


实战:多 Agent 任务交接可视化

下面是一个完整的工程示例——让三个 Agent(Planner、Coder、Reviewer)的任务交接在 PixOffice 里可见。

const OFFICE_URL = 'http://localhost:8765'

async function sendCommand(command: object) {
  const res = await fetch(`${OFFICE_URL}/scene/commands`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      protocolVersion: '2.0',
      sceneId: 'office-1',
      ...command
    })
  })
  const { commandId } = await res.json()

  // 轮询等待完成
  while (true) {
    await new Promise(r => setTimeout(r, 500))
    const poll = await fetch(`${OFFICE_URL}/scene/commands/${commandId}`)
    const result = await poll.json()
    if (result.status !== 'pending') return result
  }
}

// Planner 走到 Coder 桌子交代任务
await sendCommand({
  commandId: `plan-to-code-${Date.now()}`,
  type: 'activity.start',
  capability: 'office.visit',
  participants: [
    { entityId: 'planner', role: 'visitor' },
    { entityId: 'coder', role: 'host' }
  ],
  params: {
    stops: [{ hostId: 'coder', message: '需求文档在 /tasks/auth.md,请实现登录逻辑。', reply: '好的' }],
    durationMs: 4000
  }
})

// Coder 切换到专注状态
await sendCommand({
  commandId: `coder-focus-${Date.now()}`,
  type: 'activity.start',
  capability: 'office.focus',
  participants: [{ entityId: 'coder', role: 'worker' }],
  params: { durationMs: 30000 }
})

// 实际执行编码任务...
// await runCodingAgent('coder', '/tasks/auth.md')

// Coder 走到 Reviewer 桌子提交审查
await sendCommand({
  commandId: `code-to-review-${Date.now()}`,
  type: 'activity.start',
  capability: 'office.visit',
  participants: [
    { entityId: 'coder', role: 'visitor' },
    { entityId: 'reviewer', role: 'host' }
  ],
  params: {
    stops: [{ hostId: 'reviewer', message: 'PR #42 已提交,请审查。', reply: '马上看' }],
    durationMs: 3000
  }
})

这段代码跑起来之后,PixOffice 界面里你能看到角色移动、停下来交换消息、然后切换工作状态——多 Agent 工作流的进展有了物理映射。


数据源接入(Dashboard 集成)

PixOffice 支持接入外部业务数据源,通过 VITE_OFFICE_DASHBOARD_URL 环境变量配置:

VITE_OFFICE_DASHBOARD_URL=http://localhost:9000/dashboard

Dashboard endpoint 需要返回场景实体的当前状态快照:

{
  "entities": [
    { "id": "agent-1", "name": "Planner", "status": "idle", "workload": 0.3 },
    { "id": "agent-2", "name": "Coder", "status": "working", "workload": 0.9 },
    { "id": "agent-3", "name": "Reviewer", "status": "available", "workload": 0.1 }
  ],
  "tasks": [
    { "id": "task-42", "assignedTo": "agent-2", "priority": "high" }
  ]
}

场景会根据这份数据初始化角色状态;HTTP 命令可以在此基础上叠加动态行为。


接入注意事项

命令 ID 唯一性:每条 Scene Command 的 commandId 必须唯一,建议用 ${type}-${Date.now()}-${uuid} 格式。重复 ID 会导致轮询结果混淆。

场景 ID 一致性:sceneId 在整个 session 里保持一致,不同 sceneId 的命令互不干扰但也不共享状态。

实体 ID 先发现再用:调用任何命令前先 GET /scene/capabilities,确认目标 entityId 存在。硬编码实体 ID 在场景数据更新后会静默失败。

早期项目:PixOffice 目前 7 颗星,创建于 2026-09-30,API 字段和路由随时可能变化。建议在集成层封装一个薄适配器,把 protocolVersion 和端点路径集中管理,减少升级时的改动面。


MIT 开源。五个 npm workspace 包目前未发布到 registry,需从源码引用。开源仅供学习参考。


🇬🇧 English

PixOffice: Engineering Integration Guide for AI Multi-Agent Visualization

When multiple AI agents are running in parallel, the question isn’t whether they’re working — it’s whether you can tell what they’re doing. Logs are noisy, stdout is a wall of text, and by the time you notice a collision, two agents have been pushing the same task in different directions for an hour.

PixOffice adds a visualization layer: a 2D virtual office scene that you control via HTTP commands. Your agents can walk to a desk, hold a meeting, say something, switch to a focus state. The visual output is a side effect — the actual value is that external systems can drive scene state through standard HTTP, making agent status transitions physically observable.

GitHub: https://github.com/workbzw/pixoffice | ⭐ 7 | MIT | TypeScript


Package Structure

PixOffice uses npm workspaces with five packages. For most integration scenarios, you only need to run the dev server and speak HTTP:

PackageResponsibilityNeeded for HTTP integration?
contractsShared protocol types (Zod schemas)No — just send JSON
runtimeCore engine, works headless in Node.js (no React/Pixi/DOM)Only if building a custom backend
renderer-pixiPixi.js rendering hostOnly for visual display
animation-frameFrame animation playerFrontend dependency
scene-officeOffice scene data and behavior pluginsFrontend dependency

Starting a Local Instance

git clone https://github.com/workbzw/pixoffice.git
cd pixoffice && npm install && npm run dev

Two ports after startup:

  • Frontend display: http://localhost:5173 (Vite dev server)
  • Action Gateway: http://localhost:8765 (HTTP API)

curl -X POST http://localhost:8765/scene/commands \
  -H 'Content-Type: application/json' \
  -d '{
    "protocolVersion": "2.0",
    "sceneId": "office-1",
    "commandId": "task-handoff-001",
    "type": "activity.start",
    "capability": "office.visit",
    "participants": [
      { "entityId": "marvis", "role": "visitor" },
      { "entityId": "code-agent", "role": "host" }
    ],
    "params": {
      "stops": [{ "hostId": "code-agent", "message": "Review this PR when you get a chance.", "reply": "On it" }],
      "durationMs": 3000
    }
  }'

Poll for result: GET /scene/commands/{commandId}

Built-in capabilities: office.visit, office.meeting, office.focus, scene.move, scene.say, office.emote

Discover all entities and capabilities: GET /scene/capabilities


Integration Path 2: Legacy Actions API (Quick Start)

# Walk agent to a desk
curl -X POST http://localhost:8765/actions \
  -d '{"type":"desk_visit","visitor":1,"host":5,"message":"Task assigned."}'

# Move to grid position
curl -X POST http://localhost:8765/actions \
  -d '{"type":"move","entityId":"agent-3","x":12,"y":8}'

# Speak
curl -X POST http://localhost:8765/actions \
  -d '{"type":"say","entityId":"agent-2","text":"Code review done."}'

Synchronous — no commandId or polling. Good for prototyping.


Integration Path 3: Chat SDK Injection

Set VITE_PIXOFFICE_CHAT_URL to point at your agent’s streaming endpoint, or inject directly via the chatSource prop on <OfficeApp>.

Your endpoint returns NDJSON — one JSON object per line with type: "delta" | "done" | "error".


End-to-End Example: Multi-Agent Task Handoff

async function agentHandoff(from: string, to: string, message: string) {
  const res = await fetch('http://localhost:8765/scene/commands', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      protocolVersion: '2.0', sceneId: 'office-1',
      commandId: `handoff-${Date.now()}`,
      type: 'activity.start', capability: 'office.visit',
      participants: [
        { entityId: from, role: 'visitor' },
        { entityId: to, role: 'host' }
      ],
      params: { stops: [{ hostId: to, message, reply: 'Got it' }], durationMs: 3000 }
    })
  })
  return res.json()
}

// Planner → Coder
await agentHandoff('planner', 'coder', 'Implement /tasks/auth.md')

// Coder works, then → Reviewer
await agentHandoff('coder', 'reviewer', 'PR #42 ready for review')

Integration Notes

  • commandId uniqueness: Use ${type}-${Date.now()}-${uuid}. Duplicate IDs cause polling mismatches.
  • Entity IDs: Always call GET /scene/capabilities before sending commands; hardcoded entity IDs fail silently when scene data changes.
  • Early-stage project: 7 stars, created 2026-09-30 — API shape may change. Wrap integration in a thin adapter that centralizes protocolVersion and endpoint paths.

MIT license. The five npm workspace packages are not published to the registry — reference from source. For technical reference only.

💬 评论与讨论

使用 GitHub 账号登录后发表评论

关于本站 · 免责声明

🍄 Mushroom Research Blog 是非营利、免费公开的个人科技观察博客与公众号 XStack18,不接受商业合作、不代表任何企业或机构立场,也不谋求商业利益。我们以个人视角客观中立地记录和分析 AI、Web3 等领域的最新模型发布与技术动态——不止转述新闻标题或二手信息,而是给出有独立思考的深入分析,希望帮更多人获得有价值的一手科技认知。

⚠️ 文中介绍的开源代码与模型,仅供学习交流与技术借鉴。它们大多仍处于早期阶段,有待进一步研究和验证,请勿直接用于工作或生产环境;如需采用,请先自行充分测试,并核实其许可证与安全性。
Open-source code and models featured here are shared for learning and reference only. Most are early-stage and still need further study and verification — please don't use them directly in your work or in production. Test them thoroughly and check their licenses and security first.

  1. 本站文章均为作者基于公开信息的个人研究与观点整理,不代表文中提及的任何公司、产品、模型的官方立场,未与其构成商业关联或合作关系。
  2. 科技行业信息更新极快,我们尽力保证内容准确、及时,但不对完整性、实时性做绝对保证,具体请以相关企业/项目官方公告为准。
  3. 文中引用的第三方商标、产品名称、图片、数据等版权归原权利人所有,我们会尽量注明来源;如你认为存在版权疑问或侵权,请通过下方邮箱联系我们,收到通知后会尽快核实处理(更正、加注来源或删除)。
  4. 文章内容仅为技术科普与个人观点,不构成投资、法律或其他专业建议,据此进行任何决策的后果需自行判断和承担。

📮 侵权 / 勘误 / 合作咨询:[email protected]