Omnigent 架构总览
在 Claude Code / Codex / Pi / 自定义 agent 之上的统一层 —— 跨设备实时协作、混用多 agent、统一策略与沙箱
一句话定位:Omnigent 是一个"元 harness"。它不重新发明 agent,而是在各家 agent 框架(Claude Code、Codex、Pi) 之上抽象出统一层,让你能够 swap or combine harnesses(随意切换/组合)、跨设备接管同一个 live session、 并对所有 agent 统一加上策略(policies)和沙箱(sandbox)。核心思想是: Server 只做协调,真正的 agent 执行发生在你的机器或云沙箱上。
图 1 · Omnigent 六层架构:客户端 → Server → Host → Runner → Harness/Executor → 模型
①客户端层
跨设备实时协作 —— 会话跟随你走:终端发起、浏览器继续、手机接管,消息/子 agent/终端/文件全程同步。
技术栈与通道
前端在 ap-web/:React 18 + TypeScript + Vite + Tailwind + xterm(终端模拟)。
vite build 的产物输出到 omnigent/server/static/web-ui/,由 server 在 / 直接 serve。
与 Server 三种通道:
REST:会话 CRUD / 发消息 WS /v1/sessions/updates:实时推快照+diff WS .../terminal:桥接 tmux PTY 到浏览器
②Server 层 —— 轻量协调器
FastAPI,本身不跑 agent 代码。负责存储会话/用户/agent/策略、做路由与策略校验。内存注册表放活连接,DB 是跨副本真相,因此可水平扩展。代码在 omnigent/server/。
| 路由模块 | 职责 |
|---|---|
routes/sessions.py | 会话 CRUD、消息派发、SSE 事件流、文件上传(最大模块) |
routes/host_tunnel.py | WS /v1/hosts/{id}/tunnel —— host 守护进程外连 |
routes/runner_tunnel.py | WS /v1/runners/{id}/tunnel —— runner 外连 |
routes/hosts.py | 列出 host、启动 runner、代理文件系统浏览 |
routes/auth.py / accounts_auth.py | header / 账号密码 / OIDC 三种认证,4 级权限 |
routes/*_policies.py | session / server-wide 策略 CRUD |
持久化(omnigent/db/ + omnigent/stores/):SQLAlchemy + Alembic,SQLite(本地)或 Postgres(部署)。核心表:
conversations(会话)、conversation_items(消息/工具调用)、agents、hosts、users、session_permissions、files。每表对应一个 Store 抽象。
③Host 层 —— 真正执行的地方
omnigent host 守护进程,可以是你的笔记本,也可以是云沙箱(Modal/Daytona = managed host)。代码在 omnigent/host/。
身份 host_<uuid> 存在 ~/.omnigent/config.yaml,首次 omnigent host 自动创建。
守护进程主动外连 Server 建 WebSocket 隧道,收到 host.launch_runner 帧后派生一个 Runner 子进程(每个 session 一个),并监控其退出、上报状态。
④Runner 层 —— 每会话一个进程
每个 session 派生一个 FastAPI 子进程(omnigent/runner/),是 host 与 harness 之间的中间层。
| 职责 | 说明 |
|---|---|
| harness 生命周期 | 按对话 spawn / 监控 / 回收 harness 子进程,空闲回收 |
| 工具分发 | 把 harness 的工具调用回传 Server 执行(文件、shell、MCP) |
| 资源管理 | 文件、终端(tmux PTY)、MCP 池 |
| 成本 / 审批 | 统计 token 与费用;中转策略 ASK 审批流 |
⑤Harness + Executor —— meta-harness 核心
这是"统一层"真正落地的地方。每个 harness 被包成一个讲同一套 Omnigent REST 协议的 FastAPI 服务,内部用 Executor 适配各家 SDK/CLI。
核心 7 条设计单独成文 → Meta-Harness 核心 7 设计。
Harness 注册表 omnigent/runtime/harnesses/__init__.py
_HARNESS_MODULES = {
"claude-sdk": "...claude_sdk_harness",
"claude-native": "...claude_native_harness", # 包真实 Claude Code CLI
"codex": "...codex_harness",
"codex-native": "...codex_native_harness", # 包真实 codex CLI
"pi": "...pi_harness",
"openai-agents": "...openai_agents_sdk_harness",
}
统一接口 —— 为什么能 swap / combine
所有 harness 最终都实现同一个抽象:
class Executor:
async def run_turn(messages, tools, system_prompt, config)
-> AsyncIterator[ExecutorEvent]
# 事件:TextChunk · ToolCallRequest · TurnComplete · ReasoningChunk ...
上层(workflow / runner)只认 Executor 这套事件流,完全不关心底下是 Claude SDK 还是 codex CLI。
这就是 README 所说 "swap or combine harnesses without rewriting" 的实现根基。具体实现在 omnigent/inner/*_executor.py(例如 codex_executor.py)。
⑥底层模型 / CLI
凭证全部一等公民:API key、订阅(Claude Pro/Max、ChatGPT/Codex)、兼容网关(OpenRouter/Ollama)。
native harness 直接包真实 CLI(Claude Code / codex),复用其订阅登录。
Agent 配置:agent.yaml → AgentSpec
一个 agent 由声明式 YAML 定义(docs/AGENT_YAML_SPEC.md),解析为 AgentSpec(omnigent/spec/types.py)。
| 字段 | 含义 |
|---|---|
executor | harness + model + auth —— 跑在什么上 |
prompt | 系统提示 |
tools | MCP 服务、Python 函数、子 agent |
guardrails | 策略、标签、ASK 超时 |
os_env | 本地文件/shell 沙箱配置 |
spawn | 是否允许用 sys_session_create 创建自定义子 agent |
多 agent 编排
编排器(如示例 examples/polly/)通过系统工具异步派发子 agent:
sys_session_send 派活
sys_read_inbox 收结果
sys_session_create 创建子 agent
每个子 agent 各自跑自己的 harness —— 例如 polly 的大脑跑 Claude,把编码任务委派给 codex 子 agent,
这些 codex 子 agent 共享你的 Codex 订阅(凭证桥接见下文)。
策略与沙箱(横切)
三级策略(session → agent → server-wide)在工具调用边界由 PolicyEngine 评估,返回 ALLOW / DENY / ASK。
内置:成本预算、危险工具需审批、GitHub/Google 工作区限制、模型路由等。沙箱按 os_env 走 Linux bwrap / macOS seatbelt。
一次用户请求的完整数据流
- 浏览器创建会话
POST /v1/sessions,Server 建conversations行并选定 host - Server 经 host 隧道发
host.launch_runner→ Host 派生 Runner 子进程 - Runner 主动外连
WS /v1/runners/{id}/tunnel注册 - 用户发消息
POST /v1/sessions/{id}/events→ Server 过策略、存 DB、经隧道转给 Runner - Runner 经 Unix socket 转给 harness 子进程 → harness 跑 LLM 循环
- harness 要调工具 → 回传 Server 执行(文件/shell/MCP)→ 结果回灌继续循环
- 事件流式回传 → Server 经
WS /v1/sessions/updates推给前端实时渲染
Codex 订阅如何被多 agent 共用
每个 session 创建私有临时 CODEX_HOME,再把用户真实 ~/.codex/ 桥接进去
(omnigent/inner/codex_executor.py):
auth.json → 软链接(共享订阅 + token 自动刷新) config.toml → 复制(隔离模型/成本策略) 剥离 OPENAI_API_KEY(强制走订阅而非按量计费)
因此多个 agent/session 共享同一份订阅凭证,但各自的模型选择与会话历史互不干扰。
目录速查
| 目录 | 是什么 |
|---|---|
omnigent/cli.py | CLI 总入口(omnigent/omni) |
omnigent/server/ | FastAPI server、路由、认证 |
omnigent/host/ | host 守护进程 |
omnigent/runner/ | runner + WS 隧道传输 |
omnigent/runtime/harnesses/ | harness 注册与进程管理 |
omnigent/inner/*_executor.py | 各家 Executor 实现(含 codex_executor.py) |
omnigent/spec/ | AgentSpec 类型定义 |
omnigent/policies/ · sandbox/ | 策略与沙箱 |
omnigent/stores/ · db/ | 持久化 |
ap-web/ | React 前端 |
deploy/ | Docker / Render / Railway / Fly / Modal 部署 |
examples/polly · debby | 示例 agent(多 agent 编排器 / 双头脑) |