增强AI插件
This commit is contained in:
300
.tasks/2025-11-20_2_add_user_tools_to_ai.md
Normal file
300
.tasks/2025-11-20_2_add_user_tools_to_ai.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# 背景
|
||||
文件名: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 工具调用架构(参考)
|
||||
```python
|
||||
# 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:双智能体架构
|
||||
|
||||
**架构设计**:
|
||||
- ToolAgent(ReActAgent)专门处理工具调用
|
||||
- ChatAgent(现有架构)处理普通对话
|
||||
- 路由逻辑判断使用哪个智能体
|
||||
|
||||
**优势**:职责分离,灵活性高
|
||||
**劣势**:架构复杂,维护成本高,上下文共享困难
|
||||
|
||||
---
|
||||
|
||||
### 方案D:轻量级工具注入
|
||||
|
||||
**架构设计**:
|
||||
- 预处理:分析消息,预先调用工具
|
||||
- 将工具结果注入到提示词
|
||||
- 正常调用 `llm.achat()`
|
||||
|
||||
**优势**:改动极小,性能影响最小
|
||||
**劣势**:AI 无法主动决定使用工具,智能程度低
|
||||
|
||||
---
|
||||
|
||||
## 最终推荐方案:方案A(ReActAgent 架构)
|
||||
|
||||
### 实施要点
|
||||
|
||||
#### 1. 在 WPSConfigSystem.py 添加方法
|
||||
```python
|
||||
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
|
||||
|
||||
**导入新增**:
|
||||
```python
|
||||
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个场景)
|
||||
- 明确工具使用原则(何时用/何时不用)
|
||||
- 包含错误处理指导
|
||||
- 强调 <at> 标签使用规则
|
||||
|
||||
### 三个工具函数
|
||||
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()
|
||||
- 工具调用失败 → 返回友好错误信息
|
||||
- 整体异常 → 降级到简单对话模式
|
||||
|
||||
# 最终审查
|
||||
(待完成后填写)
|
||||
|
||||
Reference in New Issue
Block a user