Appearance
Broker 开发教程
Broker = 可分享的应用包(manifest + UI + 插件),可在市场安装、跨用户复用。本文覆盖完整开发流程、签名机制、从简单到复杂的实例。
Broker 长什么样
📄
src/broker/workshop/__init__.py— Broker 加载器 📄src/broker/hub.py— BrokerHub 核心 📄src/bridge/routes/broker_workshop.py— REST API
manifest.json 结构
json
{
"id": "my_awesome_broker",
"name": "我的应用",
"version": "1.0.0",
"description": "一句话描述",
"author_name": "Your Name",
"author_pubkey": "base64-encoded-public-key",
"ui": {
"entry": "ui/index.html",
"width": 800,
"height": 600
},
"capabilities_required": [
"network.http",
"storage.kv"
],
"role_defs": {
"assistant": {
"description": "提供 XXX 能力",
"tools": ["my_tool"]
}
},
"triggers": [
{"type": "schedule", "cron": "0 9 * * *", "action": "morning_greeting"},
{"type": "event", "event": "user.login", "action": "welcome"}
],
"recipes": ["recipes/my_recipe.json"]
}字段说明
| 字段 | 必填 | 说明 |
|---|---|---|
id | ✅ | broker_id,必须唯一,与目录名一致 |
name | ✅ | 显示名 |
version | ✅ | semver 格式 |
author_pubkey | ✅ | 作者公钥(Ed25519) |
ui.entry | ✅ | iframe 入口 HTML |
capabilities_required | ❌ | 需要的能力(网络/存储等) |
role_defs | ❌ | 定义 agent 角色 |
triggers | ❌ | 触发条件(定时/事件) |
开发流程
1. 从模板起步
bash
# 拷贝 starter 模板
cp -r workspace/manager/brokers/starter_broker/ workspace/manager/brokers/my_broker/
# 或直接从仓库
git clone <repo> && cd familiars/workspace/manager/brokers/starter_broker/2. 本地开发
bash
# 安装到本地
python main.py broker install workspace/manager/brokers/my_broker/
# 在交换所工坊中查看
# Desktop → 应用 → 交换所工坊 → 已安装3. 发布
bash
# 生成作者密钥(首次)
python main.py broker keygen --name "my-name"
# → ~/.familiars/authors/my-name.key
# 打包
python main.py broker pack workspace/manager/brokers/my_broker/
# → my_broker.broker.zip
# 签名
python main.py broker sign my_broker.broker.zip --author my-name
# → 写入 SIGNATURE 文件到 zip 内
# 发布到 relay
python main.py broker publish my_broker.broker.zip
# → 上传到 FAMILIARS_MARKETPLACE_URL签名与安全
📄
src/broker/workshop/install.py:verify_signature()
实例一:简单 Broker —— 天气助手
目标:每天早上 9 点推送天气预报到聊天。
manifest.json
json
{
"id": "weather_assistant",
"name": "天气助手",
"version": "1.0.0",
"description": "每天早上推送天气预报",
"author_name": "Demo Author",
"author_pubkey": "your-base64-pubkey",
"ui": {
"entry": "ui/index.html",
"width": 400,
"height": 300
},
"capabilities_required": [
"network.http"
],
"triggers": [
{
"type": "schedule",
"cron": "0 9 * * *",
"action": "push_weather"
}
]
}plugins/weather.py
python
from src.broker.workshop import BrokerPlugin
import httpx
class WeatherPlugin(BrokerPlugin):
def on_trigger(self, trigger_name: str):
if trigger_name == "push_weather":
self.fetch_and_push()
def fetch_and_push(self):
# 调用天气 API
resp = httpx.get("https://api.weather.com/v1/current", params={
"location": "Beijing",
"apikey": self.config.get("api_key")
})
data = resp.json()
# 推送到聊天
self.emit_event("chat.message", {
"text": f"☀️ 今日天气:{data['temp']}°C,{data['condition']}"
})ui/index.html
html
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 20px; }
.weather { text-align: center; }
</style>
</head>
<body>
<div class="weather">
<h2>🌤️ 天气助手</h2>
<p>每天 9:00 自动推送</p>
<button onclick="testPush()">测试推送</button>
</div>
<script>
async function testPush() {
const res = await fetch('/api/broker/weather_assistant/trigger/push_weather', {
method: 'POST',
headers: {'X-Broker-Token': window.brokerToken}
});
alert(res.ok ? '已推送' : '推送失败');
}
</script>
</body>
</html>实例二:中等 Broker —— 待办同步器
目标:把 Familiars 待办同步到外部服务(Notion/Todoist)。
manifest.json
json
{
"id": "todo_sync",
"name": "待办同步器",
"version": "1.0.0",
"description": "同步待办到 Notion/Todoist",
"capabilities_required": [
"network.http",
"storage.kv"
],
"role_defs": {
"sync_agent": {
"description": "执行同步任务",
"tools": ["sync_to_notion", "sync_to_todoist"]
}
},
"recipes": ["recipes/sync_recipe.json"]
}recipes/sync_recipe.json
json
{
"id": "sync_todos",
"name": "待办同步",
"nodes": [
{
"id": "starter",
"type": "starter",
"config": {
"inputs": [
{"name": "target", "enum": ["notion", "todoist"]},
{"name": "filter", "string", "default": "all"}
]
}
},
{
"id": "fetch_todos",
"type": "llm_call",
"config": {
"tool_whitelist": ["todo_list"],
"output_var": "todos"
}
},
{
"id": "sync",
"type": "llm_call",
"role": "sync_agent",
"config": {
"tool_whitelist": ["sync_to_notion", "sync_to_todoist"],
"user_prompt_template": "同步以下待办到 {{target}}:{{todos}}"
}
},
{
"id": "summary",
"type": "summary",
"config": {
"outputs": [{"name": "synced_count", "from": "sync.count"}]
}
}
]
}实例三:复杂 Broker —— Ventaris 公会系统
目标:完整的公会系统(成员/任务/勋章/投票),参考
workspace/manager/brokers/ventaris/。这是目前代码库中最复杂的 Broker —— 4 个 tab 页、5 个插件、2 个 recipe、完整的 VTP 经济系统。
复杂度对比
| 维度 | 实例二(待办同步) | Ventaris 公会 |
|---|---|---|
| 插件数 | 1 | 4(guild/tasks/medals/wallet) |
| recipe 数 | 1 | 2(create_task/approve_task) |
| UI 页面 | 单页 | 4 tab(公会/任务/勋章/我的) |
| 经济系统 | 无 | VTP 钱包 + 打赏 + 任务悬赏 |
| 权限模型 | 无 | 6 角色 RBAC |
目录结构
ventaris/
├── manifest.json
├── ui/
│ ├── index.html
│ ├── tabs/
│ │ ├── guild.html # 公会主页
│ │ ├── tasks.html # 任务看板
│ │ ├── medals.html # 勋章墙
│ │ └── profile.html # 个人主页
│ └── components/
│ ├── TaskCard.js
│ ├── MedalWall.js
│ └── BountyBoard.js
├── plugins/
│ ├── guild.py # 公会核心逻辑
│ ├── tasks.py # 任务系统
│ ├── medals.py # 勋章系统
│ └── wallet.py # VTP 钱包
├── recipes/
│ ├── create_task.json
│ └── approve_task.json
└── triggers.json关键能力
| 能力 | 实现 |
|---|---|
| 成员管理 | plugins/guild.py: invite/kick/role |
| 任务系统 | plugins/tasks.py: create/approve/reward |
| VTP 钱包 | plugins/wallet.py: balance/transfer/reward |
| 勋章墙 | plugins/medals.py: earn/display |
| 投票 | plugins/guild.py: vote/proposal |
市场(relay)
客户端市场
bash
# 获取索引
curl https://api.familiars.cn/marketplace/index
# 安装
python main.py broker install-from-url https://api.familiars.cn/marketplace/download/my_broker生产 relay
bash
# 发布
python main.py broker publish my_broker.broker.zip
# → 进入审核队列
# 查看状态
python main.py broker marketplace-index
# 审核(管理员)
python main.py broker approve <broker_id>📄
deploy/relay/app/— relay 服务器部署
常见坑
| 问题 | 原因 | 解决 |
|---|---|---|
| 安装失败 | manifest.id 与目录名不一致 | 对齐两者 |
| 封面不显示 | cover.png 未上传到 relay | 发布时包含 cover |
| 插件不加载 | 未声明 capabilities_required | manifest 声明需要 |
| 密钥丢失 | ~/.familiars/authors/*.key 被删 | 无法恢复,需新密钥 |
| UI 空白 | iframe 跨域 | 检查 CORS 配置 |
调试
bash
# 列出已安装 broker
python main.py broker list
# 查看详情
python main.py broker inspect my_broker
# 查看日志
tail -f workspace/.bridge.log | grep broker
# 验证签名
python main.py broker verify my_broker.broker.zip更多
- 完整源码:
src/broker/ - starter 模板:
workspace/manager/brokers/starter_broker/ - Ventaris 示例:
workspace/manager/brokers/ventaris/ - 完整来源:
BROKER_DEVELOPMENT.md
