乐于分享
好东西不私藏

OpenAgents 源码深度解析:重构多智能体协作的网络模型

OpenAgents 源码深度解析:重构多智能体协作的网络模型

与其打造一个「智能的」代理,不如打造一个「懂得如何让智能体协作的网络」。

OpenAgents 正在做的事情,可能是 AI Agent 生态中「最被低估的基础架构创新」。

当大家都在讨论如何让单个 Agent 变得更聪明时,OpenAgents 提出了一个更根本的问题:如果未来有成千上万的 AI 代理在不同的工具、平台和服务上运行,它们如何相互发现、通信和协作?

他们的答案是:一个事件驱动的网络模型(OpenAgents Network Model),定义了智能体之间通信、发现、共享资源和跨网络路由的通用规则。

这不是另一个 Agent 框架,而是一个让所有 Agent 能够互操作的基础层。就像 TCP/IP 之于互联网,OpenAgents 试图成为「智能体互联网」的协议栈。

一、核心思想:事件,而非请求

OpenAgents 最根本的设计决策是:所有交互都建模为事件(events)。

事件即一切

在传统的 Agent 框架中,你会看到各种不同的抽象:

  • Messages(消息):Agent A 发给 Agent B 的文字
  • Commands(命令):让另一个 Agent 执行某个操作
  • RPC Calls(远程调用):同步的函数调用
  • Notifications(通知):单向推送

OpenAgents 把它们全部统一为 Event 对象。一个事件包含:

class Event(BaseModel):
    idstr                      # 唯一标识符 (UUID/ULID)
    typestr                    # 事件类型,如 "workspace.message.posted"
    source: str                  # 发送方地址,如 "openagents:claude-agent"
    target: str                  # 接收方地址(从不为空)
    payload: Any                 # 事件载荷,结构取决于 type
    metadata: Dict[strAny]     # 协议级元数据(如 in_reply_to)
    timestamp: int               # 时间戳(毫秒)
    network: str                 # 事件起源的网络 ID
    visibility: EventVisibility  # 可见性控制

为什么用事件? 因为事件能够组合。请求-响应是一对事件通过 in_reply_to 关联;广播是发给 agent:broadcast;工具调用是发给 resource/tool/search_web一个原语(event)搞定所有通信模式——点对点、广播、发布订阅、请求响应。

事件类型遵循命名空间规范

network.*              # 核心事件(保留命名空间,所有实现必须支持)
  network.agent.join
  network.resource.invoke
  workspace.*           # 扩展事件(Workspace 产品用)
  workspace.message.posted
  myapp.task.assigned   # 自定义扩展事件(任何非 network.* 的命名空间)

核心事件(network.*) 定义了网络必须支持的基础操作:Agent 加入/离开、资源注册/发现、通道创建等。其他都是扩展。

二、网络:有边界的上下文

OpenAgents 的核心抽象是 Network —— 一个 Agent 能够相互通信的有界上下文。

网络的属性

Network {
  id:              string        # 全局唯一(如 "a1b2c3d4")
  name:            string        # 人类可读名称
  access: {
    policy:        open | token | invite | did-verify
    min_verification: 0 | 1 | 2 | 3
  }
  delivery:        at-least-once | at-most-once
  status:          active | paused | archived

  agents:          [Agent]       # 成员列表
  mods:            [Mod]         # 有序的事件管道
  channels:        [Channel]     # 命名的事件流
  groups:          [Group]       # 命名
  resources:       [Resource]    # 共享工具、文件、上下文

  transports:      [Transport]   # 支持的网络传输(HTTP, WS, gRPC...)
}

边界不泄漏

OpenAgents 最重要的设计约束:事件不会自动泄露。 在 Network A 内发出的事件永远不会被发送到 Network B,除非某个同时属于两个网络的 Agent 显式地桥接它们。

这就像现实世界:一个 Slack 工作区、一个 Discord 服务器、一个 Kubernetes 命名空间——每个都有其自己的规则。Agent 如果需要参与多个上下文,就加入多个网络。模型通过跨网络寻址({network}::{entity})原生支持这一点。

成员身份与角色

每个 Agent 在网络中都有一个成员记录:

Membership {
  address:         string         # 该网络中的地址
  role:            master | member | observer
  verification:    0 | 1 | 2 | 3   # 验证级别
  status:          online | offline
}

三、寻址:标识即地址

OpenAgents 采用 统一的标识符系统 —— 每个实体只有一个标识符,它既是路由地址,也是身份标识。没有分离的「地址」和「ID」。

实体类型

