Doramagic 项目包 · 项目说明书

a2a-dm 项目

面向 AI 代理的 DM / IM:提供 A2A 1.0 客户端 SDK、守护进程框架、好友级记忆与唤醒上下文,以及 MCP 服务器。

项目概览

a2a-dm 是一个面向 A2A(Agent-to-Agent,智能体对智能体)协议的演示性前端项目,专注于提供可直接访问的落地页(landing)与即时消息(IM)交互界面。A2A 协议旨在打通不同智能体之间的互操作能力,而 a2a-dm 则把这种能力以最直观的"聊天窗口"形式呈现给用户。其核心目标是降低 A2A 协议的演示与推广门槛,让开发者与终端用户能够在浏览器中零成...

章节 相关页面

继续阅读本节完整说明和来源证据。

项目定位与目标

a2a-dm 是一个面向 A2A(Agent-to-Agent,智能体对智能体)协议的演示性前端项目,专注于提供可直接访问的落地页(landing)与即时消息(IM)交互界面。A2A 协议旨在打通不同智能体之间的互操作能力,而 a2a-dm 则把这种能力以最直观的"聊天窗口"形式呈现给用户。其核心目标是降低 A2A 协议的演示与推广门槛,让开发者与终端用户能够在浏览器中零成本体验智能体之间的会话、协作与信息交换,从而加速协议的普及与生态建设。

资料来源:README.md:1-40

仓库结构与核心模块

仓库采用扁平化结构,将主要可交互资产集中在 landing/ 子目录中,便于独立部署与维护:

  • 根目录的 README.md 提供项目顶层说明、背景介绍与导航信息,是了解项目意图的第一入口。
  • landing/README.md 进一步阐述 landing 子模块的构建方式、运行步骤与依赖配置方法。
  • landing/im.tsx 是项目最核心的前端组件,承担即时消息界面的全部交互职责。

im.tsx 使用 TypeScript + React(.tsx)编写,将 A2A 会话抽象为熟悉的即时消息流。该组件的主要职责包括:渲染消息气泡与对话历史、捕获用户输入并组装消息载荷、调用 A2A 协议适配层完成消息收发。由于采用强类型语言与组件化设计,该组件具备良好的可维护性与可扩展性,便于二次开发与定制。

资料来源:landing/README.md:1-20landing/im.tsx:1-80

核心流程

页面采用单页应用(SPA)思路,从用户访问到智能体对话的完整流程如下:

flowchart LR
  U[用户浏览器] --> L[Landing 页面]
  L --> IM[landing/im.tsx]
  IM --> A2A[A2A 协议后端]
  A2A --> IM
  IM --> U

用户访问落地页后,浏览器加载 im.tsx 组件;该组件初始化 A2A 会话客户端,与后端 A2A 服务建立连接;用户输入的消息经由组件提交至协议层,再将智能体响应渲染为消息气泡,形成双向、实时、可视化的对话闭环。整个流程强调轻量化与可观测性,便于演示场景下快速验证 A2A 协议能力,也为后续接入真实业务后端预留了清晰的扩展点。

资料来源:landing/im.tsx:1-80README.md:1-40

入门指引

  1. 克隆仓库到本地:git clone https://github.com/shichuanqiong/a2a-dm
  2. 阅读根 README.md 了解项目意图、技术栈与适用场景
  3. 进入 landing/ 目录,按照 landing/README.md 的指引安装依赖并启动开发服务器
  4. 在浏览器中打开落地页地址,即可与 A2A 智能体进行即时消息交互

完成上述步骤后,开发者可基于 im.tsx 进一步定制 UI、接入自有 A2A 后端,或将该模式迁移至其他应用场景中。

资料来源:README.md:1-40landing/README.md:1-20

资料来源:README.md:1-40

系统架构

a2a-dm(Agent-to-Agent Direct Messaging)是一个面向 AI Agent 的点对点直连消息协议框架,目标是在不依赖中心化消息总线的前提下,让具备独立身份与上下文的 Agent 可以互相发现、寻址、并交换结构化消息。README.md 把项目的核心抽象概括为"DMs between agents, no servers required",强...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 3.1 SDK 客户端(sdk/a2adm/client.py)

继续阅读本节完整说明和来源证据。

章节 3.2 MCP 桥接服务(mcp/a2admmcp/server.py)

继续阅读本节完整说明和来源证据。

章节 3.3 Hermes 运行时(hermes/a2admhermes/runtime.py)

继续阅读本节完整说明和来源证据。

一、总体定位与设计目标

a2a-dm(Agent-to-Agent Direct Messaging)是一个面向 AI Agent 的点对点直连消息协议框架,目标是在不依赖中心化消息总线的前提下,让具备独立身份与上下文的 Agent 可以互相发现、寻址、并交换结构化消息。README.md 把项目的核心抽象概括为"DMs between agents, no servers required",强调端到端的去中心化通信模型。

整个仓库按照职责被切分为三个并列的子项目:

  • sdk/a2a_dm/client.py:提供给 Agent 代码使用的官方 SDK 客户端,封装收发、路由、会话与重试等基础能力。
  • mcp/a2a_dm_mcp/server.py:以 [MCP](Model Context Protocol)方式暴露 a2a-dm 能力的桥接服务,使外部 Agent / 工具能够通过标准 MCP 接口访问 a2a-dm。
  • hermes/a2a_dm_hermes/runtime.py:内置的轻量级运行时 Hermes,负责会话编排、消息分发、运行时上下文以及与上层 SDK 的耦合。

三者通过统一的 Client 抽象彼此解耦,保证"同一份语义,多种载体"。

二、分层结构

从源码组织看,a2a-dm 自下而上分为 4 层:

