[modify] multi agent orchestrator

This commit is contained in:
Mark
2026-01-07 17:48:17 +08:00
parent cd76ccadc5
commit fc56e1b624
6 changed files with 272 additions and 125 deletions

View File

@@ -13,10 +13,9 @@ from app.schemas import ModelParameters
class OrchestrationMode(StrEnum): class OrchestrationMode(StrEnum):
"""图标类型枚举""" """协作模式枚举"""
SEQUENTIAL = "sequential" COLLABORATION = "collaboration" # 协作模式Agent 之间可以相互 handoff
PARALLEL = "parallel" SUPERVISOR = "supervisor" # 监督模式:由主 Agent 统一调度子 Agent
CONDITIONAL = "conditional"
class AggregationStrategy(StrEnum): class AggregationStrategy(StrEnum):
"""图标类型枚举""" """图标类型枚举"""
@@ -66,8 +65,8 @@ class MultiAgentConfig(Base):
orchestration_mode = Column( orchestration_mode = Column(
String(20), String(20),
nullable=False, nullable=False,
default="conditional", default="collaboration",
comment="协作模式: sequential|parallel|conditional|loop" comment="协作模式: collaboration协作| supervisor监督"
) )
# 子 Agent 列表 # 子 Agent 列表

View File

@@ -66,9 +66,9 @@ class MultiAgentConfigCreate(BaseModel):
master_agent_id: uuid.UUID = Field(..., description="主 Agent ID") master_agent_id: uuid.UUID = Field(..., description="主 Agent ID")
master_agent_name: Optional[str] = Field(None, max_length=100, description="主 Agent 名称") master_agent_name: Optional[str] = Field(None, max_length=100, description="主 Agent 名称")
orchestration_mode: str = Field( orchestration_mode: str = Field(
..., default="collaboration",
pattern="^(sequential|parallel|conditional|loop)$", pattern="^(collaboration|supervisor)$",
description="编排模式:sequential|parallel|conditional|loop" description="协作模式:collaboration协作| supervisor监督"
) )
sub_agents: List[SubAgentConfig] = Field(..., description="子 Agent 列表") sub_agents: List[SubAgentConfig] = Field(..., description="子 Agent 列表")
routing_rules: Optional[List[RoutingRule]] = Field(None, description="路由规则") routing_rules: Optional[List[RoutingRule]] = Field(None, description="路由规则")
@@ -90,8 +90,9 @@ class MultiAgentConfigUpdate(BaseModel):
description="模型参数配置temperature、max_tokens 等)" description="模型参数配置temperature、max_tokens 等)"
) )
orchestration_mode: Optional[str] = Field( orchestration_mode: Optional[str] = Field(
None, default="collaboration",
pattern="^(sequential|parallel|conditional|loop)$" pattern="^(collaboration|supervisor)$",
description="协作模式collaboration协作| supervisor监督"
) )
sub_agents: Optional[List[SubAgentConfig]] = None sub_agents: Optional[List[SubAgentConfig]] = None
routing_rules: Optional[List[RoutingRule]] = None routing_rules: Optional[List[RoutingRule]] = None

View File