前缀 实体 示例 说明
agent: 本地 Agent agent:charlie 网络范围,不可注册为全局 ID
openagents: 全局 Agent openagents:charlie123 注册过的、Level 2+ 的全局身份
human: 人类用户 human:raphael 仅限网络本地
channel/ 通道 channel/general 命名的事件流
mod/ Mod mod/persistence 事件管道拦截器
group/ group/team-alpha Agent 集合
resource/tool/ 工具 resource/tool/search_web 可调用的共享工具
resource/file/ 文件 resource/file/requirements.md 共享文件
resource/context/ 上下文 resource/context/project-brief 共享上下文
core 网络系统 core 保留地址,始终存在

网络作用域

本地(在当前网络内):
  agent:charlie                    隐式为 local::agent:charlie
  channel/general                  隐式为 local::channel/general

跨网络:
  network123::agent:charlie        network123 中的 agent:charlie
  network123::channel/general      network123 中的通道

解析规则(源码实现)

src/openagents/core/onm_addressing.pyparse_address() 函数可以看到完整的解析逻辑:

def parse_address(raw: str) -> Address:
    # 1. 如果包含 "::" → 以第一个 "::" 分割,左边是 network,右边是 entity
    # 2. 如果没有 "::" → network 为 "local"(隐含),整个字符串是 entity
    # 3. 确定 entity 类型:
    #    - 以 "agent:"、"openagents:"、"human:" 开头 → 对应类型
    #    - 以 "channel/"、"mod/"、"group/"、"resource/" 开头 → 对应类型
    #    - 等于 "core" → 网络系统
    #    - 裸字符串(无前缀)→ 默认为 agent:{string}

    # 返回 Address(network, entity_type, name)

这个设计非常精巧:一个字符串就能表达所有地址,从本地 Agent 到跨网络引用,从系统操作到共享资源。而且可解析、可路由、可验证。

四、验证:渐进式身份证明

OpenAgents 不强制所有场景使用同一套身份机制。它定义了四个验证级别,让每个网络可以设置自己的最低要求,每个 Agent 可以展示它拥有的级别:

Level 0 — 匿名

地址:    agent:{name} 或 human:{identifier}
证明:    无
信任:    网络本地,操作者信任所有参与者
适用:    本地开发、临时 Agent、人类用户、原型

Agent 声称一个名字,网络不经证明就接受。任何人在不同网络中都可以声称相同的名字。

Level 1 — 密钥证明

地址:    agent:{name}
证明:    挑战-响应(使用私钥签名)
信任:    网络验证了该 Agent 控制一个特定的加密密钥
适用:    需要基础认证的私有网络

网络发出挑战,Agent 用私钥签名。网络验证签名。这证明密钥所有权,但不颁发持久凭证。

Level 2 — Token (JWT)

地址:    openagents:{name}
证明:    OpenAgents 身份服务签名的 JWT
信任:    中心化验证,可在跨网络中携带
适用:    生产环境 Agent、跨网络识别

Agent 已在 OpenAgents 身份服务注册,获得 JWT 令牌。令牌携带 Agent 名字、验证级别、过期时间。其他网络可以验证 JWT,无需联系该 Agent。

支持签名算法:RS256、Ed25519、ES256。

Level 3 — DID (去中心化身份)

地址:    openagents:{name}  (可解析为 did:openagents:{name})
证明:    包含验证方法和服务端点的 W3C DID 文档
信任:    去中心化、自主管理、不依赖中心服务
适用:    最大信任度、联邦、开放生态

Agent 拥有 W3C 兼容的 DID 文档,包含公钥、认证方法和服务端点。任何第三方都可以解析该 DID 并验证 Agent 身份。

验证级别与地址形式对应表

Level 地址形式 证明 作用域 可注册为 OpenAgents ID
0 agent:{name} / human:{id} 网络本地
1 agent:{name} 挑战-响应 网络本地
2 openagents:{name} JWT 全局
3 openagents:{name} DID 文档 全局

这个渐进式模型非常务实:本地开发零摩擦,生产环境可验证,跨网络可联邦。

五、Mods:可插拔的事件管道

这是 OpenAgents 架构中最具扩展性的设计。

什么是 Mod?

Mods 是事件管道中的有序拦截器。事件在管道中流动时,Mods 可以:

  • Guard 模式:拒绝事件(如认证失败、超限)
  • Transform 模式:修改事件(如添加元数据、重写路由)
  • Observe 模式:仅观察(如日志、持久化、分析)

管道流程

Event emitted
  → [Guard mods]      可以提前拒绝
  → [Transform mods]  可以修改事件
  → [Observe mods]    可以记录但不能修改
  → Delivery to target

如果一个 Guard Mod 拒绝了事件,管道停止,事件不传递,并向源发送 network.event.error

标准 Mods

OpenAgents 定义了一套标准 Mods,任何网络都可以加载:

Mod 模式 用途
mod/auth guard 验证 Agent 身份和网络访问权限
mod/access-control guard 执行资源权限检查
mod/rate-limiter guard 防止事件洪泛
mod/enrichment transform 添加元数据(时间戳、Agent 信息)
mod/workspace transform Workspace 功能:会话、状态、委托
mod/persistence observe 将事件存储到数据库
mod/analytics observe 跟踪使用指标

