""" 联网搜索节点 - 执行搜索并将结果保存到状态 """ from typing import Optional from datetime import datetime from langchain_core.runnables.config import RunnableConfig from ...main_graph.state import MainGraphState, ErrorRecord, ErrorSeverity from ...logger import info async def web_search_node(state: MainGraphState, config: Optional[RunnableConfig] = None) -> MainGraphState: """ 联网搜索节点:执行搜索并将结果保存到状态 """ state.current_phase = "web_searching" # 发送开始事件 if config: try: from langchain_core.callbacks.manager import adispatch_custom_event callbacks = config.get("callbacks") if callbacks: await adispatch_custom_event( "react_reasoning", { "step": state.reasoning_step, "action": "web_search_start", "confidence": 1.0, "reasoning": "开始执行联网搜索..." }, callbacks=callbacks ) except Exception as e: info(f"[web_search_node] 无法发送开始事件: {e}") # 获取搜索查询 reasoning_result = state.debug_info.get("reasoning_result") search_query = reasoning_result.metadata.get("search_query", state.user_query) if reasoning_result else state.user_query try: from backend.app.core import web_search print(f"[WebSearch] 搜索: {search_query}") search_result = web_search(search_query, max_results=5) # 保存搜索结果到状态 if not hasattr(state, "web_search_results"): state.web_search_results = [] state.web_search_results.append(search_result) # 将搜索结果添加到 rag_context,供 LLM 使用 if state.rag_context: state.rag_context = f"{state.rag_context}\n\n---\n\n## 🌐 联网搜索结果:\n{search_result}" else: state.rag_context = f"## 🌐 联网搜索结果:\n{search_result}" state.success = True print(f"[WebSearch] 搜索完成") # 发送完成事件 if config: try: from langchain_core.callbacks.manager import adispatch_custom_event callbacks = config.get("callbacks") if callbacks: await adispatch_custom_event( "react_reasoning", { "step": state.reasoning_step, "action": "web_search_complete", "confidence": 1.0, "reasoning": f"联网搜索完成,找到 {len(search_result) if isinstance(search_result, list) else 1} 条结果" }, callbacks=callbacks ) except Exception as e: info(f"[web_search_node] 无法发送完成事件: {e}") except Exception as e: error_record = ErrorRecord( error_type="WebSearchError", error_message=str(e), severity=ErrorSeverity.WARNING, source="web_search_node", timestamp=datetime.now().isoformat(), retry_count=0, max_retries=2, context={"search_query": search_query} ) state.errors.append(error_record) state.current_error = error_record state.current_phase = "error_handling" state.success = False # 发送错误事件 if config: try: from langchain_core.callbacks.manager import adispatch_custom_event callbacks = config.get("callbacks") if callbacks: await adispatch_custom_event( "react_reasoning", { "step": state.reasoning_step, "action": "web_search_error", "confidence": 1.0, "reasoning": f"联网搜索失败: {str(e)}" }, callbacks=callbacks ) except Exception as e: info(f"[web_search_node] 无法发送错误事件: {e}") return state