修复三个问题:1. 子图执行后的无限循环 2. llm_call没有输出 3. 思考打印两次
- 子图执行后直接进入finalize,避免回到react_reason循环 - llm_call节点检查是否已有final_result,避免重复调用LLM - 直接在react_reason_node中通过adispatch_custom_event发送推理事件,避免通过state传递导致重复
This commit is contained in:
@@ -16,6 +16,7 @@ from datetime import datetime
|
||||
# 导入我们的 intent.py
|
||||
from app.core.intent import (
|
||||
react_reason,
|
||||
react_reason_async,
|
||||
get_route_by_reasoning,
|
||||
ReasoningAction,
|
||||
ReasoningResult
|
||||
@@ -31,31 +32,17 @@ from app.logger import info
|
||||
|
||||
# ========== 1. React 推理节点 ==========
|
||||
|
||||
def react_reason_node(state: MainGraphState, config: Optional[Dict[str, Any]] = None) -> MainGraphState:
|
||||
async def react_reason_node(state: MainGraphState, config: Optional[Dict[str, Any]] = None) -> MainGraphState:
|
||||
"""
|
||||
React 模式推理节点:判断下一步做什么
|
||||
React 模式推理节点:判断下一步做什么(异步版本)
|
||||
|
||||
Returns: 更新后的状态
|
||||
"""
|
||||
state.current_phase = "react_reasoning"
|
||||
state.reasoning_step += 1
|
||||
|
||||
# 发送推理开始事件
|
||||
if config:
|
||||
try:
|
||||
from langchain_core.runnables.config import RunnableConfig
|
||||
# 尝试获取回调管理器并发送自定义事件
|
||||
callbacks = config.get("callbacks")
|
||||
if callbacks:
|
||||
from langchain_core.callbacks.manager import adispatch_custom_event
|
||||
# 注意:这是异步操作,我们需要特殊处理
|
||||
# 这里我们使用自定义流式写入器(如果存在)
|
||||
pass
|
||||
except Exception as e:
|
||||
info(f"[react_reason] 无法发送回调事件: {e}")
|
||||
|
||||
info(f"[react_reason] 第 {state.reasoning_step} 次推理开始")
|
||||
|
||||
|
||||
# 检查是否超过最大步数
|
||||
if state.reasoning_step > state.max_steps:
|
||||
state.current_phase = "max_steps_exceeded"
|
||||
@@ -66,7 +53,7 @@ def react_reason_node(state: MainGraphState, config: Optional[Dict[str, Any]] =
|
||||
)
|
||||
state.success = False
|
||||
return state
|
||||
|
||||
|
||||
# 准备上下文
|
||||
context = {
|
||||
"retrieved_docs": state.rag_docs,
|
||||
@@ -74,15 +61,35 @@ def react_reason_node(state: MainGraphState, config: Optional[Dict[str, Any]] =
|
||||
"messages": state.messages,
|
||||
"errors": state.errors
|
||||
}
|
||||
|
||||
# 使用 intent.py 进行推理
|
||||
# 注意:这里使用同步版本,内部会根据情况处理
|
||||
result: ReasoningResult = react_reason(state.user_query, context)
|
||||
|
||||
# 使用 intent.py 进行推理(现在直接用异步版本)
|
||||
result: ReasoningResult = await react_reason_async(state.user_query, context)
|
||||
|
||||
info(f"[react_reason] 推理结果: action={result.action.name}, confidence={result.confidence}")
|
||||
if result.reasoning:
|
||||
info(f"[react_reason] 推理过程: {result.reasoning}")
|
||||
|
||||
|
||||
# 关键修复:直接发送自定义事件给 agent_service,而不是通过 state
|
||||
if config:
|
||||
try:
|
||||
from langchain_core.callbacks.manager import adispatch_custom_event
|
||||
|
||||
callbacks = config.get("callbacks")
|
||||
if callbacks:
|
||||
info(f"[react_reason] 直接发送推理事件 #{state.reasoning_step}")
|
||||
await adispatch_custom_event(
|
||||
"react_reasoning",
|
||||
{
|
||||
"step": state.reasoning_step,
|
||||
"action": result.action.name,
|
||||
"confidence": result.confidence,
|
||||
"reasoning": result.reasoning
|
||||
},
|
||||
callbacks=callbacks
|
||||
)
|
||||
except Exception as e:
|
||||
info(f"[react_reason] 无法发送自定义事件: {e}")
|
||||
|
||||
# 记录推理历史
|
||||
state.reasoning_history.append({
|
||||
"step": state.reasoning_step,
|
||||
@@ -91,30 +98,24 @@ def react_reason_node(state: MainGraphState, config: Optional[Dict[str, Any]] =
|
||||
"reasoning": result.reasoning,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
|
||||
# 更新状态
|
||||
state.debug_info["last_reasoning"] = {
|
||||
"action": result.action.name,
|
||||
"confidence": result.confidence,
|
||||
"reasoning": result.reasoning
|
||||
}
|
||||
|
||||
|
||||
# 保存推理结果到状态
|
||||
state.debug_info["reasoning_result"] = result
|
||||
|
||||
|
||||
# 确定下一步动作
|
||||
state.last_action = result.action.name
|
||||
|
||||
# 发送推理完成事件(通过状态更新,agent_service 会处理)
|
||||
# 我们在状态中保存推理内容,以便 agent_service 可以通过 state_update 事件发送
|
||||
state.debug_info["latest_reasoning"] = {
|
||||
"step": state.reasoning_step,
|
||||
"action": result.action.name,
|
||||
"confidence": result.confidence,
|
||||
"reasoning": result.reasoning,
|
||||
"sent": False # 标记是否已发送到前端
|
||||
}
|
||||
|
||||
# 关键修复:不再设置 latest_reasoning,避免 agent_service 重复读取
|
||||
if "latest_reasoning" in state.debug_info:
|
||||
del state.debug_info["latest_reasoning"]
|
||||
|
||||
return state
|
||||
|
||||
|
||||
@@ -300,6 +301,16 @@ def route_by_reasoning(state: MainGraphState) -> str:
|
||||
if state.retry_action and "rag" in state.retry_action.lower():
|
||||
return "rag_retrieve"
|
||||
return "react_reason"
|
||||
|
||||
# 关键修复:检查是否已经执行过子图,如果是,直接去 llm_call
|
||||
previous_actions = [h.get("action") for h in state.reasoning_history]
|
||||
if "subgraph_completed" in previous_actions or state.final_result:
|
||||
return "llm_call"
|
||||
|
||||
# 检查是否刚刚执行完 rag 或 web search,应该继续推理一次然后去 llm_call
|
||||
# 但为了避免死循环,我们设置一个简单的规则
|
||||
if len(previous_actions) > 3:
|
||||
return "llm_call"
|
||||
|
||||
# 获取推理结果
|
||||
reasoning_result: Optional[ReasoningResult] = state.debug_info.get("reasoning_result")
|
||||
|
||||
Reference in New Issue
Block a user