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-20、landing/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-80、README.md:1-40
入门指引
- 克隆仓库到本地:
git clone https://github.com/shichuanqiong/a2a-dm - 阅读根
README.md了解项目意图、技术栈与适用场景 - 进入
landing/目录,按照landing/README.md的指引安装依赖并启动开发服务器 - 在浏览器中打开落地页地址,即可与 A2A 智能体进行即时消息交互
完成上述步骤后,开发者可基于 im.tsx 进一步定制 UI、接入自有 A2A 后端,或将该模式迁移至其他应用场景中。
资料来源:README.md:1-40
系统架构
a2a-dm(Agent-to-Agent Direct Messaging)是一个面向 AI Agent 的点对点直连消息协议框架,目标是在不依赖中心化消息总线的前提下,让具备独立身份与上下文的 Agent 可以互相发现、寻址、并交换结构化消息。README.md 把项目的核心抽象概括为"DMs between agents, no servers required",强...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
一、总体定位与设计目标
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 配置,并对外暴露一组语义清晰的协程:send、receive、subscribe_room、create_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_address 与 envelope_to_dict,方便在异构系统之间搬运消息。
资料来源:sdk/a2a_dm/client.py:42-110
3.2 MCP 桥接服务(`mcp/a2a_dm_mcp/server.py`)
MCP Server 的角色是"翻译官":把 A2AClient 暴露的能力转换成 MCP 协议要求的 tools/list、tools/call 与 resources/read 等接口。server.py 的 register_routes 函数会把 send_message、list_rooms、read_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 是一个常驻进程式组件,承担三类职责:
- 会话编排:根据
room_id维护成员列表、权限与历史,确保只有授权 Agent 才能加入并消费消息; - 事件循环:以异步任务形式轮询 transport,处理入站 envelope 并按订阅关系 fan-out 给感兴趣的 SDK;
- 上下文注入:为每次
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 的高层级职责可归纳为三点:
- 数据建模:以强类型对象描述消息、Agent、好友关系等核心实体,便于在调用方代码中安全访问字段。
- 传输隔离:将底层 HTTP 请求封装在内部模块中,对外暴露稳定的 Pythonic 接口。
- 业务聚合:在客户端层组合"消息发送""好友管理"等高频场景,调用方无需直接拼装 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 --> Aclient.py 作为入口聚合器,会持有 _http.py 提供的传输实例,并将其注入到 dm.py 与 friends_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 中的实体(消息、会话、好友资料等)通常基于 pydantic 或 dataclasses 实现,以保证序列化与字段校验一致性。_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 应用提供稳定、可测试、可组合的消息与社交关系能力。
守护进程框架与接收器层级
a2a-dm 的 daemon 子包实现了一个常驻后台运行的"守护进程框架",专门用于接收、解析、分发并去重来自其他 A2A(Agent-to-Agent)对等节点的消息。该框架以"接收器层级(receiver hierarchy)"为核心设计模式:在公共基类之上派生出多个职责单一的接收器,分别负责 SSE 流接入、收件箱缓存、消息分类与去重判等子任务,从而在单进程内构成一...
继续阅读本节完整说明和来源证据。
概述
a2a-dm 的 daemon 子包实现了一个常驻后台运行的"守护进程框架",专门用于接收、解析、分发并去重来自其他 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.py 的 DedupReceiver 在链尾执行幂等检查,利用消息指纹(例如哈希)丢弃重复事件,确保下游业务只看到唯一消息 资料来源: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。
守护进程的生命周期包含四个阶段:
- 初始化阶段:读取配置(端点 URL、认证令牌、去重窗口大小等),构造各接收器实例。
- 链接阶段:按既定拓扑把接收器串接,注入共享上下文(如 logger、metrics sink)。
- 运行阶段:监听 SSE 流,将事件依次投递到 Inbox、Triage、Dedup;任何接收器抛出的异常都会被基类的错误钩子捕获并记录,避免单点失败拖垮整条链路 资料来源:sdk/a2a_dm/daemon/_base.py:60-140。
- 优雅停机阶段:调用
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
其核心目标可以拆解为三点:
- 状态恢复:当 daemon 从空闲态被再次唤醒时,能够加载上一次退出前未消化的任务上下文。
- 跨会话一致:同一条 Skill 在不同会话中被触发时,能够引用相同的历史片段。
- 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-120、sdk/a2a_dm/models.py:90-130
三、Daemon 唤醒模式(`_wake_mode.py`)
daemon/advanced/_wake_mode.py 是真正的"唤醒执行器"。当外部信号(用户命令、定时器、Skill hook)触发 daemon 时,它会:
- 读取持久化层中尚未过期的
WakeContext列表; - 根据优先级与
anchor排序,决定先恢复哪一段记忆; - 将上下文包装为可调用的参数,注入到目标 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-30、sdk/examples/03_context_for_wake.py:1-40、docs/WAKE_ROADMAP.md:1-30
资料来源:sdk/a2a_dm/wake_context.py:35-120、sdk/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]()
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
Agent Card 是 A2A(Agent-to-Agent)协议中用于描述代理身份、能力与交互方式的标准 JSON 文档,是客户端进行代理发现(Agent Discovery)的入口。在 a2a-dm 项目的 sdk/a2a_dm 模块中,Agent Card 与代理发现共同构成了代理注册、能力查询与任务调用的最小闭环。资料来源:README.md:1-40
在该模块下,agent_card.py 与 skill.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 | 该技能支持的输入输出类型 |
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:返回当前已注册代理的简化列表(通常只包含name、url、description),用于目录式发现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.py 与 skill.py 通过强类型模型保证结构一致性,agent_card_api.py 与 agents_api.py 通过标准 HTTP 端点提供发现能力。客户端无需硬编码代理信息即可动态接入,代理也只需发布一份符合规范的 JSON 即可被网络中的任意对端识别与调用。资料来源:README.md:1-40
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 负责对外暴露最关键的符号(如 main 或 server),确保外部引用路径稳定,避免内部重构破坏聊天驱动侧的注册逻辑。资料来源: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
在一次典型的交互中:
- 聊天驱动在用户输入后判断需要调用工具,向
a2a_dm_mcp发起tools/call请求。 server.py中的对应处理函数被触发,把载荷转发给 a2a-dm 的会话层。- 会话层返回结果或增量事件,server 将其包装为 MCP 响应结构送回聊天驱动。
- 聊天驱动把工具结果与上下文拼接后继续生成用户可见的回答。
资料来源:README.md:30-80
通过这种分层,a2a-dm 可以在不修改聊天驱动的前提下,把多 Agent 决策能力以工具形态嵌入既有对话流程中;同时 MCP 协议的标准化也使得该集成可以复用到多种客户端中。资料来源:mcp/README.md:50-70
Hermes Agent 插件
a2admhermes 是 a2a-dm 项目下的一个可插拔 Agent 模块,作为 Agent 调度体系中的"信使/网关"角色存在。其核心职责是在 Telegram 等外部即时通讯(IM)网关与 a2a-dm 的多 Agent 调度网络之间建立双向桥接,从而把用户通过 IM 发送的消息转换成 a2a-dm 的内部任务,并把执行结果回投给用户。资料来源:[hermes/RE...
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
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-30、hermes/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-35、hermes/a2a_dm_hermes/autowake.py:1-50。
关键子模块说明
网关配置(gatewaycfg.py)
gatewaycfg.py 集中保存 Telegram bot token、默认 chat_id、白名单用户、轮询间隔、超时阈值等运行参数,并通过一个 dataclass 或字典结构向其它模块暴露只读视图,避免在 delivery.py 与 autowake.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.py 与 delivery.py,并复用 autowake.py 即可形成新的网关插件,而无需修改调度核心。资料来源:hermes/README.md:20-40、hermes/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-40、hermes/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_id、name、created_at、owner_agent_id等只读字段,以及可变成员集合members: List[GroupMember]。GroupMember:表示加入房间的 Agent 实体,字段包括agent_id、display_name、role(owner/admin/member)以及加入时间joined_at。GroupMessage:群消息体,复用 A2A 通用消息结构并扩展room_id与可选reply_to字段,以支持线程化讨论。GroupEvent:事件枚举,覆盖member_joined、member_left、message_posted、room_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)协议。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
概述与定位
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 规范的直连消息应用。
部署、安装与配置
本页面向首次接触 a2a-dm 仓库的工程师,介绍该项目的整体部署方式、组件结构以及本地安装与配置的关键步骤。内容严格基于仓库根目录的 README.md 与各子项目(sdk、mcp、hermes)的 pyproject.toml,以及 .gitignore 中关于构建与运行环境的约定。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
继续阅读本节完整说明和来源证据。
1. 项目概述与组件结构
a2a-dm 是一个以 SDK、MCP 与 Hermes 三大子项目组成的 Python 工程,每个子项目都是独立可发布的 Python 包。开发者可以通过分别安装这三个包,把它们组合成完整的工作流。仓库根目录提供 README.md 作为统一的项目入口说明,而各子项目在自己的 pyproject.toml 中声明依赖与打包配置,从而实现单一仓库内的多包管理。资料来源:README.md:1-1、sdk/pyproject.toml:1-1
| 子项目 | 角色 | 入口包名(基于 pyproject.toml 中 name 字段推断) |
|---|---|---|
sdk/ | 面向业务方的开发工具包 | a2a-dm(或由该子项目自身定义) |
mcp/ | 模型/消息上下文层组件 | 由 mcp/pyproject.toml 声明 |
hermes/ | 通信/消息分发网关组件 | 由 hermes/pyproject.toml 声明 |
资料来源:sdk/pyproject.toml:1-1、mcp/pyproject.toml:1-1、hermes/pyproject.toml:1-1
2. 安装方式
2.1 依赖前置
所有子项目均基于 Python pyproject.toml(PEP 621 标准)声明依赖,因此最低运行环境需要一个符合各 pyproject.toml 中 requires-python 字段要求的 Python 解释器,以及一个兼容的包管理器(如 pip、Poetry 或 uv)。资料来源:sdk/pyproject.toml:1-1、mcp/pyproject.toml:1-1、hermes/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-1、mcp/pyproject.toml:1-1、hermes/pyproject.toml:1-1
- 克隆仓库
- 按需进入子项目目录并安装(以
sdk为例)
3. 构建与打包
每个子项目都通过 pyproject.toml 进行打包元数据声明,意味着可以通过标准的 Python 构建工具链生成 wheel 与 sdist 产物:
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-1、hermes/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-1、hermes/pyproject.toml:1-1
5. 常见安装/部署陷阱
- 不要把三个子项目分别放入隔离的虚拟环境部署后再尝试互相
import;若需要跨模块引用,请保持在同一个虚拟环境中同时安装三个包。资料来源:sdk/pyproject.toml:1-1、mcp/pyproject.toml:1-1、hermes/pyproject.toml:1-1 - 构建产物目录(
dist/、build/、*.egg-info/)在重新打包前应清理,避免被旧元数据污染。资料来源:.gitignore:1-1 - 在未阅读对应子项目
README/pyproject.toml前,请勿假定统一的默认端口或配置前缀——三个子项目是相互独立发布单元,默认值可能并不一致。资料来源:sdk/pyproject.toml:1-1、mcp/pyproject.toml:1-1、hermes/pyproject.toml:1-1
资料来源:sdk/pyproject.toml:1-1、mcp/pyproject.toml:1-1、hermes/pyproject.toml:1-1
开发、测试与路线图
本文面向希望参与 a2a-dm(Agent-to-Agent Decision Making)项目的开发者与集成方,梳理开发环境准备、测试与验证流程、贡献规范以及后续路线图。仓库由主项目目录与 sdk/、mcp/ 两个子模块组成,各自维护独立的贡献与安全文档,但整体遵循统一的开发节奏。
继续阅读本节完整说明和来源证据。
项目结构与开发入口
仓库顶层 README.md 给出了一站式指引:克隆后首先阅读主说明,然后按需进入子模块(sdk/ 或 mcp/)。每个子模块都附带各自的 CONTRIBUTING.md,意味着 SDK 与 MCP 两侧的构建命令、依赖管理与提交流程是相互独立的。
- 主入口与快速开始:README.md
- SDK 贡献指引:sdk/CONTRIBUTING.md
- MCP 贡献指引:mcp/CONTRIBUTING.md
进入任一子模块前,开发者应先确认本地的 Node/Python 版本、依赖安装方式以及代码风格工具(通常由 CONTRIBUTING.md 内列出)。
测试与集成验证
docs/INTEGRATIONS.md 是验证模块之间协作是否正常的核心参考。它描述了 SDK 与 MCP 之间、以及与外部代理(Agent)协议互通时的端到端测试思路:通过集成场景覆盖决策消息的序列化、路由与回执等关键路径。开发者在本地的验证步骤通常为:
- 按子模块
CONTRIBUTING.md完成依赖安装与构建。 - 启动示例代理或 mock 服务,复现
INTEGRATIONS.md中列出的集成用例。 - 记录失败用例并附带最小复现脚本随 PR 提交。
资料来源:docs/INTEGRATIONS.md:1-40、sdk/CONTRIBUTING.md:1-30
贡献流程与安全策略
贡献者必须遵守 SDK 与 MCP 各自定义的流程。sdk/CONTRIBUTING.md 强调在提交 PR 前运行 lint、单测与集成测试;mcp/CONTRIBUTING.md 则更关注协议层面的兼容性回归。安全相关问题不应公开提交,而应通过 sdk/SECURITY.md 中给出的渠道进行私下披露,仓库维护者会在确认后协调修复与披露时间线。
- SDK 安全披露:sdk/SECURITY.md
- 贡献流程基线:sdk/CONTRIBUTING.md
路线图(WAKE 计划)
docs/WAKE_ROADMAP.md 集中描述了项目的中期演进方向,"WAKE" 是该路线图的代号,覆盖协议增强、性能基准、跨代理互操作与可观测性等议题。文档中通常按里程碑拆解:近期聚焦稳定性与文档完善,中期引入更丰富的决策上下文,远期则探索多代理协作框架的标准化。
资料来源:docs/WAKE_ROADMAP.md:1-60、README.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 提交可被合并的贡献。
失败模式与踩坑日记
保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。
安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
假设不成立时,用户拿不到承诺的能力。
新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
风险会影响是否适合普通用户安装。
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 发现、验证与编译记录