Files
LangBot/docs/event-based-agents/06-migration-plan.md
Junyan Qin 9f23f4c572 chore: docs
2026-05-07 15:18:59 +08:00

22 KiB
Raw Permalink Blame History

分阶段迁移计划

1. 概述

EBA 架构涉及 langbot-plugin-sdk、LangBot 后端、LangBot 前端、文档和示例插件等多个仓库的改动。为降低风险、保证系统稳定性,采用分阶段渐进式迁移策略。

1.1 阶段总览

阶段 名称 范围 依赖
Phase 1 SDK 实体层 langbot-plugin-sdk
Phase 2 适配器重构 LangBot 后端 Phase 1
Phase 3 核心系统 LangBot 后端 Phase 2
Phase 4 插件 SDK 集成 langbot-plugin-sdk + LangBot Phase 3
Phase 5 WebUI 编排面板 LangBot 前端 Phase 3
Phase 6 文档与示例 langbot-wiki + langbot-plugin-demo Phase 4, 5

1.2 核心原则

  • 每个阶段结束后系统可运行:任何阶段完成后,现有功能不受影响
  • 向后兼容贯穿全程:旧接口在整个迁移期间保持可用
  • 先 SDK 后实现:先定义好接口和模型,再做具体实现
  • 先核心适配器后边缘:优先迁移用户量大的适配器

2. Phase 1SDK 实体层

目标:在 langbot-plugin-sdk 中定义新的事件体系、通用实体、API 接口和适配器基类。

仓库langbot-plugin-sdk

2.1 任务清单

# 任务 文件/模块 说明
1.1 定义通用事件基类层次 api/entities/builtin/platform/events.py 新增 MessageReceivedEvent, MessageEditedEvent, GroupMemberJoinedEvent 等,保留现有 FriendMessage/GroupMessage
1.2 定义平台特有事件基类 api/entities/builtin/platform/events.py 新增 PlatformSpecificEvent
1.3 扩展通用实体 api/entities/builtin/platform/entities.py 新增 User(统一 Friend/GroupMember 的基础)、Channel 等,保留现有实体
1.4 清理消息组件 api/entities/builtin/platform/message.py WeChatMiniPrograms 等 WeChat 特有组件标记为 platform-specific不再作为通用组件
1.5 定义新适配器基类 api/definition/abstract/platform/adapter.py 新增 AbstractPlatformAdapter(继承现有 AbstractMessagePlatformAdapter 并扩展通用 API 方法),保留旧基类
1.6 定义 API 能力声明 api/definition/abstract/platform/capabilities.py(新文件) AdapterCapabilities 数据类,声明适配器支持的事件和 API
1.7 定义 NotSupportedError api/entities/builtin/platform/errors.py(新文件) 可选 API 未实现时抛出的异常

2.2 关键设计约束

  • 所有新增定义以新增文件或新增类的方式引入,不修改现有类的字段和方法签名
  • 现有 AbstractMessagePlatformAdapter 保留不动,新基类 AbstractPlatformAdapter 继承它
  • 新事件类与旧事件类并存,通过 event_type 字段(命名空间字符串)区分

2.3 验收标准

  • 所有新增类可正常 import 且通过类型检查
  • 现有 FriendMessage, GroupMessage, AbstractMessagePlatformAdapter 等类行为不变
  • 新增单元测试覆盖事件序列化/反序列化、实体构造
  • SDK 版本号 minor bump0.x.00.x+1.0

3. Phase 2适配器重构

目标:将现有单文件适配器迁移到独立目录结构,实现新事件监听和通用 API。

仓库LangBot(后端)

3.1 适配器迁移优先级

根据用户量和代表性,建议按以下顺序迁移:

优先级 适配器 理由
P0 Telegram 用户量大API 最完善,适合作为参考实现
P0 Discord 国际用户主要平台,事件类型丰富
P1 aiocqhttpOneBot v11 国内 QQ 用户主要适配器
P1 Satori 通用协议适配器,覆盖多个平台
P2 Lark / DingTalk / Slack 企业平台,用户量中等
P2 qqofficial / WeChat 系列 国内用户
P3 Kook / LINE / WeCom 系列 用户量较小
P3 WebSocket 内置适配器,相对简单
P4 legacy/* 遗留适配器,按需决定是否迁移或废弃

3.2 单个适配器迁移步骤(以 Telegram 为例)

# 任务 说明
2.1 创建目录结构 pkg/platform/adapters/telegram/ 下创建 __init__.py, adapter.py, event_converter.py, message_converter.py, api_impl.py, types.py, manifest.yaml
2.2 迁移消息转换器 TelegramMessageConvertersources/telegram.py 搬到 adapters/telegram/message_converter.py,逻辑不变
2.3 重写事件转换器 新的 TelegramEventConverter 支持将 Telegram Update 转换为所有通用事件类型(不只是消息),不支持的事件转为 PlatformSpecificEvent
2.4 实现通用 API api_impl.py 中实现 edit_message, delete_message, get_group_info 等 Telegram 支持的通用 API
2.5 实现透传 API adapter.py 中实现 call_platform_api,将 action 映射到 Telegram Bot API 调用
2.6 声明能力 manifest.yaml 或适配器类中声明支持的事件和 API 列表
2.7 新建 Adapter 主类 TelegramAdapter 继承 AbstractPlatformAdapter(新基类),委托各模块实现
2.8 更新 manifest.yaml 更新 execution.python.path 指向新位置
2.9 验证 确保新适配器通过现有消息收发流程的测试

3.3 基础设施任务

# 任务 说明
2.A 创建 adapters/_base/ 将 SDK 中新基类的运行时辅助代码放在此处(如事件分发辅助函数)
2.B 更新 ComponentDiscovery 使 discover_blueprint 支持扫描 adapters/ 子目录中的 YAML
2.C 更新 templates/components.yaml fromDirspkg/platform/sources/ 改为 pkg/platform/adapters/(过渡期两个都扫描)
2.D 保留旧 sources/ 过渡期不删除旧文件,通过 manifest 的 deprecated: true 标记

3.4 验收标准

  • 已迁移的适配器在新目录结构下正常启动和收发消息
  • 新事件(如 message.edited)在支持的平台上正确触发
  • 通用 APIedit_message)在支持的平台上正确执行
  • 未迁移的适配器(仍在 sources/)继续正常工作
  • ComponentDiscovery 同时扫描新旧目录

4. Phase 3核心系统

目标:实现 EventBus、EventRouter 和事件处理器框架,将事件从适配器分发到不同的处理器。

仓库LangBot(后端)

4.1 任务清单

# 任务 文件/模块 说明
3.1 实现 EventBus pkg/platform/event_bus.py(新文件) 事件总线:接收适配器事件,进行日志记录,分发给 EventRouter
3.2 实现 EventRouter pkg/platform/event_router.py(新文件) 事件路由引擎:读取 Bot 的 event_handlers 配置,匹配事件类型,分发到对应 Handler
3.3 实现 PipelineHandler pkg/platform/handlers/pipeline_handler.py message.received 事件转为现有 Query进入 Pipeline 流水线
3.4 实现 AgentHandler pkg/platform/handlers/agent_handler.py 直接调用 RequestRunner 处理事件,不经过 Pipeline 多 Stage 流程
3.5 实现 WebhookHandler pkg/platform/handlers/webhook_handler.py 将事件 POST 到外部 URL解析响应执行动作重构现有 WebhookPusher
3.6 实现 PluginHandler pkg/platform/handlers/plugin_handler.py 将事件分发给插件 EventListener复用现有 plugin_connector 机制)
3.7 Bot 实体扩展 pkg/entity/persistence/bot.py 新增 event_handlers JSON 字段
3.8 数据库迁移 pkg/persistence/migrations/ 新增迁移脚本:添加 event_handlers 列,将现有 use_pipeline_uuid 数据迁移为 event_handlers 格式
3.9 重构 RuntimeBot pkg/platform/botmgr.py initialize() 中硬编码的 on_friend_message/on_group_message 回调替换为通过 EventBus 分发所有事件
3.10 重构 MessageAggregator pkg/pipeline/aggregator.py 从 RuntimeBot 解耦,作为 PipelineHandler 的内部机制(只对 message.received 事件生效)
3.11 Agent Handler 中 RequestRunner 解耦 pkg/provider/runner.py + handlers RequestRunner 需要能独立于 Pipeline Stage 运行,为 Agent Handler 提供轻量调用路径
3.12 HTTP API 扩展 pkg/api/http/controller/ 新增/更新 Bot API 端点以支持 event_handlers 的 CRUD

4.2 数据迁移策略

现有 Bot 表有 use_pipeline_uuid 字段,需要自动迁移为 event_handlers

# 迁移逻辑伪代码
for bot in all_bots:
    if bot.use_pipeline_uuid:
        bot.event_handlers = [
            {
                "event_type": "message.received",
                "handler_type": "pipeline",
                "handler_config": {
                    "pipeline_uuid": bot.use_pipeline_uuid
                }
            }
        ]
    else:
        bot.event_handlers = []

4.3 RuntimeBot 重构要点

当前 RuntimeBot.initialize() 硬编码注册两个回调:

# 现有代码 (botmgr.py)
self.adapter.register_listener(FriendMessage, on_friend_message)
self.adapter.register_listener(GroupMessage, on_group_message)

重构后改为注册通用事件回调:

# 新代码
async def on_event(event: Event, adapter: AbstractPlatformAdapter):
    await self.event_bus.emit(
        bot_uuid=self.bot_entity.uuid,
        event=event,
        adapter=adapter,
    )

# 注册所有事件类型的统一回调
self.adapter.register_listener(Event, on_event)

EventBus 接收事件后,调用 EventRouter 按配置分发。

4.4 事件处理器执行流程

EventBus.emit(bot_uuid, event, adapter)
    │
    ▼
EventRouter.route(bot_uuid, event)
    │ 查询 bot.event_handlers 配置
    │ 匹配 event_type精确匹配 > 通配符 *
    ▼
匹配到的 Handler(s)
    │
    ├── PipelineHandler.handle(event, adapter)
    │   │ 仅支持 message.received
    │   │ 构造 Query → MessageAggregator → QueryPool → Pipeline
    │   └── 沿用现有完整流水线机制
    │
    ├── AgentHandler.handle(event, adapter)
    │   │ 根据 handler_config 选择 RequestRunner
    │   │ 直接调用 runner.run() 处理事件
    │   └── 将结果通过 adapter API 回复
    │
    ├── WebhookHandler.handle(event, adapter)
    │   │ 序列化事件为 JSON
    │   │ POST 到 handler_config.url
    │   └── 解析响应,执行动作(回复消息、调用 API 等)
    │
    └── PluginHandler.handle(event, adapter)
        │ 通过 plugin_connector 分发给插件
        └── 插件 EventListener 处理

4.5 验收标准

  • message.received 事件通过 PipelineHandler 正确进入现有 Pipeline与旧行为一致
  • 新增事件(如 group.member_joined)能通过 PluginHandler 分发给插件
  • AgentHandler 能直接调用 RequestRunner至少 local-agent)处理事件并回复
  • WebhookHandler 能将事件 POST 到外部 URL
  • 数据库迁移正确执行,use_pipeline_uuid 数据迁移到 event_handlers
  • 现有 Bot 在不修改配置的情况下行为不变(自动迁移保证)

5. Phase 4插件 SDK 集成

目标:将新事件和 API 通过插件 SDK 暴露给插件开发者,同时实现兼容层。

仓库langbot-plugin-sdk + LangBot

5.1 任务清单

# 任务 说明
4.1 新增插件事件包装 api/entities/events.py 中为每个通用事件新增插件级事件类(如 MessageEditedReceived, MemberJoinedReceived
4.2 兼容层实现 PersonMessageReceived / GroupMessageReceived 由新的 MessageReceivedEvent 自动生成,旧事件作为新事件的 alias
4.3 新 API 暴露 LangBotAPIProxy 中新增方法:edit_message, delete_message, get_group_info, get_user_info, call_platform_api
4.4 通信协议扩展 entities/io/actions/enums.py 中新增 action 枚举(如 EDIT_MESSAGE, DELETE_MESSAGE, GET_GROUP_INFO, CALL_PLATFORM_API
4.5 Runtime Handler 扩展 在 PluginConnectionHandler / ControlConnectionHandler 中添加新 action 的处理逻辑
4.6 EventListener 扩展 确保 @handler() 装饰器支持注册新事件类型
4.7 QueryBasedAPI 扩展 QueryBasedAPIProxy 中新增事件上下文相关的 APIget_event_source_adapter

5.2 兼容层详细设计

新事件系统                         旧事件系统(兼容层)
─────────────                    ─────────────────
MessageReceivedEvent             ┌→ PersonMessageReceived (chat_type == "private")
  (chat_type: "private"|"group") ┤
                                 └→ GroupMessageReceived  (chat_type == "group")

实现方式:在 RuntimeEventDispatcher 中,当分发 MessageReceivedEvent 给插件时,同时生成对应的旧事件类实例。插件可以用新事件类或旧事件类注册 handler都能收到。

5.3 验收标准

  • 现有插件(使用旧事件和 API无需修改即可运行
  • 新插件可以使用新事件类型(如 MemberJoinedReceived)注册 handler
  • 新 APIedit_message)可通过 self.edit_message()event_context.edit_message() 调用
  • 透传 API call_platform_api 可正常调用适配器特有功能
  • 所有新 action 的通信协议正确工作stdio / WebSocket

6. Phase 5WebUI 编排面板

目标:在 WebUI 的 Bot 管理页面实现事件处理器的可视化编排。

仓库LangBot(前端 web/

6.1 任务清单

# 任务 说明
5.1 Bot 编辑页面扩展 在 Bot 编辑页面新增「事件处理」面板
5.2 事件处理器列表组件 可视化展示当前 Bot 的 event_handlers 列表,支持增删改排序
5.3 事件类型选择器 下拉选择事件类型(命名空间分组展示),支持通配符 *
5.4 Handler 类型选择与配置 选择 handler 类型后展示对应的配置表单Pipeline 选择器、Runner 选择器、Webhook URL 等)
5.5 Pipeline Handler 配置 复用现有的 Pipeline 选择 UI从现有 use_pipeline_uuid 选择器迁移)
5.6 Agent Handler 配置 Runner 选择器local-agent / dify / n8n / coze 等)+ Runner 参数配置表单
5.7 Webhook Handler 配置 URL 输入、认证方式选择、Header 配置
5.8 Plugin Handler 配置 通常无需额外配置,分发给所有匹配的插件 EventListener
5.9 HTTP API 对接 前端调用后端 API 保存/读取 event_handlers 配置
5.10 迁移提示 对于从旧版本升级的用户,如果检测到 use_pipeline_uuid 已自动迁移,展示提示说明

6.2 UI 交互设计概要

┌─ Bot 编辑页面 ─────────────────────────────────────┐
│                                                     │
│  基本信息  │  适配器配置  │  ★ 事件处理  │           │
│                                                     │
│  ┌─ 事件处理器列表 ────────────────────────────┐    │
│  │                                              │    │
│  │  ① message.received → Pipeline: "主流水线"   │    │
│  │     [编辑] [删除]                            │    │
│  │                                              │    │
│  │  ② group.member_joined → Agent: local-agent  │    │
│  │     [编辑] [删除]                            │    │
│  │                                              │    │
│  │  ③ * (默认) → Plugin                         │    │
│  │     [编辑] [删除]                            │    │
│  │                                              │    │
│  │  [+ 添加事件处理器]                           │    │
│  │                                              │    │
│  └──────────────────────────────────────────────┘    │
│                                                     │
│                              [保存]  [取消]          │
└─────────────────────────────────────────────────────┘

6.3 验收标准

  • 用户可以在 WebUI 上为 Bot 添加/编辑/删除事件处理器
  • 四种 Handler 类型均有对应的配置表单
  • 配置保存后正确写入数据库 event_handlers 字段
  • 旧版本升级后,自动迁移的配置在 UI 上正确展示
  • Pipeline Handler 的行为与旧的 use_pipeline_uuid 完全一致

7. Phase 6文档与示例

目标:更新所有面向开发者的文档和示例。

仓库langbot-wiki, langbot-plugin-demo

7.1 任务清单

# 任务 仓库 说明
6.1 EBA 架构概览文档 langbot-wiki 面向用户的新架构说明
6.2 适配器开发指南更新 langbot-wiki 如何开发一个新的适配器(新目录结构、新基类、事件转换等)
6.3 插件开发指南更新 langbot-wiki 新事件类型、新 API 的使用说明
6.4 插件迁移指南 langbot-wiki 现有插件如何迁移到新事件/API如果需要使用新能力
6.5 事件处理器配置指南 langbot-wiki WebUI 上如何配置事件处理器
6.6 示例插件更新 langbot-plugin-demo HelloPlugin 增加新事件监听示例、新 API 调用示例
6.7 新示例插件 langbot-plugin-demo 新建一个示例展示非消息事件处理(如入群欢迎)

8. 风险评估与缓解

8.1 技术风险

风险 影响 概率 缓解措施
适配器迁移中断现有功能 新旧目录并存ComponentDiscovery 同时扫描两个目录,逐个适配器迁移验证
事件模型不兼容导致插件崩溃 兼容层保证旧事件类型继续工作,新增类不修改旧类
数据库迁移失败 迁移脚本做前置校验,use_pipeline_uuid 在过渡期保留不删除
RequestRunner 解耦破坏 Pipeline Agent Handler 调用 Runner 的路径独立于 Pipeline不修改现有 Pipeline Stage 中的 Runner 调用逻辑
性能回退EventBus 额外开销) EventBus 在进程内同步分发,无额外序列化/网络开销
各平台事件差异大难以统一 通用事件只抽象最大公约数字段,差异部分保留在 source_platform_object;不支持的事件走 PlatformSpecificEvent

8.2 兼容性风险

风险 缓解措施
现有插件使用旧事件类 兼容层自动将新事件转为旧事件分发,两种事件类都能注册 handler
现有插件调用 reply() / send_message() 这两个 API 保持不变,只是底层实现可能微调
第三方基于 AbstractMessagePlatformAdapter 开发的适配器 旧基类保留,新基类继承旧基类,第三方适配器无需立即迁移
用户自定义 Pipeline 配置 Pipeline 机制完整保留PipelineHandler 只是入口变了(从 RuntimeBot 硬编码变为 EventRouter 配置)

8.3 回滚策略

每个 Phase 独立可回滚:

  • Phase 1SDK 新增类):删除新增文件,回退 SDK 版本号
  • Phase 2(适配器目录):恢复 components.yamlfromDirs 指向旧目录,旧 sources/ 未删除
  • Phase 3(核心系统):回退数据库迁移,恢复 RuntimeBot 旧的硬编码回调
  • Phase 4(插件集成):回退 SDK 版本,插件使用旧版 SDK
  • Phase 5WebUI前端回退Bot 编辑页面隐藏事件处理面板

9. 里程碑与时间线建议

里程碑 阶段 预期产出
M1 Phase 1 完成 SDK 新版本发布,包含新事件/实体/基类定义
M2 Phase 2 首批适配器Telegram + Discord 两个参考实现,验证目录结构和事件/API 体系
M3 Phase 3 核心系统 EventBus + EventRouter + 四种 Handler 可用
M4 Phase 2 剩余适配器 所有活跃适配器迁移完成
M5 Phase 4 插件集成 新 SDK 发布,插件可使用新事件和 API
M6 Phase 5 WebUI 事件处理器编排面板上线
M7 Phase 6 文档 开发者文档和示例更新完毕

建议 M1-M3 作为第一个大版本发布(如 v5.0M4-M7 在后续小版本迭代中完成。


10. 开发指引

10.1 分支策略

建议在主仓库创建 feature/eba 长期特性分支,各 Phase 在子分支上开发后合入特性分支:

main
  └── feature/eba
        ├── feature/eba-sdk-entities      (Phase 1)
        ├── feature/eba-adapter-telegram   (Phase 2)
        ├── feature/eba-adapter-discord    (Phase 2)
        ├── feature/eba-core-system        (Phase 3)
        ├── feature/eba-plugin-sdk         (Phase 4)
        └── feature/eba-webui              (Phase 5)

10.2 测试策略

层次 测试内容 工具
单元测试 事件序列化/反序列化、实体构造、API 调用 mock pytest
集成测试 EventBus → EventRouter → Handler 全链路 pytest + asyncio
适配器测试 各适配器的事件转换、消息转换、API 调用 pytest + mock SDK
端到端测试 从模拟平台事件到完整处理流程 staging 环境
插件兼容性测试 旧插件在新系统下的行为 langbot-plugin-demo

10.3 代码审查关注点

  • 新增代码是否影响现有行为
  • 兼容层是否正确映射所有旧事件/API 场景
  • 数据库迁移是否可逆
  • 新 API 的错误处理(NotSupportedError)是否一致
  • 事件模型的序列化在 stdio/WebSocket 通信中是否正确