@@ -275,12 +275,7 @@ class AppService:
) )
logger.info( logger.info(
"多智能体配置检查通过", "多智能体配置检查通过"
extra={
"app_id": str(app_id),
"master_agent_id": str(multi_agent_config.master_agent_id),
"sub_agent_count": len(multi_agent_config.sub_agents)
}
) )
def _create_agent_config( def _create_agent_config(

View File

@@ -537,7 +537,7 @@ class CollaborativeOrchestrator:
}) })
# 提取 usage # 提取 usage
if hasattr(response, 'usage_metadata'): if hasattr(response, 'usage_metadata') and response.usage_metadata:
result["usage"] = { result["usage"] = {
"prompt_tokens": response.usage_metadata.get("input_tokens", 0), "prompt_tokens": response.usage_metadata.get("input_tokens", 0),
"completion_tokens": response.usage_metadata.get("output_tokens", 0), "completion_tokens": response.usage_metadata.get("output_tokens", 0),

View File

@@ -13,16 +13,17 @@ from app.schemas.multi_agent_schema import MultiAgentRunRequest
from app.core.logging_config import get_business_logger from app.core.logging_config import get_business_logger
from app.core.exceptions import BusinessException from app.core.exceptions import BusinessException
from app.core.error_codes import BizCode from app.core.error_codes import BizCode
from app.services.multi_agent_service import MultiAgentService
logger = get_business_logger() logger = get_business_logger()
class MultiAgentHandoffsService: class MultiAgentHandoffsService:
"""Multi-Agent Handoffs 服务 - 扩展现有的 Multi-Agent Service""" """Multi-Agent Handoffs 服务 - 扩展现有的 Multi-Agent Service"""
def __init__(self, db: Session, multi_agent_service): def __init__(self, db: Session, multi_agent_service:MultiAgentService):
"""初始化服务 """初始化服务
Args: Args:
db: 数据库会话 db: 数据库会话
multi_agent_service: 现有的 MultiAgentService 实例 multi_agent_service: 现有的 MultiAgentService 实例
@@ -30,25 +31,25 @@ class MultiAgentHandoffsService:
self.db = db self.db = db
self.multi_agent_service = multi_agent_service self.multi_agent_service = multi_agent_service
self.handoff_manager = get_handoff_manager() self.handoff_manager = get_handoff_manager()
logger.info("Multi-Agent Handoffs 服务初始化完成") logger.info("Multi-Agent Handoffs 服务初始化完成")
async def run_with_handoffs( async def run_with_handoffs(
self, self,
app_id: uuid.UUID, app_id: uuid.UUID,
request: MultiAgentRunRequest request: MultiAgentRunRequest
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""运行支持 handoffs 的多 Agent 任务 """运行支持 handoffs 的多 Agent 任务
Args: Args:
app_id: 应用 ID app_id: 应用 ID
request: 运行请求 request: 运行请求
Returns: Returns:
执行结果 执行结果
""" """
start_time = time.time() start_time = time.time()
try: try:
# 1. 获取配置 # 1. 获取配置
config = self.multi_agent_service.get_config(app_id) config = self.multi_agent_service.get_config(app_id)
@@ -57,23 +58,25 @@ class MultiAgentHandoffsService:
"多 Agent 配置不存在", "多 Agent 配置不存在",
BizCode.RESOURCE_NOT_FOUND BizCode.RESOURCE_NOT_FOUND
) )
# 2. 检查是否启用 handoffs # 2. 检查是否启用 handoffs
execution_config = config.execution_config or {} execution_config = config.execution_config or {}
print("="*50)
print(execution_config)
enable_handoffs = execution_config.get("enable_handoffs", False) enable_handoffs = execution_config.get("enable_handoffs", False)
if not enable_handoffs: if not enable_handoffs:
# 降级到普通模式 # 降级到普通模式
logger.info("Handoffs 未启用,使用普通模式") logger.info("Handoffs 未启用,使用普通模式")
return await self.multi_agent_service.run(app_id, request) return await self.multi_agent_service.run(app_id, request)
# 3. 创建协作编排器 # 3. 创建协作编排器
orchestrator = CollaborativeOrchestrator( orchestrator = CollaborativeOrchestrator(
db=self.db, db=self.db,
config=config, config=config,
handoff_manager=self.handoff_manager handoff_manager=self.handoff_manager
) )
# 4. 执行协作 # 4. 执行协作
result = await orchestrator.execute_with_handoffs( result = await orchestrator.execute_with_handoffs(
message=request.message, message=request.message,
@@ -81,11 +84,11 @@ class MultiAgentHandoffsService:
user_id=request.user_id, user_id=request.user_id,
variables=request.variables variables=request.variables
) )
# 5. 增强结果 # 5. 增强结果
result["mode"] = "handoffs" result["mode"] = "handoffs"
result["elapsed_time"] = time.time() - start_time result["elapsed_time"] = time.time() - start_time
logger.info( logger.info(
"Handoffs 执行完成", "Handoffs 执行完成",
extra={ extra={
@@ -95,27 +98,27 @@ class MultiAgentHandoffsService:
"elapsed_time": result["elapsed_time"] "elapsed_time": result["elapsed_time"]
} }
) )
return result return result
except Exception as e: except Exception as e:
logger.error(f"Handoffs 执行失败: {str(e)}") logger.error(f"Handoffs 执行失败: {str(e)}")
# 降级到普通模式 # 降级到普通模式
logger.info("降级到普通模式") logger.info("降级到普通模式")
return await self.multi_agent_service.run(app_id, request) return await self.multi_agent_service.run(app_id, request)
async def run_stream_with_handoffs( async def run_stream_with_handoffs(
self, self,
app_id: uuid.UUID, app_id: uuid.UUID,
request: MultiAgentRunRequest request: MultiAgentRunRequest
) -> AsyncGenerator[str, None]: ) -> AsyncGenerator[str, None]:
"""流式运行支持 handoffs 的多 Agent 任务 """流式运行支持 handoffs 的多 Agent 任务
Args: Args:
app_id: 应用 ID app_id: 应用 ID
request: 运行请求 request: 运行请求
Yields: Yields:
SSE 格式的事件流 SSE 格式的事件流
""" """
@@ -125,24 +128,24 @@ class MultiAgentHandoffsService:
if not config: if not config:
yield f"data: {{\"event\": \"error\", \"error\": \"配置不存在\"}}\n\n" yield f"data: {{\"event\": \"error\", \"error\": \"配置不存在\"}}\n\n"
return return
# 2. 检查是否启用 handoffs # 2. 检查是否启用 handoffs
execution_config = config.execution_config or {} execution_config = config.execution_config or {}
enable_handoffs = execution_config.get("enable_handoffs", False) enable_handoffs = execution_config.get("enable_handoffs", False)
if not enable_handoffs: if not enable_handoffs:
# 降级到普通流式模式 # 降级到普通流式模式
async for event in self.multi_agent_service.run_stream(app_id, request): async for event in self.multi_agent_service.run_stream(app_id, request):
yield event yield event
return return
# 3. 创建协作编排器 # 3. 创建协作编排器
orchestrator = CollaborativeOrchestrator( orchestrator = CollaborativeOrchestrator(
db=self.db, db=self.db,
config=config, config=config,
handoff_manager=self.handoff_manager handoff_manager=self.handoff_manager
) )
# 4. 流式执行 # 4. 流式执行
async for event in orchestrator.execute_stream_with_handoffs( async for event in orchestrator.execute_stream_with_handoffs(
message=request.message, message=request.message,
@@ -151,27 +154,27 @@ class MultiAgentHandoffsService:
variables=request.variables variables=request.variables
): ):
yield event yield event
except Exception as e: except Exception as e:
logger.error(f"流式 Handoffs 执行失败: {str(e)}") logger.error(f"流式 Handoffs 执行失败: {str(e)}")
yield f"data: {{\"event\": \"error\", \"error\": \"{str(e)}\"}}\n\n" yield f"data: {{\"event\": \"error\", \"error\": \"{str(e)}\"}}\n\n"
def get_handoff_history( def get_handoff_history(
self, self,
conversation_id: str conversation_id: str
) -> Optional[Dict[str, Any]]: ) -> Optional[Dict[str, Any]]:
"""获取会话的 handoff 历史 """获取会话的 handoff 历史
Args: Args:
conversation_id: 会话 ID conversation_id: 会话 ID
Returns: Returns:
Handoff 历史信息 Handoff 历史信息
""" """
state = self.handoff_manager.get_state(conversation_id) state = self.handoff_manager.get_state(conversation_id)
if not state: if not state:
return None return None
return { return {
"conversation_id": state.conversation_id, "conversation_id": state.conversation_id,
"current_agent_id": state.current_agent_id, "current_agent_id": state.current_agent_id,
@@ -190,27 +193,27 @@ class MultiAgentHandoffsService:
"created_at": state.created_at.isoformat(), "created_at": state.created_at.isoformat(),
"updated_at": state.updated_at.isoformat() "updated_at": state.updated_at.isoformat()
} }
def clear_handoff_state(self, conversation_id: str): def clear_handoff_state(self, conversation_id: str):
"""清除会话的 handoff 状态 """清除会话的 handoff 状态
Args: Args:
conversation_id: 会话 ID conversation_id: 会话 ID
""" """
self.handoff_manager.clear_state(conversation_id) self.handoff_manager.clear_state(conversation_id)
logger.info(f"清除 handoff 状态: {conversation_id}") logger.info(f"清除 handoff 状态: {conversation_id}")
async def test_handoff_routing( async def test_handoff_routing(
self, self,
app_id: uuid.UUID, app_id: uuid.UUID,
message: str message: str
) -> Dict[str, Any]: ) -> Dict[str, Any]:
"""测试 handoff 路由决策(不实际执行) """测试 handoff 路由决策(不实际执行)
Args: Args:
app_id: 应用 ID app_id: 应用 ID
message: 测试消息 message: 测试消息
Returns: Returns:
路由决策结果 路由决策结果
""" """
@@ -221,7 +224,7 @@ class MultiAgentHandoffsService:
"多 Agent 配置不存在", "多 Agent 配置不存在",
BizCode.RESOURCE_NOT_FOUND BizCode.RESOURCE_NOT_FOUND
) )
# 2. 解析 sub agents # 2. 解析 sub agents
sub_agents = {} sub_agents = {}
for agent_data in config.sub_agents: for agent_data in config.sub_agents:
@@ -230,37 +233,37 @@ class MultiAgentHandoffsService:
sub_agents[str(agent_id)] = { sub_agents[str(agent_id)] = {
"info": agent_data "info": agent_data
} }
# 3. 测试路由 # 3. 测试路由
test_conversation_id = f"test-{uuid.uuid4()}" test_conversation_id = f"test-{uuid.uuid4()}"
# 选择初始 Agent # 选择初始 Agent
initial_agent_id = None initial_agent_id = None
message_lower = message.lower() message_lower = message.lower()
for agent_id, agent_data in sub_agents.items(): for agent_id, agent_data in sub_agents.items():
agent_info = agent_data.get("info", {}) agent_info = agent_data.get("info", {})
capabilities = agent_info.get("capabilities", []) capabilities = agent_info.get("capabilities", [])
role = agent_info.get("role", "") role = agent_info.get("role", "")
keywords = capabilities + ([role] if role else []) keywords = capabilities + ([role] if role else [])
for keyword in keywords: for keyword in keywords:
if keyword.lower() in message_lower: if keyword.lower() in message_lower:
initial_agent_id = agent_id initial_agent_id = agent_id
break break
if initial_agent_id: if initial_agent_id:
break break
if not initial_agent_id: if not initial_agent_id:
initial_agent_id = next(iter(sub_agents.keys())) initial_agent_id = next(iter(sub_agents.keys()))
# 4. 生成 handoff 工具 # 4. 生成 handoff 工具
handoff_tools = self.handoff_manager.generate_handoff_tools( handoff_tools = self.handoff_manager.generate_handoff_tools(
initial_agent_id, initial_agent_id,
sub_agents sub_agents
) )
# 5. 检查是否需要 handoff # 5. 检查是否需要 handoff
handoff_suggestion = self.handoff_manager.should_handoff( handoff_suggestion = self.handoff_manager.should_handoff(
conversation_id=test_conversation_id, conversation_id=test_conversation_id,
@@ -268,7 +271,7 @@ class MultiAgentHandoffsService:
message=message, message=message,
available_agents=sub_agents available_agents=sub_agents
) )
return { return {
"message": message, "message": message,
"initial_agent_id": initial_agent_id, "initial_agent_id": initial_agent_id,

View File

@@ -31,6 +31,10 @@ class MultiAgentOrchestrator:
self.config = config self.config = config
self.registry = AgentRegistry(db) self.registry = AgentRegistry(db)
# 兼容处理:旧的 orchestration_mode 值映射到新值
# collaboration | supervisor 是新值,其他旧值默认使用 supervisor
self._normalized_mode = self._normalize_orchestration_mode(config.orchestration_mode)
# 加载主 Agent # 加载主 Agent
# self.master_agent = self._load_agent(config.master_agent_id) # self.master_agent = self._load_agent(config.master_agent_id)
# self. config.d # self. config.d
@@ -73,10 +77,25 @@ class MultiAgentOrchestrator:
extra={ extra={
"config_id": str(config.id), "config_id": str(config.id),
"model": self.master_model_config.name, "model": self.master_model_config.name,
"sub_agent_count": len(self.sub_agents) "sub_agent_count": len(self.sub_agents),
"orchestration_mode": self._normalized_mode
} }
) )
def _normalize_orchestration_mode(self, mode: str) -> str:
"""标准化 orchestration_mode兼容旧值
Args:
mode: 原始的 orchestration_mode 值
Returns:
标准化后的模式collaboration 或 supervisor
"""
if mode in [OrchestrationMode.SUPERVISOR, "supervisor"]:
return OrchestrationMode.SUPERVISOR
# 其他所有值(包括旧的 sequential、parallel、conditional、loop 和 collaboration都映射到 collaboration
return OrchestrationMode.COLLABORATION
async def execute_stream( async def execute_stream(
self, self,
message: str, message: str,
@@ -108,7 +127,7 @@ class MultiAgentOrchestrator:
logger.info( logger.info(
"开始执行多 Agent 任务(流式)", "开始执行多 Agent 任务(流式)",
extra={ extra={
"mode": self.config.orchestration_mode, "mode": self._normalized_mode,
"message_length": len(message) "message_length": len(message)
} }
) )
@@ -116,7 +135,7 @@ class MultiAgentOrchestrator:
try: try:
# 发送开始事件 # 发送开始事件
yield self._format_sse_event("start", { yield self._format_sse_event("start", {
"mode": self.config.orchestration_mode, "mode": self._normalized_mode,
"timestamp": time.time() "timestamp": time.time()
}) })
@@ -125,7 +144,8 @@ class MultiAgentOrchestrator:
task_analysis["use_llm_routing"] = use_llm_routing task_analysis["use_llm_routing"] = use_llm_routing
# 2. 根据模式执行(流式) # 2. 根据模式执行(流式)
if self.config.orchestration_mode == OrchestrationMode.CONDITIONAL: # Supervisor 模式:由主 Agent 统一调度子 Agent
if self._normalized_mode == OrchestrationMode.SUPERVISOR:
async for event in self._execute_conditional_stream( async for event in self._execute_conditional_stream(
task_analysis, task_analysis,
conversation_id, conversation_id,
@@ -136,63 +156,23 @@ class MultiAgentOrchestrator:
user_rag_memory_id user_rag_memory_id
): ):
yield event yield event
# Collaboration 模式Agent 之间可以相互 handoff使用 handoffs_service
elif self._normalized_mode == OrchestrationMode.COLLABORATION:
async for event in self._execute_collaboration_mode_stream(
task_analysis,
conversation_id,
user_id,
web_search,
memory,
storage_type,
user_rag_memory_id
):
yield event
else: else:
# 其他模式暂时使用非流式执行,然后一次性返回 raise BusinessException(
if self.config.orchestration_mode == OrchestrationMode.SEQUENTIAL: f"不支持的编排模式: {self._normalized_mode}",
results = await self._execute_sequential( BizCode.INVALID_PARAMETER
task_analysis, )
conversation_id,
user_id,
web_search,
memory,
storage_type,
user_rag_memory_id
)
elif self.config.orchestration_mode == OrchestrationMode.PARALLEL:
results = await self._execute_parallel(
task_analysis,
conversation_id,
user_id,
web_search,
memory,
storage_type,
user_rag_memory_id
)
# elif self.config.orchestration_mode == "loop":
# results = await self._execute_loop(
# task_analysis,
# conversation_id,
# user_id,
# web_search,
# memory,
# storage_type,
# user_rag_memory_id
# )
else:
raise BusinessException(
f"不支持的编排模式: {self.config.orchestration_mode}",
BizCode.INVALID_PARAMETER
)
# 整合结果
final_result = await self._aggregate_results(results)
# 提取会话 ID
sub_conversation_id = None
if isinstance(results, dict):
sub_conversation_id = results.get("conversation_id") or results.get("result", {}).get("conversation_id")
elif isinstance(results, list) and results:
for item in results:
if "result" in item:
sub_conversation_id = item["result"].get("conversation_id")
if sub_conversation_id:
break
# 发送消息事件
yield self._format_sse_event("message", {
"content": final_result,
"conversation_id": sub_conversation_id
})
elapsed_time = time.time() - start_time elapsed_time = time.time() - start_time
@@ -205,7 +185,7 @@ class MultiAgentOrchestrator:
logger.info( logger.info(
"多 Agent 任务完成(流式)", "多 Agent 任务完成(流式)",
extra={ extra={
"mode": self.config.orchestration_mode, "mode": self._normalized_mode,
"elapsed_time": elapsed_time "elapsed_time": elapsed_time
} }
) )
@@ -213,7 +193,7 @@ class MultiAgentOrchestrator:
except Exception as e: except Exception as e:
logger.error( logger.error(
"多 Agent 任务执行失败(流式)", "多 Agent 任务执行失败(流式)",
extra={"error": str(e), "mode": self.config.orchestration_mode} extra={"error": str(e), "mode": self._normalized_mode}
) )
# 发送错误事件 # 发送错误事件
yield self._format_sse_event("error", { yield self._format_sse_event("error", {
@@ -247,10 +227,23 @@ class MultiAgentOrchestrator:
logger.info( logger.info(
"开始执行多 Agent 任务", "开始执行多 Agent 任务",
extra={"message_length": len(message)} extra={
"message_length": len(message),
"mode": self._normalized_mode
}
) )
try: try:
# Collaboration 模式:使用 handoffs_service
if self._normalized_mode == OrchestrationMode.COLLABORATION:
return await self._execute_collaboration_mode(
message,
conversation_id,
user_id,
variables
)
# Supervisor 模式:由 Master Agent 统一调度
# 1. Master Agent 分析任务并做出决策 # 1. Master Agent 分析任务并做出决策
task_analysis = await self._analyze_task(message, variables) task_analysis = await self._analyze_task(message, variables)
@@ -1411,6 +1404,162 @@ class MultiAgentOrchestrator:
return self._merge_results(results) return self._merge_results(results)
async def _execute_collaboration_mode_stream(
self,
task_analysis: Dict[str, Any],
conversation_id: Optional[uuid.UUID],
user_id: Optional[str],
web_search: bool = False,
memory: bool = True,
storage_type: str = '',
user_rag_memory_id: str = ''
):
"""Collaboration 模式流式执行 - Agent 之间可以相互 handoff
使用 handoffs_service 实现 Agent 之间的动态切换
Args:
task_analysis: 任务分析结果
conversation_id: 会话 ID
user_id: 用户 ID
web_search: 是否启用网络搜索
memory: 是否启用记忆
storage_type: 存储类型
user_rag_memory_id: RAG 记忆 ID
Yields:
SSE 格式的事件流
"""
from app.services.handoffs_service import (
convert_multi_agent_config_to_handoffs,
HandoffsService
)
message = task_analysis.get("message", "")
try:
# 1. 构建 multi_agent_config 字典
multi_agent_config = {
"sub_agents": self.config.sub_agents,
"default_model_config_id": self.config.default_model_config_id,
"model_parameters": self.config.model_parameters,
"orchestration_mode": self.config.orchestration_mode
}
# 2. 转换配置
agent_configs, model_config = convert_multi_agent_config_to_handoffs(
multi_agent_config,
self.db
)
if not agent_configs:
raise BusinessException("没有可用的子 Agent", BizCode.AGENT_CONFIG_MISSING)
if not model_config:
raise BusinessException("没有配置模型", BizCode.AGENT_CONFIG_MISSING)
# 3. 创建 HandoffsService
handoffs_service = HandoffsService(
agent_configs=agent_configs,
model_config=model_config,
streaming=True
)
# 4. 使用 handoffs_service 的流式聊天
conv_id = str(conversation_id) if conversation_id else None
async for event in handoffs_service.chat_stream(
message=message,
conversation_id=conv_id
):
# handoffs_service 返回的已经是 SSE 格式,直接 yield
yield event
except Exception as e:
logger.error(f"Collaboration 模式执行失败: {str(e)}", exc_info=True)
yield self._format_sse_event("error", {
"error": str(e),
"timestamp": time.time()
})
async def _execute_collaboration_mode(
self,
message: str,
conversation_id: Optional[uuid.UUID],
user_id: Optional[str],
variables: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
"""Collaboration 模式非流式执行 - Agent 之间可以相互 handoff
使用 handoffs_service 实现 Agent 之间的动态切换
Args:
message: 用户消息
conversation_id: 会话 ID
user_id: 用户 ID
variables: 变量参数
Returns:
执行结果
"""
from app.services.handoffs_service import (
convert_multi_agent_config_to_handoffs,
HandoffsService
)
start_time = time.time()
try:
# 1. 构建 multi_agent_config 字典
multi_agent_config = {
"sub_agents": self.config.sub_agents,
"default_model_config_id": self.config.default_model_config_id,
"model_parameters": self.config.model_parameters,
"orchestration_mode": self.config.orchestration_mode
}
# 2. 转换配置
agent_configs, model_config = convert_multi_agent_config_to_handoffs(
multi_agent_config,
self.db
)
if not agent_configs:
raise BusinessException("没有可用的子 Agent", BizCode.AGENT_CONFIG_MISSING)
if not model_config:
raise BusinessException("没有配置模型", BizCode.AGENT_CONFIG_MISSING)
# 3. 创建 HandoffsService
handoffs_service = HandoffsService(
agent_configs=agent_configs,
model_config=model_config,
streaming=False
)
# 4. 使用 handoffs_service 的非流式聊天
conv_id = str(conversation_id) if conversation_id else None
result = await handoffs_service.chat(
message=message,
conversation_id=conv_id
)
elapsed_time = time.time() - start_time
return {
"message": result.get("response", ""),
"conversation_id": result.get("conversation_id"),
"elapsed_time": elapsed_time,
"strategy": "collaboration",
"active_agent": result.get("active_agent"),
"sub_results": result
}
except Exception as e:
logger.error(f"Collaboration 模式执行失败: {str(e)}", exc_info=True)
raise
def _format_sse_event(self, event: str, data: Dict[str, Any]) -> str: def _format_sse_event(self, event: str, data: Dict[str, Any]) -> str:
"""格式化 SSE 事件 """格式化 SSE 事件