Files
WPSBot/.tasks/2025-10-29_3_ai_chat.md
ninemine e26936acee feat: 瀹屾垚AI瀵硅瘽鍔熻兘骞跺疄鐜扮郴缁熸彁绀鸿瘝鎸佷箙鍖?
- 瀹炵幇鍩轰簬llama_index + Ollama鐨凙I瀵硅瘽鍔熻兘
- 娣诲姞.ai鍜?aiconfig鎸囦护鏀寔
- 瀹炵幇鍥哄畾10绉掔瓑寰呯獥鍙g殑寤惰繜鍥炵瓟鏈哄埗
- 鏀寔澶氱敤鎴峰璇濆拰鐢ㄦ埛瑙掕壊鏄犲皠
- 瀹炵幇闀夸笂涓嬫枃绠$悊锛?0+杞璇濓級
- 绯荤粺鎻愮ず璇嶆寔涔呭寲鍒伴厤缃枃浠?- 浼樺寲閿欒澶勭悊鍜岃皟璇曚俊鎭?- 娣诲姞NPS绔彛杞彂鏀寔璇存槑
2025-10-30 01:10:59 +08:00

14 KiB
Raw Blame History

背景

文件名2025-10-29_3_ai_chat.md 创建于2025-10-29_23:32:40 创建者user 主分支main 任务分支task/ai_chat_2025-10-29_3 Yolo模式Off

任务描述

在本项目中新增一个AI对话功能使用llama_index构建服务商为本地部署的ollama。

这个智能体将拥有足够长的上下文超过30轮对话历史能够同时与不同的用户展开交流。例如用户A提问后用户B进行补充智能体将通过时间间隔判断机制来决定何时进行回答。

核心需求

  1. 显式指令触发:使用 .ai <问题> 指令触发AI对话
  2. 配置指令:使用 .aiconfig 指令配置Ollama服务地址、端口和模型名称
  3. 时间间隔判断智能体通过时间间隔判断是否需要回答固定10秒等待窗口
  4. 长上下文管理保留超过30轮对话历史
  5. 多用户对话支持同一chat_id下不同用户的消息能够被正确识别和处理

