Files
AIChatRoom/backend/services/agent_service.py

439 lines
12 KiB
Python
Raw Normal View History

"""
Agent服务
管理AI代理的配置
"""
import uuid
from datetime import datetime
from typing import List, Dict, Any, Optional
from loguru import logger
from models.agent import Agent
from services.ai_provider_service import AIProviderService
class AgentService:
"""
Agent服务类
负责Agent的CRUD操作
"""
@classmethod
async def create_agent(
cls,
name: str,
role: str,
system_prompt: str,
provider_id: str,
temperature: float = 0.7,
max_tokens: int = 2000,
capabilities: Optional[Dict[str, Any]] = None,
behavior: Optional[Dict[str, Any]] = None,
avatar: Optional[str] = None,
color: str = "#1890ff"
) -> Agent:
"""
创建新的Agent
Args:
name: Agent名称
role: 角色定义
system_prompt: 系统提示词
provider_id: 使用的AI接口ID
temperature: 温度参数
max_tokens: 最大token数
capabilities: 能力配置
behavior: 行为配置
avatar: 头像URL
color: 代表颜色
Returns:
创建的Agent文档
"""
# 验证AI接口存在
provider = await AIProviderService.get_provider(provider_id)
if not provider:
raise ValueError(f"AI接口不存在: {provider_id}")
# 生成唯一ID
agent_id = f"agent-{uuid.uuid4().hex[:8]}"
# 默认能力配置
default_capabilities = {
"memory_enabled": False,
"mcp_tools": [],
"skills": [],
"multimodal": False
}
if capabilities:
default_capabilities.update(capabilities)
# 默认行为配置
default_behavior = {
"speak_threshold": 0.5,
"max_speak_per_round": 2,
"speak_style": "balanced"
}
if behavior:
default_behavior.update(behavior)
# 创建文档
agent = Agent(
agent_id=agent_id,
name=name,
role=role,
system_prompt=system_prompt,
provider_id=provider_id,
temperature=temperature,
max_tokens=max_tokens,
capabilities=default_capabilities,
behavior=default_behavior,
avatar=avatar,
color=color,
enabled=True,
created_at=datetime.utcnow(),
updated_at=datetime.utcnow()
)
await agent.insert()
logger.info(f"创建Agent: {agent_id} ({name})")
return agent
@classmethod
async def get_agent(cls, agent_id: str) -> Optional[Agent]:
"""
获取指定Agent
Args:
agent_id: Agent ID
Returns:
Agent文档或None
"""
return await Agent.find_one(Agent.agent_id == agent_id)
@classmethod
async def get_all_agents(
cls,
enabled_only: bool = False
) -> List[Agent]:
"""
获取所有Agent
Args:
enabled_only: 是否只返回启用的Agent
Returns:
Agent列表
"""
if enabled_only:
return await Agent.find(Agent.enabled == True).to_list()
return await Agent.find_all().to_list()
@classmethod
async def get_agents_by_ids(
cls,
agent_ids: List[str]
) -> List[Agent]:
"""
根据ID列表获取多个Agent
Args:
agent_ids: Agent ID列表
Returns:
Agent列表
"""
return await Agent.find(
{"agent_id": {"$in": agent_ids}}
).to_list()
@classmethod
async def update_agent(
cls,
agent_id: str,
**kwargs
) -> Optional[Agent]:
"""
更新Agent配置
Args:
agent_id: Agent ID
**kwargs: 要更新的字段
Returns:
更新后的Agent或None
"""
agent = await cls.get_agent(agent_id)
if not agent:
return None
# 如果更新了provider_id验证其存在
if "provider_id" in kwargs:
provider = await AIProviderService.get_provider(kwargs["provider_id"])
if not provider:
raise ValueError(f"AI接口不存在: {kwargs['provider_id']}")
# 更新字段
kwargs["updated_at"] = datetime.utcnow()
for key, value in kwargs.items():
if hasattr(agent, key):
setattr(agent, key, value)
await agent.save()
logger.info(f"更新Agent: {agent_id}")
return agent
@classmethod
async def delete_agent(cls, agent_id: str) -> bool:
"""
删除Agent
Args:
agent_id: Agent ID
Returns:
是否删除成功
"""
agent = await cls.get_agent(agent_id)
if not agent:
return False
await agent.delete()
logger.info(f"删除Agent: {agent_id}")
return True
@classmethod
async def test_agent(
cls,
agent_id: str,
test_message: str = "你好,请简单介绍一下你自己。"
) -> Dict[str, Any]:
"""
测试Agent对话
Args:
agent_id: Agent ID
test_message: 测试消息
Returns:
测试结果
"""
agent = await cls.get_agent(agent_id)
if not agent:
return {
"success": False,
"message": f"Agent不存在: {agent_id}"
}
if not agent.enabled:
return {
"success": False,
"message": "Agent已禁用"
}
# 构建消息
messages = [
{"role": "system", "content": agent.system_prompt},
{"role": "user", "content": test_message}
]
# 调用AI接口
response = await AIProviderService.chat(
provider_id=agent.provider_id,
messages=messages,
temperature=agent.temperature,
max_tokens=agent.max_tokens
)
if response.success:
return {
"success": True,
"message": "测试成功",
"response": response.content,
"model": response.model,
"tokens": response.total_tokens,
"latency_ms": response.latency_ms
}
else:
return {
"success": False,
"message": response.error
}
@classmethod
async def duplicate_agent(
cls,
agent_id: str,
new_name: Optional[str] = None
) -> Optional[Agent]:
"""
复制Agent
Args:
agent_id: 源Agent ID
new_name: 新Agent名称
Returns:
新创建的Agent或None
"""
source_agent = await cls.get_agent(agent_id)
if not source_agent:
return None
return await cls.create_agent(
name=new_name or f"{source_agent.name} (副本)",
role=source_agent.role,
system_prompt=source_agent.system_prompt,
provider_id=source_agent.provider_id,
temperature=source_agent.temperature,
max_tokens=source_agent.max_tokens,
capabilities=source_agent.capabilities,
behavior=source_agent.behavior,
avatar=source_agent.avatar,
color=source_agent.color
)
@classmethod
async def generate_system_prompt(
cls,
provider_id: str,
name: str,
role: str,
description: Optional[str] = None
) -> Dict[str, Any]:
"""
使用AI生成Agent系统提示词
Args:
provider_id: AI接口ID
name: Agent名称
role: 角色定位
description: 额外描述可选
Returns:
生成结果包含success和生成的prompt
"""
# 验证AI接口存在
provider = await AIProviderService.get_provider(provider_id)
if not provider:
return {
"success": False,
"message": f"AI接口不存在: {provider_id}"
}
# 构建生成提示词的请求
generate_prompt = f"""请为一个AI Agent编写系统提示词system prompt
Agent名称{name}
角色定位{role}
{f'补充说明:{description}' if description else ''}
要求
1. 提示词应简洁专业控制在200字以内
2. 明确该Agent的核心职责和专业领域
3. 说明在多Agent讨论中应该关注什么
4. 使用中文编写
5. 不要包含任何问候语或开场白直接给出提示词内容
请直接输出系统提示词不要有任何额外的解释或包装"""
try:
messages = [{"role": "user", "content": generate_prompt}]
response = await AIProviderService.chat(
provider_id=provider_id,
messages=messages,
temperature=0.7,
max_tokens=1000
)
if response.success:
# 清理可能的包装文本
content = response.content.strip()
# 移除可能的markdown代码块标记
if content.startswith("```"):
lines = content.split("\n")
content = "\n".join(lines[1:])
if content.endswith("```"):
content = content[:-3]
content = content.strip()
return {
"success": True,
"prompt": content,
"model": response.model,
"tokens": response.total_tokens
}
else:
return {
"success": False,
"message": response.error or "生成失败"
}
except Exception as e:
logger.error(f"生成系统提示词失败: {e}")
return {
"success": False,
"message": f"生成失败: {str(e)}"
}
# Agent预设模板
AGENT_TEMPLATES = {
"product_manager": {
"name": "产品经理",
"role": "产品规划和需求分析专家",
"system_prompt": """你是一位经验丰富的产品经理,擅长:
- 分析用户需求和痛点
- 制定产品策略和路线图
- 平衡业务目标和用户体验
- 与团队协作推进产品迭代
在讨论中你需要从产品角度出发关注用户价值商业可行性和优先级排序
请用专业但易懂的语言表达观点""",
"color": "#1890ff"
},
"developer": {
"name": "开发工程师",
"role": "技术实现和架构设计专家",
"system_prompt": """你是一位资深的软件开发工程师,擅长:
- 系统架构设计
- 代码实现和优化
- 技术方案评估
- 性能和安全考量
在讨论中你需要从技术角度出发关注实现可行性技术债务和最佳实践
请提供具体的技术建议和潜在风险评估""",
"color": "#52c41a"
},
"designer": {
"name": "设计师",
"role": "用户体验和界面设计专家",
"system_prompt": """你是一位专业的UI/UX设计师擅长:
- 用户体验设计
- 界面视觉设计
- 交互流程优化
- 设计系统构建
在讨论中你需要从设计角度出发关注用户体验视觉美感和交互流畅性
请提供设计建议并考虑可用性和一致性""",
"color": "#eb2f96"
},
"moderator": {
"name": "主持人",
"role": "讨论主持和共识判断专家",
"system_prompt": """你是讨论的主持人,负责:
- 引导讨论方向
- 总结各方观点
- 判断是否达成共识
- 提炼行动要点
在讨论中你需要保持中立促进有效沟通并在适当时机总结讨论成果
当各方观点趋于一致时请明确指出并总结共识内容""",
"color": "#722ed1"
}
}