管道排序

Mods 按模式排序(guard < transform < observe),同一模式内按 priority 排序(数字越小越靠前)。这样,认证和速率限制的 Guard 最先执行,持久化和分析的最后执行。

源码实现(src/openagents/core/onm_pipeline.py):

_MODE_ORDER = {"guard"0"transform"1"observe"2}

class Pipeline:
    def _sort(self):
        self._mods.sort(key=lambda m: (_MODE_ORDER.get(m.mode, 99), m.priority))

    async def process(self, event: Event, context: PipelineContext) -> Event:
        for mod in self._mods:
            if not mod.matches(event.type):
                continue
            try:
                if mod.mode == "guard":
                    result = await mod.process(event, context)
                    if result is None:
                        raise EventRejected(mod.name, "rejected by guard")
                    event = result
                elif mod.mode == "transform":
                    result = await mod.process(event, context)
                    if result is not None:
                        event = result
                elif mod.mode == "observe":
                    await mod.process(event, context)  # 返回值忽略
            except EventRejected:
                raise
            except Exception:
                logger.exception("Mod %s raised an unexpected error", mod.name)
                raise
        return event

持久化是可选的

事件持久化不是模型的核心要求。它由 mod/persistence 提供,按需加载

  • mod/persistence 的网络:事件存储,可通过 network.events.query 查询
  • 没有 mod/persistence 的网络:事件传递完即丢弃,查询返回空或错误

这种设计非常干净:核心模型保持小而稳定,所有高级能力都是可选的 Mods。

六、资源:共享的工具、文件和上下文

OpenAgents 将共享资源提升为一等公民,有自己专用的地址空间 resource/

资源类型

类型 地址 描述
工具 resource/tool/{name} 一个可调用的函数或 API
文件 resource/file/{path} 共享文档、数据文件
上下文 resource/context/{name} 共享内存、指令、知识

资源属性与权限

Resource {
  address:       string              e.g., resource/tool/search_web
  type:          tool | file | context
  owner:         string              拥有者的 Agent 地址
  description:   string              人类可读描述

  schema:        {}                  tools: 输入输出模式
  content_type:  string              files: MIME 类型

  permissions: {
    read:        AccessRule          谁可以看到资源存在并读取
    write:       AccessRule          谁可以修改(仅文件/上下文)
    invoke:      AccessRule          谁可以调用(仅工具)
    admin:       AccessRule          谁可以更改权限或注销
  }
}

权限规则示例:

  • "network":网络内任何 Agent
  • "role:master":仅特定角色
  • "group/team-alpha":仅特定组的成员
  • "agents:[addr1, addr2]":显式白名单
  • "owner":仅所有者

资源发现

Agent 通过向 core 发送 network.resource.discover 事件来发现可用资源:

# 请求
Event {
  type"network.resource.discover",
  source: "agent:alice",
  target: "core",
  payload: { type"tool" }  # 可选过滤器
}

# 响应
Event {
  type"network.resource.discover.response",
  target: "agent:alice",
  payload: {
    resources: [
      {
        address: "resource/tool/search_web",
        owner: "openagents:claude-agent",
        description: "Search the web for information",
        schema: { input: { query: "string" }, output: { results: "array" } },
        your_permissions: ["read""invoke"]
      }
    ]
  }
}

权限执行

mod/access-control 在事件管道中拦截针对资源的操作,验证源 Agent 是否有对应权限。没有细粒度权限需求的网络可以跳过这个 Mod。

七、传输无关:HTTP, WebSocket, gRPC, stdio, A2A, MCP

OpenAgents 的核心模型是传输无关的。事件是抽象的,如何变成网络上的字节流是传输绑定的任务。

标准绑定

传输 风格 用例
HTTP/REST 请求-响应、轮询 Web UI、简单集成、Workspace 前端
WebSocket 双向、实时 实时 Agent 通信、动态更新
gRPC 流式、高性能 高吞吐 Agent 网络、SDK 对 SDK
SSE 服务器推 单向通知、实时推送
Stdio 换行符分隔 JSON 本地子进程 Agent(如 MCP)
A2A Google Agent-to-Agent 协议 与 A2A 兼容的 Agent 互操作
MCP Model Context Protocol 与 MCP 兼容的工具和 Agent 互操作

两个在同一网络中的 Agent,一个用 HTTP,一个用 WebSocket,可以无缝通信。网络在两端处理传输转换,事件是相同的,只有序列化不同。

HTTP 绑定(参考实现)

HTTP 绑定是 OpenAgents Workspace 的主要传输:

Join network:       POST /v1/join            { agent_id, credentials }
Leave network:      POST /v1/leave           { agent_id }
Send event:         POST /v1/events          { event JSON }
Poll events:        GET  /v1/events          ?after={last_event_id}&limit=50
Heartbeat:          POST /v1/heartbeat       { agent_id }
Discovery:          GET  /v1/discover        (network.agent.discover 的简写)
Network profile:    GET  /v1/profile         (返回 NetworkProfile)

这个简单的 HTTP API 让浏览器、手机 App、任何能发 HTTP 请求的东西都能接入网络。

八、跨网络通信:发送方驱动

OpenAgents 中的网络是有边界的。跨网络通信是发送方驱动的——发送方 Agent 必须直接连接到目标网络。没有自动的网络间路由。

流程

1. agent:alice 在 network A 中,想联系 openagents:bob(在 network B)。
2. alice 通过 DID、直接 URL 或配置解析 network B 的资料。
3. alice 使用 network B 的一种传输方式连接并加入。
4. alice 使用 network B 的本地寻址发送事件:
   Event { source: "agent:alice", target: "openagents:bob", ... }
5. Network B 将事件路由到 openagents:bob。

跨网络寻址

{network}::{entity} 格式告诉发送方(而非发送方网络)应该路由到哪个网络:

network123::agent:charlie   → 到达 network "network123" 中的 agent:charlie

发送方必须知道如何到达目标网络(通过配置文件、DID 解析或硬编码 URL)。

九、与 MCP 的关系:互补而非竞争

MCP(Model Context Protocol)是 Anthropic 推出的、让 LLM 应用连接外部数据源和工具的协议。许多人问:OpenAgents 和 MCP 是什么关系?

答案是:互补。

  • MCP 关注的是「单个 LLM 应用如何连接到外部工具和数据」。它定义了标准的服务器-客户端架构,LLM 应用(宿主)通过 stdio 或 SSE 连接到 MCP 服务器。
  • OpenAgents 关注的是「多个 Agent 如何在共享网络中相互发现、通信和协作」。

实际上,OpenAgents 内置了 MCP 传输绑定src/openagents/sdk/transports/mcp.py)。这意味着:

  1. 一个 OpenAgents 网络可以暴露 MCP 端点,让任何 MCP 客户端(如 Claude Desktop)把它当作一个标准 MCP 服务器使用。
  2. 一个 OpenAgents Agent 可以作为 MCP 客户端连接到外部 MCP 服务器,将 MCP 工具桥接到 OpenAgents 网络,注册为 resource/tool/
  3. 通过这种桥接,MCP 生态系统中的工具可以被 OpenAgents 网络中的所有 Agent 共享;反过来,OpenAgents 网络中注册的工具也可以被 MCP 宿主使用。
MCP 客户端                OpenAgents 网络
   │                          │
   │   MCP 连接 (stdio/SSE)   │
   ↓                          ↓
MCP Transport Bridge  ←→  MCP Transport Bridge
   │                          │
   │   MCP 调用               │   OpenAgents 事件
   ↓                          ↓
 工具 ↔ resource/tool/xyz

这种设计让 OpenAgents 成为多协议网关:不取代 MCP,而是连接它。

十、与 A2A 的对比:拓扑决定差异

Google 的 A2A(Agent-to-Agent)协议与 OpenAgents 经常被拿来比较。它们目标相似但拓扑根本不同:

维度 A2A 协议 OpenAgents Network Model
拓扑 点对点(客户端→服务器) 多对多在共享网络内
核心抽象 任务及其生命周期状态 流经网络的事件
通信模型 请求-响应:发消息 → 得任务结果 连续事件流:事件流动,部分是响应
Agent 模型 暴露技能的透明黑盒 网络成员,有地址、角色、验证、共享资源
有界上下文 无(Agent 直接交互) 网络是基础边界;事件不泄漏
发现 通过 well-known URI (/.well-known/agent-card.json) 和注册表 网络内事件式发现 (network.agent.discover) + 跨网络 DID 解析
状态模型 状态化任务生命周期(pending → working → completed/failed) 无状态事件;状态是应用级的,持久化是可选的 mod/persistence
扩展性 Agent Card 中声明的技能 事件管道中的 Mods,扩展事件命名空间
流式传输 SSE + Webhooks 传输依赖(WebSocket, SSE, 轮询)
共享资源 未解决(MCP 负责工具) 一等公民:工具、文件、上下文,带权限
多 Agent 组 未解决(仅双边) 通道、组、广播寻址

关键差异

1. 任务中心 vs. 事件中心
A2A 围绕任务组织协作——客户端发送消息,服务器创建任务,推进状态,产生产物。OpenAgents 没有任务概念。一切皆事件。请求-响应模式被建模为由 metadata.in_reply_to 链接的事件对。这使模型更灵活(事件可以单向、扇出或对话式),但更少关于工作流结构。

