# backend/app/agent/hybrid_router.py from enum import Enum from typing import Optional, List, Dict, Any from dataclasses import dataclass import sys import os # 添加项目路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) from app.agent.intent_classifier import IntentClassifier, IntentType, get_intent_classifier class RouterAction(Enum): """路由动作""" FAST_RAG = "fast_rag" # 快速 RAG 路径 FAST_TOOL = "fast_tool" # 快速工具路径 REACT_LOOP = "react_loop" # React 循环路径 DIRECT_ANSWER = "direct_answer" # 直接回答 CLARIFY = "clarify" # 澄清反问 @dataclass class RouterDecision: """路由决策结果""" action: RouterAction intent: IntentType confidence: float reasoning: str metadata: Dict[str, Any] = None class HybridRouter: """混合路由决策器""" def __init__( self, intent_classifier: IntentClassifier, rag_pipeline = None, tool_registry: Dict[str, Any] = None, react_graph = None ): self.classifier = intent_classifier self.rag = rag_pipeline self.tools = tool_registry or {} self.react_graph = react_graph async def route(self, user_input: str, context: Optional[str] = None) -> RouterDecision: """ 路由决策 Args: user_input: 用户输入 context: 对话上下文 Returns: RouterDecision """ # 1. 意图分类 intent_result = await self.classifier.classify(user_input, context) # 2. 根据意图路由 decision = self._make_decision(intent_result, user_input) return decision def _make_decision(self, intent_result: IntentResult, user_input: str) -> RouterDecision: """根据意图做出路由决策""" intent = intent_result.intent_type confidence = intent_result.confidence # 低置信度 → 走 React 循环(更安全) if confidence < 0.6: return RouterDecision( action=RouterAction.REACT_LOOP, intent=intent, confidence=confidence, reasoning=f"置信度 {confidence:.2f} 较低,走 React 循环" ) # 根据意图路由 routing_map = { IntentType.KNOWLEDGE: RouterAction.FAST_RAG, IntentType.REALTIME: RouterAction.FAST_TOOL, IntentType.ACTION: RouterAction.FAST_TOOL, IntentType.CHITCHAT: RouterAction.DIRECT_ANSWER, IntentType.CLARIFY: RouterAction.CLARIFY, IntentType.MIXED: RouterAction.REACT_LOOP, IntentType.UNKNOWN: RouterAction.REACT_LOOP, } action = routing_map.get(intent, RouterAction.REACT_LOOP) return RouterDecision( action=action, intent=intent, confidence=confidence, reasoning=intent_result.reasoning ) async def execute(self, decision: RouterDecision, user_input: str, thread_id: str) -> str: """ 根据决策执行对应路径 Args: decision: 路由决策 user_input: 用户输入 thread_id: 线程 ID Returns: 最终答案 """ if decision.action == RouterAction.FAST_RAG: return await self._execute_fast_rag(user_input) elif decision.action == RouterAction.FAST_TOOL: return await self._execute_fast_tool(user_input) elif decision.action == RouterAction.DIRECT_ANSWER: return await self._execute_direct_answer(user_input) elif decision.action == RouterAction.CLARIFY: return await self._execute_clarify(user_input) elif decision.action == RouterAction.REACT_LOOP: return await self._execute_react_loop(user_input, thread_id) else: return await self._execute_react_loop(user_input, thread_id) async def _execute_fast_rag(self, user_input: str) -> str: """快速 RAG 路径""" print("🚀 执行快速 RAG 路径") # 1. 检索文档(如果 RAG 可用) docs = [] if self.rag and hasattr(self.rag, 'aretrieve'): docs = await self.rag.aretrieve(user_input) # 2. 格式化上下文 context = "" if self.rag and hasattr(self.rag, 'format_context'): context = self.rag.format_context(docs) # 3. 生成回答 prompt = f""" 请根据以下文档回答用户问题。 参考文档: {context or "(无文档)"} 用户问题: {user_input} """ response = await self.classifier.llm.ainvoke(prompt) return response.content async def _execute_fast_tool(self, user_input: str) -> str: """快速工具路径""" print("🚀 执行快速工具路径") # 这里简化处理,实际项目中: # 1. 解析需要调用的工具 # 2. 生成工具参数 # 3. 执行工具 # 4. 生成回答 return "快速工具路径:功能开发中..." async def _execute_direct_answer(self, user_input: str) -> str: """直接回答路径""" print("💬 执行直接回答路径") prompt = f""" 用户说: {user_input} 请友好回应。 """ response = await self.classifier.llm.ainvoke(prompt) return response.content async def _execute_clarify(self, user_input: str) -> str: """澄清反问路径""" print("❓ 执行澄清反问路径") prompt = f""" 用户说: {user_input} 用户的问题不太明确,请礼貌地询问更多细节。 """ response = await self.classifier.llm.ainvoke(prompt) return response.content async def _execute_react_loop(self, user_input: str, thread_id: str) -> str: """React 循环路径""" print("🔄 执行 React 循环路径") # 这里调用现有的完整 LangGraph 流程 # 具体实现根据您的项目结构 return "React 循环路径:调用现有 LangGraph..." # 便捷函数 async def hybrid_agent_route( user_input: str, thread_id: str, context: Optional[str] = None ) -> str: """ 混合 Agent 路由入口函数 Args: user_input: 用户输入 thread_id: 线程 ID context: 对话上下文 Returns: 最终答案 """ # 获取依赖(实际项目应该用依赖注入) classifier = get_intent_classifier() # rag = get_rag_pipeline() # tools = get_tool_registry() # graph = get_react_graph() # 创建路由器 router = HybridRouter( intent_classifier=classifier, rag_pipeline=None, # 实际项目中传入 tool_registry={}, # 实际项目中传入 react_graph=None # 实际项目中传入 ) # 路由决策 decision = await router.route(user_input, context) print(f"🧭 路由决策: {decision.action} (意图: {decision.intent}, 置信度: {decision.confidence:.2f})") print(f"📝 推理: {decision.reasoning}") # 执行 # result = await router.execute(decision, user_input, thread_id) # return result # 临时返回 return f"路由决策: {decision.action}"