Files
multiAgentTry/backend/app/services/role_allocator.py
Claude Code dc398d7c7b 完整实现 Swarm 多智能体协作系统
- 新增 CLIPluginAdapter 统一接口 (backend/app/core/agent_adapter.py)
- 新增 LLM 服务层,支持 Anthropic/OpenAI/DeepSeek/Ollama (backend/app/services/llm_service.py)
- 新增 Agent 执行引擎,支持文件锁自动管理 (backend/app/services/agent_executor.py)
- 新增 NativeLLMAgent 原生 LLM 适配器 (backend/app/adapters/native_llm_agent.py)
- 新增进程管理器 (backend/app/services/process_manager.py)
- 新增 Agent 控制 API (backend/app/routers/agents_control.py)
- 新增 WebSocket 实时通信 (backend/app/routers/websocket.py)
- 更新前端 AgentsPage,支持启动/停止 Agent
- 测试通过:Agent 启动、批量操作、栅栏同步

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:32:11 +08:00

200 lines
5.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
角色分配器 - AI 驱动的角色分配
分析任务描述,自动为 Agent 分配最适合的角色
"""
import asyncio
from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum
from .agent_registry import AgentRegistry, AgentInfo
class AgentRole(str, Enum):
"""Agent 角色枚举"""
ARCHITECT = "architect"
PRODUCT_MANAGER = "pm"
DEVELOPER = "developer"
QA = "qa"
REVIEWER = "reviewer"
@dataclass
class RoleWeight:
"""角色权重配置"""
role: str
weight: float
keywords: List[str]
def matches(self, text: str) -> int:
"""计算匹配分数"""
score = 0
text_lower = text.lower()
for keyword in self.keywords:
if keyword.lower() in text_lower:
score += 1
return score
class RoleAllocator:
"""
角色分配器
分析任务描述,为 Agent 分配最适合的角色
"""
# 角色权重配置(来自 design-spec.md
ROLE_WEIGHTS = {
"pm": RoleWeight("pm", 1.5, ["需求", "产品", "规划", "用户", "功能", "priority", "requirement", "product"]),
"architect": RoleWeight("architect", 1.5, ["架构", "设计", "方案", "技术", "系统", "design", "architecture"]),
"developer": RoleWeight("developer", 1.0, ["开发", "实现", "编码", "代码", "function", "implement", "code"]),
"reviewer": RoleWeight("reviewer", 1.3, ["审查", "review", "检查", "验证", "校对", "check"]),
"qa": RoleWeight("qa", 1.2, ["测试", "test", "质量", "bug", "验证", "quality"]),
}
def __init__(self):
pass
def _analyze_task_roles(self, task: str) -> Dict[str, float]:
"""
分析任务需要的角色及其权重
Args:
task: 任务描述
Returns:
角色权重字典
"""
scores = {}
for role_name, role_weight in self.ROLE_WEIGHTS.items():
match_score = role_weight.matches(task)
if match_score > 0:
scores[role_name] = match_score * role_weight.weight
else:
# 即使没有匹配关键词,也给予基础权重
scores[role_name] = 0.1 * role_weight.weight
return scores
async def allocate_roles(
self,
task: str,
available_agents: List[str]
) -> Dict[str, str]:
"""
为任务分配角色
Args:
task: 任务描述
available_agents: 可用的 Agent ID 列表
Returns:
Agent ID -> 角色映射
"""
# 获取所有 Agent 信息
# 注意:在实际实现中,这会从 AgentRegistry 获取
# 这里简化处理,假设已有 Agent 信息
# 分析任务需要的角色
role_scores = self._analyze_task_roles(task)
# 按分数排序角色
sorted_roles = sorted(role_scores.items(), key=lambda x: -x[1])
# 简单分配:将可用 Agent 按顺序分配给角色
allocation = {}
for i, agent_id in enumerate(available_agents):
if i < len(sorted_roles):
allocation[agent_id] = sorted_roles[i][0]
else:
allocation[agent_id] = "developer" # 默认角色
return allocation
def get_primary_role(self, task: str) -> str:
"""
获取任务的主要角色
Args:
task: 任务描述
Returns:
主要角色名称
"""
role_scores = self._analyze_task_roles(task)
if not role_scores:
return "developer"
return max(role_scores.items(), key=lambda x: x[1])[0]
async def suggest_agents_for_task(
self,
task: str,
all_agents: List[AgentInfo],
count: int = 3
) -> List[AgentInfo]:
"""
为任务推荐合适的 Agent
Args:
task: 任务描述
all_agents: 所有可用 Agent 列表
count: 推荐数量
Returns:
推荐的 Agent 列表
"""
primary_role = self.get_primary_role(task)
# 按角色匹配度排序
scored_agents = []
for agent in all_agents:
if agent.role == primary_role:
scored_agents.append((agent, 10)) # 完全匹配高分
elif agent.role in ["architect", "developer", "reviewer"]:
scored_agents.append((agent, 5)) # 相关角色中分
else:
scored_agents.append((agent, 1)) # 其他角色低分
# 按分数排序
scored_agents.sort(key=lambda x: -x[1])
return [agent for agent, _ in scored_agents[:count]]
def explain_allocation(self, task: str, allocation: Dict[str, str]) -> str:
"""
解释角色分配的原因
Args:
task: 任务描述
allocation: 分配结果
Returns:
解释文本
"""
role_scores = self._analyze_task_roles(task)
primary = self.get_primary_role(task)
lines = [f"任务分析: {task}", f"主要角色: {primary}"]
lines.append("角色权重:")
for role, score in sorted(role_scores.items(), key=lambda x: -x[1]):
lines.append(f" - {role}: {score:.2f}")
lines.append("分配结果:")
for agent_id, role in allocation.items():
lines.append(f" - {agent_id}: {role}")
return "\n".join(lines)
# 全局单例
_allocator_instance: Optional[RoleAllocator] = None
def get_role_allocator() -> RoleAllocator:
"""获取角色分配器单例"""
global _allocator_instance
if _allocator_instance is None:
_allocator_instance = RoleAllocator()
return _allocator_instance