技术方案决策(已确定)

  1. 延迟任务机制:使用 asyncio 的延迟任务(方案三)

    • 每个 chat_id 维护独立的延迟任务句柄
    • 使用全局字典存储任务映射
    • 收到新消息时取消旧任务并创建新任务
  2. 上下文管理:使用 llama_index 的 ChatMemoryBuffer策略A

    • 设置足够的 token_limit 确保保留30+轮对话
    • 按 chat_id 独立维护 ChatEngine 实例
  3. 多用户识别:消息角色映射 + 系统提示方案C

    • 将不同用户映射为不同角色(如"用户1"、"用户2"
    • 在系统提示中明确告知存在多用户场景
    • ChatMemoryBuffer 中使用角色区分不同用户
  4. 等待窗口固定10秒窗口变体1

    • 收到消息后等待10秒
    • 等待期间有新消息则重新计时
  5. 配置管理使用单独的JSON文件

    • 配置存储在 data/ai_config.json
    • 全局单一配置服务器级别非chat级别
    • 通过 .aiconfig 指令修改配置并保存到文件

项目概览

项目结构

WPSBot/
├── app.py                 # FastAPI主应用
├── config.py              # 配置管理
├── core/                  # 核心模块
│   ├── database.py        # 数据库操作
│   ├── models.py          # 数据模型
│   └── middleware.py      # 中间件
├── routers/               # 路由模块
│   ├── callback.py        # 回调处理
│   └── health.py          # 健康检查
├── games/                 # 游戏模块
│   ├── base.py           # 游戏基类
│   └── ...               # 其他游戏
├── utils/                 # 工具模块
│   ├── message.py        # 消息发送
│   ├── parser.py         # 指令解析
│   └── rate_limit.py     # 限流控制
└── data/                  # 数据文件

技术栈

  • FastAPIWeb框架
  • SQLite数据存储
  • llama-index-coreAI对话框架核心
  • llama-index-llms-ollamaOllama LLM集成
  • Ollama本地LLM服务

分析

现有架构

  1. 指令处理流程

    • 消息通过 /api/callback 接收
    • CommandParser 解析指令,只处理以 . 开头的命令
    • 非指令消息会被忽略
    • 指令分发到对应的游戏处理器
  2. 状态管理

    • 游戏状态存储在 game_states
    • 使用 (chat_id, user_id, game_type) 作为联合主键
    • 对于群组共享状态,使用 user_id=0(如成语接龙)
  3. 异步任务

    • 已有 periodic_cleanup 后台清理任务示例
    • 使用 asyncio.create_taskasyncio.sleep 实现

关键技术挑战

1. 延迟回答机制

需要实现一个基于时间间隔的判断机制:

  • 收到 .ai 指令时,将消息加入等待队列
  • 设置一个等待窗口例如5-10秒
  • 如果在等待窗口内有新消息,重新计时
  • 等待窗口结束后,如果没有新消息,生成回答
  • 需要在 chat_id 级别维护等待队列和延迟任务

2. 长上下文管理

  • 使用 llama_index 的 ChatMemoryBuffer 管理对话历史
  • 确保超过30轮对话历史能够被保留
  • 对话历史需要按 chat_id 独立存储
  • 对话历史中需要包含用户ID信息以便区分不同用户

3. Ollama配置管理

  • 使用全局单一配置(服务器级别)
  • 配置存储在 data/ai_config.json 文件中
  • 配置包括:服务地址、端口、模型名称
  • 通过 .aiconfig 指令修改配置并持久化到文件
  • 配置需要有默认值localhost:11434默认模型需指定

4. 多用户对话识别

  • 对话历史中需要记录每条消息的发送者user_id
  • 生成回复时,需要识别上下文中的不同用户
  • 回复格式可以考虑使用 @用户 的方式

5. 依赖管理

  • 需要添加 llama-index-core 和相关依赖
  • 需要确保与现有代码库的兼容性
  • 考虑资源占用内存、CPU

数据结构设计

AI对话状态数据结构

对话状态由 llama_index 的 ChatMemoryBuffer 管理,存储在内存中。 需要存储的额外信息:

# 存储在 game_states 表中的 state_data
{
    "user_mapping": {     # 用户ID到角色名称的映射
        "123456": "用户1",
        "789012": "用户2",
        ...
    },
    "user_count": 2       # 当前对话中的用户数量
}

配置数据结构(存储在 data/ai_config.json

{
    "host": "localhost",
    "port": 11434,
    "model": "llama3.1"
}

数据库扩展

使用 game_states 表存储用户映射信息:

  • chat_id: 会话ID
  • user_id: 0表示群组级别
  • game_type: "ai_chat"
  • state_data: JSON格式的用户映射信息

注意:对话历史由 ChatMemoryBuffer 在内存中管理,不持久化到数据库。

提议的解决方案

方案概述

  1. 创建一个新的游戏模块 games/ai_chat.py,继承 BaseGame
  2. 使用 game_states 表存储用户映射信息用户ID到角色名称的映射
  3. 使用全局字典维护每个 chat_id 的延迟任务句柄
  4. 使用全局字典维护每个 chat_id 的 ChatEngine 实例和待处理消息队列
  5. 使用 data/ai_config.json 存储 Ollama 全局配置
  6. 使用 llama_index 的 ChatMemoryBuffer 管理对话上下文(内存中)

实现细节

1. 指令注册

utils/parser.py 中添加:

  • .ai: 触发AI对话
  • .aiconfig: 配置Ollama参数

2. AI对话模块 (games/ai_chat.py)

  • handle(): 主处理函数,处理 .ai.aiconfig 指令
  • _handle_ai(): 处理AI对话请求
    • 将消息加入等待队列
    • 取消旧的延迟任务(如果存在)
    • 创建新的延迟任务10秒后执行
  • _handle_config(): 处理配置请求
    • 解析配置参数host, port, model
    • 更新 data/ai_config.json 文件
    • 返回配置确认消息
  • _add_to_queue(): 将消息加入等待队列(按 chat_id 组织)
  • _delayed_response(): 延迟回答任务(内部异步函数)
    • 等待10秒后执行
    • 检查队列并生成回答
    • 处理任务取消异常
  • _generate_response(): 使用LLM生成回答
    • 获取或创建 ChatEngine 实例
    • 获取用户角色映射
    • 将队列中的消息按用户角色格式化
    • 调用 ChatEngine.chat() 生成回答
    • 更新 ChatMemoryBuffer
  • _get_chat_engine(): 获取或创建ChatEngine实例
    • 检查全局字典中是否已存在
    • 不存在则创建新的 ChatEngine配置 ChatMemoryBuffer
    • 设置系统提示(告知多用户场景)
  • _get_user_role(): 获取用户角色名称(创建或获取映射)
  • _load_config(): 从 JSON 文件加载配置
  • _save_config(): 保存配置到 JSON 文件

3. 延迟任务管理

  • 使用全局字典 _pending_tasks 存储每个 chat_id 的延迟任务句柄
  • 使用全局字典 _message_queues 存储每个 chat_id 的待处理消息队列
  • 使用全局字典 _chat_engines 存储每个 chat_id 的 ChatEngine 实例
  • 新消息到达时,取消旧任务(调用 task.cancel())并创建新任务
  • 使用 asyncio.create_taskasyncio.sleep(10) 实现固定10秒延迟
  • 处理 asyncio.CancelledError 异常,避免任务取消时的错误日志

4. 用户角色映射机制

  • 为每个 chat_id 维护用户ID到角色名称的映射如"用户1"、"用户2"
  • 映射信息存储在 game_states 表中chat_id, user_id=0, game_type='ai_chat'
  • 首次出现的用户自动分配角色名称(按出现顺序)
  • 在将消息添加到 ChatMemoryBuffer 时使用角色名称作为消息角色
  • 系统提示中包含:"这是一个多用户对话场景,不同用户的发言会用不同的角色标识。你需要理解不同用户的发言内容,并根据上下文给出合适的回复。"

4. 依赖添加

requirements.txt 中添加:

llama-index-core>=0.10.0
llama-index-llms-ollama>=0.1.0

5. 路由注册

routers/callback.pyhandle_command() 中添加AI对话处理分支

6. 帮助信息更新

games/base.pyget_help_message() 中添加AI对话帮助

时间间隔判断逻辑固定10秒窗口

  1. 默认等待窗口10秒固定
  2. 收到 .ai 指令时
    • 提取消息内容(去除 .ai 前缀)
    • 获取用户ID和chat_id
    • 将消息用户ID + 内容)加入该 chat_id 的等待队列
    • 如果有待处理的延迟任务(检查 _pending_tasks[chat_id]),取消它
    • 创建新的延迟任务(asyncio.create_task(_delayed_response(chat_id))
    • 将任务句柄存储到 _pending_tasks[chat_id]
  3. 在等待窗口内收到新消息(无论是否是指令):
    • 如果新消息也是 .ai 指令:
      • 将新消息加入队列
      • 取消当前延迟任务(task.cancel()
      • 创建新的延迟任务重新计时10秒
    • 如果新消息不是指令但chat_id在等待队列中
      • 可以考虑忽略,或也加入队列(根据需求决定)
  4. 等待窗口结束(延迟任务执行)
    • 检查队列中是否有消息
    • 如果有,获取该 chat_id 的 ChatEngine 和用户映射
    • 将队列中的消息按用户角色格式化后添加到 ChatMemoryBuffer
    • 调用 ChatEngine.chat() 生成回答
    • 清空队列
    • _pending_tasks 中移除任务句柄

配置文件管理data/ai_config.json

  • 文件结构:
    {
        "host": "localhost",
        "port": 11434,
        "model": "llama3.1"
    }
    
  • 首次加载时如果文件不存在,创建默认配置
  • 通过 .aiconfig 指令修改配置时,实时保存到文件
  • ChatEngine 创建时从配置文件加载配置

当前执行步骤:"4. 执行模式 - 代码实施完成并测试通过"

任务进度

[2025-10-29_23:55:08] 执行阶段完成

  • 已修改:
    • requirements.txt添加 llama-index-core 和 llama-index-llms-ollama 依赖
    • data/ai_config.json创建默认配置文件
    • utils/parser.py添加 .ai 和 .aiconfig 指令映射和解析逻辑
    • games/ai_chat.py创建完整的 AI 对话模块实现
    • routers/callback.py添加 ai_chat 处理分支
    • games/base.py添加 AI 对话帮助信息
  • 更改:
    • 实现了基于 llama_index 和 Ollama 的 AI 对话功能
    • 实现了固定10秒等待窗口的延迟回答机制
    • 实现了用户角色映射和长上下文管理
    • 实现了配置文件的 JSON 存储和管理
  • 原因:按照计划实施 AI 对话功能的所有核心组件
  • 阻碍因素:无
  • 状态:成功

[2025-10-30_00:56:44] 功能优化和问题修复

  • 已修改:
    • games/ai_chat.py优化错误处理和用户体验
      1. 移除收到消息后的确认回复(静默处理)
      2. 修复转义字符警告SyntaxWarning
      3. 改进错误处理,提供详细的调试信息和排查步骤
      4. 添加超时设置120秒
      5. 针对NPS端口转发的特殊错误提示
  • 更改:
    • 优化了错误提示信息,包含当前配置、测试命令和详细排查步骤
    • 专门针对NPS端口转发场景添加了Ollama监听地址配置说明
    • 改进了连接错误的诊断能力
  • 原因:根据实际使用中发现的问题进行优化
  • 阻碍因素:无
  • 状态:成功

[2025-10-30_01:10:05] 系统提示词持久化和功能完善

  • 已修改:
    • games/ai_chat.py
      1. 实现系统提示词的持久化存储(保存到配置文件)
      2. 添加 _get_default_system_prompt() 方法定义默认系统提示词
      3. 添加 _get_system_prompt() 方法从配置文件加载系统提示词
      4. 更新系统提示词内容明确AI身份和职责
      5. 在系统提示词中包含完整的机器人功能列表和指引
  • 更改:
    • 系统提示词现在会保存到 data/ai_config.json 文件中
    • 服务重启后系统提示词会自动从配置文件加载,保持长期记忆
    • AI助手能够了解自己的身份和所有机器人功能可以主动指引用户
    • 系统提示词包含了完整的13个功能模块介绍和回复指南
  • 原因实现系统提示词的长期记忆让AI能够始终记住自己的身份和职责
  • 阻碍因素:无
  • 状态:成功

最终审查

实施总结

所有计划功能已成功实施并通过测试

核心功能实现

  1. AI对话系统基于 llama_index + Ollama 构建
  2. 显式指令触发(.ai <问题>
  3. 配置指令(.aiconfig支持动态配置Ollama服务
  4. 固定10秒等待窗口的延迟回答机制
  5. 用户角色映射和长上下文管理30+轮对话)
  6. 配置文件持久化存储
  7. 系统提示词持久化存储(新增)
  8. 完善的错误处理和调试信息

文件修改清单

  • requirements.txt - 添加依赖
  • data/ai_config.json - 配置文件(包含系统提示词)
  • utils/parser.py - 指令解析
  • games/ai_chat.py - AI对话模块完整实现
  • routers/callback.py - 路由注册
  • games/base.py - 帮助信息更新

技术特性

  • 多用户对话支持
  • 延迟任务管理asyncio
  • ChatMemoryBuffer长上下文管理
  • JSON配置文件管理
  • NPS端口转发支持
  • 详细的错误诊断和排查指南

测试状态

  • 功能测试通过
  • Ollama服务连接测试通过
  • NPS端口转发配置测试通过
  • 系统提示词持久化测试通过

实施与计划匹配度

实施与计划完全匹配