Files
NewWPSBot/.tasks/2025-11-20_2_add_user_tools_to_ai.md
2025-11-20 15:40:03 +08:00

9.3 KiB
Raw Blame History

背景

文件名2025-11-20_2_add_user_tools_to_ai.md 创建于2025-11-20_15:25:43 创建者admin 主分支main 任务分支:无(不创建分支) Yolo模式Off

任务描述

为 AI 聊天插件ChatAI.py添加用户 ID 与用户名转换的工具调用功能,让 AI 能够主动查询用户信息。

具体需求

  1. AI 应该能够通过工具调用实现以下功能:

    • 根据 user_id 查询 username
    • 根据 username 查询 user_id
    • 查询所有存在的 username 列表
  2. 使用 LlamaIndex 框架的高级功能FunctionTool + AgentWorkflow + ReActAgent

  3. 参考 NewsReport.py 的工具调用架构实现

项目概览

  • 项目NewWPSBot
  • 相关文件
    • Plugins/Others/ChatAI.py - AI 对话插件(需要改造)
    • Plugins/WPSConfigSystem.py - 用户配置系统(需要添加查询所有用户名的方法)
    • Plugins/Others/NewsReport.py - 参考实现(已实现工具调用)

分析

WPSConfigSystem.py 现状

  • 已有方法:get_user_name(user_id: int) - 第201-206行
  • 已有方法:find_user_id_by_username(username: str) - 第238-248行
  • 缺失方法:查询所有用户名列表
  • 数据表:user_info (user_id, username, userurl, userpoint)

ChatAI.py 现状第1-428行

  • 当前使用简单的 Ollama LLM + ChatMessage 架构
  • 通过 llm.achat() 进行对话
  • 没有工具调用能力
  • 维护全局历史 global_history
  • 单例模式:ChatAIAgent.get_instance()

NewsReport.py 工具调用架构(参考)

# 1. 导入
from llama_index.core.tools import FunctionTool
from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.core.agent.workflow.react_agent import ReActAgent

# 2. 创建工具
tools = [
    FunctionTool.from_defaults(
        fn=self._tool_function,
        name="tool_name",
        description="工具描述"
    ),
]

# 3. 创建 Agent
agent = ReActAgent(
    llm=self.llm,
    tools=tools,
    verbose=True,
    system_prompt=system_prompt,
)

# 4. 创建 Workflow
self.workflow = AgentWorkflow(
    agents=[agent],
    timeout=600.0,
)

# 5. 执行
result = await self.workflow.run(user_msg=query)

技术要点

  1. 工具函数必须是同步函数(从 NewsReport.py 看,工具函数如 _get_current_date() 都是同步的)
  2. WPSConfigAPI 需要通过 Architecture.Get() 获取
  3. 系统提示词需要明确指导 AI 何时使用工具
  4. 需要保留现有的历史消息管理功能

提议的解决方案

方案探索INNOVATE 阶段)

方案A完全重构为 ReActAgent 架构 推荐

架构设计

  • 移除 llm.achat() 调用方式
  • 使用 AgentWorkflow + ReActAgent
  • 历史消息通过系统提示词传递
  • 工具函数独立实现

优势

  • 与 NewsReport.py 架构统一,易于维护
  • ReActAgent 专门为工具调用优化
  • 工具调用日志清晰verbose=True
  • 扩展性强,易于添加新工具

劣势

  • 需要大幅度重构现有代码
  • 历史消息管理方式需改变
  • qwen3:0.6b 小模型的工具调用能力需验证

关键改进

  • 保留历史消息数组结构,调用时转换为提示词
  • 添加错误处理和降级机制
  • 可根据消息内容智能决定是否启用工具

方案B混合架构 - 保留对话 + 添加工具层

架构设计

  • 保留 llm.achat() 作为主要对话方式
  • AI 在回复中使用特殊标记触发工具(如 [TOOL:get_username:123]
  • 后处理解析工具调用并再次调用 LLM

优势

  • 改动最小,风险低
  • 保留现有历史消息机制
  • 对话连贯性不受影响

劣势

  • 需要自定义工具调用协议
  • 可能需要多轮 LLM 调用
  • 工具调用智能程度较低

方案C双智能体架构

架构设计

  • ToolAgentReActAgent专门处理工具调用
  • ChatAgent现有架构处理普通对话
  • 路由逻辑判断使用哪个智能体

优势:职责分离,灵活性高 劣势:架构复杂,维护成本高,上下文共享困难


方案D轻量级工具注入

架构设计

  • 预处理:分析消息,预先调用工具
  • 将工具结果注入到提示词
  • 正常调用 llm.achat()

优势:改动极小,性能影响最小 劣势AI 无法主动决定使用工具,智能程度低


最终推荐方案方案AReActAgent 架构)

实施要点

1. 在 WPSConfigSystem.py 添加方法

def get_all_usernames(self) -> List[Dict[str, Any]]:
    """获取所有用户名列表"""
    cursor = get_db().conn.cursor()
    cursor.execute(
        "SELECT user_id, username FROM user_info WHERE username != '' AND username IS NOT NULL"
    )
    rows = cursor.fetchall()
    return [{"user_id": row["user_id"], "username": row["username"]} for row in rows]

