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

生成时间：2026-07-05 07:12:31 UTC

## 目录

- [项目概览](#page-1)
- [系统架构](#page-2)
- [Python SDK 核心 API](#page-3)
- [守护进程框架与接收器层级](#page-4)
- [唤醒上下文与跨会话记忆](#page-5)
- [Agent Card 与代理发现](#page-6)
- [MCP 服务器与聊天驱动集成](#page-7)
- [Hermes Agent 插件](#page-8)
- [群聊 v0.10 设计](#page-9)
- [示例与桥接模式](#page-10)
- [部署、安装与配置](#page-11)
- [开发、测试与路线图](#page-12)

<a id='page-1'></a>

## 项目概览

### 相关页面

相关主题：[系统架构](#page-2), [部署、安装与配置](#page-11)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
- [landing/README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/landing/README.md)
- [landing/im.tsx](https://github.com/shichuanqiong/a2a-dm/blob/main/landing/im.tsx)
</details>

# 项目概览

## 项目定位与目标

`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）思路，从用户访问到智能体对话的完整流程如下：

```mermaid
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]()

## 入门指引

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-40]()、[landing/README.md:1-20]()

---

<a id='page-2'></a>

## 系统架构

### 相关页面

相关主题：[项目概览](#page-1), [Python SDK 核心 API](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
- [sdk/a2a_dm/client.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/client.py)
- [mcp/a2a_dm_mcp/server.py](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/a2a_dm_mcp/server.py)
- [hermes/a2a_dm_hermes/runtime.py](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/runtime.py)
</details>

# 系统架构

## 一、总体定位与设计目标

`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"，意味着协议细节被有意封装在该层以上，避免污染调用方代码。

```python
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` 是一个常驻进程式组件，承担三类职责：

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 的完整数据流：

```mermaid
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 暴露给外部生态，构成一套灵活且可组合的消息通信基础设施。

---

<a id='page-3'></a>

## Python SDK 核心 API

### 相关页面

相关主题：[系统架构](#page-2), [守护进程框架与接收器层级](#page-4), [Agent Card 与代理发现](#page-6)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [sdk/a2a_dm/__init__.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/__init__.py)
- [sdk/a2a_dm/client.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/client.py)
- [sdk/a2a_dm/dm.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/dm.py)
- [sdk/a2a_dm/models.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/models.py)
- [sdk/a2a_dm/_http.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/_http.py)
- [sdk/a2a_dm/friends_api.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/friends_api.py)
</details>

# Python SDK 核心 API

## 概述

`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 服务端"的单向依赖链。下图展示了典型的一次消息发送路径：

```mermaid
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.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 应用提供稳定、可测试、可组合的消息与社交关系能力。

---

<a id='page-4'></a>

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

### 相关页面

相关主题：[Python SDK 核心 API](#page-3), [唤醒上下文与跨会话记忆](#page-5), [示例与桥接模式](#page-10)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [sdk/a2a_dm/daemon/__init__.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/__init__.py)
- [sdk/a2a_dm/daemon/_base.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/_base.py)
- [sdk/a2a_dm/daemon/_dedup.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/_dedup.py)
- [sdk/a2a_dm/daemon/_inbox.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/_inbox.py)
- [sdk/a2a_dm/daemon/_sse.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/_sse.py)
- [sdk/a2a_dm/daemon/triage.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/triage.py)
</details>

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

## 概述

`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 图展示整条接收器链路的拓扑与数据流向：

```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]()。

---

<a id='page-5'></a>

## 唤醒上下文与跨会话记忆

### 相关页面

相关主题：[守护进程框架与接收器层级](#page-4), [示例与桥接模式](#page-10)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [sdk/a2a_dm/wake_context.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/wake_context.py)
- [sdk/a2a_dm/daemon/advanced/_wake_mode.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/daemon/advanced/_wake_mode.py)
- [sdk/a2a_dm/skill.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/skill.py)
- [sdk/a2a_dm/models.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/models.py)
- [docs/WAKE_ROADMAP.md](https://github.com/shichuanqiong/a2a-dm/blob/main/docs/WAKE_ROADMAP.md)
- [sdk/examples/03_context_for_wake.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/03_context_for_wake.py)
</details>

# 唤醒上下文与跨会话记忆

## 一、定位与职责

在 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]()

```mermaid
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 时，它会：

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-30]()、[sdk/examples/03_context_for_wake.py:1-40]()、[docs/WAKE_ROADMAP.md:1-30]()

---

<a id='page-6'></a>

## Agent Card 与代理发现

### 相关页面

相关主题：[Python SDK 核心 API](#page-3), [群聊 v0.10 设计](#page-9)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [sdk/a2a_dm/agent_card.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/agent_card.py)
- [sdk/a2a_dm/agent_card_api.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/agent_card_api.py)
- [sdk/a2a_dm/agents_api.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/agents_api.py)
- [sdk/a2a_dm/skill.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/skill.py)
- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
</details>

# Agent Card 与代理发现

## 概述与定位

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` | 该技能支持的输入输出类型 |

资料来源：[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`：返回当前已注册代理的简化列表（通常只包含 `name`、`url`、`description`），用于目录式发现
- `POST /agents`：提交 Agent Card 完成代理注册

资料来源：[sdk/a2a_dm/agents_api.py:1-50]()

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

## 发现工作流

```mermaid
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]()

---

<a id='page-7'></a>

## MCP 服务器与聊天驱动集成

### 相关页面

相关主题：[系统架构](#page-2), [部署、安装与配置](#page-11)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [mcp/a2a_dm_mcp/__init__.py](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/a2a_dm_mcp/__init__.py)
- [mcp/a2a_dm_mcp/__main__.py](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/a2a_dm_mcp/__main__.py)
- [mcp/a2a_dm_mcp/server.py](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/a2a_dm_mcp/server.py)
- [mcp/README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/README.md)
- [mcp/pyproject.toml](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/pyproject.toml)
- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
</details>

# MCP 服务器与聊天驱动集成

## 模块定位与总体职责

`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]()

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

```mermaid
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]()

在一次典型的交互中：

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]()

---

<a id='page-8'></a>

## Hermes Agent 插件

### 相关页面

相关主题：[守护进程框架与接收器层级](#page-4), [MCP 服务器与聊天驱动集成](#page-7)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [hermes/README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/README.md)
- [hermes/a2a_dm_hermes/__init__.py](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/__init__.py)
- [hermes/a2a_dm_hermes/autowake.py](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/autowake.py)
- [hermes/a2a_dm_hermes/delivery.py](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/delivery.py)
- [hermes/a2a_dm_hermes/gatewaycfg.py](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/gatewaycfg.py)
- [hermes/a2a_dm_hermes/plugin.yaml](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/a2a_dm_hermes/plugin.yaml)
</details>

# Hermes Agent 插件

## 概述与定位

`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]()。

## 核心数据流

```mermaid
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]()。

---

<a id='page-9'></a>

## 群聊 v0.10 设计

### 相关页面

相关主题：[Python SDK 核心 API](#page-3), [唤醒上下文与跨会话记忆](#page-5), [开发、测试与路线图](#page-12)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [docs/GROUP_CHAT_v0.10.md](https://github.com/shichuanqiong/a2a-dm/blob/main/docs/GROUP_CHAT_v0.10.md)
- [sdk/a2a_dm/groups_api.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/groups_api.py)
- [sdk/a2a_dm/groups_models.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/a2a_dm/groups_models.py)
- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
</details>

# 群聊 v0.10 设计

## 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 的端到端消息流如下：

```mermaid
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]()

---

<a id='page-10'></a>

## 示例与桥接模式

### 相关页面

相关主题：[守护进程框架与接收器层级](#page-4), [唤醒上下文与跨会话记忆](#page-5)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [sdk/examples/README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/README.md)
- [sdk/examples/01_send_dm.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/01_send_dm.py)
- [sdk/examples/02_daemon_basic.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/02_daemon_basic.py)
- [sdk/examples/03_context_for_wake.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/03_context_for_wake.py)
- [sdk/examples/04_triage_with_cap.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/04_triage_with_cap.py)
- [sdk/examples/05_wake_mode.py](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/examples/05_wake_mode.py)
</details>

# 示例与桥接模式

## 概述与定位

`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]()

## 桥接模式的工作流

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

```mermaid
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 规范的直连消息应用。

---

<a id='page-11'></a>

## 部署、安装与配置

### 相关页面

相关主题：[项目概览](#page-1), [MCP 服务器与聊天驱动集成](#page-7), [Hermes Agent 插件](#page-8)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
- [sdk/pyproject.toml](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/pyproject.toml)
- [mcp/pyproject.toml](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/pyproject.toml)
- [hermes/pyproject.toml](https://github.com/shichuanqiong/a2a-dm/blob/main/hermes/pyproject.toml)
- [.gitignore](https://github.com/shichuanqiong/a2a-dm/blob/main/.gitignore)
</details>

# 部署、安装与配置

本页面向首次接触 **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 本地安装流程

推荐的安装顺序为：

1. **克隆仓库**
   ```bash
   git clone https://github.com/shichuanqiong/a2a-dm
   cd a2a-dm
   ```
2. **按需进入子项目目录并安装**（以 `sdk` 为例）
   ```bash
   cd sdk
   pip install -e .
   ```
   对 `mcp/` 与 `hermes/` 子项目重复同样的步骤，三个子项目互为独立包，可以在同一虚拟环境中并存安装。资料来源：[sdk/pyproject.toml:1-1]()、[mcp/pyproject.toml:1-1]()、[hermes/pyproject.toml:1-1]()

## 3. 构建与打包

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

```bash
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]()

---

<a id='page-12'></a>

## 开发、测试与路线图

### 相关页面

相关主题：[项目概览](#page-1), [群聊 v0.10 设计](#page-9)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/shichuanqiong/a2a-dm/blob/main/README.md)
- [docs/INTEGRATIONS.md](https://github.com/shichuanqiong/a2a-dm/blob/main/docs/INTEGRATIONS.md)
- [docs/WAKE_ROADMAP.md](https://github.com/shichuanqiong/a2a-dm/blob/main/docs/WAKE_ROADMAP.md)
- [sdk/CONTRIBUTING.md](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/CONTRIBUTING.md)
- [mcp/CONTRIBUTING.md](https://github.com/shichuanqiong/a2a-dm/blob/main/mcp/CONTRIBUTING.md)
- [sdk/SECURITY.md](https://github.com/shichuanqiong/a2a-dm/blob/main/sdk/SECURITY.md)
</details>

# 开发、测试与路线图

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

## 项目结构与开发入口

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

- 主入口与快速开始：[README.md](README.md)
- SDK 贡献指引：[sdk/CONTRIBUTING.md](sdk/CONTRIBUTING.md)
- MCP 贡献指引：[mcp/CONTRIBUTING.md](mcp/CONTRIBUTING.md)

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

## 测试与集成验证

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

1. 按子模块 `CONTRIBUTING.md` 完成依赖安装与构建。
2. 启动示例代理或 mock 服务，复现 `INTEGRATIONS.md` 中列出的集成用例。
3. 记录失败用例并附带最小复现脚本随 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/SECURITY.md)
- 贡献流程基线：[sdk/CONTRIBUTING.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 提交可被合并的贡献。

---

<!-- evidence_pipeline_checked: true -->

---

## Doramagic 踩坑日志

项目：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

<!-- canonical_name: shichuanqiong/a2a-dm; human_manual_source: deepwiki_human_wiki -->
