|
|
@@ -52,45 +52,72 @@ class ExecutionCollector:
|
|
|
# 初始化执行记录
|
|
|
execution_record = {
|
|
|
"input": input_info,
|
|
|
- "execution": {
|
|
|
- "modules": {}
|
|
|
- },
|
|
|
- "result": {
|
|
|
- "type": None,
|
|
|
- "content": None,
|
|
|
- "raw_data": None
|
|
|
+ "execution": {},
|
|
|
+ "output": {
|
|
|
+ "result": None,
|
|
|
},
|
|
|
"metadata": {
|
|
|
- "execution_time": 0,
|
|
|
+ "execution_time": input_info.get("execution_time", 0),
|
|
|
"cache_hits": [],
|
|
|
"errors": []
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- # 收集各模块的执行详情
|
|
|
try:
|
|
|
- # 1. 收集 function_knowledge 的详情
|
|
|
- function_detail = self._collect_function_knowledge_detail(cache_dir)
|
|
|
- if function_detail:
|
|
|
- execution_record["execution"]["modules"]["function_knowledge"] = function_detail
|
|
|
-
|
|
|
- # 2. 收集 multi_search 的详情
|
|
|
- multi_detail = self._collect_multi_search_detail(cache_dir)
|
|
|
- if multi_detail:
|
|
|
- execution_record["execution"]["modules"]["multi_search"] = multi_detail
|
|
|
+ # 1. Generate Query
|
|
|
+ query_detail = self._read_json(cache_dir, 'function_knowledge', 'generated_query.json')
|
|
|
+ if query_detail:
|
|
|
+ execution_record["execution"]["generate_query"] = query_detail
|
|
|
+ if query_detail.get("cached"):
|
|
|
+ execution_record["metadata"]["cache_hits"].append("generate_query")
|
|
|
+
|
|
|
+ # 2. Select Tool
|
|
|
+ tool_detail = self._read_json(cache_dir, 'function_knowledge', 'selected_tool.json')
|
|
|
+ if tool_detail:
|
|
|
+ execution_record["execution"]["select_tool"] = tool_detail
|
|
|
+ if tool_detail.get("cached"):
|
|
|
+ execution_record["metadata"]["cache_hits"].append("select_tool")
|
|
|
+
|
|
|
+ # 3. Check for Search or Tool Call
|
|
|
+ tool_call_detail = self._read_json(cache_dir, 'function_knowledge', 'tool_call.json')
|
|
|
|
|
|
- # 3. 收集 llm_search 的详情
|
|
|
- llm_detail = self._collect_llm_search_detail(cache_dir)
|
|
|
- if llm_detail:
|
|
|
- execution_record["execution"]["modules"]["llm_search"] = llm_detail
|
|
|
+ if tool_call_detail:
|
|
|
+ # Flow A: Tool Call
|
|
|
+
|
|
|
+ # Extract Params
|
|
|
+ params_detail = self._read_json(cache_dir, 'function_knowledge', 'extracted_params.json')
|
|
|
+ if params_detail:
|
|
|
+ execution_record["execution"]["extract_params"] = params_detail
|
|
|
+ if params_detail.get("cached"):
|
|
|
+ execution_record["metadata"]["cache_hits"].append("extract_params")
|
|
|
+
|
|
|
+ # Tool Call
|
|
|
+ execution_record["execution"]["tool_call"] = tool_call_detail
|
|
|
+ if tool_call_detail.get("cached"):
|
|
|
+ execution_record["metadata"]["cache_hits"].append("tool_call")
|
|
|
+
|
|
|
+ # Result
|
|
|
+ execution_record["output"]["result"] = tool_call_detail.get("result", "")
|
|
|
|
|
|
- # 4.设置结果信息
|
|
|
- result_detail = self._collect_result_detail(cache_dir)
|
|
|
- if result_detail:
|
|
|
- execution_record["result"] = result_detail
|
|
|
+ else:
|
|
|
+ # Flow B: Search (Multi/LLM)
|
|
|
+ search_detail = self._collect_search_detail(cache_dir)
|
|
|
+ if search_detail:
|
|
|
+ execution_record["execution"]["knowledge_search"] = search_detail
|
|
|
+
|
|
|
+ # Result
|
|
|
+ # merged_knowledge_detail from multi_search usually contains final response
|
|
|
+ merged_detail = search_detail.get("multi_search_merge")
|
|
|
+ if merged_detail:
|
|
|
+ execution_record["result"]["type"] = "knowledge_search"
|
|
|
+ response = merged_detail.get("response", "")
|
|
|
+ execution_record["result"]["content"] = response
|
|
|
+ execution_record["result"]["success"] = True
|
|
|
+ if merged_detail.get("cached"):
|
|
|
+ execution_record["metadata"]["cache_hits"].append("multi_search_merge")
|
|
|
|
|
|
- # 5. 计算总结信息
|
|
|
- self._calculate_summary(execution_record)
|
|
|
+ # Clean up metadata
|
|
|
+ # execution_time is retrieved from input_info if provided
|
|
|
|
|
|
logger.info("✓ 执行记录收集完成")
|
|
|
logger.info("=" * 60)
|
|
|
@@ -100,91 +127,63 @@ class ExecutionCollector:
|
|
|
execution_record["metadata"]["errors"].append(str(e))
|
|
|
|
|
|
return execution_record
|
|
|
-
|
|
|
- def _collect_function_knowledge_detail(self, cache_dir: str) -> Dict[str, Any]:
|
|
|
- """收集function_knowledge模块的详情"""
|
|
|
- detail_file = os.path.join(cache_dir, 'function_knowledge', 'execution_detail.json')
|
|
|
-
|
|
|
- if os.path.exists(detail_file):
|
|
|
- try:
|
|
|
- with open(detail_file, 'r', encoding='utf-8') as f:
|
|
|
- detail = json.load(f)
|
|
|
- logger.info(" ✓ 收集 function_knowledge 详情")
|
|
|
- return detail
|
|
|
- except Exception as e:
|
|
|
- logger.error(f" ✗ 读取 function_knowledge 详情失败: {e}")
|
|
|
-
|
|
|
- return None
|
|
|
-
|
|
|
- def _collect_multi_search_detail(self, cache_dir: str) -> Dict[str, Any]:
|
|
|
- """收集multi_search模块的详情"""
|
|
|
- detail_file = os.path.join(cache_dir, 'multi_search', 'execution_detail.json')
|
|
|
-
|
|
|
- if os.path.exists(detail_file):
|
|
|
- try:
|
|
|
- with open(detail_file, 'r', encoding='utf-8') as f:
|
|
|
- detail = json.load(f)
|
|
|
- logger.info(" ✓ 收集 multi_search 详情")
|
|
|
- return detail
|
|
|
- except Exception as e:
|
|
|
- logger.error(f" ✗ 读取 multi_search 详情失败: {e}")
|
|
|
-
|
|
|
- return None
|
|
|
-
|
|
|
- def _collect_llm_search_detail(self, cache_dir: str) -> Dict[str, Any]:
|
|
|
- """收集llm_search模块的详情"""
|
|
|
- detail_file = os.path.join(cache_dir, 'llm_search', 'execution_detail.json')
|
|
|
-
|
|
|
- if os.path.exists(detail_file):
|
|
|
- try:
|
|
|
- with open(detail_file, 'r', encoding='utf-8') as f:
|
|
|
- detail = json.load(f)
|
|
|
- logger.info(" ✓ 收集 llm_search 详情")
|
|
|
- return detail
|
|
|
- except Exception as e:
|
|
|
- logger.error(f" ✗ 读取 llm_search 详情失败: {e}")
|
|
|
-
|
|
|
- return None
|
|
|
-
|
|
|
- def _collect_result_detail(self, cache_dir: str) -> Dict[str, Any]:
|
|
|
- """收集result模块的详情"""
|
|
|
- detail_file = os.path.join(cache_dir, 'function_knowledge', 'tool_result.json')
|
|
|
|
|
|
- if os.path.exists(detail_file):
|
|
|
+ def _read_json(self, base_dir: str, *paths) -> Dict[str, Any]:
|
|
|
+ """读取JSON文件"""
|
|
|
+ file_path = os.path.join(base_dir, *paths)
|
|
|
+ if os.path.exists(file_path):
|
|
|
try:
|
|
|
- with open(detail_file, 'r', encoding='utf-8') as f:
|
|
|
- detail = json.load(f)
|
|
|
- logger.info(" ✓ 收集 result 详情")
|
|
|
- return detail
|
|
|
+ with open(file_path, 'r', encoding='utf-8') as f:
|
|
|
+ return json.load(f)
|
|
|
except Exception as e:
|
|
|
- logger.error(f" ✗ 读取 result 详情失败: {e}")
|
|
|
-
|
|
|
+ logger.warning(f"读取JSON文件失败 {file_path}: {e}")
|
|
|
return None
|
|
|
-
|
|
|
- def _calculate_summary(self, execution_record: Dict[str, Any]):
|
|
|
- """计算总结信息"""
|
|
|
- total_time = 0
|
|
|
- cache_hits = []
|
|
|
+
|
|
|
+ def _collect_search_detail(self, cache_dir: str) -> Dict[str, Any]:
|
|
|
+ """收集搜索流程详情"""
|
|
|
+ search_detail = {}
|
|
|
|
|
|
- # 遍历所有模块
|
|
|
- for module_name, module_detail in execution_record["execution"]["modules"].items():
|
|
|
- if "execution_time" in module_detail:
|
|
|
- total_time += module_detail["execution_time"]
|
|
|
-
|
|
|
- if "cache_hits" in module_detail:
|
|
|
- cache_hits.extend([f"{module_name}/{hit}" for hit in module_detail["cache_hits"]])
|
|
|
+ # 1. LLM Search
|
|
|
+ llm_detail = {}
|
|
|
|
|
|
- execution_record["metadata"]["execution_time"] = total_time
|
|
|
- execution_record["metadata"]["cache_hits"] = cache_hits
|
|
|
-
|
|
|
+ # Generated Queries
|
|
|
+ queries_detail = self._read_json(cache_dir, 'llm_search', 'generated_queries.json')
|
|
|
+ if queries_detail:
|
|
|
+ llm_detail["generated_queries"] = queries_detail
|
|
|
+
|
|
|
+ # Search Results
|
|
|
+ # Search for search_result_XXX.json
|
|
|
+ search_results = []
|
|
|
+ llm_search_dir = os.path.join(cache_dir, 'llm_search', 'search_results')
|
|
|
+ if os.path.exists(llm_search_dir):
|
|
|
+ for filename in sorted(os.listdir(llm_search_dir)):
|
|
|
+ if filename.endswith('.json') and filename.startswith('search_result_'):
|
|
|
+ res = self._read_json(llm_search_dir, filename)
|
|
|
+ if res:
|
|
|
+ search_results.append(res)
|
|
|
+ if search_results:
|
|
|
+ llm_detail["search_results"] = search_results
|
|
|
+
|
|
|
+ # Merge
|
|
|
+ merge_detail_llm = self._read_json(cache_dir, 'llm_search', 'merged_knowledge_detail.json')
|
|
|
+ if merge_detail_llm:
|
|
|
+ llm_detail["merge"] = merge_detail_llm
|
|
|
+
|
|
|
+ if llm_detail:
|
|
|
+ search_detail["llm_search"] = llm_detail
|
|
|
+
|
|
|
+ # 2. Multi Search Merge
|
|
|
+ merge_detail_multi = self._read_json(cache_dir, 'multi_search', 'merged_knowledge_detail.json')
|
|
|
+ if merge_detail_multi:
|
|
|
+ search_detail["multi_search_merge"] = merge_detail_multi
|
|
|
+
|
|
|
+ return search_detail if search_detail else None
|
|
|
+
|
|
|
def _create_empty_record(self, input_info: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
"""创建空的执行记录"""
|
|
|
return {
|
|
|
"input": input_info,
|
|
|
- "execution": {
|
|
|
- "steps": [],
|
|
|
- "modules": {}
|
|
|
- },
|
|
|
+ "execution": {},
|
|
|
"result": {
|
|
|
"type": "error",
|
|
|
"content": "缓存目录不存在",
|
|
|
@@ -255,5 +254,9 @@ if __name__ == "__main__":
|
|
|
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
|
|
|
- record = collect_and_save_execution_record(cache_key, input_info)
|
|
|
- print(json.dumps(record, ensure_ascii=False, indent=2))
|
|
|
+ # 注意:测试时需要确保缓存目录有数据,否则会返回空记录
|
|
|
+ try:
|
|
|
+ record = collect_and_save_execution_record(cache_key, input_info)
|
|
|
+ print(json.dumps(record, ensure_ascii=False, indent=2))
|
|
|
+ except Exception as e:
|
|
|
+ print(f"Test failed: {e}")
|