2. 双边 vs. 网络
A2A 定义 Agent A 如何与 Agent B 说话。OpenAgents 定义 Agent A、B、C、D 如何在共享网络中通信——有通道、组、广播和 Mods 调解交互。A2A 没有「网络」作为有界上下文的概念,没有事件管道,没有 Mod 系统。

3. 发现模型
A2A 使用 well-known URI,每个 Agent 在其 /.well-known/agent-card.json 发布技能、认证要求、端点。OpenAgents 使用网络内事件式发现,以及跨网络 DID 解析。

4. 身份与验证
A2A 将认证委托给标准的 HTTP 方案(Bearer tokens, OAuth2, API keys),在 Agent Card 中声明。OpenAgents 定义了四个渐进式验证级别(匿名→密钥证明→JWT→DID),验证级别作为每个 Agent 网络成员资格的一部分被追踪。

互操作性

OpenAgents 网络模型将 A2A 列为传输绑定。这意味着:

  • 一个 OpenAgents Agent 可以暴露 A2A 兼容接口,发布描述其能力的 Agent Card。
  • 一个 A2A 客户端可以与 OpenAgents Agent 交互,完全不知道它背后是一个网络——它只看到一个标准的 A2A 端点。
  • 反向地,OpenAgents 网络可以通过将 A2A 视为传输来集成外部 A2A Agent:在边界处事件被翻译为 A2A 消息/任务。
外部 A2A Agent                     OpenAgents 网络
┌──────────────┐                      ┌───────────────────────┐
│              │  A2A SendMessage      │                       │
│  A2A Client  │ ──────────────────→  │  A2A Transport Bridge │
│              │                      │  (翻译为 Event)       │
│              │  ←──────────────────  │                       │
│              │  A2A Task/Artifact    │  ← 网络中的事件       │
└──────────────┘                      └───────────────────────┘

A2A 传输绑定将:

  • A2A SendMessage → OpenAgents 事件(适当类型和目标)
  • A2A Task 状态 → OpenAgents 事件
  • A2A Artifact → OpenAgents 事件载荷或 resource/file/
  • A2A AgentSkill → OpenAgents resource/tool/ 注册

这使得 A2A 成为外部互操作的对等协议,而 OpenAgents 网络模型是 Agent 系统内部架构。

十一、Workspace 产品:模型的具体实现

OpenAgents Workspace 是一个托管的产品,让多 Agent 协作开箱即用。它就是一个预配置的 OpenAgents Network:

Network {
  id:       "{workspace-slug}"        e.g., "a1b2c3d4"
  name:     "{workspace-name}"        e.g., "My Research Workspace"

  access: {
    policy:          "token"
    min_verification: 0              接受匿名 Agent
  }

  delivery:  "at-least-once"

  mods: [
    mod/auth                          guard     — 验证工作区 token
    mod/access-control                guard     — 检查资源权限
    mod/workspace                     transform — 会话管理、状态、委托
    mod/persistence                   observe   — 保存事件到 PostgreSQL
  ]

  transports: [
    { type: "http",      endpoint: "https://workspace.openagents.org/v1/ws/{slug}" }
    { type: "websocket", endpoint: "wss://workspace.openagents.org/ws/{slug}" }
  ]
}

Workspace 概念到模型的映射

Workspace 概念 模型等价物
Workspace Network
Workspace token 网络访问令牌
Session / thread channel/session-{id}
Chat message workspace.message.posted 事件
Status update workspace.message.status 事件
Agent roster network.agent.discover 响应
Master agent 线程级属性(不是模型概念,Workspace 实现细节)
Human user human:{email} 在网络中
Invitation workspace.invitation.created 事件

Workspace 特有的事件类型(扩展)

workspace.message.posted          会话中的聊天消息
workspace.message.status          会话中的状态更新
workspace.session.created         新会话/线程创建
workspace.session.updated         会话重命名、状态更改
workspace.invitation.created      发送的 Agent 邀请
workspace.invitation.accepted     Agent 接受邀请
workspace.invitation.rejected     Agent 拒绝邀请

十二、技术栈与实现细节

从源码结构来看,OpenAgents 的技术栈选择务实且现代:

Python 生态

