dashboard-nanobot/design/topic-mcp.md

272 lines
8.4 KiB
Markdown
Raw Normal View History

2026-03-13 06:40:54 +00:00
# Topic 消息流方案(`topic_mcp`
## 1. 目标与边界
### 1.1 目标
- 将“对话消息”与“任务反馈消息”分离。
- 新增 RSS 风格 Topic 面板,支持按 Topic 订阅和无干扰查看。
- 由模型决定“是否写入 Topic、写入哪个 Topic”。
### 1.2 约束
- 尽量不修改 nanobot 引擎源码(`engines/nanobot-*`)。
- 若必须扩展能力,优先通过 Dashboard 内嵌 MCP Server 实现。
- MCP Server 固定命名:`topic_mcp`。
## 2. 术语统一(避免混淆)
- `transport_channel`:机器人对外通信渠道(`dashboard/telegram/feishu/qq/...`)。
- `topic`Dashboard 内的消息流分组(例如 `inbox`、`build`、`alerts`)。
- `topic_item`:某个 topic 下的一条消息。
## 3. 总体架构
```mermaid
flowchart LR
U["User"] --> UI["Dashboard UI"]
UI --> API["Dashboard Backend (FastAPI)"]
API --> DB["SQLite topic_* tables"]
API --> MCP["topic_mcp (streamableHttp)"]
BOT["nanobot"] -->|"MCP call"| MCP
MCP --> DB
BOT -->|"normal chat via dashboard transport_channel"| API
API --> UI
```
说明:
- 聊天消息仍走现有 dashboard 渠道。
- Topic 写入走 `topic_mcp` 工具调用,不侵入 nanobot 核心 loop/channel。
- Topic 路由与投递对所有 `transport_channel` 生效(`dashboard/feishu/telegram/qq/...`),即无论用户从哪个渠道发起请求,只要模型调用 `topic_*` 工具,都会统一写入 Topic 面板。
## 4. `topic_mcp` 配置策略(默认写入、不可删除)
### 4.1 写入位置
写入 bot 的 `.nanobot/config.json`
```json
{
"tools": {
"mcpServers": {
"topic_mcp": {
"type": "streamableHttp",
"url": "http://host.docker.internal:8000/api/mcp/topic",
"headers": {
"x-topic-mcp-token": "<bot-scoped-token>"
},
"toolTimeout": 30
}
}
}
}
```
### 4.2 不可删除规则
在 Dashboard 后端实现硬约束:
1. Bot 创建后自动注入 `topic_mcp`
2. `PUT /api/bots/{bot_id}/mcp-config` 全量更新时,若缺失 `topic_mcp`,后端自动补回。
3.`topic_mcp` 的关键字段做白名单校验(`type/url/headers/toolTimeout`)。
4. 返回给前端时标记 `locked=true`,前端禁用删除按钮(但以后端校验为准)。
## 5. `topic_mcp` 工具定义
建议工具集V1
1. `topic_list_topics`
- 作用:返回当前 bot 可投递的 topic 清单与路由说明。
- 用途:让模型先了解可投递目标,避免“靠名字猜”。
2. `topic_get_schema`
- 作用:返回允许的 `view` 结构定义(声明式渲染,不允许脚本)。
- 用途:让模型生成可渲染卡片,而非任意 HTML/JS。
3. `topic_route`
- 作用:输入候选内容,返回 `should_publish`、`topic_key`、`confidence`、`reason`。
- 用途:把“该不该发、发到哪”交给 Dashboard 规则层,降低模型随意性。
4. `topic_publish`
- 作用:写入一条 topic 消息。
- 关键字段:`topic_key/title/content/level/tags/view/dedupe_key`.
说明:
- 不建议 V1 暴露 `topic_create/topic_delete` 给模型。
- topic 由用户在 Dashboard 维护,模型仅消费已发布规则并投递。
- `sendProgress/sendToolHints` 产生的进度流和工具提示流不应投递到 Topic默认硬过滤
## 6. 数据模型Backend
### 6.1 `topic_bot_settings`
- `id` (PK)
- `bot_id` (unique, index)
- `topic_enabled`Topic 总开关,默认 `true`
- `created_at/updated_at`
### 6.2 `topic_topic`
- `id` (PK)
- `bot_id` (index)
- `topic_key` (unique with `bot_id`)
- `name`
- `description`
- `is_active`
- `is_default_fallback`
- `routing_json`(包含 include/exclude/examples/priority
- `view_schema_json`(允许的渲染模板)
- `created_at/updated_at`
### 6.3 `topic_item`
- `id` (PK)
- `bot_id` (index)
- `topic_key` (index)
- `title`
- `content`
- `level` (`info/warn/error/success`)
- `tags_json`
- `view_json`
- `source` (`mcp/manual/system`)
- `dedupe_key` (index)
- `is_read`
- `created_at`
约束:
- 同一 `bot_id + dedupe_key` 可设置幂等去重窗口(如 10 分钟)。
- 未命中 topic 时回退到默认 topic推荐 `inbox`)。
## 7. 后端 APIDashboard
面向 UI 的 REST示例
- `GET /api/bots/{bot_id}/topics`
- `POST /api/bots/{bot_id}/topics`
- `PUT /api/bots/{bot_id}/topics/{topic_key}`
- `DELETE /api/bots/{bot_id}/topics/{topic_key}`(禁止删除 fallback
- `GET /api/bots/{bot_id}/topic-settings`
- `PUT /api/bots/{bot_id}/topic-settings`(配置 `topic_enabled` 开关)
- `GET /api/bots/{bot_id}/topic-items?topic_key=...&cursor=...`
- `POST /api/bots/{bot_id}/topic-items/{id}/read`
面向 bot 的 MCP
- `POST /api/mcp/topic`streamableHttp
## 8. 路由策略(模型如何判断)
最终策略是“模型 + 规则引擎”:
1. 模型提取候选信息(摘要、类型、重要度)。
2. 调用 `topic_route` 获取决策建议。
3. `should_publish=true` 时调用 `topic_publish`
4. `should_publish=false` 不写 Topic仅保留聊天输出。
5.`topic_enabled=false` 时,`topic_route` 固定返回 `should_publish=false`
6. 当消息被判定为 progress/tool-hint对应 `sendProgress/sendToolHints` 流)时,固定 `should_publish=false`
topic 的路由配置建议包含:
- `purpose`topic 用途
- `include_when`:应收条件
- `exclude_when`:排除条件
- `examples`:正反例
- `priority`:冲突优先级
- `system_filters`:系统硬过滤(如 progress/tool-hint
金融信息 topic 路由示例(`topic_key=finance_market`
```json
{
"purpose": "沉淀与金融市场相关的关键结论和告警,便于用户集中查看。",
"include_when": [
"内容涉及股票/指数/外汇/利率/宏观数据/财报",
"包含明确数值、时间点、事件影响判断",
"属于'可执行建议'或'风险提示'"
],
"exclude_when": [
"纯寒暄或无结论聊天",
"与金融无关的任务进度",
"重复内容且dedupe_key命中窗口"
],
"examples": {
"positive": [
"美联储议息后10Y美债收益率上行20bp成长股承压",
"AAPL财报超预期但指引下调盘后转跌建议关注开盘波动"
],
"negative": [
"我已经开始处理你的请求",
"文件上传成功"
]
},
"priority": 80,
"fallback_topic_key": "inbox"
}
```
## 9. 前端 Topic Panel
UI 结构建议:
- 左列topic 列表(未读计数、筛选)
- 中列topic item 流(时间倒序、分页)
- 右列item 详情与结构化视图渲染
- 顶部:`Topic Enabled` 开关(开/关)
开关行为:
- `ON`:正常执行 `topic_route/topic_publish`
- `OFF`Topic 面板只读历史,不接收新投递;`topic_route` 返回 `should_publish=false`
- `topic_mcp` 配置仍保留且不可删除,避免反复改写 `config.json`
渲染要求:
- `view` 仅支持声明式类型:`markdown/card/table/checklist/metric/timeline`
- 禁止执行脚本与任意 HTML 注入
- 超长内容折叠 + 展开
## 10. 安全与治理
- `topic_mcp` 使用 bot 级 token 鉴权。
- 限流:每 bot 每分钟最大 publish 次数。
- 去重:`dedupe_key` + 时间窗口。
- 噪声过滤:`sendProgress/sendToolHints` 的进度与工具提示消息不进入 Topic。
- 降级:无 topic/路由失败时投递 `inbox` 或直接跳过(按策略)。
- 审计:记录每次 `topic_route/topic_publish` 调用。
## 11. 分阶段落地
### Phase 1最小可用
- 新增 `topic_bot_settings` / `topic_topic` / `topic_item`
- 新增 Topic Panel 基础查询展示
- 实现 `topic_mcp` + `topic_publish`
- 注入并锁定 `config.json.tools.mcpServers.topic_mcp`
### Phase 2稳定化
- 增加 `topic_list_topics/topic_get_schema/topic_route`
- 加去重、限流、fallback、审计日志
- 增加 topic 管理 UI规则编辑
### Phase 3体验增强
- item 模板优化与卡片渲染
- 未读/置顶/归档
- 统计与告警topic 热点、失败率)
## 12. 与现有代码对接点
- MCP 配置接口:`/api/bots/{bot_id}/mcp-config`
文件:[main.py](/Users/jiliu/WorkSpace/dashboard-nanobot/backend/main.py)
- 前端主面板:
[BotDashboardModule.tsx](/Users/jiliu/WorkSpace/dashboard-nanobot/frontend/src/modules/dashboard/BotDashboardModule.tsx)
- 实时同步:
[useBotsSync.ts](/Users/jiliu/WorkSpace/dashboard-nanobot/frontend/src/hooks/useBotsSync.ts)
原则:
- 不改 nanobot 核心引擎行为;
- 通过 Dashboard 承担 Topic 规则、投递和展示。