Files
Bubbles/REFACTOR_PLAN.md
2026-02-04 17:35:08 +08:00

3.3 KiB
Raw Blame History

Bubbles 改造计划

核心问题

Bubbles 是个单次意图分类器,不是 Agent。AI Router 做一次 chat/function 分类就结束了,无法多步推理、自主决策。这是"死板"的根源。


一、Agent 循环(最高优先级)

processMsg 的单次分类改成工具调用循环。AI 自己决定调什么工具、调几次、什么时候停。

改动范围: robot.py 的消息处理主流程,commands/ai_router.py 的路由逻辑

目标状态:

消息进入 → Agent 循环开始
  → LLM 返回工具调用 → 执行工具 → 结果喂回 LLM → 继续推理
  → LLM 返回纯文本 → 循环结束,发送回复
  → 达到最大步数 → 强制结束

必须包含的防护:

  • 最大步数限制(防无限循环)
  • 死循环检测:同一工具连续 3 次相同输入时中断
  • 单步超时

二、工具标准化

定义统一的 Tool 接口,把现有功能改写成标准工具,让 Agent 循环能调用。

改动范围: 新建 tools/ 目录,重构 commands/ai_functions.pycommands/reminder_router.py

Tool 接口定义:

class Tool:
    name: str                  # 工具唯一标识
    description: str           # 给 LLM 看的功能描述
    parameters: dict           # JSON Schema 参数定义

    async def execute(self, params: dict, ctx: MessageContext) -> str:
        """执行工具,返回文本结果"""

需要改写的现有功能:

  • reminder_hubreminder_create / reminder_list / reminder_delete(拆开,消灭二级路由)
  • perplexity_searchweb_search
  • handle_chitchat 不再是工具,而是 Agent 循环的默认文本输出路径

工具描述走 LLM 原生的 function calling / tool_use 协议,不再拼进提示词字符串。


三、模型 Fallback

当前模型挂了就挂了。必须加 fallback 链。

改动范围: robot.py 的模型调用层,各 ai_providers/ 适配器

目标状态:

# config.yaml
models:
  default:
    primary: deepseek
    fallbacks: [chatgpt, kimi]

必须实现:

  • 区分可重试错误429 限流、超时、服务端 500和不可重试错误401 密钥无效)
  • 可重试错误:指数退避重试(初始 2s最大 30s
  • 不可重试或重试耗尽:切下一个 fallback 模型
  • 记录失败模型的冷却时间,短期内不再尝试

四、上下文压缩

当前 max_history 按条数硬截断,丢失早期重要信息。

改动范围: robot.py 的历史消息获取逻辑,commands/handlers.py 的对话构建

目标状态:

  • 监控当前对话的 token 总量
  • 接近模型上下文窗口上限时,对早期消息做摘要压缩
  • 保留最近 N 轮完整对话 + 早期对话的 LLM 生成摘要
  • 替代现在的简单条数截断

执行状态

一、工具标准化  ✅ 已完成 — tools/__init__.py, tools/reminder.py, tools/web_search.py, tools/history.py
二、Agent 循环  ✅ 已完成 — 移除 AI RouterLLM 直接通过 _execute_with_tools 自主调用工具
三、模型 Fallback  ✅ 已完成 — _handle_chitchat 级联候选模型ai_providers/fallback.py 重试/冷却
四、上下文压缩  ✅ 已完成 — func_summary.get_compressed_context(),字符预算代替固定条数截断