内容
<p align="center">
<img src="assets/logo.png" alt="LAD-A2A Logo" width="120">
</p>
<h1 align="center">本地代理发现,用于A2A(LAD-A2A)</h1>
<p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="Apache License"></a>
<a href="https://github.com/franzvill/lad/actions/workflows/tests.yml"><img src="https://github.com/franzvill/lad/actions/workflows/tests.yml/badge.svg" alt="测试"></a>
<a href="spec/spec.md"><img src="https://img.shields.io/badge/spec-draft-orange.svg" alt="规格版本"></a>
<a href="https://lad-a2a.org"><img src="https://img.shields.io/badge/docs-lad--a2a.org-blue.svg" alt="文档"></a>
</p>
<p align="center"><strong>一种用于在本地网络上发现支持A2A的代理的开放协议。</strong></p>
LAD-A2A解决了人工智能代理生态系统中的一个关键问题:当设备加入网络时——无论是酒店Wi-Fi、办公局域网、游轮、医院园区——用户的AI助手如何发现和连接到本地代理?虽然 [A2A](https://a2a-protocol.org) 定义了代理到代理的通信,[MCP](https://modelcontextprotocol.io) 定义了代理到工具的集成,**LAD-A2A定义了代理发现**。
使用LAD-A2A,代理可以:
- **自动发现**加入网络时的本地A2A代理
- **验证身份**通过签名的AgentCards和DIDs
- **获取用户同意**在建立连接之前
- **协商能力**通过标准的A2A机制
## 查看实际操作
<div align="center">
https://github.com/user-attachments/assets/a6a06e95-729b-465a-857c-6a87da52b302
<em>真正的mDNS发现 → LAD-A2A协议 → A2A JSON-RPC通信</em>
</div>
## 为什么是LAD-A2A?
人工智能代理越来越强大,但它们仍然与物理环境隔离。客人的AI助手无法发现酒店的礼宾代理。员工的助手无法找到建筑物的房间预订代理。患者的助手不知道医院提供导航代理。
LAD-A2A通过提供以下功能解决了这个问题:
- **零配置发现:** 代理通过mDNS/DNS-SD( `_lad-a2a._tcp` )和众所周知的端点自动找到彼此。
- **诚实的信任模型:** 本地网络默认是敌对的。LAD-A2A仔细分离了**通道身份验证** (TLS证明你已经到达了URL中的主机)和**身份验证** (域/JWS/DID锚定到组织)。
- **明确的用户同意:** 在首次联系之前,需要人类批准,并以验证的身份为关键——绝不自动批准。
- **生态系统对齐:** LAD-A2A仅处理发现——一旦代理被验证和批准,标准的A2A通信就会接管。
## 它如何融入
<p align="center">
<img src="assets/protocol-triangle.png" alt="协议栈:LAD-A2A → A2A → MCP" width="350">
</p>
| 协议 | 角色 | 规格 |
|----------|------|---------------|
| **LAD-A2A** | 发现和信任引导 | [lad-a2a.org](https://lad-a2a.org) |
| **A2A** | 代理到代理通信 | [a2a-protocol.org](https://a2a-protocol.org) |
| **MCP** | 代理到工具/数据 | [modelcontextprotocol.io](https://modelcontextprotocol.io) |
LAD-A2A是**第一次握手**。它回答了“谁在这里?”这样A2A就可以回答“你能做什么?”而MCP可以回答“我怎么做?”
## 发现机制
LAD-A2A支持多种发现路径,并具有自动故障转移:
| 机制 | 环境 | 描述 |
|-----------|-------------|-------------|
| **mDNS/DNS-SD** | LAN,消费者Wi-Fi | 通过LAD拥有的 `_lad-a2a._tcp` 服务类型进行零配置发现 |
| **众所周知的端点** | 强制门户,Web | 网络域上的 `/.well-known/lad/agents` |
| **DHCP选项** | 企业网络 | 包含发现URL的自定义选项 |
| **二维码/近场通信** | 物理备用 | 受限网络的AgentCard的直接链接 |
## 入门指南
### 交互式演示(推荐)
使用具有两个AI代理的完整演示体验LAD-A2A:
```bash
cd demo
cp .env.example .env
# 将您的OpenAI API密钥添加到.env
./run_demo.sh
```
打开 http://localhost:8000 查看:
- 真实的mDNS发现( `_a2a._tcp.local` )
- LAD-A2A协议正在运行
- A2A JSON-RPC 2.0通信
- 基于LLM的查询路由
参见 [demo/README.md](demo/README.md) 以获取完整文档。
### 本地运行
```bash
cd reference
pip install -e .
# 启动发现服务器(仅限开发)
python -m server.lad_server --name "我的代理" --port 8080
# 在另一个终端中发现代理。 --no-verify-tls 选择plaintext进行本地开发;如果没有它,客户端会拒绝非https URL作为发现失败。
python -m client.lad_client --url http://localhost:8080 --no-verify-tls
```
> **注意:** 上面的示例在本地开发中使用HTTP。在生产环境中,**需要TLS**,按照 [安全规格](spec/spec.md#4-security-requirements):所有端点必须使用TLS 1.2+,非https URL作为发现失败,而不仅仅是未经验证的代理。
## 示例:酒店礼宾
```
1. 客人设备加入“ExampleHotel-Guest”Wi-Fi
2. 客户端查询mDNS的_lad-a2a._tcp.local和众所周知的端点,然后按身份密钥聚合和去重
3. 发现响应包括AgentCard URL(https)和DID身份密钥
4. 客户端通过验证的TLS获取卡片并验证身份(JWS/DID锚定到组织域);失败的方法是致命的
5. 客户端提示用户,分别显示通道和身份:“Domain-authenticated:concierge.examplehotel.com — 连接?”
6. 用户批准 → 标准A2A会话开始(这是第一次联系)
7. 用户询问:“早餐时间是什么时候?” → 代理通过A2A响应
```
## 安全模型
本地网络**默认是敌对的**——有效的TLS证书对于攻击者拥有的类似域名是威胁模型的一部分,而不是防御措施。LAD-A2A强制执行:
| 要求 | 描述 |
|-------------|-------------|
| **通道 ≠ 身份** | 验证的TLS身份验证 *通道* ;它本身永远不会标记代理为“已验证” |
| **锚定身份** | 域/JWS/DID,每个都绑定到组织域;失败的更强方法致命(无较弱的回退) |
| **新鲜签名的卡片** | JWS AgentCards带有短暂的 `exp` ;过期/重放的卡片被拒绝 |
| **明确的同意** | 在首次联系之前,需要人类批准,并以验证的身份为关键——绝不自动批准 |
| **限制和隐私** | 有界的发现响应;无通配符CORS;同意前的数据最小化 |
参见 **[信任模型](https://lad-a2a.org/trust-model/)** 以了解通道/身份分离是关键的原因。
## 文档
**📚 [lad-a2a.org](https://lad-a2a.org) 上的完整文档**
| 资源 | 描述 |
|----------|-------------|
| 📖 [规格](https://lad-a2a.org/spec/spec/) | 带有JSON模式的完整协议规格 |
| 🔧 [参考实现](https://lad-a2a.org/reference/) | Python服务器和客户端库 |
| 🎮 [交互式演示](https://lad-a2a.org/demo/) | 带有mDNS + A2A的完整演示 |
| 📚 [示例](https://lad-a2a.org/examples/) | 集成场景和用例 |
## 用例
| 环境 | 示例交互 |
|-------------|---------------------|
| **酒店** | “水疗中心的计划是什么?” / “请求延迟退房” |
| **游轮** | “今晚的演出在哪里?” / “预订岸上游览” |
| **办公室** | “预订会议室4B” / “查找可用桌子” |
| **医院** | “导航到放射科” / “检查预约状态” |
| **体育场** | “找到我的座位” / “订购食物到第112区” |
| **智慧城市** | “下一班公交车到市中心?” / “查找我附近的停车位” |
## 贡献
我们欢迎为LAD-A2A协议做出贡献。
- **问题和讨论:** [GitHub讨论](https://github.com/franzvill/lad/discussions)
- **问题和反馈:** [GitHub问题](https://github.com/franzvill/lad/issues)
- **贡献指南:** [CONTRIBUTING.md](CONTRIBUTING.md)
## 许可证
该项目在 [Apache License 2.0](LICENSE) 下获得许可。