diff --git a/backend/app/main_graph/nodes/hybrid_router.py b/backend/app/main_graph/nodes/hybrid_router.py index dc41b92..beaa30c 100644 --- a/backend/app/main_graph/nodes/hybrid_router.py +++ b/backend/app/main_graph/nodes/hybrid_router.py @@ -30,6 +30,7 @@ class HybridRouterResult: suggested_tools: list = field(default_factory=list) path: str = "react_loop" # fast_chitchat / fast_rag / fast_tool / react_loop reasoning: str = "" + reasoning_result: Optional[ReasoningResult] = None # 保存完整的 ReasoningResult,用于复用! # ========== 规则配置 ========== @@ -87,7 +88,8 @@ def _map_reasoning_to_router(reasoning_result: ReasoningResult) -> HybridRouterR confidence=reasoning_result.confidence, suggested_tools=suggested_tools, path=path, - reasoning=reasoning_result.reasoning + reasoning=reasoning_result.reasoning, + reasoning_result=reasoning_result # 保存完整结果! ) diff --git a/backend/app/main_graph/nodes/reasoning.py b/backend/app/main_graph/nodes/reasoning.py index 92ed312..ccf231d 100644 --- a/backend/app/main_graph/nodes/reasoning.py +++ b/backend/app/main_graph/nodes/reasoning.py @@ -7,8 +7,8 @@ from typing import Optional from datetime import datetime from langchain_core.runnables.config import RunnableConfig -from backend.app.core.intent import react_reason_async, ReasoningResult -from ...main_graph.state import MainGraphState +from backend.app.core.intent import react_reason_async, ReasoningResult, ReasoningAction +from ..state import MainGraphState from backend.app.logger import info from ._utils import dispatch_custom_event, make_react_event @@ -20,6 +20,55 @@ async def react_reason_node(state: MainGraphState, config: Optional[RunnableConf info(f"[推理] 第 {state.reasoning_step} 次推理开始") + # ================================================== + # 优化:如果是第一次推理,检查 hybrid_router 的结果! + # 避免重复推理! + # ================================================== + if state.reasoning_step == 1 and state.hybrid_router.decision and state.hybrid_router.decision.reasoning_result: + # 有保存的推理结果,直接复用! + decision = state.hybrid_router.decision + result: ReasoningResult = decision.reasoning_result + + info(f"[推理] 第1次推理,复用 hybrid_router 结果: action={result.action.name}, confidence={result.confidence}") + if result.reasoning: + info(f"[推理] 推理过程: {result.reasoning}") + + # 记录推理历史 + state.reasoning_history.append({ + "step": state.reasoning_step, + "action": result.action.name, + "confidence": result.confidence, + "reasoning": result.reasoning, + "timestamp": datetime.now().isoformat() + }) + + # 更新状态 + state.react_reasoning.last_reasoning = { + "action": result.action.name, + "confidence": result.confidence, + "reasoning": result.reasoning + } + state.react_reasoning.reasoning_result = result + state.last_action = result.action.name + + # 发送推理事件 + await dispatch_custom_event( + "react_reasoning", + make_react_event( + state.reasoning_step, + result.action.name, + result.confidence, + result.reasoning + ), + config + ) + + return state + + # ================================================== + # 原来的逻辑(第二次推理或没有保存结果时使用) + # ================================================== + # 步骤1: 准备上下文 context = { "retrieved_docs": state.rag_docs, @@ -47,7 +96,7 @@ async def react_reason_node(state: MainGraphState, config: Optional[RunnableConf "timestamp": datetime.now().isoformat() }) - # 步骤3: 更新状态 - 只使用新的结构化字段 + # 步骤4: 更新状态 - 只使用新的结构化字段 state.react_reasoning.last_reasoning = { "action": result.action.name, "confidence": result.confidence,