2. 改造 ChatAI.py

导入新增

from llama_index.core.tools import FunctionTool
from llama_index.core.agent.workflow import AgentWorkflow
from llama_index.core.agent.workflow.react_agent import ReActAgent
from PWF.Convention.Runtime.Architecture import Architecture

添加 _initialize_agent() 方法

  • 获取 WPSConfigAPI 实例
  • 创建三个工具函数
  • 初始化 ReActAgent
  • 创建 AgentWorkflow

工具函数

  1. get_username_by_id(user_id: int) -> str
  2. get_userid_by_name(username: str) -> str
  3. list_all_usernames() -> str

修改 chat() 方法

  • 将历史消息格式化为提示词
  • 使用 await self.workflow.run(user_msg=...)
  • 保留历史消息管理逻辑
  • 添加错误处理

更新系统提示词

  • 告知 AI 可用的三个工具
  • 说明工具使用场景和时机
  • 保持原有的 @用户 格式规则

技术挑战与解决方案

  1. 历史消息管理:保留数组结构,调用时动态转换
  2. WPSConfigAPI 访问:在 _initialize_agent() 中通过 Architecture.Get() 获取
  3. 错误处理:工具调用失败时返回友好提示,不中断对话
  4. 模型兼容性:测试 qwen3:0.6b 的工具调用能力,必要时提供降级方案

当前执行步骤:"4. 执行完成,等待测试"

任务进度

[2025-11-20_15:25:43]

  • 状态:研究完成
  • 已完成:
    • 分析 WPSConfigSystem.py 现有功能
    • 分析 ChatAI.py 当前架构
    • 研究 NewsReport.py 工具调用实现
    • 创建任务文件
  • 下一步:进入 INNOVATE 模式

[2025-11-20_15:30:00]

  • 状态:创新完成
  • 已完成:
    • 探索了 4 种技术方案ReActAgent、混合架构、双智能体、轻量级注入
    • 评估各方案优劣势和技术风险
    • 确定推荐方案:完全 ReActAgent 架构
    • 更新任务文件,记录方案分析
  • 下一步:进入 PLAN 模式

[2025-11-20_15:35:00]

  • 状态:规划完成
  • 已完成:
    • 制定详细的代码修改规格
    • 设计完整的系统提示词(包含工具使用说明、示例、错误处理)
    • 明确每个函数的签名和实现细节
    • 创建8项实施清单
    • 添加降级机制设计
  • 下一步:进入 EXECUTE 模式

[2025-11-20_15:38:25]

  • 状态:执行完成
  • 已修改文件:
    • Plugins/WPSConfigSystem.py添加 get_all_usernames() 方法)
    • Plugins/Others/ChatAI.py完全重构为 ReActAgent 架构)
  • 已完成修改:
    1. WPSConfigSystem.py 添加 get_all_usernames() 方法
    2. ChatAI.py 添加导入FunctionTool, AgentWorkflow, ReActAgent
    3. ChatAIAgent.init() 添加 workflow 和 config_api 属性
    4. ChatAIAgent.init() 添加 _initialize_agent() 调用
    5. 实现 _initialize_agent() 方法(包含三个工具函数)
    6. 实现 _build_system_prompt() 方法详细提示词约200行
    7. 重构 chat() 方法使用 workflow.run()
    8. 添加 _fallback_chat() 降级方法
  • Linter 检查: 无错误
  • 更改摘要:
    • 新增方法get_all_usernames() (WPSConfigSystem)
    • 新增方法_initialize_agent() (ChatAI)
    • 新增方法_build_system_prompt() (ChatAI)
    • 新增方法_fallback_chat() (ChatAI)
    • 重构方法chat() (ChatAI)
    • 新增工具函数get_username_by_id, get_userid_by_name, list_all_usernames
    • 新增导入FunctionTool, AgentWorkflow, ReActAgent
  • 下一步:用户测试工具调用功能

详细实施规格PLAN 阶段输出)

实施清单

  1. 在 WPSConfigSystem.py 添加 get_all_usernames() 方法
  2. 在 ChatAI.py 添加新的导入语句
  3. 在 ChatAIAgent.init() 添加 workflow 和 config_api 属性
  4. 在 ChatAIAgent.init() 添加 _initialize_agent() 调用
  5. 添加 _initialize_agent() 方法(创建三个工具)
  6. 添加 _build_system_prompt() 方法(详细提示词)
  7. 重构 chat() 方法使用 workflow.run()
  8. 添加 _fallback_chat() 降级方法

关键设计

系统提示词特点

  • 详细说明三个工具的用途、参数、返回值
  • 提供大量使用示例5个场景
  • 明确工具使用原则(何时用/何时不用)
  • 包含错误处理指导
  • 强调 标签使用规则

三个工具函数

  1. get_username_by_id(user_id: int) -> str
  2. get_userid_by_name(username: str) -> str
  3. list_all_usernames() -> str

错误处理

  • Workflow 初始化失败 → 使用 _fallback_chat()
  • 工具调用失败 → 返回友好错误信息
  • 整体异常 → 降级到简单对话模式

最终审查

(待完成后填写)