refactor(tool_use): 添加工具调用历史记录功能,优化工具执行器的提示词和历史管理

refactor(chat_stream_impression_tool): 简化聊天流印象更新逻辑,直接使用传入参数更新
refactor(user_profile_tool): 优化用户画像更新逻辑,直接覆盖更新并移除二步调用机制
This commit is contained in:
Windpicker-owo
2025-11-02 12:43:44 +08:00
parent 28a70f85d5
commit dfb0626521
3 changed files with 172 additions and 333 deletions

View File

@@ -26,6 +26,10 @@ def init_tool_executor_prompt():
请仔细分析聊天内容,考虑以下几点:
1. 内容中是否包含需要查询信息的问题
2. 是否有明确的工具使用指令
3. 之前的工具调用是否提供了有用的信息
4. 是否需要基于之前的工具结果进行进一步的查询
{tool_history}
If you need to use a tool, please directly call the corresponding tool function. If you do not need to use any tool, simply output "No tool needed".
"""
@@ -61,6 +65,10 @@ class ToolExecutor:
"""待处理的第二步工具调用,格式为 {tool_name: step_two_definition}"""
self._log_prefix_initialized = False
# 工具调用历史
self.tool_call_history: list[dict[str, Any]] = []
"""工具调用历史,包含工具名称、参数和结果"""
# logger.info(f"{self.log_prefix}工具执行器初始化完成") # 移到异步初始化中
async def _initialize_log_prefix(self):
@@ -100,6 +108,9 @@ class ToolExecutor:
bot_name = global_config.bot.nickname
# 构建工具调用历史文本
tool_history = self._format_tool_history()
# 构建工具调用提示词
prompt = await global_prompt_manager.format_prompt(
"tool_executor_prompt",
@@ -108,6 +119,7 @@ class ToolExecutor:
sender=sender,
bot_name=bot_name,
time_now=time_now,
tool_history=tool_history,
)
logger.debug(f"{self.log_prefix}开始LLM工具调用分析")
@@ -149,6 +161,83 @@ class ToolExecutor:
return tool_definitions
def _format_tool_history(self, max_history: int = 5) -> str:
"""格式化工具调用历史为文本
Args:
max_history: 最多显示的历史记录数量
Returns:
格式化的工具历史文本
"""
if not self.tool_call_history:
return ""
# 只取最近的几条历史
recent_history = self.tool_call_history[-max_history:]
history_lines = ["历史工具调用记录:"]
for i, record in enumerate(recent_history, 1):
tool_name = record.get("tool_name", "unknown")
args = record.get("args", {})
result_preview = record.get("result_preview", "")
status = record.get("status", "success")
# 格式化参数
args_str = ", ".join([f"{k}={v}" for k, v in args.items()])
# 格式化记录
status_emoji = "" if status == "success" else ""
history_lines.append(f"{i}. {status_emoji} {tool_name}({args_str})")
if result_preview:
# 限制结果预览长度
if len(result_preview) > 200:
result_preview = result_preview[:200] + "..."
history_lines.append(f" 结果: {result_preview}")
return "\n".join(history_lines)
def _add_tool_to_history(self, tool_name: str, args: dict, result: dict | None, status: str = "success"):
"""添加工具调用到历史记录
Args:
tool_name: 工具名称
args: 工具参数
result: 工具结果
status: 执行状态 (success/error)
"""
# 生成结果预览
result_preview = ""
if result:
content = result.get("content", "")
if isinstance(content, str):
result_preview = content
elif isinstance(content, list | dict):
import json
try:
result_preview = json.dumps(content, ensure_ascii=False)
except Exception:
result_preview = str(content)
else:
result_preview = str(content)
record = {
"tool_name": tool_name,
"args": args,
"result_preview": result_preview,
"status": status,
"timestamp": time.time(),
}
self.tool_call_history.append(record)
# 限制历史记录数量,避免内存溢出
max_history_size = 5
if len(self.tool_call_history) > max_history_size:
self.tool_call_history = self.tool_call_history[-max_history_size:]
async def execute_tool_calls(self, tool_calls: list[ToolCall] | None) -> tuple[list[dict[str, Any]], list[str]]:
"""执行工具调用
@@ -183,6 +272,7 @@ class ToolExecutor:
# 执行每个工具调用
for tool_call in tool_calls:
tool_name = getattr(tool_call, "func_name", "unknown_tool")
tool_args = getattr(tool_call, "args", {})
try:
logger.debug(f"{self.log_prefix}执行工具: {tool_name}")
@@ -204,8 +294,15 @@ class ToolExecutor:
tool_results.append(tool_info)
used_tools.append(tool_name)
logger.info(f"{self.log_prefix}工具{tool_name}执行成功,类型: {tool_info['type']}")
preview = content[:200]
preview = content[:200] if isinstance(content, str) else str(content)[:200]
logger.debug(f"{self.log_prefix}工具{tool_name}结果内容: {preview}...")
# 记录到历史
self._add_tool_to_history(tool_name, tool_args, result, status="success")
else:
# 工具返回空结果也记录到历史
self._add_tool_to_history(tool_name, tool_args, None, status="success")
except Exception as e:
logger.error(f"{self.log_prefix}工具{tool_name}执行失败: {e}")
# 添加错误信息到结果中
@@ -218,6 +315,9 @@ class ToolExecutor:
}
tool_results.append(error_info)
# 记录失败到历史
self._add_tool_to_history(tool_name, tool_args, None, status="error")
return tool_results, used_tools
async def execute_tool_call(
@@ -404,13 +504,32 @@ class ToolExecutor:
"timestamp": time.time(),
}
logger.info(f"{self.log_prefix}直接工具执行成功: {tool_name}")
# 记录到历史
self._add_tool_to_history(tool_name, tool_args, result, status="success")
return tool_info
except Exception as e:
logger.error(f"{self.log_prefix}直接工具执行失败 {tool_name}: {e}")
# 记录失败到历史
self._add_tool_to_history(tool_name, tool_args, None, status="error")
return None
def clear_tool_history(self):
"""清除工具调用历史"""
self.tool_call_history.clear()
logger.debug(f"{self.log_prefix}已清除工具调用历史")
def get_tool_history(self) -> list[dict[str, Any]]:
"""获取工具调用历史
Returns:
工具调用历史列表
"""
return self.tool_call_history.copy()
"""
ToolExecutor使用示例
@@ -436,4 +555,22 @@ result = await executor.execute_specific_tool_simple(
tool_name="get_knowledge",
tool_args={"query": "机器学习"}
)
# 4. 使用工具历史 - 连续对话中的工具调用
# 第一次调用
await executor.execute_from_chat_message(
target_message="查询今天的天气",
chat_history="",
sender="用户"
)
# 第二次调用时会自动包含上次的工具调用历史
await executor.execute_from_chat_message(
target_message="那明天呢?",
chat_history="",
sender="用户"
)
# 5. 获取和清除历史
history = executor.get_tool_history() # 获取历史记录
executor.clear_tool_history() # 清除历史记录
"""