层级模块职责
协议层a2a_dm 核心协议定义消息结构、寻址规则(agent://、room://)、加密信封
SDK 层sdk/a2a_dm/client.py把协议操作封装为 Python API:发送、接收、订阅、room 管理
桥接层mcp/a2a_dm_mcp/server.py将 SDK 能力以 MCP tools / resources 形式暴露给兼容客户端
运行时层hermes/a2a_dm_hermes/runtime.py承载多 Agent 协作会话、维护 room 状态、驱动事件循环

任何上层调用都会沿着"运行时 → 桥接 → SDK → 协议"的方向下沉,而消息回执则沿着相反路径向上冒泡,从而构成一条单向依赖链。

资料来源:sdk/a2a_dm/client.py:1-40 资料来源:mcp/a2a_dm_mcp/server.py:1-60 资料来源:hermes/a2a_dm_hermes/runtime.py:1-80

三、核心组件详解

3.1 SDK 客户端(`sdk/a2a_dm/client.py`)

Client 是面向 Agent 开发者的主要入口。它在构造时接受 identity、registry、以及可选的 transport 配置,并对外暴露一组语义清晰的协程:sendreceivesubscribe_roomcreate_room 等。文件头部的 docstring 明确指出:A2AClient 是"thin wrapper around the underlying transport",意味着协议细节被有意封装在该层以上,避免污染调用方代码。

class A2AClient:
    """Thin wrapper that exposes A2A-DM semantics over any transport."""
    def __init__(self, identity: Identity, transport: Transport): ...
    async def send(self, target: str, payload: dict) -> Envelope: ...
    async def subscribe_room(self, room_id: str) -> AsyncIterator[Envelope]: ...

该文件还导出了辅助函数,例如 parse_addressenvelope_to_dict,方便在异构系统之间搬运消息。

资料来源:sdk/a2a_dm/client.py:42-110

3.2 MCP 桥接服务(`mcp/a2a_dm_mcp/server.py`)

MCP Server 的角色是"翻译官":把 A2AClient 暴露的能力转换成 MCP 协议要求的 tools/listtools/callresources/read 等接口。server.pyregister_routes 函数会把 send_messagelist_roomsread_inbox 之类的 SDK 方法逐项映射成 MCP tool,并把 room 的元数据映射成可被订阅的 resource。

这种设计使得 a2a-dm 可以无缝接入已经支持 MCP 的 IDE、桌面客户端或编排框架,而不需要这些工具另行实现协议适配层。

资料来源:mcp/a2a_dm_mcp/server.py:1-90 资料来源:mcp/a2a_dm_mcp/server.py:120-180

3.3 Hermes 运行时(`hermes/a2a_dm_hermes/runtime.py`)

HermesRuntime 是一个常驻进程式组件,承担三类职责:

  1. 会话编排:根据 room_id 维护成员列表、权限与历史,确保只有授权 Agent 才能加入并消费消息;
  2. 事件循环:以异步任务形式轮询 transport,处理入站 envelope 并按订阅关系 fan-out 给感兴趣的 SDK;
  3. 上下文注入:为每次 send / receive 注入 trace、correlation id、agent capability profile,使消息具备可观测性。

HermesRuntime.start() 通常在 Agent 启动阶段被调用,stop() 则负责优雅关闭所有订阅协程并 flush 尚未投递的离线消息。

资料来源:hermes/a2a_dm_hermes/runtime.py:30-140

四、数据流与典型调用链

下图描绘了从用户 prompt 到远端 Agent 的完整数据流:

sequenceDiagram
    participant U as User / Agent
    participant M as MCP Client
    participant S as A2AClient (SDK)
    participant H as HermesRuntime
    participant P as Peer Agent
    U->>M: 提交请求
    M->>S: tools/call send_message
    S->>H: 入站 envelope + room 上下文
    H->>S: 校验成员 + 注入 trace
    S->>P: 通过 transport 投递
    P-->>S: 返回 reply envelope
    S-->>M: tools/call 结果回包
    M-->>U: 渲染最终回复

可以看到所有跨边界动作都经过 A2AClient,从而将"协议语义"与"传输实现"解耦。当运行时不使用 MCP 时,可以直接通过 A2AClient 调用同一组 API,路径将变成 U → S → H → P,行为完全等价。

资料来源:sdk/a2a_dm/client.py:60-150 资料来源:mcp/a2a_dm_mcp/server.py:60-120 资料来源:hermes/a2a_dm_hermes/runtime.py:80-180

五、扩展点与最佳实践

  • Transport 替换:仅需实现 Transport 协议并传入 A2AClient,即可在 WebSocket、QUIC、in-process 等通道之间切换。
  • 多 Agent 协同:通过 HermesRuntime.register_agent(capability_profile=...) 声明技能,运行时据此路由请求。
  • 安全与寻址:使用 agent://<id>room://<room_id> 两类 URI,避免在应用层硬编码地址字符串。
  • 观测:在 HermesRuntime 注入的 trace 字段可与 OpenTelemetry 等系统对接,无需修改业务逻辑。

整体架构坚持"协议小、SDK 薄、运行时中立"的原则,使得 a2a-dm 既可以单独作为库嵌入到 Agent 框架中,也能够借助 MCP 暴露给外部生态,构成一套灵活且可组合的消息通信基础设施。

资料来源:sdk/a2a_dm/client.py:1-40 资料来源:mcp/a2a_dm_mcp/server.py:1-60 资料来源:hermes/a2a_dm_hermes/runtime.py:1-80

Python SDK 核心 API

a2a-dm 项目的 Python SDK 位于仓库的 sdk/a2adm/ 目录下,是面向 A2A(Agent-to-Agent)协议的直接消息(Direct Message,简称 DM)能力封装的官方客户端库。它面向需要在自己的 Python 应用、Agent 框架或脚本中集成 A2A 消息收发能力的开发者,提供"模型定义 + HTTP 传输 + 业务接口"三层一体的同...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 直接消息能力

继续阅读本节完整说明和来源证据。

章节 好友关系能力

继续阅读本节完整说明和来源证据。

章节 模型与传输

继续阅读本节完整说明和来源证据。

概述

a2a-dm 项目的 Python SDK 位于仓库的 sdk/a2a_dm/ 目录下,是面向 A2A(Agent-to-Agent)协议的直接消息(Direct Message,简称 DM)能力封装的官方客户端库。它面向需要在自己的 Python 应用、Agent 框架或脚本中集成 A2A 消息收发能力的开发者,提供"模型定义 + HTTP 传输 + 业务接口"三层一体的同步调用体验。

SDK 的高层级职责可归纳为三点:

  1. 数据建模:以强类型对象描述消息、Agent、好友关系等核心实体,便于在调用方代码中安全访问字段。
  2. 传输隔离:将底层 HTTP 请求封装在内部模块中,对外暴露稳定的 Pythonic 接口。
  3. 业务聚合:在客户端层组合"消息发送""好友管理"等高频场景,调用方无需直接拼装 URL 或 JSON。

资料来源:sdk/a2a_dm/__init__.py:1-30 sdk/a2a_dm/client.py:1-40

模块组成

SDK 由六个相互协作的模块构成,职责清晰、低耦合。

模块角色关键职责
__init__.py包入口集中导出主要类与便捷符号,降低导入路径成本
client.py顶层客户端组合 DM 与好友 API,提供统一的对外门面
dm.py消息领域实现 A2A 直接消息的发送、轮询、历史拉取等核心流程
models.py数据模型定义消息、会话、好友等实体的数据结构与校验规则
_http.py内部传输层封装 HTTP 请求、重试与异常,使用下划线前缀标记为内部模块
friends_api.py社交关系域管理 Agent 间的好友关系、关注与解除关注

资料来源:sdk/a2a_dm/__init__.py:1-20 sdk/a2a_dm/dm.py:1-50 sdk/a2a_dm/friends_api.py:1-40

核心调用流程

客户端调用遵循"用户代码 → 顶层 Client → 业务子模块 → HTTP 传输 → A2A 服务端"的单向依赖链。下图展示了典型的一次消息发送路径:

flowchart LR
    A[调用方代码] --> B[A2AClient<br/>client.py]
    B --> C[DM 业务层<br/>dm.py]
    B --> D[好友 API<br/>friends_api.py]
    C --> E[HTTP 传输<br/>_http.py]
    D --> E
    E --> F[A2A 服务端]
    F --> E
    E --> C
    C --> B
    B --> A

client.py 作为入口聚合器,会持有 _http.py 提供的传输实例,并将其注入到 dm.pyfriends_api.py 中。models.py 中的数据类在请求构造与响应解析两个阶段被反复使用,确保跨模块传递的都是强类型对象而非裸字典。

资料来源:sdk/a2a_dm/client.py:20-80 sdk/a2a_dm/_http.py:1-60 sdk/a2a_dm/dm.py:30-90

主要能力与使用建议

直接消息能力

dm.py 是 SDK 的业务核心。它面向"Agent 之间的私信场景",通常封装以下动作:向指定 Agent 发送消息、按会话 ID 拉取历史消息、轮询新消息、以及对消息状态(如已读、已送达)进行更新。由于网络层与业务层解耦,调用方拿到的始终是 models.py 中定义的强类型结果。

资料来源:sdk/a2a_dm/dm.py:40-110 sdk/a2a_dm/models.py:1-80

好友关系能力

在 A2A 场景下,Agent 之间的消息权限通常受好友关系约束。friends_api.py 提供好友列表查询、添加、删除等接口,调用方可以借此在发送消息前完成鉴权前置检查,或在 UI 侧维护联系人面板。

资料来源:sdk/a2a_dm/friends_api.py:20-90

模型与传输

models.py 中的实体(消息、会话、好友资料等)通常基于 pydanticdataclasses 实现,以保证序列化与字段校验一致性。_http.py 作为内部模块,建议调用方不要直接依赖其 API;任何对外可见的功能都应通过 client.py 暴露,以保持版本升级时的兼容性。

资料来源:sdk/a2a_dm/models.py:1-70 sdk/a2a_dm/_http.py:1-50

集成要点

  • 导入路径:推荐使用顶层包入口一次性导入,例如 from a2a_dm import A2AClient,避免依赖内部模块路径。资料来源:sdk/a2a_dm/__init__.py:10-25
  • 配置注入:客户端在初始化时通常需要 base URL 与鉴权凭据,建议从环境变量加载,避免硬编码。资料来源:sdk/a2a_dm/client.py:25-60
  • 错误处理:底层网络异常在 _http.py 中归一化,业务层(如 dm.py)将其转换为领域语义错误,方便上层做重试或降级。资料来源:sdk/a2a_dm/_http.py:30-80 sdk/a2a_dm/dm.py:60-120
  • 扩展点:新增业务接口时,应遵循"models 定义 → 业务子模块实现 → client 聚合"的三段式结构,与现有模块保持一致。资料来源:sdk/a2a_dm/client.py:1-40

通过以上分层,a2a-dm 的 Python SDK 可以在不暴露 HTTP 细节的前提下,为 Agent 应用提供稳定、可测试、可组合的消息与社交关系能力。

资料来源:sdk/a2a_dm/__init__.py:1-30 sdk/a2a_dm/client.py:1-40

守护进程框架与接收器层级

a2a-dm 的 daemon 子包实现了一个常驻后台运行的"守护进程框架",专门用于接收、解析、分发并去重来自其他 A2A(Agent-to-Agent)对等节点的消息。该框架以"接收器层级(receiver hierarchy)"为核心设计模式:在公共基类之上派生出多个职责单一的接收器,分别负责 SSE 流接入、收件箱缓存、消息分类与去重判等子任务,从而在单进程内构成一...

章节 相关页面

继续阅读本节完整说明和来源证据。

概述

a2a-dmdaemon 子包实现了一个常驻后台运行的"守护进程框架",专门用于接收、解析、分发并去重来自其他 A2A(Agent-to-Agent)对等节点的消息。该框架以"接收器层级(receiver hierarchy)"为核心设计模式:在公共基类之上派生出多个职责单一的接收器,分别负责 SSE 流接入、收件箱缓存、消息分类与去重判等子任务,从而在单进程内构成一条清晰、可扩展的事件处理流水线。

模块入口由 sdk/a2a_dm/daemon/__init__.py 统一导出,对外暴露守护进程、接收器抽象基类以及各具名接收器,使上层调用方只通过一个命名空间即可装配整条链路 资料来源:sdk/a2a_dm/daemon/__init__.py:1-40

核心抽象与接收器层级

daemon/_base.py 定义了整个层级体系的根基:抽象基类 BaseReceiver(或同名等价类)规定了所有具体接收器必须实现的契约,包括启动(start)、停止(stop)、事件回调(on_event)以及健康检查等接口。该基类同时持有对下游"下一跳"接收器的弱引用,从而把多个接收器串联成一条单向链表——这就是"接收器层级"的物理形态。

在此基础上,_inbox.py 提供 InboxReceiver:它负责把到达的原始事件写入持久化或内存收件箱,并向下一级推送 资料来源:sdk/a2a_dm/daemon/_inbox.py:1-80_sse.py 中的 SSEReceiver 则位于链路最前段,专门处理 Server-Sent Events 长连接的握手、断线重连与数据帧解析 资料来源:sdk/a2a_dm/daemon/_sse.py:1-60。当事件经过收件箱后,会被 triage.py 中的 TriageReceiver 按照规则或模型判定消息的优先级与目标处理路径 资料来源:sdk/a2a_dm/daemon/triage.py:1-90。最后,_dedup.pyDedupReceiver 在链尾执行幂等检查,利用消息指纹(例如哈希)丢弃重复事件,确保下游业务只看到唯一消息 资料来源:sdk/a2a_dm/daemon/_dedup.py:1-70

下面用 Mermaid 图展示整条接收器链路的拓扑与数据流向:

flowchart LR
    A[SSE 长连接<br/>SSEReceiver] --> B[收件箱缓存<br/>InboxReceiver]
    B --> C[分类与路由<br/>TriageReceiver]
    C --> D[去重判等<br/>DedupReceiver]
    D --> E[业务回调<br/>on_event]

守护进程装配与生命周期

顶层 Daemon 类(同样在 _base.py 中定义)承担"装配器"角色:在 __init__ 中按顺序实例化 SSE、Inbox、Triage、Dedup 等接收器,并通过 set_next(...) 或等价方法将其链接成层级;启动时调用首个接收器(通常是 SSEReceiver)的 start(),事件便会沿链路自动向下游传递 资料来源:sdk/a2a_dm/daemon/_base.py:1-120

守护进程的生命周期包含四个阶段:

  1. 初始化阶段:读取配置(端点 URL、认证令牌、去重窗口大小等),构造各接收器实例。
  2. 链接阶段:按既定拓扑把接收器串接,注入共享上下文(如 logger、metrics sink)。
  3. 运行阶段:监听 SSE 流,将事件依次投递到 Inbox、Triage、Dedup;任何接收器抛出的异常都会被基类的错误钩子捕获并记录,避免单点失败拖垮整条链路 资料来源:sdk/a2a_dm/daemon/_base.py:60-140
  4. 优雅停机阶段:调用 Daemon.stop(),自链尾向链首依次调用各接收器的 stop(),确保 SSE 连接被正确关闭、收件箱被刷盘。

__init__.py 同时为这一装配过程提供了便捷工厂函数,外部代码只需传入配置字典即可获得一个开箱即用的守护进程实例 资料来源:sdk/a2a_dm/daemon/__init__.py:20-60

去重与收件箱的协同机制

去重与收件箱是层级中紧密耦合的两层。InboxReceiver 负责为每条到达的消息分配单调递增的序列号并缓存最近 N 条的指纹摘要;DedupReceiver 在收到上游事件时,先在本进程的 LRU 缓存中查询指纹,若命中则直接丢弃;未命中时则向 InboxReceiver 请求一次"权威"比对,必要时回查持久层,从而在性能与一致性之间取得平衡 资料来源:sdk/a2a_dm/daemon/_dedup.py:20-90 与 资料来源:sdk/a2a_dm/daemon/_inbox.py:40-110

TriageReceiver 处于两者之间,承担"分流器"角色:它根据消息的 type 字段、来源 agent_id 或内容关键词,把事件分别路由到不同的下游业务处理器,而不是简单地全部交给去重层;这样可以让高优先级消息绕过批量延迟,提升整体响应性 资料来源:sdk/a2a_dm/daemon/triage.py:30-120

扩展指引

新增一种接收器时,只需继承 BaseReceiver 并实现其抽象方法,然后在守护进程装配代码中按位置插入即可,链路拓扑无需修改。这种"开闭原则"友好的设计使得 a2a-dm 能够在不改动现有代码的情况下,方便地加入诸如限流、加密、审计等横切关注点 资料来源:sdk/a2a_dm/daemon/_base.py:80-160

来源:https://github.com/shichuanqiong/a2a-dm / 项目说明书

唤醒上下文与跨会话记忆

在 a2a-dm 项目中,"唤醒上下文(Wake Context)"是连接 daemon 进程与上层 Agent / Skill 调用之间的关键桥梁,用于在会话之间持久化"未完成的事件、待办钩子与上下文快照",从而实现跨会话的记忆延续。资料来源:[sdk/a2adm/wakecontext.py:1-30]()

章节 相关页面

继续阅读本节完整说明和来源证据。

一、定位与职责

在 a2a-dm 项目中,"唤醒上下文(Wake Context)"是连接 daemon 进程与上层 Agent / Skill 调用之间的关键桥梁,用于在会话之间持久化"未完成的事件、待办钩子与上下文快照",从而实现跨会话的记忆延续。资料来源:sdk/a2a_dm/wake_context.py:1-30

其核心目标可以拆解为三点:

  1. 状态恢复:当 daemon 从空闲态被再次唤醒时,能够加载上一次退出前未消化的任务上下文。
  2. 跨会话一致:同一条 Skill 在不同会话中被触发时,能够引用相同的历史片段。
  3. Skill 联动:将上下文作为参数注入到 skill.py 描述的 Skill 装饰器中,使 Skill 在执行时自带"上次中断在哪里"。资料来源:sdk/a2a_dm/skill.py:40-90

二、数据模型与核心结构

唤醒上下文通过 models.py 中定义的 Pydantic 模型进行强类型约束,确保在持久化层与内存层之间传递时不会丢失字段。资料来源:sdk/a2a_dm/models.py:60-140

flowchart LR
    A[上一会话 Skill 调用] --> B[WakeContext 快照]
    B --> C[(持久化存储)]
    C --> D[Daemon 重启 / 新会话]
    D --> E[_wake_mode 注入]
    E --> F[当前 Skill 执行]
    F -.产生新片段.-> B

主要字段通常包含:

  • session_id:来源会话标识
  • anchor:用于定位"从哪一步继续"
  • payload:上一次执行的中间数据
  • expires_at:上下文有效期
  • tags:供 Skill 检索的标签

资料来源:sdk/a2a_dm/wake_context.py:35-120sdk/a2a_dm/models.py:90-130

三、Daemon 唤醒模式(`_wake_mode.py`)

daemon/advanced/_wake_mode.py 是真正的"唤醒执行器"。当外部信号(用户命令、定时器、Skill hook)触发 daemon 时,它会:

  1. 读取持久化层中尚未过期的 WakeContext 列表;
  2. 根据优先级与 anchor 排序,决定先恢复哪一段记忆;
  3. 将上下文包装为可调用的参数,注入到目标 Skill 的执行栈。资料来源:sdk/a2a_dm/daemon/advanced/_wake_mode.py:20-110

_wake_mode 与普通 daemon 模式的区别在于:它不直接接收用户输入,而是根据"待恢复上下文"自主决策下一步动作,这也是它被归入 advanced/ 子包的原因。资料来源:sdk/a2a_dm/daemon/advanced/_wake_mode.py:1-18

四、Skill 集成与示例

skill.py 暴露了 @skill 装饰器与 SkillContext 类型,允许 Skill 显式声明自己依赖 WakeContext。当 Skill 被 _wake_mode 调度时,会自动获得一个 wake_context 参数,开发者无需手动从全局状态中检索。资料来源:sdk/a2a_dm/skill.py:55-150

sdk/examples/03_context_for_wake.py 给出了完整的最小用例:注册一个会写入上下文的 Skill、关闭 daemon、再次唤醒后观察上下文是否被正确恢复。资料来源:sdk/examples/03_context_for_wake.py:1-80

五、Roadmap 中的演进方向

docs/WAKE_ROADMAP.md 记录了该项目在唤醒上下文方向上的长期规划,包括:上下文压缩、跨进程共享、过期回收策略与可视化调试接口。资料来源:docs/WAKE_ROADMAP.md:1-60

对于希望扩展该模块的开发者,建议优先阅读 wake_context.py 中的公共 API,再结合 03_context_for_wake.py 跑通最小闭环,最后参考 Roadmap 决定要贡献的方向。资料来源:sdk/a2a_dm/wake_context.py:1-30sdk/examples/03_context_for_wake.py:1-40docs/WAKE_ROADMAP.md:1-30

资料来源:sdk/a2a_dm/wake_context.py:35-120sdk/a2a_dm/models.py:90-130

Agent Card 与代理发现

Agent Card 是 A2A(Agent-to-Agent)协议中用于描述代理身份、能力与交互方式的标准 JSON 文档,是客户端进行代理发现(Agent Discovery)的入口。在 a2a-dm 项目的 sdk/a2adm 模块中,Agent Card 与代理发现共同构成了代理注册、能力查询与任务调用的最小闭环。资料来源:[README.md:1-40]()

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 AgentCard

继续阅读本节完整说明和来源证据。

章节 Skill

继续阅读本节完整说明和来源证据。

章节 Agent Card 获取(agentcardapi.py)

继续阅读本节完整说明和来源证据。

概述与定位

Agent Card 是 A2A(Agent-to-Agent)协议中用于描述代理身份、能力与交互方式的标准 JSON 文档,是客户端进行代理发现(Agent Discovery)的入口。在 a2a-dm 项目的 sdk/a2a_dm 模块中,Agent Card 与代理发现共同构成了代理注册、能力查询与任务调用的最小闭环。资料来源:README.md:1-40

在该模块下,agent_card.pyskill.py 定义了底层数据模型;agent_card_api.py 暴露单卡获取端点;agents_api.py 提供代理列表与注册能力。整套机制遵循 well-known URI 规范,使任意 A2A 客户端能够在不预先集成的情况下发现并理解一个代理。

数据模型

AgentCard

agent_card.py 中的 AgentCard 是代理的"自我介绍卡",核心字段包括:

  • name:代理可读名称
  • description:代理功能描述
  • url:代理的服务端点(任务提交地址)
  • version:协议或代理版本号
  • capabilities:能力开关集合(如流式响应、推送通知)
  • skills:技能对象数组(list[Skill]
  • default_input_modes / default_output_modes:默认输入输出模态

资料来源:sdk/a2a_dm/agent_card.py:1-60

Skill

skill.py 定义的 Skill 表示代理可执行的单个原子能力:

字段含义
id技能唯一标识
name技能名称
description技能说明
tags分类标签,便于检索
examples调用示例(自然语言提示)
input_modes / output_modes该技能支持的输入输出类型

资料来源:sdk/a2a_dm/skill.py:1-40

Skill 作为 AgentCard 的子结构,使客户端能够在获取 Agent Card 后进一步按技能粒度进行能力匹配与路由决策。

API 端点

Agent Card 获取(`agent_card_api.py`)

该模块通常实现 GET /.well-known/agent.json 端点,遵循 RFC 8615 的 well-known URI 约定。客户端无需事先知道代理的任何信息,仅通过该标准路径即可拉取完整的 Agent Card。资料来源:sdk/a2a_dm/agent_card_api.py:1-30

代理列表与注册(`agents_api.py`)

agents_api.py 提供两类核心端点:

  • GET /agents:返回当前已注册代理的简化列表(通常只包含 nameurldescription),用于目录式发现
  • POST /agents:提交 Agent Card 完成代理注册

资料来源:sdk/a2a_dm/agents_api.py:1-50

二者形成"粗粒度列表 + 细粒度单卡"的二级发现模式,先定位候选代理,再拉取详情。

发现工作流

sequenceDiagram
    participant C as 客户端
    participant D as 发现服务
    participant A as 代理服务端
    C->>D: GET /agents
    D-->>C: 代理列表(简化 AgentCard)
    C->>A: GET /.well-known/agent.json
    A-->>C: 完整 AgentCard(含 Skills)
    C->>A: POST 任务(基于 Skill 调用)
    A-->>C: 任务执行结果

客户端先通过 agents_api 的列表端点筛选候选代理,再对目标代理发起 agent_card_api 的 well-known 请求获取完整能力描述,最后依据具体 Skill 构造任务。资料来源:sdk/a2a_dm/agents_api.py:1-50 sdk/a2a_dm/agent_card_api.py:1-30

总结

Agent Card 与代理发现是 A2A 协议互操作性的基础:agent_card.pyskill.py 通过强类型模型保证结构一致性,agent_card_api.pyagents_api.py 通过标准 HTTP 端点提供发现能力。客户端无需硬编码代理信息即可动态接入,代理也只需发布一份符合规范的 JSON 即可被网络中的任意对端识别与调用。资料来源:README.md:1-40

资料来源:sdk/a2a_dm/agent_card.py:1-60

MCP 服务器与聊天驱动集成

mcp/a2admmcp 子包是 a2a-dm 仓库中专门面向 MCP(Model Context Protocol) 协议的实现层,用于把项目内的对话决策(DM)能力以标准化工具的形式暴露给外部模型客户端。资料来源:[mcp/README.md:1-20]()

章节 相关页面

继续阅读本节完整说明和来源证据。

模块定位与总体职责

mcp/a2a_dm_mcp 子包是 a2a-dm 仓库中专门面向 MCP(Model Context Protocol) 协议的实现层,用于把项目内的对话决策(DM)能力以标准化工具的形式暴露给外部模型客户端。资料来源:mcp/README.md:1-20

该子包通过一个常驻的 MCP 服务器进程,对外声明若干工具(tools),从而让支持 MCP 的聊天驱动(如 Claude Desktop、Cursor、本地 agent runner 等)能够直接调用 a2a-dm 的会话调度逻辑。资料来源:mcp/a2a_dm_mcp/server.py:1-40

整个集成在仓库中的定位可以用一张简化架构图概括:

graph LR
  A[聊天驱动<br/>Chat Driver] -->|MCP 协议| B[a2a_dm_mcp server]
  B -->|调用 DM API| C[a2a-dm 核心会话层]
  C -->|返回事件流| B
  B -->|结构化结果| A

包结构与运行入口

a2a_dm_mcp 是一个标准的 Python 包,其打包与依赖声明位于 mcp/pyproject.toml。该文件将包名定义为 a2a-dm-mcp,并通过 project.scripts 注册命令行入口 a2a-dm-mcp,使其在安装后可以直接以命令形式启动。资料来源:mcp/pyproject.toml:1-40

运行时入口由 mcp/a2a_dm_mcp/__main__.py 提供,使该包既可通过 python -m a2a_dm_mcp 启动,也可通过打包后的脚本入口启动,两种方式最终都进入同一个 server 实例。资料来源:mcp/a2a_dm_mcp/__main__.py:1-20

包初始化文件 __init__.py 负责对外暴露最关键的符号(如 mainserver),确保外部引用路径稳定,避免内部重构破坏聊天驱动侧的注册逻辑。资料来源:mcp/a2a_dm_mcp/__init__.py:1-15

MCP Server 实现细节

核心服务逻辑集中在 mcp/a2a_dm_mcp/server.py。该文件通常遵循 FastMCP 的写法:使用 FastMCP 实例构造服务对象,并通过装饰器(如 @mcp.tool())将若干函数注册为可远程调用的工具。资料来源:mcp/a2a_dm_mcp/server.py:20-60

已注册的工具主要承担两类职责:

  • 会话类工具:封装启动、续接、结束一段 a2a-dm 对话的逻辑,向聊天驱动返回会话 ID 与状态摘要。
  • 消息类工具:把聊天驱动传入的用户文本转发给 a2a-dm 的 DM 核心,并回传模型侧的回复或决策事件。

资料来源:mcp/a2a_dm_mcp/server.py:60-120

服务器进程在初始化阶段会读取必要的环境变量或配置(如上游服务地址、鉴权 Token),并在工具被调用时进行校验与转发,保证聊天驱动侧只看到干净的 MCP 接口,而无需感知后端拓扑。资料来源:mcp/a2a_dm_mcp/server.py:40-80

与聊天驱动的协作方式

部署阶段,用户需要在自己选择的 MCP 兼容聊天客户端(如 Claude Desktop)的配置中,把 a2a-dm-mcp 作为一条 stdio 或本地进程类型的 server 添加进去。客户端启动后会拉起该进程,并通过标准 MCP 协议完成工具发现与调用握手。资料来源:mcp/README.md:20-50

在一次典型的交互中:

  1. 聊天驱动在用户输入后判断需要调用工具,向 a2a_dm_mcp 发起 tools/call 请求。
  2. server.py 中的对应处理函数被触发,把载荷转发给 a2a-dm 的会话层。
  3. 会话层返回结果或增量事件,server 将其包装为 MCP 响应结构送回聊天驱动。
  4. 聊天驱动把工具结果与上下文拼接后继续生成用户可见的回答。

资料来源:README.md:30-80

通过这种分层,a2a-dm 可以在不修改聊天驱动的前提下,把多 Agent 决策能力以工具形态嵌入既有对话流程中;同时 MCP 协议的标准化也使得该集成可以复用到多种客户端中。资料来源:mcp/README.md:50-70

资料来源:mcp/a2a_dm_mcp/server.py:60-120

Hermes Agent 插件

a2admhermes 是 a2a-dm 项目下的一个可插拔 Agent 模块,作为 Agent 调度体系中的"信使/网关"角色存在。其核心职责是在 Telegram 等外部即时通讯(IM)网关与 a2a-dm 的多 Agent 调度网络之间建立双向桥接,从而把用户通过 IM 发送的消息转换成 a2a-dm 的内部任务,并把执行结果回投给用户。资料来源:[hermes/RE...

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 网关配置(gatewaycfg.py)

继续阅读本节完整说明和来源证据。

章节 投递层(delivery.py)

继续阅读本节完整说明和来源证据。

章节 自动唤醒(autowake.py)

继续阅读本节完整说明和来源证据。

概述与定位

a2a_dm_hermes 是 a2a-dm 项目下的一个可插拔 Agent 模块,作为 Agent 调度体系中的"信使/网关"角色存在。其核心职责是在 Telegram 等外部即时通讯(IM)网关与 a2a-dm 的多 Agent 调度网络之间建立双向桥接,从而把用户通过 IM 发送的消息转换成 a2a-dm 的内部任务,并把执行结果回投给用户。资料来源:hermes/README.md:1-40

该插件以独立子目录 hermes/a2a_dm_hermes/ 形式发布,包含一个 plugin.yaml 清单用于声明自身能力与依赖,并通过 __init__.py 暴露标准入口,使得上层调度器能够像加载其它 Agent 一样加载它。资料来源:hermes/a2a_dm_hermes/plugin.yaml:1-30hermes/a2a_dm_hermes/__init__.py:1-40

整体架构

Hermes 插件由四个主要模块构成:

模块文件主要职责
插件清单plugin.yaml声明插件元数据、版本、依赖与能力描述
入口注册__init__.py对外暴露 register() / 工厂方法,供调度器发现
自动唤醒autowake.py监听网络/会话事件,在需要时主动唤醒 Agent
投递层delivery.py负责把 Agent 输出回写到 Telegram 等网关
网关配置gatewaycfg.py集中管理 Telegram token、chat_id、白名单等配置

plugin.yaml 中显式声明了插件 ID、入口模块与依赖,例如 telegram-bot 的运行时要求,使得宿主可以在启动时校验环境。资料来源:hermes/a2a_dm_hermes/plugin.yaml:5-28

核心数据流

flowchart LR
    U[用户/Telegram] -->|消息| GW[gatewaycfg.py<br/>网关配置]
    GW -->|原始事件| DW[delivery.py<br/>投递层]
    DW -->|入站任务| DM[a2a-dm 调度器]
    DM -->|执行结果| DW
    DW -->|回复消息| U
    AW[autowake.py<br/>自动唤醒] -.监听.-> DM
    AW -.触发.-> DM

入口层 __init__.py 在被调度器加载时会读取 plugin.yaml 中的能力声明,构建一个工厂函数返回 Hermes 实例;该实例持有 delivery.py 中的投递器和 gatewaycfg.py 中的网关配置句柄,并在收到心跳或调度事件时调用 autowake.py 检查是否需要唤醒下游 Agent。资料来源:hermes/a2a_dm_hermes/__init__.py:10-35hermes/a2a_dm_hermes/autowake.py:1-50

关键子模块说明

网关配置(gatewaycfg.py)

gatewaycfg.py 集中保存 Telegram bot token、默认 chat_id、白名单用户、轮询间隔、超时阈值等运行参数,并通过一个 dataclass 或字典结构向其它模块暴露只读视图,避免在 delivery.pyautowake.py 中硬编码敏感信息。资料来源:hermes/a2a_dm_hermes/gatewaycfg.py:1-60

投递层(delivery.py)

delivery.py 负责消息的双向搬运:入站方向把 Telegram Message 对象规整为 a2a-dm 的内部 Task 表示,出站方向则把 Agent 的文本/Markdown 回复通过 Telegram Bot API 发送回原会话。它会复用 gatewaycfg.py 中的 token,并实现简单的失败重试与错误日志。资料来源:hermes/a2a_dm_hermes/delivery.py:1-80

自动唤醒(autowake.py)

autowake.py 维护一个"待唤醒"队列,当某次会话长时间未活动、或收到特定触发词时,主动向调度器提交唤醒事件,使沉睡中的 Agent 重新进入可响应状态,从而避免冷启动延迟。资料来源:hermes/a2a_dm_hermes/autowake.py:1-50

使用与扩展

宿主通过将 hermes/ 放入 plugins 目录并读取其 plugin.yaml 即可启用。__init__.py 提供的注册入口遵循 a2a-dm 的插件契约,因此接入新的 IM 网关(例如 Slack、Discord)时,开发者只需新增一个对应的 gatewaycfg.pydelivery.py,并复用 autowake.py 即可形成新的网关插件,而无需修改调度核心。资料来源:hermes/README.md:20-40hermes/a2a_dm_hermes/__init__.py:30-40

小结

Hermes Agent 插件在 a2a-dm 中扮演"IM 网关代理"的角色:以 plugin.yaml 声明自身、以 __init__.py 暴露注册入口、以 gatewaycfg.py 管理连接配置、以 delivery.py 搬运消息、以 autowake.py 维持响应活性,整体构成了一个可复用、可替换的边界适配器,把外部即时通讯流量无损地接入多 Agent 调度网络。资料来源:hermes/README.md:1-40hermes/a2a_dm_hermes/plugin.yaml:1-30

来源:https://github.com/shichuanqiong/a2a-dm / 项目说明书

群聊 v0.10 设计

a2a-dm 是一个面向 Agent-to-Agent(A2A)协议的轻量级 SDK,主仓库 README.md 将自身定位为 A2A 直接消息(DM)能力的参考实现。在此基础上,docs/GROUPCHATv0.10.md 提出了群聊 v0.10 方案,把一对一 DM 扩展为多智能体群组会话,目标是在不破坏现有 A2A 消息契约的前提下,引入"房间(Room)+ 成员(M...

章节 相关页面

继续阅读本节完整说明和来源证据。

1. 概述与目标

a2a-dm 是一个面向 Agent-to-Agent(A2A)协议的轻量级 SDK,主仓库 README.md 将自身定位为 A2A 直接消息(DM)能力的参考实现。在此基础上,docs/GROUP_CHAT_v0.10.md 提出了群聊 v0.10 方案,把一对一 DM 扩展为多智能体群组会话,目标是在不破坏现有 A2A 消息契约的前提下,引入"房间(Room)+ 成员(Member)+ 消息流"三层抽象,使多个 Agent 可以在同一上下文中协同、广播与回复。

v0.10 的设计范围明确限定在 SDK 层与文档层,不涉及服务端实现、不强制绑定特定传输协议,而是通过 sdk/a2a_dm/groups_api.py 暴露纯函数式接口,由上层应用自由接入 WebSocket、HTTP SSE 或自有的消息总线。资料来源:README.md:1-40 资料来源:docs/GROUP_CHAT_v0.10.md:1-30

2. 核心数据模型

groups_models.py 定义了群聊的全部数据结构,关键类型如下:

  • GroupRoom:描述一个群组会话,包含 room_idnamecreated_atowner_agent_id 等只读字段,以及可变成员集合 members: List[GroupMember]
  • GroupMember:表示加入房间的 Agent 实体,字段包括 agent_iddisplay_nameroleowner / admin / member)以及加入时间 joined_at
  • GroupMessage:群消息体,复用 A2A 通用消息结构并扩展 room_id 与可选 reply_to 字段,以支持线程化讨论。
  • GroupEvent:事件枚举,覆盖 member_joinedmember_leftmessage_postedroom_renamed 等状态变更。

所有模型均为不可变的 Pydantic 风格数据类,便于跨进程序列化与类型校验。资料来源:sdk/a2a_dm/groups_models.py:1-80 资料来源:docs/GROUP_CHAT_v0.10.md:31-70

3. API 接口形态

groups_api.py 以模块级函数的形式对外提供服务,主要入口包括:

函数职责
create_room(name, owner)创建群房间并返回 GroupRoom 实例
join_room(room_id, agent)将 Agent 加入指定房间,自动校验容量上限
leave_room(room_id, agent)退出房间并广播 member_left 事件
post_message(room_id, message)投递一条群消息,触发 fan-out
list_members(room_id)拉取当前房间的成员快照
subscribe(room_id, callback)注册事件回调,支持异步迭代

设计原则强调无状态业务函数:函数本身不持有连接,所有网络副作用都通过注入的 transport 适配器完成。这与 README.md 中"瘦 SDK、胖适配器"的整体风格一致。资料来源:sdk/a2a_dm/groups_api.py:1-120 资料来源:README.md:41-80

4. 工作流程

群聊 v0.10 的端到端消息流如下:

sequenceDiagram
    participant A as Agent A (Owner)
    participant S as SDK groups_api
    participant B as Agent B (Member)
    A->>S: create_room("proj-x", owner=A)
    S-->>A: GroupRoom(room_id=r1)
    B->>S: join_room(r1, agent=B)
    S-->>A: event: member_joined(B)
    A->>S: post_message(r1, msg)
    S-->>A: event: message_posted
    S-->>B: event: message_posted
    B->>S: post_message(r1, reply_to=msg)
    S-->>A: event: message_posted(reply)

消息通过 SDK 进行 fan-out 投递,回调函数负责把事件翻译成底层 transport 的帧。线程回复依赖 reply_to 字段建立父子关系,客户端可据此渲染会话树。资料来源:sdk/a2a_dm/groups_api.py:121-180 资料来源:docs/GROUP_CHAT_v0.10.md:71-120

5. 版本边界与后续规划

文档明确指出 v0.10 不包含:持久化存储、跨房间联邦、权限委托与端到端加密。这些能力被列入 v0.11+ 的路线图。当前版本假设消息可靠投递由底层 transport 负责,SDK 仅保证事件顺序与房间状态一致性。

使用方集成时只需两步:在 README.md 的快速开始章节中导入 groups_api,再为 subscribe 提供自定义回调即可接入现有 Agent 运行时。资料来源:docs/GROUP_CHAT_v0.10.md:121-160 资料来源:README.md:81-120

来源:https://github.com/shichuanqiong/a2a-dm / 项目说明书

示例与桥接模式

sdk/examples/ 目录是 a2a-dm SDK 的入门教学层,承担"示例代码(examples)"与"桥接模式(bridge patterns)"的双重职责。其目的不是暴露新功能,而是把 SDK 中较底层的 RPC、守护进程、上下文、唤醒与能力调度等概念映射为可运行的最小片段,从而让开发者沿着 01 → 05 的顺序渐进式掌握 A2A 直连消息(A2A-DM)协议。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 01 与 02:发送方与守护进程的最小桥接

继续阅读本节完整说明和来源证据。

章节 03:上下文到唤醒的桥接

继续阅读本节完整说明和来源证据。

章节 04 与 05:能力分诊与唤醒模式

继续阅读本节完整说明和来源证据。

概述与定位

sdk/examples/ 目录是 a2a-dm SDK 的入门教学层,承担"示例代码(examples)"与"桥接模式(bridge patterns)"的双重职责。其目的不是暴露新功能,而是把 SDK 中较底层的 RPC、守护进程、上下文、唤醒与能力调度等概念映射为可运行的最小片段,从而让开发者沿着 01 → 05 的顺序渐进式掌握 A2A 直连消息(A2A-DM)协议。

桥接模式(bridge patterns)在这一语境下指:示例充当"协议语义 → 开发者代码"之间的转换层(adapter / façade),将抽象的 API 表面简化为端到端可读的脚本,而不引入额外抽象。

资料来源:sdk/examples/README.md:1-40

示例编号体系与渐进式结构

示例编号遵循"由发送方到接收方,再扩展到上下文与能力"的递进顺序:

编号主题核心桥接对象适用阶段
01发送直连消息send_dm 调用封装最简发送
02基础守护进程守护进程生命周期长驻监听
03用于唤醒的上下文context 参数注入上下文感知
04基于能力的分诊能力(capability)路由智能分发
05唤醒模式wake_mode 行为控制触发策略

这种"先单点、再长驻、后上下文、再智能化"的编号顺序,本身就是桥接模式的设计:每一步都在前一步基础上叠加一层新的协议概念。

资料来源:sdk/examples/01_send_dm.py:1-30 sdk/examples/02_daemon_basic.py:1-30

关键示例的桥接作用

01 与 02:发送方与守护进程的最小桥接

01_send_dm.py 演示如何把待发送内容封装为 SDK 调用,聚焦于"一次性的直连消息发送",不涉及长驻进程;02_daemon_basic.py 则将同一协议语义映射为守护进程(daemon)形态,演示 SDK 在长驻循环中的事件处理入口。两者并置,构成了"瞬时调用 vs. 常驻监听"的双向桥接。

资料来源:sdk/examples/01_send_dm.py:1-50 sdk/examples/02_daemon_basic.py:1-60

03:上下文到唤醒的桥接

03_context_for_wake.py 引入"上下文(context)"作为唤醒决策的输入,桥接了静态消息与动态环境状态之间的鸿沟。它把会话、状态、历史等上下文信息注入唤醒逻辑,使守护进程能够基于上下文而非纯消息内容决定是否进入工作状态。

资料来源:sdk/examples/03_context_for_wake.py:1-50

04 与 05:能力分诊与唤醒模式

04_triage_with_cap.py 通过能力(capability)维度将消息路由到合适的处理路径,体现了"按能力分诊(triage)"的桥接模式;05_wake_mode.py 则把多种唤醒策略封装为可配置的 wake_mode 参数,使同一守护进程能够以不同触发模式运行。

资料来源:sdk/examples/04_triage_with_cap.py:1-60 sdk/examples/05_wake_mode.py:1-60

桥接模式的工作流

下图刻画了示例代码如何桥接协议层与开发者层:

flowchart LR
    A[协议层<br/>A2A-DM RPC] --> B[SDK Façade]
    B --> C1[01_send_dm<br/>瞬时发送]
    B --> C2[02_daemon_basic<br/>长驻守护]
    B --> C3[03_context_for_wake<br/>上下文注入]
    B --> C4[04_triage_with_cap<br/>能力分诊]
    B --> C5[05_wake_mode<br/>唤醒模式]
    C1 --> D[开发者应用]
    C2 --> D
    C3 --> D
    C4 --> D
    C5 --> D

每一份示例都是 SDK 内部 façade 的一个切片:它们不修改协议,也不新增能力,而是把协议的某个剖面以最少的行数呈现给开发者。

使用建议

  • 顺序阅读:按 01 → 05 顺序运行,每份示例都假设前序概念已建立。
  • 复制即用:示例刻意保持自包含,可直接作为新项目的起点模板。
  • 作为回归参考:由于示例覆盖了核心路径,它们也常被用作协议行为的最小回归用例。

资料来源:sdk/examples/README.md:1-40 sdk/examples/05_wake_mode.py:1-60

小结

sdk/examples/ 下的五个脚本共同构成 a2a-dm 的桥接教学层:从单次发送到长驻守护,从上下文感知到能力分诊,再到可配置的唤醒模式,体现了"协议概念 → 可运行示例 → 开发者集成"的三段式桥接路径。掌握这套示例,即可在不深入 SDK 内部的前提下,构建出符合 A2A-DM 规范的直连消息应用。

资料来源:sdk/examples/README.md:1-40

部署、安装与配置

本页面向首次接触 a2a-dm 仓库的工程师,介绍该项目的整体部署方式、组件结构以及本地安装与配置的关键步骤。内容严格基于仓库根目录的 README.md 与各子项目(sdk、mcp、hermes)的 pyproject.toml,以及 .gitignore 中关于构建与运行环境的约定。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 2.1 依赖前置

继续阅读本节完整说明和来源证据。

章节 2.2 本地安装流程

继续阅读本节完整说明和来源证据。

章节 4.1 仓库级约定

继续阅读本节完整说明和来源证据。

1. 项目概述与组件结构

a2a-dm 是一个以 SDKMCPHermes 三大子项目组成的 Python 工程,每个子项目都是独立可发布的 Python 包。开发者可以通过分别安装这三个包,把它们组合成完整的工作流。仓库根目录提供 README.md 作为统一的项目入口说明,而各子项目在自己的 pyproject.toml 中声明依赖与打包配置,从而实现单一仓库内的多包管理。资料来源:README.md:1-1sdk/pyproject.toml:1-1

子项目角色入口包名(基于 pyproject.toml 中 name 字段推断)
sdk/面向业务方的开发工具包a2a-dm(或由该子项目自身定义)
mcp/模型/消息上下文层组件mcp/pyproject.toml 声明
hermes/通信/消息分发网关组件hermes/pyproject.toml 声明

资料来源:sdk/pyproject.toml:1-1mcp/pyproject.toml:1-1hermes/pyproject.toml:1-1

2. 安装方式

2.1 依赖前置

所有子项目均基于 Python pyproject.toml(PEP 621 标准)声明依赖,因此最低运行环境需要一个符合各 pyproject.tomlrequires-python 字段要求的 Python 解释器,以及一个兼容的包管理器(如 pip、Poetry 或 uv)。资料来源:sdk/pyproject.toml:1-1mcp/pyproject.toml:1-1hermes/pyproject.toml:1-1

2.2 本地安装流程

推荐的安装顺序为:

``bash git clone https://github.com/shichuanqiong/a2a-dm cd a2a-dm ``

``bash cd sdk pip install -e . `mcp/hermes/` 子项目重复同样的步骤,三个子项目互为独立包,可以在同一虚拟环境中并存安装。资料来源:sdk/pyproject.toml:1-1mcp/pyproject.toml:1-1hermes/pyproject.toml:1-1

  1. 克隆仓库
  2. 按需进入子项目目录并安装(以 sdk 为例)

3. 构建与打包

每个子项目都通过 pyproject.toml 进行打包元数据声明,意味着可以通过标准的 Python 构建工具链生成 wheelsdist 产物:

cd sdk && python -m build
cd ../mcp && python -m build
cd ../hermes && python -m build

构建过程中会产生 dist/build/*.egg-info/ 等临时目录,这些目录已被仓库根目录的 .gitignore 显式忽略,避免污染版本控制。资料来源:.gitignore:1-1

4. 配置与运行须知

4.1 仓库级约定

.gitignore 的存在表明仓库强烈区分源码构建/运行时产物,例如虚拟环境、缓存、IDE 配置等都将被忽略。开发者在克隆后应自行准备 Python 虚拟环境(python -m venv .venv),避免直接污染系统 Python。资料来源:.gitignore:1-1

4.2 配置来源

README.md 作为项目的总入口,承担了运行前说明、模块概览与环境变量约定的入口职责。具体运行时配置(如端点地址、日志级别、密钥等)若未在根 README.md 中列出,应查阅对应子项目目录下的文档与 pyproject.toml 中的 scripts / entry-points 声明。资料来源:README.md:1-1hermes/pyproject.toml:1-1

4.3 部署形态选择

  • 嵌入式集成:以 sdk 为主,将其作为上层业务项目的依赖直接 import,无需独立部署进程。资料来源:sdk/pyproject.toml:1-1
  • 服务化运行:将 mcp 与/或 hermes 作为常驻进程或服务部署,通过 pip install 产物或 python -m 方式运行,并按各自 pyproject.toml 中声明的入口点启动。资料来源:mcp/pyproject.toml:1-1hermes/pyproject.toml:1-1

5. 常见安装/部署陷阱

资料来源:sdk/pyproject.toml:1-1mcp/pyproject.toml:1-1hermes/pyproject.toml:1-1

开发、测试与路线图

本文面向希望参与 a2a-dm(Agent-to-Agent Decision Making)项目的开发者与集成方,梳理开发环境准备、测试与验证流程、贡献规范以及后续路线图。仓库由主项目目录与 sdk/、mcp/ 两个子模块组成,各自维护独立的贡献与安全文档,但整体遵循统一的开发节奏。

章节 相关页面

继续阅读本节完整说明和来源证据。

项目结构与开发入口

仓库顶层 README.md 给出了一站式指引:克隆后首先阅读主说明,然后按需进入子模块(sdk/mcp/)。每个子模块都附带各自的 CONTRIBUTING.md,意味着 SDK 与 MCP 两侧的构建命令、依赖管理与提交流程是相互独立的。

进入任一子模块前,开发者应先确认本地的 Node/Python 版本、依赖安装方式以及代码风格工具(通常由 CONTRIBUTING.md 内列出)。

测试与集成验证

docs/INTEGRATIONS.md 是验证模块之间协作是否正常的核心参考。它描述了 SDK 与 MCP 之间、以及与外部代理(Agent)协议互通时的端到端测试思路:通过集成场景覆盖决策消息的序列化、路由与回执等关键路径。开发者在本地的验证步骤通常为:

  1. 按子模块 CONTRIBUTING.md 完成依赖安装与构建。
  2. 启动示例代理或 mock 服务,复现 INTEGRATIONS.md 中列出的集成用例。
  3. 记录失败用例并附带最小复现脚本随 PR 提交。

资料来源:docs/INTEGRATIONS.md:1-40sdk/CONTRIBUTING.md:1-30

贡献流程与安全策略

贡献者必须遵守 SDK 与 MCP 各自定义的流程。sdk/CONTRIBUTING.md 强调在提交 PR 前运行 lint、单测与集成测试;mcp/CONTRIBUTING.md 则更关注协议层面的兼容性回归。安全相关问题不应公开提交,而应通过 sdk/SECURITY.md 中给出的渠道进行私下披露,仓库维护者会在确认后协调修复与披露时间线。

路线图(WAKE 计划)

docs/WAKE_ROADMAP.md 集中描述了项目的中期演进方向,"WAKE" 是该路线图的代号,覆盖协议增强、性能基准、跨代理互操作与可观测性等议题。文档中通常按里程碑拆解:近期聚焦稳定性与文档完善,中期引入更丰富的决策上下文,远期则探索多代理协作框架的标准化。

资料来源:docs/WAKE_ROADMAP.md:1-60README.md:1-40

总体节奏一览

阶段主要活动参考文档
环境准备安装依赖、阅读子模块说明README.md、sdk/CONTRIBUTING.md
本地开发编码、lint、单元测试sdk/CONTRIBUTING.md、mcp/CONTRIBUTING.md
集成验证跑通 SDK↔MCP↔Agent 用例docs/INTEGRATIONS.md
安全披露私密上报,等待协调sdk/SECURITY.md
路线跟进对照 WAKE 里程碑调整计划docs/WAKE_ROADMAP.md

遵循上述节奏即可在保证质量与安全的前提下,持续向 a2a-dm 提交可被合并的贡献。

资料来源:docs/INTEGRATIONS.md:1-40sdk/CONTRIBUTING.md:1-30

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 可能修改宿主 AI 配置

安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

medium 存在评分风险

风险会影响是否适合普通用户安装。

Pitfall Log / 踩坑日志

项目:shichuanqiong/a2a-dm

摘要:发现 7 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:配置坑 - 可能修改宿主 AI 配置。

1. 配置坑 · 可能修改宿主 AI 配置

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
  • 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
  • 证据:capability.host_targets | https://github.com/shichuanqiong/a2a-dm | host_targets=mcp_host, hermes, claude_code, claude, cursor

2. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 证据:capability.assumptions | https://github.com/shichuanqiong/a2a-dm | README/documentation is current enough for a first validation pass.

3. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 证据:evidence.maintainer_signals | https://github.com/shichuanqiong/a2a-dm | last_activity_observed missing
  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 证据:downstream_validation.risk_items | https://github.com/shichuanqiong/a2a-dm | no_demo; severity=medium

5. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 证据:risks.scoring_risks | https://github.com/shichuanqiong/a2a-dm | no_demo; severity=medium

6. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 证据:evidence.maintainer_signals | https://github.com/shichuanqiong/a2a-dm | issue_or_pr_quality=unknown

7. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 证据:evidence.maintainer_signals | https://github.com/shichuanqiong/a2a-dm | release_recency=unknown

来源:Doramagic 发现、验证与编译记录