""" Agent 调度器服务 实现多种调度策略 """ from typing import List, Optional from app.models import Agent class BaseScheduler: """调度器基类""" def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: """选择 Agent,子类实现""" raise NotImplementedError class RoundRobinScheduler(BaseScheduler): """轮询调度器""" def __init__(self): self._index = 0 def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: if not agents: return None # 只选择在线的 Agent online_agents = [a for a in agents if a.status == 'online'] if not online_agents: return None # 轮询选择 agent = online_agents[self._index % len(online_agents)] self._index += 1 return agent class WeightedRoundRobinScheduler(BaseScheduler): """加权轮询调度器(默认)""" def __init__(self): self._index = 0 self._weights = {} def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: if not agents: return None # 只选择在线的 Agent online_agents = [a for a in agents if a.status == 'online'] if not online_agents: return None # 计算总权重 total_weight = sum(a.weight for a in online_agents) if total_weight == 0: return online_agents[0] if online_agents else None # 加权轮询 current_weight = self._index % total_weight cumulative = 0 for agent in online_agents: cumulative += agent.weight if current_weight < cumulative: self._index += 1 return agent return online_agents[-1] class LeastConnectionsScheduler(BaseScheduler): """最少连接调度器""" def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: if not agents: return None # 只选择在线且未达连接上限的 Agent available_agents = [ a for a in agents if a.status == 'online' and a.current_sessions < a.connection_limit ] if not available_agents: return None # 选择连接数最少的 return min(available_agents, key=lambda a: a.current_sessions) class LeastResponseTimeScheduler(BaseScheduler): """最快响应调度器(基于最后心跳时间)""" def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: if not agents: return None # 只选择在线的 Agent online_agents = [a for a in agents if a.status == 'online'] if not online_agents: return None # 选择最近有心跳的(响应快的) from datetime import datetime now = datetime.utcnow() def response_score(agent): if not agent.last_heartbeat: return float('inf') # 最近心跳 = 分数低 = 优先选择 return (now - agent.last_heartbeat).total_seconds() return min(online_agents, key=response_score) class CapabilityMatchScheduler(BaseScheduler): """能力匹配调度器""" def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: if not agents or not context: return None required_capabilities = context.get('capabilities', []) if not required_capabilities: # 没有特殊要求,使用加权轮询 return WeightedRoundRobinScheduler().select_agent(agents, context) # 只选择在线且有对应能力的 Agent matching_agents = [] for agent in agents: if agent.status != 'online': continue agent_caps = agent.capabilities or [] # 检查是否具备所有必需能力 if all(cap in agent_caps for cap in required_capabilities): matching_agents.append(agent) if not matching_agents: # 没有匹配的,回退到加权轮询 return WeightedRoundRobinScheduler().select_agent(agents, context) # 在匹配的 Agent 中使用加权轮询 return WeightedRoundRobinScheduler().select_agent(matching_agents, context) class AgentScheduler: """Agent 调度器工厂""" STRATEGIES = { 'round_robin': RoundRobinScheduler, 'weighted_round_robin': WeightedRoundRobinScheduler, 'least_connections': LeastConnectionsScheduler, 'least_response_time': LeastResponseTimeScheduler, 'capability_match': CapabilityMatchScheduler, } def __init__(self, strategy: str = 'weighted_round_robin'): self._strategy_name = strategy self._scheduler = self.STRATEGIES.get(strategy, WeightedRoundRobinScheduler)() def select_agent(self, agents: List[Agent], context: dict = None) -> Optional[Agent]: """选择 Agent""" return self._scheduler.select_agent(agents, context) def get_strategy(self) -> str: """获取当前策略""" return self._strategy_name @classmethod def get_available_strategies(cls) -> list: """获取可用策略列表""" return list(cls.STRATEGIES.keys())