|
|
@@ -43,41 +43,12 @@ class FunctionKnowledge:
|
|
|
self.use_cache = use_cache
|
|
|
self.cache = CacheManager() if use_cache else None
|
|
|
|
|
|
- # 执行详情收集
|
|
|
- self.execution_detail = {
|
|
|
- "generate_query": {},
|
|
|
- "select_tool": {},
|
|
|
- "extract_params": {},
|
|
|
- "execution_time": 0,
|
|
|
- "cache_hits": []
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
logger.info(f"缓存状态: {'启用' if use_cache else '禁用'}")
|
|
|
logger.info("=" * 80)
|
|
|
|
|
|
- def _save_execution_detail(self, cache_key: str):
|
|
|
- """保存执行详情到缓存"""
|
|
|
- if not self.use_cache or not self.cache:
|
|
|
- return
|
|
|
-
|
|
|
- try:
|
|
|
- import hashlib
|
|
|
- question_hash = hashlib.md5(cache_key.encode('utf-8')).hexdigest()[:12]
|
|
|
- detail_dir = os.path.join(
|
|
|
- self.cache.base_cache_dir,
|
|
|
- question_hash,
|
|
|
- 'function_knowledge'
|
|
|
- )
|
|
|
- os.makedirs(detail_dir, exist_ok=True)
|
|
|
-
|
|
|
- detail_file = os.path.join(detail_dir, 'execution_detail.json')
|
|
|
- with open(detail_file, 'w', encoding='utf-8') as f:
|
|
|
- json.dump(self.execution_detail, f, ensure_ascii=False, indent=2)
|
|
|
-
|
|
|
- logger.info(f"✓ 执行详情已保存: {detail_file}")
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"✗ 保存执行详情失败: {e}")
|
|
|
+
|
|
|
|
|
|
def _load_prompt(self, filename: str) -> str:
|
|
|
"""加载prompt文件内容"""
|
|
|
@@ -109,12 +80,11 @@ class FunctionKnowledge:
|
|
|
|
|
|
# 尝试从缓存读取
|
|
|
if self.use_cache:
|
|
|
- cached_query = self.cache.get(combined_question, 'function_knowledge', 'generated_query.txt')
|
|
|
- if cached_query:
|
|
|
- logger.info(f"✓ 使用缓存的Query: {cached_query}")
|
|
|
- # 记录缓存命中
|
|
|
- self.execution_detail["generate_query"].update({"cached": True, "query": cached_query, "prompt": prompt})
|
|
|
- return cached_query
|
|
|
+ cached_data = self.cache.get(combined_question, 'function_knowledge', 'generated_query.json')
|
|
|
+ if cached_data:
|
|
|
+ query = cached_data.get('query', cached_data.get('response', ''))
|
|
|
+ logger.info(f"✓ 使用缓存的Query: {query}")
|
|
|
+ return query
|
|
|
|
|
|
logger.info("→ 调用Gemini生成Query...")
|
|
|
query = generate_text(prompt=prompt)
|
|
|
@@ -122,17 +92,14 @@ class FunctionKnowledge:
|
|
|
|
|
|
logger.info(f"✓ 生成Query: {query}")
|
|
|
|
|
|
- # 写入缓存
|
|
|
+ # 保存到缓存(包含完整的prompt和response)
|
|
|
if self.use_cache:
|
|
|
- self.cache.set(combined_question, 'function_knowledge', 'generated_query.txt', query)
|
|
|
-
|
|
|
- # 记录详情
|
|
|
- self.execution_detail["generate_query"] = {
|
|
|
- "cached": False,
|
|
|
- "prompt": prompt,
|
|
|
- "response": query,
|
|
|
- "query": query
|
|
|
- }
|
|
|
+ query_data = {
|
|
|
+ "prompt": prompt,
|
|
|
+ "response": query,
|
|
|
+ "query": query
|
|
|
+ }
|
|
|
+ self.cache.set(combined_question, 'function_knowledge', 'generated_query.json', query_data)
|
|
|
|
|
|
return query
|
|
|
except Exception as e:
|
|
|
@@ -159,16 +126,11 @@ class FunctionKnowledge:
|
|
|
|
|
|
# 尝试从缓存读取
|
|
|
if self.use_cache:
|
|
|
- cached_tool = self.cache.get(combined_question, 'function_knowledge', 'selected_tool.txt')
|
|
|
- if cached_tool:
|
|
|
- logger.info(f"✓ 使用缓存的工具: {cached_tool}")
|
|
|
- # 记录缓存命中
|
|
|
- self.execution_detail["select_tool"].update({
|
|
|
- "cached": True,
|
|
|
- "response": json.loads(cached_tool),
|
|
|
- "prompt": prompt,
|
|
|
- })
|
|
|
- return json.loads(cached_tool)
|
|
|
+ cached_data = self.cache.get(combined_question, 'function_knowledge', 'selected_tool.json')
|
|
|
+ if cached_data:
|
|
|
+ result_json = cached_data.get('response', {})
|
|
|
+ logger.info(f"✓ 使用缓存的工具: {result_json}")
|
|
|
+ return result_json
|
|
|
|
|
|
logger.info("→ 调用Gemini选择工具...")
|
|
|
result = generate_text(prompt=prompt)
|
|
|
@@ -181,16 +143,13 @@ class FunctionKnowledge:
|
|
|
|
|
|
logger.info(f"✓ 选择结果: {result_json.get('工具名', 'None')}")
|
|
|
|
|
|
- # 写入缓存
|
|
|
+ # 保存到缓存(包含完整的prompt和response)
|
|
|
if self.use_cache:
|
|
|
- self.cache.set(combined_question, 'function_knowledge', 'selected_tool.txt', result)
|
|
|
-
|
|
|
- # 记录详情
|
|
|
- self.execution_detail["select_tool"] = {
|
|
|
- "cached": False,
|
|
|
- "prompt": prompt,
|
|
|
- "response": result_json,
|
|
|
- }
|
|
|
+ tool_data = {
|
|
|
+ "prompt": prompt,
|
|
|
+ "response": result_json
|
|
|
+ }
|
|
|
+ self.cache.set(combined_question, 'function_knowledge', 'selected_tool.json', tool_data)
|
|
|
|
|
|
return result_json
|
|
|
except Exception as e:
|
|
|
@@ -250,22 +209,18 @@ class FunctionKnowledge:
|
|
|
# 加载prompt
|
|
|
prompt_template = self._load_prompt("function_knowledge_extract_tool_params_prompt.md")
|
|
|
prompt = prompt_template.format(
|
|
|
- query=query,
|
|
|
+ tool_mcp_name=tool_id,
|
|
|
+ tool_instructions=tool_instructions,
|
|
|
all_tool_params=tool_params
|
|
|
)
|
|
|
|
|
|
# 尝试从缓存读取
|
|
|
if self.use_cache:
|
|
|
- cached_params = self.cache.get(combined_question, 'function_knowledge', 'tool_params.json')
|
|
|
- if cached_params:
|
|
|
- logger.info(f"✓ 使用缓存的参数: {cached_params}")
|
|
|
- # 记录缓存命中
|
|
|
- self.execution_detail["extract_params"].update({
|
|
|
- "cached": True,
|
|
|
- "params": cached_params,
|
|
|
- "prompt": prompt,
|
|
|
- })
|
|
|
- return cached_params
|
|
|
+ cached_data = self.cache.get(combined_question, 'function_knowledge', 'extracted_params.json')
|
|
|
+ if cached_data:
|
|
|
+ params = cached_data.get('params', {})
|
|
|
+ logger.info(f"✓ 使用缓存的参数: {params}")
|
|
|
+ return params
|
|
|
|
|
|
# 调用LLM提取参数
|
|
|
logger.info(" → 调用Gemini提取参数...")
|
|
|
@@ -288,17 +243,14 @@ class FunctionKnowledge:
|
|
|
|
|
|
logger.info(f"✓ 提取参数成功: {params}")
|
|
|
|
|
|
- # 写入缓存
|
|
|
+ # 保存到缓存(包含完整的prompt和response)
|
|
|
if self.use_cache:
|
|
|
- self.cache.set(combined_question, 'function_knowledge', 'tool_params.json', params)
|
|
|
-
|
|
|
- # 记录详情
|
|
|
- self.execution_detail["extract_params"].update({
|
|
|
- "cached": False,
|
|
|
- "prompt": prompt,
|
|
|
- "response": response_text,
|
|
|
- "params": params
|
|
|
- })
|
|
|
+ params_data = {
|
|
|
+ "prompt": prompt,
|
|
|
+ "response": response_text,
|
|
|
+ "params": params
|
|
|
+ }
|
|
|
+ self.cache.set(combined_question, 'function_knowledge', 'extracted_params.json', params_data)
|
|
|
|
|
|
return params
|
|
|
|
|
|
@@ -343,6 +295,24 @@ class FunctionKnowledge:
|
|
|
except Exception as e:
|
|
|
logger.error(f"✗ 保存知识失败: {e}")
|
|
|
|
|
|
+ def organize_tool_result(self, tool_result: dict) -> dict:
|
|
|
+ """
|
|
|
+ 组织工具调用结果,确保包含必要字段
|
|
|
+
|
|
|
+ Args:
|
|
|
+ tool_result: 原始工具调用结果
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ dict: 组织后的工具调用结果
|
|
|
+ """
|
|
|
+ prompt_template = self._load_prompt("tool_result_prettify_prompt.md")
|
|
|
+ prompt = prompt_template.format(
|
|
|
+ input=tool_result,
|
|
|
+ )
|
|
|
+ organized_result = generate_text(prompt=prompt)
|
|
|
+ organized_result = organized_result.strip()
|
|
|
+ return organized_result
|
|
|
+
|
|
|
def get_knowledge(self, question: str, post_info: str, persona_info: str) -> dict:
|
|
|
"""
|
|
|
获取方法知识的主流程(重构后)
|
|
|
@@ -383,15 +353,21 @@ class FunctionKnowledge:
|
|
|
|
|
|
# 检查工具调用缓存
|
|
|
if self.use_cache:
|
|
|
- cached_tool_result = self.cache.get(combined_question, 'function_knowledge', 'tool_result.json')
|
|
|
- if cached_tool_result:
|
|
|
+ cached_tool_call = self.cache.get(combined_question, 'function_knowledge', 'tool_call.json')
|
|
|
+ if cached_tool_call:
|
|
|
logger.info(f"✓ 使用缓存的工具调用结果")
|
|
|
- tool_result = cached_tool_result
|
|
|
+ tool_result = cached_tool_call.get('result', {})
|
|
|
else:
|
|
|
logger.info(f" → 调用工具,参数: {arguments}")
|
|
|
tool_result = call_tool(tool_id, arguments)
|
|
|
- # 缓存工具调用结果
|
|
|
- self.cache.set(combined_question, 'function_knowledge', 'tool_result.json', tool_result)
|
|
|
+ tool_result = self.organize_tool_result(tool_result)
|
|
|
+ # 保存工具调用信息(包含工具名、入参、结果)
|
|
|
+ tool_call_data = {
|
|
|
+ "tool_name": tool_id,
|
|
|
+ "arguments": arguments,
|
|
|
+ "result": tool_result
|
|
|
+ }
|
|
|
+ self.cache.set(combined_question, 'function_knowledge', 'tool_call.json', tool_call_data)
|
|
|
else:
|
|
|
logger.info(f" → 调用工具,参数: {arguments}")
|
|
|
tool_result = call_tool(tool_id, arguments)
|
|
|
@@ -408,9 +384,8 @@ class FunctionKnowledge:
|
|
|
logger.info("[后台任务] 保存知识到文件...")
|
|
|
threading.Thread(target=self.save_knowledge_to_file, args=(knowledge, combined_question)).start()
|
|
|
|
|
|
- # 计算执行时间并保存详情
|
|
|
- self.execution_detail["execution_time"] = time.time() - start_time
|
|
|
- self._save_execution_detail(combined_question)
|
|
|
+ # 计算执行时间
|
|
|
+ execution_time = time.time() - start_time
|
|
|
|
|
|
# 收集所有执行记录
|
|
|
logger.info("=" * 80)
|
|
|
@@ -441,10 +416,9 @@ class FunctionKnowledge:
|
|
|
import traceback
|
|
|
logger.error(traceback.format_exc())
|
|
|
|
|
|
- # 即使失败也尝试保存详情和收集记录
|
|
|
+ # 即使失败也尝试收集记录
|
|
|
try:
|
|
|
- self.execution_detail["execution_time"] = time.time() - start_time
|
|
|
- self._save_execution_detail(combined_question)
|
|
|
+ execution_time = time.time() - start_time
|
|
|
|
|
|
from knowledge_v2.execution_collector import collect_and_save_execution_record
|
|
|
execution_record = collect_and_save_execution_record(
|