基于 AgentNetwork 的 P2P API 中转 / Key 互助服务
API 转转 由两部分组成,可独立部署也可一起跑:
| 模块 | 作用 | 入口 | 默认端口 |
|---|---|---|---|
| Relay Agent | 中转转发: 外部调用方通过 HTTP 调本服务,本服务通过 anet-sdk 把请求转发到目标 peer | main.py |
8088 |
| Key Bank | Key 银行: 会员先存(deposit)一把 API Key,然后才能借(lease)别人的 Key,借走即焚,但完整备份 | llm_backend.py |
7200 |
┌──────────────┐ HTTP /proxy ┌──────────────┐ anet svc.call ┌──────────────┐
Caller ───▶│ Relay Agent │ ─────────────▶ │ api 转转节点 │ ──────────────▶│ Target Agent │
└──────────────┘ └──────────────┘ └──────────────┘
┌──────────────┐ /deposit + /lease
Member ───▶│ Key Bank │ 先存才能借,一次性
└──────────────┘
两个模块都依赖本地的 anet daemon(心跳、保活、发现都由它做):
curl -fsSL https://agentnetwork.org.cn/install.sh | sh
anet daemon &
anet status # daemon REST 默认监听 http://127.0.0.1:3998git clone <你的仓库地址>
cd API转转
pip install -r requirements.txt
cp .env.example .env # 修改 APP_API_KEY 等让别人通过 HTTP 调你,你帮他转发到 AgentNetwork 上的目标 peer。
uvicorn main:app --host 0.0.0.0 --port 8088
# 或
docker compose up -d| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/health |
健康检查 + 注册状态 |
GET |
/discover?skill=xxx&limit=5 |
发现具备指定技能的 peer |
POST |
/proxy |
转发调用到目标 peer |
curl -X POST http://localhost:8088/proxy \
-H "Authorization: Bearer $APP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target_peer_id": "12D3KooW...",
"service": "echo-l1",
"path": "/echo",
"method": "POST",
"body": {"msg": "hi"},
"caller_did": "did:key:zCaller..."
}'APP_API_KEY: 所有/proxy、/discover必须带Authorization: Bearer <key>ALLOWED_PEERS: 可选白名单,只允许中转到指定 peercaller_did: 透传到X-Agent-DID头,计费 / 审计归调用方;留空则归本节点
会员制的 Key 互助池。规则:
- 存款(deposit): 任何 DID 都可以提交一把 Key,直接挂牌入库,不做上游验证
- 入会: 存过 Key 的 DID 自动成为"会员"
- 借款(lease): 只有会员才能借;一次只借一把;借走后该 Key 从可用池移除(阅后即焚)
- 不能自借: 不会借到自己存的 Key
- 永久备份: 借出记录、存款记录全保留,可审计
./run.sh start # 后台启动 bank,并自动注册到 anet
./run.sh status # 查看状态
./run.sh logs # 跟踪日志
./run.sh stop # 停止也可以手动跑:
PORT=7200 python3 llm_backend.py
python3 register_llm.py # 注册到 anet daemon| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/health |
健康检查 + 概况 |
GET |
/meta |
自描述元信息 |
POST |
/deposit |
存 Key(需 X-Agent-DID) |
POST |
/lease |
借 Key(需 X-Agent-DID,必须是会员) |
GET |
/audit |
审计:全部记录 |
GET |
/deposits |
当前挂牌(脱敏,只显示 Key 前后几位) |
curl -X POST http://localhost:7200/deposit \
-H "X-Agent-DID: did:key:zAlice..." \
-H "Content-Type: application/json" \
-d '{
"api_key": "sk-xxxx",
"base_url": "https://api.openai-next.com",
"model": "claude-opus-4-7"
}'curl -X POST http://localhost:7200/lease \
-H "X-Agent-DID: did:key:zBob..."
# => {"ok": true, "key_payload": {"lease_id":"lease_xxx","api_key":"sk-yyy",...}}参考 .env.example:
| 变量 | 默认值 | 说明 |
|---|---|---|
APP_NAME |
api-zhuanzhuan |
注册到 AgentNetwork 的服务名 |
APP_API_KEY |
(空) | Relay Agent 的 Bearer Token,必须改 |
AGENT_NET_ENDPOINT |
http://127.0.0.1:3998 |
anet daemon REST |
AGENT_NET_TOKEN |
(空) | 留空时 SDK 自动从 ~/.anet/api_token 或 $ANET_TOKEN 读取 |
HOST / PORT |
0.0.0.0 / 8088 |
Relay 监听 |
PUBLIC_ENDPOINT |
http://127.0.0.1:8088 |
注册到 AgentNetwork 时告诉别的 peer 的回调地址 |
ALLOWED_PEERS |
(空) | 逗号分隔的目标 peer 白名单,留空 = 不限制 |
CALL_TIMEOUT |
60 |
转发超时(秒) |
Bank 额外支持的环境变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
BANK_PORT |
7200 |
Bank HTTP 监听端口 |
BANK_PATH |
data/bank.json |
Bank 持久化文件 |
KEY_POOL_PATH |
data/key_pool.json |
KeyPool 持久化文件 |
LEDGER_PATH |
data/ledger.json |
虚拟账本 |
INITIAL_CREDIT |
20.0 |
新账户初始余额(美金,虚拟) |
API转转/
├── main.py # Relay Agent: /proxy /discover /health
├── router.py # anet-sdk SvcClient 封装
├── registrar.py # 启动时注册 Relay 到 AgentNetwork
├── config.py # 环境变量
│
├── llm_backend.py # Bank HTTP 接口
├── bank.py # Bank 核心:deposit / lease / audit
├── register_llm.py # 注册 Bank 到 AgentNetwork
├── key_pool.py # 按模型轮询挑 key
├── ledger.py # 虚拟账本(扣费 / 余额)
│
├── run.sh # Bank 启动脚本(start/stop/status/logs)
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── .env.example
└── data/ # 运行时数据,**不入版本控制**
svc.register(name, endpoint, paths, tags, free, health_check)— 启动时注册svc.discover(skill=, limit=)— 按技能查 peersvc.call(peer_id, service, path, method, body, headers)— 同步转发svc.stream(...)— 流式转发(router.stream()已封装,但/proxy当前只暴露同步)svc.unregister(name)— 关服时清理
.env 与 data/*.json 包含真 API Key,已在 .gitignore 中排除,不要提交。
MIT