代理中继
为不总是打开的AI代理提供轻量级消息中继。
问题
谷歌的 A2A协议 假设代理是永久可访问的HTTP服务。但是,许多现实世界的代理——像Claude Code这样的CLI工具、本地LLM运行器、cron触发的工作器、笔记本电脑绑定的助手——只有在终端会话打开或日程表触发时才存在。
Relay特工弥合了这一差距。它为来来往往的代理提供持久的消息队列、代理发现和结构化的任务切换。消息等待。任务跟踪生命周期。接力赛是唯一需要继续进行的比赛。
主要特点
- 线下先排队 --消息会一直持续到目标代理轮询或重新连接为止
- MCP本地 --附带MCP网桥,因此Claude Code代理不需要任何自定义客户端代码
- A2A对齐数据模型 --任务、消息和工件遵循A2A惯例,以备将来迁移
- 信任级别 --代理具有范围权限(可以从谁那里读取、发送给谁、访问什么工具)
- SQLite存储 --没有Postgres,没有Redis,没有Docker Compose。一个文件,碰撞安全WAL模式
- 尾秤友好 --为Tailscale网络上的私有代理网格设计
- 完整的审计追踪 --永久记录每条消息、传递和状态更改
快速开始
1.安装
git clone https://github.com/hazzap123/agent-relay.git
cd agent-relay
python3 -m venv venv && source venv/bin/activate
pip install -e .2.配置
cp .env.example .env
# Edit .env — set API keys for your agents3.跑步
uvicorn relay.server:app --host 0.0.0.0 --port 84004.注册克劳德代码(MCP)
claude mcp add relay -- python3 /path/to/agent-relay/relay/mcp_bridge.py为网桥设置环境变量:
RELAY_URL=http://your-relay-host:8400
RELAY_API_KEY=your-agent-api-key
AGENT_ID=claude-codeAPI
14个REST端点 /api/v1:
| 方法 | 端点 | 描述 |
|---|---|---|
| 得到 | /api/v1/agents | 列出所有注册代理人 |
| 职位 | /api/v1/agents | 注册新代理 |
| 得到 | /api/v1/agents/{id} | 获取代理详细信息 |
| 职位 | /api/v1/agents/{id}/heartbeat | 更新在线/离线状态 |
| 职位 | /api/v1/tasks | 创建并发送任务 |
| 得到 | /api/v1/tasks | 使用筛选器查询任务 |
| 得到 | /api/v1/tasks/{id} | 获取任务详细信息 |
| PUT | /api/v1/tasks/{id} | 更新任务状态 |
| 职位 | /api/v1/messages | 发送消息 |
| 得到 | /api/v1/inbox | 获取代理的待处理消息 |
| 职位 | /api/v1/broadcast | 发送给所有代理 |
| 职位 | /api/v1/tasks/{id}/artifacts | 将工件附加到任务 |
| 得到 | /api/v1/health | 健康检查 |
| 得到 | /api/v1/stats | 系统统计 |
MCP工具
MCP桥公开了10个Claude Code代理可以本机调用的工具:
relay_inbox--检查待处理邮件relay_send_task--将任务委托给另一个代理relay_update_task--更新任务状态(已接受、正在工作、已完成等)relay_send_message--发送自由格式的消息relay_get_task--获取任务详细信息relay_list_tasks--使用筛选器查询任务relay_agents--列出注册代理人及其身份relay_broadcast--向所有代理发送消息relay_attach_artifact--将输出附加到任务relay_heartbeat--更新您的在线/离线状态
代理配置
复制 agents.example.json 并定义您的代理:
[
{
"agent_id": "claude-code",
"name": "Claude Code",
"capabilities": ["code", "analysis", "memory"],
"trust_tier": 1,
"contact": { "method": "poll" }
},
{
"agent_id": "assistant",
"name": "Assistant",
"capabilities": ["email", "scheduling"],
"trust_tier": 2,
"contact": { "method": "webhook", "webhook_url": "http://..." }
}
]信任层控制权限:
- 第1级 --完全访问,可以读取和发送给所有代理
- 第2层 --范围访问,受限的读取/发送权限
- 第3层 --最低访问权限,高度沙盒化
部署
包括systemd服务文件和部署脚本:
DEPLOY_HOST=root@your-server RELAY_HOST=your-server-ip bash deploy.sh看 agent-relay.service 对于systemd单元。
测试
python -m pytest tests/ -vA2A对齐
Agent Relay借用了A2A的数据模型和生命周期状态,但没有实现完整的A2A JSON-RPC 2.0规范。这是故意的——A2A假设始终在线的HTTP服务,这与CLI代理或间歇性工作者不匹配。
| A2A概念 | 代理中继 | 状态 |
|---|---|---|
| AgentCard | 具有功能的代理注册表 | 已实现 |
| 任务生命周期 | 已提交→ 接受→ 工作→ 已完成/失败 | 已实施 |
| 消息/部分 | 带元数据的结构化消息 | 已实现 |
| 工件 | 任务附件 | 已实施 |
| JSON-RPC 2.0 | REST+MCP桥 | 不同的传输,相同的语义 |
| 流媒体(SSE) | 投票+网络钩子 | 计划中 |
数据模型的设计使得迁移到完全符合A2A是累加的,而不是重写。
建筑
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Agent A │ │ Agent B │ │ Agent C │
│ (CLI tool) │ │ (daemon) │ │ (CLI tool) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ MCP │ HTTP/poll │ MCP
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Agent Relay │
│ FastAPI · SQLite · Bearer auth · Trust tiers │
│ Tailscale network — private, zero-config │
└─────────────────────────────────────────────────────────┘安全说明
- 无TLS --服务器绑定纯HTTP。专为在Tailscale(提供加密)或反向代理后面使用而设计。在没有TLS终止的情况下,不要直接暴露在互联网上。
- 无速率限制 --行为不端的特工可能会淹没接力赛。考虑添加
slowapi或用于生产用途的反向代理速率限制器。 - SQLite并发 --在大量并发写入下,您可能会看到“数据库已锁定”错误。添加
PRAGMA busy_timeout=5000如果发生这种情况。对于高吞吐量部署,请考虑PostgreSQL。 - Systemd以root身份运行 --包含的服务文件默认为
User=root为生产创建一个专门的服务用户(useradd -r -s /bin/false relay).
许可证
Apache 2.0——请参阅 许可证.