整个核心和 SDK 使用 Python 3.12+,利用:

  • Pydantic 做类型安全的模型定义(EventAddressNetworkConfig
  • aiohttp 作为 HTTP 服务器和客户端
  • asyncio 原生异步处理高并发
  • yaml 配置管理
  • sqlite/PostgreSQL(通过 workspace_manager)做持久化

架构分层

├── openagents/
│   ├── core/              # ONM 核心模型(纯Python,无外部依赖)
│   │   ├── onm_events.py    # 事件定义
│   │   ├── onm_addressing.py # 寻址解析
│   │   ├── onm_mods.py       # Mod 抽象
│   │   ├── onm_pipeline.py   # 事件管道
│   │   └── onm_network.py    # 网络概念(早期设计)
│   │
│   ├── sdk/               # 可运行的实现
│   │   ├── network.py        # AgentNetwork(运行实体)
│   │   ├── transports/       # HTTP, WS, gRPC, MCP, A2A
│   │   ├── event_gateway.py  # 事件网关
│   │   ├── topology.py       # 拓扑(集中式/去中心化)
│   │   ├── mod_registry.py   # Mod 注册表
│   │   └── workspace_manager.py  # 工作区存储
│   │
│   ├── client/            # CLI 工具(agn)
│   │   ├── cli.py            # 命令行入口
│   │   └── launchers/        # Agent 启动器
│   │
│   └── studio/            # Web UI(前端单独仓库)

事件网关(Event Gateway)

event_gateway.py 是网络的心脏。它接收事件,运行管道,路由到目标,处理跨网络桥接。

network.py_create_network_context() 可以看到,网络创建时就建立了一个 EventGateway 实例,并注入 emit_event 回调:

async def emit_event(event: Event, enable_delivery: bool = True):
    return await self.event_gateway.process_event(event, enable_delivery=enable_delivery)

这个 emit_event 函数作为所有 Mod 产生副作用(side effects)的标准方式。

传输设计

每种传输都继承 Transport 基类,实现 send()receive()connect()close() 等接口。HTTP 传输(http.py)使用 aiohttp 暴露 REST API,同时可选择性地服务 MCP (/mcp) 和 Studio (/studio) 端点。

MCP 传输支持让 Claude Desktop 等 MCP 主机可以把 OpenAgents 网络当作一个 MCP 服务器使用,反之亦然——OpenAgents 可以作为 MCP 客户端连接到外部 MCP 服务器。

Mod 注册表(Mod Registry)

mod_registry.py 管理动态加载的 Mods。网络从配置文件加载 Mods,Mods 可以是内置的(如 mod/auth)或第三方插件(从 PyPI 安装)。

网络初始化时,ModRegistry 实例化所有 Mod,将它们加入管道的 Pipeline 对象。

十三、技术架构的优雅之处

OpenAgents 的网络模型展示了罕见的设计成熟度。让我总结它的几个优雅之处:

1. 单一原语,无限可能

一个 Event 对象搞定所有通信模式。不需要为消息、命令、通知分别设计类型。不需要专用的 API 端点。各种协作模式都只是事件类型不同。

2. 边界明确,安全可控

网络作为有界上下文,事件不自动泄漏。跨网络通信必须是发送方主动桥接。这提供了天然的安全边界:一个工作区的数据不会意外溢出到另一个。

3. 渐进增强,从简单到复杂

  • 本地开发:零配置,所有 Agent 匿名,网络开放
  • 生产环境:添加 token 认证、速率限制、持久化
  • 联邦场景:启用 DID 验证,跨网络路由

同一个模型适应从小作坊到跨国企业的所有场景。

4. 管道拦截,无限可扩展

Mod 系统让网络行为可以在不修改核心的情况下无限扩展。添加审计日志?写一个 mod/audit。添加会话超时?写一个 mod/session-timeout。添加自定义授权逻辑?写一个 mod/my-auth

核心模型保持小而稳定(ONM spec 文档仅 30 页),所有高级功能都是可选的插件。

5. 传输无关,协议中立

核心不关心事件用 HTTP、WebSocket、gRPC、stdio、A2A 还是 MCP 传输。绑定可以随时添加,不影响核心语义。这意味着今天写的逻辑,五年后依然可用,无论传输技术如何变迁。

6. 资源作为一等公民

工具、文件、上下文不再是第三方附加,而是网络模型的一部分。它们有地址、有权限、可通过标准事件操作。这种统一性让「共享」变得自然——任何 Agent 发布一个资源,整个网络都能发现和使用。

7. 地址即身份

openagents:{name} 既是路由地址,也是身份标识。DID 映射让跨网络验证成为可能。没有分离的「注册表」和「路由器」——一个地址搞定。

8. 事件溯源的内置可能

mod/persistence 将所有事件存储到数据库。这意味着任何 Agent 都可以通过 network.events.query 重建任意会话的完整历史。配合 mod/access-control,可以构建细粒度的审计系统。

十四、与 AsyncAPI 的关系:文档与运行的互补

AsyncAPI 是描述异步 API 的开放规范(OpenAPI 的异步版本)。它定义了机器可读的方式来描述通道、消息、操作、服务器和协议绑定。

关系:互补,不竞争。

关注点 AsyncAPI OpenAgents Network Model
目的 描述异步 API 用于文档和代码生成 定义 Agent 如何在运行时通信、发现、共享资源
核心抽象 通道、消息、操作 网络、事件、Mods、寻址
Agent 身份 未涉及 四层验证(L0–L3),统一寻址,DID 映射
发现 带外(开发者门户、目录) 网络内事件式发现 (network.agent.discover) + 跨网络 DID 解析
事件管道 未涉及 Mods:有序的 guard → transform → observe 拦截器
共享资源 未涉及 一等公民:工具、文件、上下文,带权限
传输 协议无关(19+ 绑定) 协议无关(HTTP, WebSocket, gRPC, stdio, A2A, MCP)
网络边界 未涉及 明确的作用域,跨网络寻址 ({network}::{entity})

如何协同工作: 一个 OpenAgents 网络的传输端点可以使用 AsyncAPI 文档描述。例如,Workspace 的 WebSocket 绑定可以写一个 AsyncAPI spec——列出事件类型作为消息,channel/ 实体作为通道,core 作为系统通道。这让外部开发者可以生成客户端代码并理解接口,而无需阅读完整模型 spec。

AsyncAPI 文档描述接口表面:
  通道 → channel/general, channel/session-{id}, core
  消息 → workspace.message.posted, network.agent.join, ...
  服务器 → wss://workspace.openagents.org/ws/{slug}

OpenAgents Network Model 定义底层行为:
  事件如何路由、谁可以发送什么、哪些 Mods 拦截、
  如何验证 Agent 身份、如何共享资源

AsyncAPI 是网络外部表面的文档工具。OpenAgents Network Model 是底层的运行时架构。

十五、为什么 OpenAgents 重要

当前 Agent 生态的碎片化

今天的 AI Agent 生态是割裂的:

  • 每个框架有自己的 Agent 身份方式(API keys, OAuth, 或无)
  • 每个框架有自己的通信协议(HTTP JSON, WebSocket, gRPC, 子进程 stdio)
  • 每个框架有自己的发现机制(硬编码 URL, 服务注册, well-known)
  • 没有标准方式让 Agent A(运行在 Cursor)与 Agent B(运行在 Claude Code)共享文件或协调工作

结果是:Agent 的「互联网」不存在。 每个 Agent 是孤岛,需要定制胶水代码才能互操作。

OpenAgents 提出的解决方案

就像 TCP/IP 让互联网成为可能,OpenAgents 试图提供 Agent 互操作所需的基础层:

  • 统一的身份系统:从匿名到 DID,渐进式验证
  • 统一的事件协议:一个原语表达所有交互
  • 统一的发现机制:网络内事件发现 + 跨网络 DID 解析
  • 统一的关系边界:网络作为有界上下文,边界的收缩与扩展都有明确语义
  • 统一的扩展机制:Mods 让网络功能可组合

能带来什么?

如果 OpenAgents 模型被广泛采纳,我们可以期望:

  1. 跨平台 Agent 协作成为默认:运行在 Cursor 里的 Agent 与运行在 Claude Code 的 Agent 可以是同一网络的成员,共享文件、工具、上下文,直接 @提及协作。

  2. Agent 市场:你可以在网络上注册一个 Agent 作为 resource/tool/{name} 提供「股票分析」能力,其他 Agent 可以通过标准事件 network.resource.invoke 调用它,就像调用本地函数。

  3. 工作流引擎:一个「工作流 Agent」可以在网络上订阅 network.agent.discover 动态发现可用工具,组装成可重复使用的流程,并将结果写入 resource/file/ 共享回来。

  4. 联邦:你的公司网络(acme-corp)和外包合作伙伴网络(vendor-xyz)可以联邦——相互发现 Agent 和工具,基于令牌或 DID 建立信任边界。

  5. 审计与合规:启用 mod/persistencemod/access-control,所有 Agent 交互都有不可篡改的审计日志。

  6. 开发工具标准化:不再需要为每个 Agent 框架写适配器。一个网络接口,所有框架都能接入。

现实挑战

  • 采用度:需要足够多的 Agent 框架支持才能产生网络效应。
  • 性能:事件管道 + 多跳跨网络可能引入延迟。需要优化。
  • 安全性:DID 验证、资源权限、跨网络信任需要仔细设计。
  • 工具生态系统:需要丰富的基座 Mods(审计、监控、计费)才能满足企业需求。

这些挑战都是可解决的,而且 OpenAgents 团队似乎有清晰的 roadmap。

十六、代码中看到的未来

从源码中可以看到一些有趣的设计决策:

1. 网络模式:集中式 vs. 去中心化

topology.py 定义了 NetworkModeCENTRALIZED(有中心枢纽)和 DECENTRALIZED(无中心,P2P)。这意味着 OpenAgents 可以运行在两种拓扑:

  • 托管服务(如 Workspace)用集中式
  • 自托管、离线网络、点对点协作可以用去中心化

2. A2A 集成是头等公民

src/openagents/sdk/transports/a2a.py 实现了 Google A2A 协议桥接。这个决定意味着 OpenAgents 不试图取代 A2A,而是兼容它。一个 OpenAgents Agent 可以作为 A2A 服务器,也可以作为 A2A 客户端连接外部 Agent。

3. MCP 集成深入

MCP 传输不只是桥接消息,还支持:

  • MCP 工具收集:OpenAgents 网络可以把自身注册的工具以 MCP 格式暴露给外部客户端
  • MCP 协议会话管理
  • SSE 用于 MCP 通知

这表明 OpenAgents 团队认真对待与现有生态(尤其是 Claude 生态)的互操作。

4. 工作区管理器抽象

workspace_manager.py 抽象了存储后端,支持:

  • 持久化工作区(目录结构:agents/, files/, mods/, logs/
  • 临时工作区(内存存储,用于测试)

工作区目录结构有清晰的约定:

workspace/
├── agents/           # Agent 配置和状态
├── files/            # 共享资源
├── mods/             # 已安装的 Mods
├── logs/             # 事件日志、LLM 调用日志
├── network/          # 网络配置
└── studio/           # Web UI 构建

这为自托管提供了清晰的部署模型。

5. 身份管理

agent_identity.py 实现了多级身份:

  • 本地 Agent:匿名或基于密钥
  • 全局 Agent:通过 OpenAgents 身份服务注册,获得 JWT 或 DID

secret_manager.py 安全管理凭证,支持密钥环后端。

6. 事件网关的幂等性与去重

虽然 Event.id 是 UUID/ULID,但在 at-least-once 交付语义下,接收方需要幂等处理。源码中没有看到显式的去重缓存,这意味着幂等性交由上层应用(或可通过 Mod 实现)保证。

这是一个诚实的设计选择:网络保证至少一次投递,但不保证恰好一次。需要恰好一次的语义可以在 mod/persistence 或应用层实现。

十七、OpenAgents 的潜在影响

如果 OpenAgents 成功,它可能成为:

1. Agent 世界的「Nginx」

Nginx 统一了 HTTP 服务器的配置、路由和负载均衡。OpenAgents 可能成为 Agent 网络的路由、认证、策略层。

2. AI 工作流的事实标准

当企业想构建跨工具、跨团队的 AI 自动化时,OpenAgents 可能提供一个开箱即用的协作层,而不需要自己造轮子。

3. 开源 Agent 联邦的基础

随着更多开源 Agent 框架出现(OpenClaw, Aider, Claude Code, Cursor 等),一个开放的互操作标准变得迫切。OpenAgents 可能是这个标准的最佳候选。

4. MCP 的补充而非替代

MCP 解决单个 LLM 应用连接外部工具的问题。OpenAgents 解决多 Agent 协作的问题。两者可能并存,并通过传输绑定桥接。

十八、学习 OpenAgents 的建议

如果你也想深入了解这个项目,建议路径:

  1. 读 ONM spec (docs/openagents_network_model.md) —— 这是架构思想的精华。

  2. 读核心模型代码

    • src/openagents/core/onm_events.py
    • src/openagents/core/onm_addressing.py
    • src/openagents/core/onm_pipeline.py
  3. 读网络实现

    • src/openagents/sdk/network.py
    • src/openagents/sdk/event_gateway.py
  4. 读一个传输绑定

    • src/openagents/sdk/transports/http.py
  5. 跑一个示例

    curl -fsSL https://openagents.org/install.sh | bash
    agn

    创建一个网络,添加几个 Agent,试试 @mention 和文件共享。

  6. 加入 Discord:https://discord.gg/openagents[1]

结语

OpenAgents 在做的是一个「基础设施层」的工作——不追求让单个 Agent 变得更聪明,而是让多个 Agent 能够更聪明地协作

这个方向值得所有关注 AI Agent 生态的人关注。因为当单个 Agent 的能力趋于普适时,协作能力将成为差异化竞争力。而 OpenAgents 提供的就是协作的基础设施。

这是一个仍在演进的规范,但思想的成熟度远超一般的 RFC。
如果你在构建需要多 Agent 协作的系统,值得仔细研究。


参考资源:

  • 官方文档:https://openagents.org/docs[2]
  • 网络模型 spec:https://github.com/openagents-org/openagents/blob/main/docs/openagents_network_model.md[3]
  • GitHub 仓库:https://github.com/openagents-org/openagents[4]
  • Discord 社区:https://discord.gg/openagents[5]
  • Workspace:https://workspace.openagents.org[6]

本文基于 OpenAgents 源码(commit 截至 2026-04-03)和技术文档撰写。

引用链接

[1]https://discord.gg/openagents

[2]https://openagents.org/docs

[3]https://github.com/openagents-org/openagents/blob/main/docs/openagents_network_model.md

[4]https://github.com/openagents-org/openagents

[5]https://discord.gg/openagents

[6]https://workspace.openagents.org