[modify] manage multi agent logic
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
"""多 Agent 控制器"""
|
"""多 Agent 控制器"""
|
||||||
import uuid
|
import uuid
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Query, Path
|
from fastapi import APIRouter, Depends, Query, Path
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
@@ -7,9 +9,9 @@ from app.db import get_db
|
|||||||
from app.dependencies import get_current_user
|
from app.dependencies import get_current_user
|
||||||
from app.core.response_utils import success
|
from app.core.response_utils import success
|
||||||
from app.core.logging_config import get_business_logger
|
from app.core.logging_config import get_business_logger
|
||||||
from app.schemas import multi_agent_schema
|
from app.schemas import multi_agent_schema, MultiAgentConfigUpdate, MultiAgentConfigSchema
|
||||||
from app.schemas.response_schema import PageData, PageMeta
|
from app.schemas.response_schema import PageData, PageMeta
|
||||||
from app.services.multi_agent_service import MultiAgentService
|
from app.services.multi_agent_service import MultiAgentService, get_multi_agent_service
|
||||||
from app.models import User
|
from app.models import User
|
||||||
|
|
||||||
router = APIRouter(prefix="/apps", tags=["Multi-Agent"])
|
router = APIRouter(prefix="/apps", tags=["Multi-Agent"])
|
||||||
@@ -18,36 +20,35 @@ logger = get_business_logger()
|
|||||||
|
|
||||||
# ==================== 多 Agent 配置管理 ====================
|
# ==================== 多 Agent 配置管理 ====================
|
||||||
|
|
||||||
@router.post(
|
# @router.post(
|
||||||
"/{app_id}/multi-agent",
|
# "/{app_id}/multi-agent",
|
||||||
summary="创建多 Agent 配置"
|
# summary="创建多 Agent 配置"
|
||||||
)
|
# )
|
||||||
def create_multi_agent_config(
|
# def create_multi_agent_config(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
data: multi_agent_schema.MultiAgentConfigCreate = ...,
|
# data: multi_agent_schema.MultiAgentConfigCreate = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""创建多 Agent 配置
|
# """创建多 Agent 配置
|
||||||
|
|
||||||
支持四种编排模式:
|
# 支持四种编排模式:
|
||||||
- sequential: 顺序执行
|
# - sequential: 顺序执行
|
||||||
- parallel: 并行执行
|
# - parallel: 并行执行
|
||||||
- conditional: 条件路由
|
# - conditional: 条件路由
|
||||||
- loop: 循环执行
|
# - loop: 循环执行
|
||||||
"""
|
# """
|
||||||
service = MultiAgentService(db)
|
# service = MultiAgentService(db)
|
||||||
config = service.create_config(
|
# config = service.create_config(
|
||||||
app_id=app_id,
|
# app_id=app_id,
|
||||||
data=data,
|
# data=data,
|
||||||
created_by=current_user.id
|
# created_by=current_user.id
|
||||||
)
|
# )
|
||||||
|
|
||||||
return success(
|
|
||||||
data=multi_agent_schema.MultiAgentConfigSchema.model_validate(config),
|
|
||||||
msg="多 Agent 配置创建成功"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# return success(
|
||||||
|
# data=multi_agent_schema.MultiAgentConfigSchema.model_validate(config),
|
||||||
|
# msg="多 Agent 配置创建成功"
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
@@ -69,8 +70,8 @@ def get_multi_agent_configs(
|
|||||||
# 返回默认模板
|
# 返回默认模板
|
||||||
default_template = {
|
default_template = {
|
||||||
"app_id": str(app_id),
|
"app_id": str(app_id),
|
||||||
"master_agent_id": None,
|
"default_model_config_id": None,
|
||||||
"master_agent_name": None,
|
"model_parameters": None,
|
||||||
"orchestration_mode": "conditional",
|
"orchestration_mode": "conditional",
|
||||||
"sub_agents": [],
|
"sub_agents": [],
|
||||||
"routing_rules": [],
|
"routing_rules": [],
|
||||||
@@ -96,464 +97,464 @@ def get_multi_agent_configs(
|
|||||||
)
|
)
|
||||||
def update_multi_agent_config(
|
def update_multi_agent_config(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
data: multi_agent_schema.MultiAgentConfigUpdate = ...,
|
data: MultiAgentConfigUpdate = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
|
multi_agent_service: Annotated[MultiAgentService, Depends(get_multi_agent_service)] = None,
|
||||||
):
|
):
|
||||||
"""更新多 Agent 配置"""
|
"""更新多 Agent 配置"""
|
||||||
service = MultiAgentService(db)
|
config = multi_agent_service.update_config(app_id, data)
|
||||||
config = service.update_config(app_id, data)
|
print("="*50)
|
||||||
|
print(config.default_model_config_id)
|
||||||
return success(
|
return success(
|
||||||
data=multi_agent_schema.MultiAgentConfigSchema.model_validate(config),
|
data=MultiAgentConfigSchema.model_validate(config),
|
||||||
msg="多 Agent 配置更新成功"
|
msg="多 Agent 配置更新成功"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.delete(
|
# @router.delete(
|
||||||
"/{app_id}/multi-agent",
|
# "/{app_id}/multi-agent",
|
||||||
summary="删除多 Agent 配置"
|
# summary="删除多 Agent 配置"
|
||||||
)
|
# )
|
||||||
def delete_multi_agent_config(
|
# def delete_multi_agent_config(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""删除多 Agent 配置"""
|
# """删除多 Agent 配置"""
|
||||||
service = MultiAgentService(db)
|
# service = MultiAgentService(db)
|
||||||
service.delete_config(app_id)
|
# service.delete_config(app_id)
|
||||||
|
|
||||||
return success(msg="多 Agent 配置删除成功")
|
# return success(msg="多 Agent 配置删除成功")
|
||||||
|
|
||||||
# ==================== 多 Agent 运行 ====================
|
# ==================== 多 Agent 运行 ====================
|
||||||
|
|
||||||
@router.post(
|
# @router.post(
|
||||||
"/{app_id}/multi-agent/run",
|
# "/{app_id}/multi-agent/run",
|
||||||
summary="运行多 Agent 任务"
|
# summary="运行多 Agent 任务"
|
||||||
)
|
# )
|
||||||
async def run_multi_agent(
|
# async def run_multi_agent(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
request: multi_agent_schema.MultiAgentRunRequest = ...,
|
# request: multi_agent_schema.MultiAgentRunRequest = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""运行多 Agent 任务
|
# """运行多 Agent 任务
|
||||||
|
|
||||||
根据配置的编排模式执行多个 Agent:
|
# 根据配置的编排模式执行多个 Agent:
|
||||||
- sequential: 按优先级顺序执行
|
# - sequential: 按优先级顺序执行
|
||||||
- parallel: 并行执行所有 Agent
|
# - parallel: 并行执行所有 Agent
|
||||||
- conditional: 根据条件选择 Agent
|
# - conditional: 根据条件选择 Agent
|
||||||
- loop: 循环执行直到满足条件
|
# """
|
||||||
"""
|
# service = MultiAgentService(db)
|
||||||
service = MultiAgentService(db)
|
# result = await service.run(app_id, request)
|
||||||
result = await service.run(app_id, request)
|
|
||||||
|
|
||||||
return success(
|
# return success(
|
||||||
data=multi_agent_schema.MultiAgentRunResponse(**result),
|
# data=multi_agent_schema.MultiAgentRunResponse(**result),
|
||||||
msg="多 Agent 任务执行成功"
|
# msg="多 Agent 任务执行成功"
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
# ==================== 智能路由测试 ====================
|
# # ==================== 智能路由测试 ====================
|
||||||
|
|
||||||
@router.post(
|
# @router.post(
|
||||||
"/{app_id}/multi-agent/test-routing",
|
# "/{app_id}/multi-agent/test-routing",
|
||||||
summary="测试智能路由(支持 Master Agent 模式)"
|
# summary="测试智能路由(支持 Master Agent 模式)"
|
||||||
)
|
# )
|
||||||
async def test_routing(
|
# async def test_routing(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
request: multi_agent_schema.RoutingTestRequest = ...,
|
# request: multi_agent_schema.RoutingTestRequest = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""测试智能路由功能(重构版 - 支持 Master Agent)
|
# """测试智能路由功能(重构版 - 支持 Master Agent)
|
||||||
|
|
||||||
支持三种路由模式:
|
# 支持三种路由模式:
|
||||||
- master_agent: 使用 Master Agent 决策(推荐)
|
# - master_agent: 使用 Master Agent 决策(推荐)
|
||||||
- llm_router: 使用旧 LLM 路由器(向后兼容)
|
# - llm_router: 使用旧 LLM 路由器(向后兼容)
|
||||||
- rule_only: 仅使用规则路由(最快)
|
# - rule_only: 仅使用规则路由(最快)
|
||||||
|
|
||||||
参数:
|
# 参数:
|
||||||
- message: 测试消息
|
# - message: 测试消息
|
||||||
- conversation_id: 会话 ID(可选)
|
# - conversation_id: 会话 ID(可选)
|
||||||
- routing_model_id: 路由模型 ID(可选)
|
# - routing_model_id: 路由模型 ID(可选)
|
||||||
- use_llm: 是否启用 LLM(默认 False)
|
# - use_llm: 是否启用 LLM(默认 False)
|
||||||
- keyword_threshold: 关键词置信度阈值(默认 0.8)
|
# - keyword_threshold: 关键词置信度阈值(默认 0.8)
|
||||||
- force_new: 是否强制重新路由(默认 False)
|
# - force_new: 是否强制重新路由(默认 False)
|
||||||
"""
|
# """
|
||||||
from app.services.conversation_state_manager import ConversationStateManager
|
# from app.services.conversation_state_manager import ConversationStateManager
|
||||||
from app.services.llm_router import LLMRouter
|
# from app.services.llm_router import LLMRouter
|
||||||
from app.models import ModelConfig
|
# from app.models import ModelConfig
|
||||||
|
|
||||||
# 1. 获取多 Agent 配置
|
# # 1. 获取多 Agent 配置
|
||||||
service = MultiAgentService(db)
|
# service = MultiAgentService(db)
|
||||||
config = service.get_config(app_id)
|
# config = service.get_config(app_id)
|
||||||
|
|
||||||
if not config:
|
# if not config:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg="应用未配置多 Agent,无法测试路由"
|
# msg="应用未配置多 Agent,无法测试路由"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 2. 准备子 Agent 信息
|
# # 2. 准备子 Agent 信息
|
||||||
sub_agents = {}
|
# sub_agents = {}
|
||||||
for sub_agent_info in config.sub_agents:
|
# for sub_agent_info in config.sub_agents:
|
||||||
agent_id = sub_agent_info["agent_id"]
|
# agent_id = sub_agent_info["agent_id"]
|
||||||
sub_agents[agent_id] = {
|
# sub_agents[agent_id] = {
|
||||||
"name": sub_agent_info.get("name", agent_id),
|
# "name": sub_agent_info.get("name", agent_id),
|
||||||
"role": sub_agent_info.get("role", "")
|
# "role": sub_agent_info.get("role", "")
|
||||||
}
|
# }
|
||||||
|
|
||||||
# 3. 获取路由模型(如果指定)
|
# # 3. 获取路由模型(如果指定)
|
||||||
routing_model = None
|
# routing_model = None
|
||||||
if request.routing_model_id:
|
# if request.routing_model_id:
|
||||||
routing_model = db.get(ModelConfig, request.routing_model_id)
|
# routing_model = db.get(ModelConfig, request.routing_model_id)
|
||||||
if not routing_model:
|
# if not routing_model:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"路由模型不存在: {request.routing_model_id}"
|
# msg=f"路由模型不存在: {request.routing_model_id}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 4. 初始化路由器
|
# # 4. 初始化路由器
|
||||||
state_manager = ConversationStateManager()
|
# state_manager = ConversationStateManager()
|
||||||
router = LLMRouter(
|
# router = LLMRouter(
|
||||||
db=db,
|
# db=db,
|
||||||
state_manager=state_manager,
|
# state_manager=state_manager,
|
||||||
routing_rules=config.routing_rules or [],
|
# routing_rules=config.routing_rules or [],
|
||||||
sub_agents=sub_agents,
|
# sub_agents=sub_agents,
|
||||||
routing_model_config=routing_model,
|
# routing_model_config=routing_model,
|
||||||
use_llm=request.use_llm and routing_model is not None
|
# use_llm=request.use_llm and routing_model is not None
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 5. 设置阈值
|
# # 5. 设置阈值
|
||||||
if request.keyword_threshold:
|
# if request.keyword_threshold:
|
||||||
router.keyword_high_confidence_threshold = request.keyword_threshold
|
# router.keyword_high_confidence_threshold = request.keyword_threshold
|
||||||
|
|
||||||
# 6. 执行路由
|
# # 6. 执行路由
|
||||||
try:
|
# try:
|
||||||
routing_result = await router.route(
|
# routing_result = await router.route(
|
||||||
message=request.message,
|
# message=request.message,
|
||||||
conversation_id=str(request.conversation_id) if request.conversation_id else None,
|
# conversation_id=str(request.conversation_id) if request.conversation_id else None,
|
||||||
force_new=request.force_new
|
# force_new=request.force_new
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 7. 获取 Agent 信息
|
# # 7. 获取 Agent 信息
|
||||||
agent_id = routing_result["agent_id"]
|
# agent_id = routing_result["agent_id"]
|
||||||
agent_info = sub_agents.get(agent_id, {})
|
# agent_info = sub_agents.get(agent_id, {})
|
||||||
|
|
||||||
# 8. 构建响应
|
# # 8. 构建响应
|
||||||
response_data = {
|
# response_data = {
|
||||||
"message": request.message,
|
# "message": request.message,
|
||||||
"routing_result": {
|
# "routing_result": {
|
||||||
"agent_id": agent_id,
|
# "agent_id": agent_id,
|
||||||
"agent_name": agent_info.get("name", agent_id),
|
# "agent_name": agent_info.get("name", agent_id),
|
||||||
"agent_role": agent_info.get("role", ""),
|
# "agent_role": agent_info.get("role", ""),
|
||||||
"confidence": routing_result["confidence"],
|
# "confidence": routing_result["confidence"],
|
||||||
"strategy": routing_result["strategy"],
|
# "strategy": routing_result["strategy"],
|
||||||
"topic": routing_result["topic"],
|
# "topic": routing_result["topic"],
|
||||||
"topic_changed": routing_result["topic_changed"],
|
# "topic_changed": routing_result["topic_changed"],
|
||||||
"reason": routing_result["reason"],
|
# "reason": routing_result["reason"],
|
||||||
"routing_method": routing_result["routing_method"]
|
# "routing_method": routing_result["routing_method"]
|
||||||
},
|
# },
|
||||||
"cmulti-agent/batch-test-routingonfig_info": {
|
# "cmulti-agent/batch-test-routingonfig_info": {
|
||||||
"use_llm": request.use_llm and routing_model is not None,
|
# "use_llm": request.use_llm and routing_model is not None,
|
||||||
"routing_model": routing_model.name if routing_model else None,
|
# "routing_model": routing_model.name if routing_model else None,
|
||||||
"keyword_threshold": router.keyword_high_confidence_threshold,
|
# "keyword_threshold": router.keyword_high_confidence_threshold,
|
||||||
"total_sub_agents": len(sub_agents)
|
# "total_sub_agents": len(sub_agents)
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
|
||||||
return success(
|
# return success(
|
||||||
data=response_data,
|
# data=response_data,
|
||||||
msg="路由测试成功"
|
# msg="路由测试成功"
|
||||||
)
|
# )
|
||||||
|
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.error(f"路由测试失败: {str(e)}")
|
# logger.error(f"路由测试失败: {str(e)}")
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"路由测试失败: {str(e)}"
|
# msg=f"路由测试失败: {str(e)}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
# @router.post(
|
||||||
"/{app_id}/multi-agent/test-master-agent",
|
# "/{app_id}/multi-agent/test-master-agent",
|
||||||
summary="测试 Master Agent 决策"
|
# summary="测试 Master Agent 决策"
|
||||||
)
|
# )
|
||||||
async def test_master_agent(
|
# async def test_master_agent(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
request: multi_agent_schema.RoutingTestRequest = ...,
|
# request: multi_agent_schema.RoutingTestRequest = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""测试 Master Agent 的路由决策能力
|
# """测试 Master Agent 的路由决策能力
|
||||||
|
|
||||||
这个接口专门用于测试新的 Master Agent 路由器,
|
# 这个接口专门用于测试新的 Master Agent 路由器,
|
||||||
可以看到 Master Agent 的完整决策过程。
|
# 可以看到 Master Agent 的完整决策过程。
|
||||||
|
|
||||||
返回信息包括:
|
# 返回信息包括:
|
||||||
- 选中的 Agent
|
# - 选中的 Agent
|
||||||
- 置信度
|
# - 置信度
|
||||||
- 决策理由
|
# - 决策理由
|
||||||
- 是否需要协作
|
# - 是否需要协作
|
||||||
- 路由策略(master_agent / rule_fast_path / fallback)
|
# - 路由策略(master_agent / rule_fast_path / fallback)
|
||||||
"""
|
# """
|
||||||
from app.services.conversation_state_manager import ConversationStateManager
|
# from app.services.conversation_state_manager import ConversationStateManager
|
||||||
from app.services.master_agent_router import MasterAgentRouter
|
# from app.services.master_agent_router import MasterAgentRouter
|
||||||
from app.models import ModelConfig
|
# from app.models import ModelConfig
|
||||||
|
|
||||||
# 1. 获取多 Agent 配置
|
# # 1. 获取多 Agent 配置
|
||||||
service = MultiAgentService(db)
|
# service = MultiAgentService(db)
|
||||||
config = service.get_config(app_id)
|
# config = service.get_config(app_id)
|
||||||
|
|
||||||
if not config:
|
# if not config:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg="应用未配置多 Agent,无法测试"
|
# msg="应用未配置多 Agent,无法测试"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 2. 加载 Master Agent
|
# # 2. 加载 Master Agent
|
||||||
from app.models import AppRelease, App
|
# from app.models import AppRelease, App
|
||||||
|
|
||||||
master_release = db.get(AppRelease, config.master_agent_id)
|
# master_release = db.get(AppRelease, config.master_agent_id)
|
||||||
if not master_release:
|
# if not master_release:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"Master Agent 发布版本不存在: {config.master_agent_id}"
|
# msg=f"Master Agent 发布版本不存在: {config.master_agent_id}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 获取应用信息
|
# # 获取应用信息
|
||||||
app = db.get(App, master_release.app_id)
|
# app = db.get(App, master_release.app_id)
|
||||||
if not app:
|
# if not app:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"应用不存在: {master_release.app_id}"
|
# msg=f"应用不存在: {master_release.app_id}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 创建 Master Agent 代理对象
|
# # 创建 Master Agent 代理对象
|
||||||
class AgentConfigProxy:
|
# class AgentConfigProxy:
|
||||||
def __init__(self, release, app, config_data):
|
# def __init__(self, release, app, config_data):
|
||||||
self.id = release.id
|
# self.id = release.id
|
||||||
self.app_id = release.app_id
|
# self.app_id = release.app_id
|
||||||
self.app = app
|
# self.app = app
|
||||||
self.name = release.name
|
# self.name = release.name
|
||||||
self.description = release.description
|
# self.description = release.description
|
||||||
self.system_prompt = config_data.get("system_prompt")
|
# self.system_prompt = config_data.get("system_prompt")
|
||||||
self.default_model_config_id = release.default_model_config_id
|
# self.default_model_config_id = release.default_model_config_id
|
||||||
|
|
||||||
config_data = master_release.config or {}
|
# config_data = master_release.config or {}
|
||||||
master_agent_config = AgentConfigProxy(master_release, app, config_data)
|
# master_agent_config = AgentConfigProxy(master_release, app, config_data)
|
||||||
|
|
||||||
# 3. 获取 Master Agent 的模型配置
|
# # 3. 获取 Master Agent 的模型配置
|
||||||
master_model_config = db.get(ModelConfig, master_agent_config.default_model_config_id)
|
# master_model_config = db.get(ModelConfig, master_agent_config.default_model_config_id)
|
||||||
if not master_model_config:
|
# if not master_model_config:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"Master Agent 模型配置不存在: {master_agent_config.default_model_config_id}"
|
# msg=f"Master Agent 模型配置不存在: {master_agent_config.default_model_config_id}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 4. 准备子 Agent 信息
|
# # 4. 准备子 Agent 信息
|
||||||
sub_agents = {}
|
# sub_agents = {}
|
||||||
for sub_agent_info in config.sub_agents:
|
# for sub_agent_info in config.sub_agents:
|
||||||
agent_id = sub_agent_info["agent_id"]
|
# agent_id = sub_agent_info["agent_id"]
|
||||||
|
|
||||||
# 加载子 Agent
|
# # 加载子 Agent
|
||||||
sub_release = db.get(AppRelease, uuid.UUID(agent_id))
|
# sub_release = db.get(AppRelease, uuid.UUID(agent_id))
|
||||||
if sub_release:
|
# if sub_release:
|
||||||
sub_app = db.get(App, sub_release.app_id)
|
# sub_app = db.get(App, sub_release.app_id)
|
||||||
sub_config_data = sub_release.config or {}
|
# sub_config_data = sub_release.config or {}
|
||||||
sub_agent_config = AgentConfigProxy(sub_release, sub_app, sub_config_data)
|
# sub_agent_config = AgentConfigProxy(sub_release, sub_app, sub_config_data)
|
||||||
|
|
||||||
sub_agents[agent_id] = {
|
# sub_agents[agent_id] = {
|
||||||
"config": sub_agent_config,
|
# "config": sub_agent_config,
|
||||||
"info": sub_agent_info
|
# "info": sub_agent_info
|
||||||
}
|
# }
|
||||||
|
|
||||||
# 5. 初始化 Master Agent 路由器
|
# # 5. 初始化 Master Agent 路由器
|
||||||
state_manager = ConversationStateManager()
|
# state_manager = ConversationStateManager()
|
||||||
router = MasterAgentRouter(
|
# router = MasterAgentRouter(
|
||||||
db=db,
|
# db=db,
|
||||||
master_agent_config=master_agent_config,
|
# master_agent_config=master_agent_config,
|
||||||
master_model_config=master_model_config,
|
# master_model_config=master_model_config,
|
||||||
sub_agents=sub_agents,
|
# sub_agents=sub_agents,
|
||||||
state_manager=state_manager,
|
# state_manager=state_manager,
|
||||||
enable_rule_fast_path=True
|
# enable_rule_fast_path=True
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 6. 执行路由决策
|
# # 6. 执行路由决策
|
||||||
try:
|
# try:
|
||||||
decision = await router.route(
|
# decision = await router.route(
|
||||||
message=request.message,
|
# message=request.message,
|
||||||
conversation_id=str(request.conversation_id) if request.conversation_id else None,
|
# conversation_id=str(request.conversation_id) if request.conversation_id else None,
|
||||||
variables=None
|
# variables=None
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 7. 获取选中的 Agent 信息
|
# # 7. 获取选中的 Agent 信息
|
||||||
agent_id = decision["selected_agent_id"]
|
# agent_id = decision["selected_agent_id"]
|
||||||
agent_info = sub_agents.get(agent_id, {}).get("info", {})
|
# agent_info = sub_agents.get(agent_id, {}).get("info", {})
|
||||||
|
|
||||||
# 8. 构建响应
|
# # 8. 构建响应
|
||||||
response_data = {
|
# response_data = {
|
||||||
"message": request.message,
|
# "message": request.message,
|
||||||
"master_agent": {
|
# "master_agent": {
|
||||||
"name": master_agent_config.name,
|
# "name": master_agent_config.name,
|
||||||
"model": master_model_config.name
|
# "model": master_model_config.name
|
||||||
},
|
# },
|
||||||
"decision": {
|
# "decision": {
|
||||||
"selected_agent_id": agent_id,
|
# "selected_agent_id": agent_id,
|
||||||
"selected_agent_name": agent_info.get("name", "未知"),
|
# "selected_agent_name": agent_info.get("name", "未知"),
|
||||||
"selected_agent_role": agent_info.get("role", ""),
|
# "selected_agent_role": agent_info.get("role", ""),
|
||||||
"confidence": decision["confidence"],
|
# "confidence": decision["confidence"],
|
||||||
"reasoning": decision.get("reasoning", ""),
|
# "reasoning": decision.get("reasoning", ""),
|
||||||
"topic": decision.get("topic", ""),
|
# "topic": decision.get("topic", ""),
|
||||||
"strategy": decision["strategy"],
|
# "strategy": decision["strategy"],
|
||||||
"routing_method": decision.get("routing_method", ""),
|
# "routing_method": decision.get("routing_method", ""),
|
||||||
"need_collaboration": decision.get("need_collaboration", False),
|
# "need_collaboration": decision.get("need_collaboration", False),
|
||||||
"collaboration_agents": decision.get("collaboration_agents", [])
|
# "collaboration_agents": decision.get("collaboration_agents", [])
|
||||||
},
|
# },
|
||||||
"config_info": {
|
# "config_info": {
|
||||||
"total_sub_agents": len(sub_agents),
|
# "total_sub_agents": len(sub_agents),
|
||||||
"enable_rule_fast_path": True
|
# "enable_rule_fast_path": True
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
|
||||||
return success(
|
# return success(
|
||||||
data=response_data,
|
# data=response_data,
|
||||||
msg="Master Agent 决策测试成功"
|
# msg="Master Agent 决策测试成功"
|
||||||
)
|
# )
|
||||||
|
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.error(f"Master Agent 决策测试失败: {str(e)}")
|
# logger.error(f"Master Agent 决策测试失败: {str(e)}")
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg=f"测试失败: {str(e)}"
|
# msg=f"测试失败: {str(e)}"
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
# @router.post(
|
||||||
"/{app_id}/multi-agent/batch-test-routing",
|
# "/{app_id}/multi-agent/batch-test-routing",
|
||||||
summary="批量测试智能路由"
|
# summary="批量测试智能路由"
|
||||||
)
|
# )
|
||||||
async def batch_test_routing(
|
# async def batch_test_routing(
|
||||||
app_id: uuid.UUID = Path(..., description="应用 ID"),
|
# app_id: uuid.UUID = Path(..., description="应用 ID"),
|
||||||
request: multi_agent_schema.BatchRoutingTestRequest = ...,
|
# request: multi_agent_schema.BatchRoutingTestRequest = ...,
|
||||||
current_user: User = Depends(get_current_user),
|
# current_user: User = Depends(get_current_user),
|
||||||
db: Session = Depends(get_db),
|
# db: Session = Depends(get_db),
|
||||||
):
|
# ):
|
||||||
"""批量测试智能路由功能
|
# """批量测试智能路由功能
|
||||||
|
|
||||||
用于测试多条消息的路由效果,并统计准确率
|
# 用于测试多条消息的路由效果,并统计准确率
|
||||||
|
|
||||||
参数:
|
# 参数:
|
||||||
- test_cases: 测试用例列表
|
# - test_cases: 测试用例列表
|
||||||
- routing_model_id: 路由模型 ID(可选)
|
# - routing_model_id: 路由模型 ID(可选)
|
||||||
- use_llm: 是否启用 LLM
|
# - use_llm: 是否启用 LLM
|
||||||
- keyword_threshold: 关键词置信度阈值
|
# - keyword_threshold: 关键词置信度阈值
|
||||||
"""
|
# """
|
||||||
from app.services.conversation_state_manager import ConversationStateManager
|
# from app.services.conversation_state_manager import ConversationStateManager
|
||||||
from app.services.llm_router import LLMRouter
|
# from app.services.llm_router import LLMRouter
|
||||||
from app.models import ModelConfig
|
# from app.models import ModelConfig
|
||||||
|
|
||||||
# 1. 获取多 Agent 配置
|
# # 1. 获取多 Agent 配置
|
||||||
service = MultiAgentService(db)
|
# service = MultiAgentService(db)
|
||||||
config = service.get_config(app_id)
|
# config = service.get_config(app_id)
|
||||||
|
|
||||||
if not config:
|
# if not config:
|
||||||
return success(
|
# return success(
|
||||||
data=None,
|
# data=None,
|
||||||
msg="应用未配置多 Agent,无法测试路由"
|
# msg="应用未配置多 Agent,无法测试路由"
|
||||||
)
|
# )
|
||||||
|
|
||||||
# 2. 准备子 Agent 信息
|
# # 2. 准备子 Agent 信息
|
||||||
sub_agents = {}
|
# sub_agents = {}
|
||||||
for sub_agent_info in config.sub_agents:
|
# for sub_agent_info in config.sub_agents:
|
||||||
agent_id = sub_agent_info["agent_id"]
|
# agent_id = sub_agent_info["agent_id"]
|
||||||
sub_agents[agent_id] = {
|
# sub_agents[agent_id] = {
|
||||||
"name": sub_agent_info.get("name", agent_id),
|
# "name": sub_agent_info.get("name", agent_id),
|
||||||
"role": sub_agent_info.get("role", "")
|
# "role": sub_agent_info.get("role", "")
|
||||||
}
|
# }
|
||||||
|
|
||||||
# 3. 获取路由模型
|
# # 3. 获取路由模型
|
||||||
routing_model = None
|
# routing_model = None
|
||||||
if request.routing_model_id:
|
# if request.routing_model_id:
|
||||||
routing_model = db.get(ModelConfig, request.routing_model_id)
|
# routing_model = db.get(ModelConfig, request.routing_model_id)
|
||||||
|
|
||||||
# 4. 初始化路由器
|
# # 4. 初始化路由器
|
||||||
state_manager = ConversationStateManager()
|
# state_manager = ConversationStateManager()
|
||||||
router = LLMRouter(
|
# router = LLMRouter(
|
||||||
db=db,
|
# db=db,
|
||||||
state_manager=state_manager,
|
# state_manager=state_manager,
|
||||||
routing_rules=config.routing_rules or [],
|
# routing_rules=config.routing_rules or [],
|
||||||
sub_agents=sub_agents,
|
# sub_agents=sub_agents,
|
||||||
routing_model_config=routing_model,
|
# routing_model_config=routing_model,
|
||||||
use_llm=request.use_llm and routing_model is not None
|
# use_llm=request.use_llm and routing_model is not None
|
||||||
)
|
# )
|
||||||
|
|
||||||
if request.keyword_threshold:
|
# if request.keyword_threshold:
|
||||||
router.keyword_high_confidence_threshold = request.keyword_threshold
|
# router.keyword_high_confidence_threshold = request.keyword_threshold
|
||||||
|
|
||||||
# 5. 批量测试
|
# # 5. 批量测试
|
||||||
results = []
|
# results = []
|
||||||
correct_count = 0
|
# correct_count = 0
|
||||||
total_count = len(request.test_cases)
|
# total_count = len(request.test_cases)
|
||||||
|
|
||||||
for test_case in request.test_cases:
|
# for test_case in request.test_cases:
|
||||||
try:
|
# try:
|
||||||
routing_result = await router.route(
|
# routing_result = await router.route(
|
||||||
message=test_case.message,
|
# message=test_case.message,
|
||||||
conversation_id=str(uuid.uuid4()) # 每个测试用例使用独立会话
|
# conversation_id=str(uuid.uuid4()) # 每个测试用例使用独立会话
|
||||||
)
|
# )
|
||||||
|
|
||||||
agent_id = routing_result["agent_id"]
|
# agent_id = routing_result["agent_id"]
|
||||||
agent_info = sub_agents.get(agent_id, {})
|
# agent_info = sub_agents.get(agent_id, {})
|
||||||
|
|
||||||
# 判断是否正确
|
# # 判断是否正确
|
||||||
is_correct = None
|
# is_correct = None
|
||||||
if test_case.expected_agent_id:
|
# if test_case.expected_agent_id:
|
||||||
is_correct = (agent_id == str(test_case.expected_agent_id))
|
# is_correct = (agent_id == str(test_case.expected_agent_id))
|
||||||
if is_correct:
|
# if is_correct:
|
||||||
correct_count += 1
|
# correct_count += 1
|
||||||
|
|
||||||
results.append({
|
# results.append({
|
||||||
"message": test_case.message,
|
# "message": test_case.message,
|
||||||
"description": test_case.description,
|
# "description": test_case.description,
|
||||||
"routed_agent_id": agent_id,
|
# "routed_agent_id": agent_id,
|
||||||
"routed_agent_name": agent_info.get("name"),
|
# "routed_agent_name": agent_info.get("name"),
|
||||||
"expected_agent_id": str(test_case.expected_agent_id) if test_case.expected_agent_id else None,
|
# "expected_agent_id": str(test_case.expected_agent_id) if test_case.expected_agent_id else None,
|
||||||
"is_correct": is_correct,
|
# "is_correct": is_correct,
|
||||||
"confidence": routing_result["confidence"],
|
# "confidence": routing_result["confidence"],
|
||||||
"routing_method": routing_result["routing_method"],
|
# "routing_method": routing_result["routing_method"],
|
||||||
"strategy": routing_result["strategy"]
|
# "strategy": routing_result["strategy"]
|
||||||
})
|
# })
|
||||||
|
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
logger.error(f"测试用例失败: {test_case.message}, 错误: {str(e)}")
|
# logger.error(f"测试用例失败: {test_case.message}, 错误: {str(e)}")
|
||||||
results.append({
|
# results.append({
|
||||||
"message": test_case.message,
|
# "message": test_case.message,
|
||||||
"description": test_case.description,
|
# "description": test_case.description,
|
||||||
"error": str(e)
|
# "error": str(e)
|
||||||
})
|
# })
|
||||||
|
|
||||||
# 6. 统计
|
# # 6. 统计
|
||||||
accuracy = None
|
# accuracy = None
|
||||||
if correct_count > 0:
|
# if correct_count > 0:
|
||||||
total_with_expected = sum(1 for r in results if r.get("expected_agent_id"))
|
# total_with_expected = sum(1 for r in results if r.get("expected_agent_id"))
|
||||||
if total_with_expected > 0:
|
# if total_with_expected > 0:
|
||||||
accuracy = correct_count / total_with_expected * 100
|
# accuracy = correct_count / total_with_expected * 100
|
||||||
|
|
||||||
response_data = {
|
# response_data = {
|
||||||
"total_count": total_count,
|
# "total_count": total_count,
|
||||||
"correct_count": correct_count,
|
# "correct_count": correct_count,
|
||||||
"accuracy": accuracy,
|
# "accuracy": accuracy,
|
||||||
"results": results,
|
# "results": results,
|
||||||
"config_info": {
|
# "config_info": {
|
||||||
"use_llm": request.use_llm and routing_model is not None,
|
# "use_llm": request.use_llm and routing_model is not None,
|
||||||
"routing_model": routing_model.name if routing_model else None,
|
# "routing_model": routing_model.name if routing_model else None,
|
||||||
"keyword_threshold": router.keyword_high_confidence_threshold
|
# "keyword_threshold": router.keyword_high_confidence_threshold
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
|
||||||
return success(
|
# return success(
|
||||||
data=response_data,
|
# data=response_data,
|
||||||
msg=f"批量测试完成,准确率: {accuracy:.1f}%" if accuracy else "批量测试完成"
|
# msg=f"批量测试完成,准确率: {accuracy:.1f}%" if accuracy else "批量测试完成"
|
||||||
)
|
# )
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import datetime
|
|||||||
from typing import Optional, List, Dict, Any, Union
|
from typing import Optional, List, Dict, Any, Union
|
||||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer
|
from pydantic import BaseModel, Field, ConfigDict, field_serializer
|
||||||
|
|
||||||
|
from app.schemas import ModelParameters
|
||||||
|
|
||||||
|
|
||||||
# ==================== 子 Agent 配置 ====================
|
# ==================== 子 Agent 配置 ====================
|
||||||
|
|
||||||
@@ -82,6 +84,11 @@ class MultiAgentConfigUpdate(BaseModel):
|
|||||||
"""更新多 Agent 配置"""
|
"""更新多 Agent 配置"""
|
||||||
master_agent_id: Optional[uuid.UUID] = None
|
master_agent_id: Optional[uuid.UUID] = None
|
||||||
master_agent_name: Optional[str] = Field(None, max_length=100, description="主 Agent 名称")
|
master_agent_name: Optional[str] = Field(None, max_length=100, description="主 Agent 名称")
|
||||||
|
default_model_config_id : uuid.UUID = Field(description="默认模型配置ID")
|
||||||
|
model_parameters: ModelParameters | None = Field(
|
||||||
|
default_factory=ModelParameters,
|
||||||
|
description="模型参数配置(temperature、max_tokens 等)"
|
||||||
|
)
|
||||||
orchestration_mode: Optional[str] = Field(
|
orchestration_mode: Optional[str] = Field(
|
||||||
None,
|
None,
|
||||||
pattern="^(sequential|parallel|conditional|loop)$"
|
pattern="^(sequential|parallel|conditional|loop)$"
|
||||||
@@ -104,6 +111,11 @@ class MultiAgentConfigSchema(BaseModel):
|
|||||||
app_id: uuid.UUID
|
app_id: uuid.UUID
|
||||||
master_agent_id: uuid.UUID
|
master_agent_id: uuid.UUID
|
||||||
master_agent_name: Optional[str]
|
master_agent_name: Optional[str]
|
||||||
|
default_model_config_id : uuid.UUID | None = Field(description="默认模型配置ID")
|
||||||
|
model_parameters: ModelParameters | None = Field(
|
||||||
|
default_factory=ModelParameters,
|
||||||
|
description="模型参数配置(temperature、max_tokens 等)"
|
||||||
|
)
|
||||||
orchestration_mode: str
|
orchestration_mode: str
|
||||||
sub_agents: List[Dict[str, Any]]
|
sub_agents: List[Dict[str, Any]]
|
||||||
routing_rules: Optional[List[Dict[str, Any]]]
|
routing_rules: Optional[List[Dict[str, Any]]]
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import uuid
|
|||||||
from typing import Dict, Any, List, Optional, Tuple
|
from typing import Dict, Any, List, Optional, Tuple
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
|
from app.schemas import ModelParameters
|
||||||
from app.services.conversation_state_manager import ConversationStateManager
|
from app.services.conversation_state_manager import ConversationStateManager
|
||||||
from app.models import ModelConfig, AgentConfig
|
from app.models import ModelConfig, AgentConfig
|
||||||
from app.core.logging_config import get_business_logger
|
from app.core.logging_config import get_business_logger
|
||||||
|
from app.services.model_service import ModelApiKeyService
|
||||||
|
|
||||||
logger = get_business_logger()
|
logger = get_business_logger()
|
||||||
|
|
||||||
@@ -30,8 +32,8 @@ class MasterAgentRouter:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
db: Session,
|
db: Session,
|
||||||
master_agent_config: AgentConfig,
|
|
||||||
master_model_config: ModelConfig,
|
master_model_config: ModelConfig,
|
||||||
|
model_parameters: ModelParameters,
|
||||||
sub_agents: Dict[str, Any],
|
sub_agents: Dict[str, Any],
|
||||||
state_manager: ConversationStateManager,
|
state_manager: ConversationStateManager,
|
||||||
enable_rule_fast_path: bool = True
|
enable_rule_fast_path: bool = True
|
||||||
@@ -40,15 +42,14 @@ class MasterAgentRouter:
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
db: 数据库会话
|
db: 数据库会话
|
||||||
master_agent_config: Master Agent 配置
|
|
||||||
master_model_config: Master Agent 使用的模型配置
|
master_model_config: Master Agent 使用的模型配置
|
||||||
sub_agents: 子 Agent 配置字典
|
sub_agents: 子 Agent 配置字典
|
||||||
state_manager: 会话状态管理器
|
state_manager: 会话状态管理器
|
||||||
enable_rule_fast_path: 是否启用规则快速路径(性能优化)
|
enable_rule_fast_path: 是否启用规则快速路径(性能优化)
|
||||||
"""
|
"""
|
||||||
self.db = db
|
self.db = db
|
||||||
self.master_agent_config = master_agent_config
|
|
||||||
self.master_model_config = master_model_config
|
self.master_model_config = master_model_config
|
||||||
|
self.model_parameters = model_parameters
|
||||||
self.sub_agents = sub_agents
|
self.sub_agents = sub_agents
|
||||||
self.state_manager = state_manager
|
self.state_manager = state_manager
|
||||||
self.enable_rule_fast_path = enable_rule_fast_path
|
self.enable_rule_fast_path = enable_rule_fast_path
|
||||||
@@ -56,7 +57,6 @@ class MasterAgentRouter:
|
|||||||
logger.info(
|
logger.info(
|
||||||
"Master Agent 路由器初始化",
|
"Master Agent 路由器初始化",
|
||||||
extra={
|
extra={
|
||||||
"master_agent": master_agent_config.name,
|
|
||||||
"sub_agent_count": len(sub_agents),
|
"sub_agent_count": len(sub_agents),
|
||||||
"enable_rule_fast_path": enable_rule_fast_path
|
"enable_rule_fast_path": enable_rule_fast_path
|
||||||
}
|
}
|
||||||
@@ -349,10 +349,7 @@ class MasterAgentRouter:
|
|||||||
from app.models import ModelApiKey, ModelType
|
from app.models import ModelApiKey, ModelType
|
||||||
|
|
||||||
# 获取 API Key 配置
|
# 获取 API Key 配置
|
||||||
api_key_config = self.db.query(ModelApiKey).filter(
|
api_key_config = ModelApiKeyService.get_a_api_key(self.db, self.master_model_config.id)
|
||||||
ModelApiKey.model_config_id == self.master_model_config.id,
|
|
||||||
ModelApiKey.is_active == True
|
|
||||||
).first()
|
|
||||||
|
|
||||||
if not api_key_config:
|
if not api_key_config:
|
||||||
raise Exception("Master Agent 模型没有可用的 API Key")
|
raise Exception("Master Agent 模型没有可用的 API Key")
|
||||||
@@ -364,15 +361,20 @@ class MasterAgentRouter:
|
|||||||
"model_name": api_key_config.model_name
|
"model_name": api_key_config.model_name
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
temperature = 0.3 # 决策任务使用较低温度
|
||||||
|
max_tokens = 1000
|
||||||
|
extra_params = None
|
||||||
|
if self.model_parameters:
|
||||||
|
extra_params = {"temperature": temperature,
|
||||||
|
"max_tokens":max_tokens
|
||||||
|
}
|
||||||
# 创建 RedBearModelConfig
|
# 创建 RedBearModelConfig
|
||||||
model_config = RedBearModelConfig(
|
model_config = RedBearModelConfig(
|
||||||
model_name=api_key_config.model_name,
|
model_name=api_key_config.model_name,
|
||||||
provider=api_key_config.provider,
|
provider=api_key_config.provider,
|
||||||
api_key=api_key_config.api_key,
|
api_key=api_key_config.api_key,
|
||||||
base_url=api_key_config.api_base,
|
base_url=api_key_config.api_base,
|
||||||
temperature=0.3, # 决策任务使用较低温度
|
extra_params = extra_params
|
||||||
max_tokens=1000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建 LLM 实例
|
# 创建 LLM 实例
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from typing import Dict, Any, List, Optional, AsyncIterator, Tuple
|
|||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.models import MultiAgentConfig, AgentConfig, ModelConfig
|
from app.models import MultiAgentConfig, AgentConfig, ModelConfig
|
||||||
|
from app.models.multi_agent_model import AggregationStrategy, OrchestrationMode
|
||||||
from app.services.agent_registry import AgentRegistry
|
from app.services.agent_registry import AgentRegistry
|
||||||
from app.services.master_agent_router import MasterAgentRouter
|
from app.services.master_agent_router import MasterAgentRouter
|
||||||
from app.services.conversation_state_manager import ConversationStateManager
|
from app.services.conversation_state_manager import ConversationStateManager
|
||||||
@@ -31,7 +32,10 @@ class MultiAgentOrchestrator:
|
|||||||
self.registry = AgentRegistry(db)
|
self.registry = AgentRegistry(db)
|
||||||
|
|
||||||
# 加载主 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.default_model_config_id = config.default_model_config_id
|
||||||
|
self.model_parameters = config.model_parameters
|
||||||
|
|
||||||
# 加载子 Agent
|
# 加载子 Agent
|
||||||
self.sub_agents = {}
|
self.sub_agents = {}
|
||||||
@@ -47,18 +51,18 @@ class MultiAgentOrchestrator:
|
|||||||
self.state_manager = ConversationStateManager()
|
self.state_manager = ConversationStateManager()
|
||||||
|
|
||||||
# 获取 Master Agent 的模型配置
|
# 获取 Master Agent 的模型配置
|
||||||
if not hasattr(self.master_agent, 'default_model_config_id'):
|
if not self.default_model_config_id:
|
||||||
raise BusinessException("Master Agent 缺少模型配置", BizCode.AGENT_CONFIG_MISSING)
|
raise BusinessException("Master Agent 缺少模型配置", BizCode.AGENT_CONFIG_MISSING)
|
||||||
|
|
||||||
self.master_model_config = self.db.get(ModelConfig, self.master_agent.default_model_config_id)
|
self.master_model_config = self.db.get(ModelConfig, self.default_model_config_id)
|
||||||
if not self.master_model_config:
|
if not self.master_model_config:
|
||||||
raise BusinessException("Master Agent 模型配置不存在", BizCode.AGENT_CONFIG_MISSING)
|
raise BusinessException("Master Agent 模型配置不存在", BizCode.AGENT_CONFIG_MISSING)
|
||||||
|
|
||||||
# 初始化 Master Agent 路由器
|
# 初始化 Master Agent 路由器
|
||||||
self.router = MasterAgentRouter(
|
self.router = MasterAgentRouter(
|
||||||
db=db,
|
db=db,
|
||||||
master_agent_config=self.master_agent,
|
|
||||||
master_model_config=self.master_model_config,
|
master_model_config=self.master_model_config,
|
||||||
|
model_parameters=self.model_parameters,
|
||||||
sub_agents=self.sub_agents,
|
sub_agents=self.sub_agents,
|
||||||
state_manager=self.state_manager,
|
state_manager=self.state_manager,
|
||||||
enable_rule_fast_path=config.execution_config.get("enable_rule_fast_path", True)
|
enable_rule_fast_path=config.execution_config.get("enable_rule_fast_path", True)
|
||||||
@@ -68,7 +72,6 @@ class MultiAgentOrchestrator:
|
|||||||
"多 Agent 编排器初始化完成",
|
"多 Agent 编排器初始化完成",
|
||||||
extra={
|
extra={
|
||||||
"config_id": str(config.id),
|
"config_id": str(config.id),
|
||||||
"master_agent": self.master_agent.name,
|
|
||||||
"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)
|
||||||
}
|
}
|
||||||
@@ -122,7 +125,7 @@ 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 == "conditional":
|
if self.config.orchestration_mode == OrchestrationMode.CONDITIONAL:
|
||||||
async for event in self._execute_conditional_stream(
|
async for event in self._execute_conditional_stream(
|
||||||
task_analysis,
|
task_analysis,
|
||||||
conversation_id,
|
conversation_id,
|
||||||
@@ -135,7 +138,7 @@ class MultiAgentOrchestrator:
|
|||||||
yield event
|
yield event
|
||||||
else:
|
else:
|
||||||
# 其他模式暂时使用非流式执行,然后一次性返回
|
# 其他模式暂时使用非流式执行,然后一次性返回
|
||||||
if self.config.orchestration_mode == "sequential":
|
if self.config.orchestration_mode == OrchestrationMode.SEQUENTIAL:
|
||||||
results = await self._execute_sequential(
|
results = await self._execute_sequential(
|
||||||
task_analysis,
|
task_analysis,
|
||||||
conversation_id,
|
conversation_id,
|
||||||
@@ -145,7 +148,7 @@ class MultiAgentOrchestrator:
|
|||||||
storage_type,
|
storage_type,
|
||||||
user_rag_memory_id
|
user_rag_memory_id
|
||||||
)
|
)
|
||||||
elif self.config.orchestration_mode == "parallel":
|
elif self.config.orchestration_mode == OrchestrationMode.PARALLEL:
|
||||||
results = await self._execute_parallel(
|
results = await self._execute_parallel(
|
||||||
task_analysis,
|
task_analysis,
|
||||||
conversation_id,
|
conversation_id,
|
||||||
@@ -155,16 +158,16 @@ class MultiAgentOrchestrator:
|
|||||||
storage_type,
|
storage_type,
|
||||||
user_rag_memory_id
|
user_rag_memory_id
|
||||||
)
|
)
|
||||||
elif self.config.orchestration_mode == "loop":
|
# elif self.config.orchestration_mode == "loop":
|
||||||
results = await self._execute_loop(
|
# results = await self._execute_loop(
|
||||||
task_analysis,
|
# task_analysis,
|
||||||
conversation_id,
|
# conversation_id,
|
||||||
user_id,
|
# user_id,
|
||||||
web_search,
|
# web_search,
|
||||||
memory,
|
# memory,
|
||||||
storage_type,
|
# storage_type,
|
||||||
user_rag_memory_id
|
# user_rag_memory_id
|
||||||
)
|
# )
|
||||||
else:
|
else:
|
||||||
raise BusinessException(
|
raise BusinessException(
|
||||||
f"不支持的编排模式: {self.config.orchestration_mode}",
|
f"不支持的编排模式: {self.config.orchestration_mode}",
|
||||||
@@ -968,17 +971,17 @@ class MultiAgentOrchestrator:
|
|||||||
else:
|
else:
|
||||||
# 2. 降级:使用旧的路由逻辑
|
# 2. 降级:使用旧的路由逻辑
|
||||||
logger.warning("未获取到 Master Agent 决策,使用旧路由逻辑(流式)")
|
logger.warning("未获取到 Master Agent 决策,使用旧路由逻辑(流式)")
|
||||||
use_llm = task_analysis.get("use_llm_routing", True)
|
# use_llm = task_analysis.get("use_llm_routing", True)
|
||||||
selected_agent_info = await self._route_by_rules(
|
# selected_agent_info = await self._route_by_rules(
|
||||||
message,
|
# message,
|
||||||
task_analysis["sub_agents"],
|
# task_analysis["sub_agents"],
|
||||||
use_llm=use_llm,
|
# use_llm=use_llm,
|
||||||
conversation_id=str(conversation_id) if conversation_id else None
|
# conversation_id=str(conversation_id) if conversation_id else None
|
||||||
)
|
# )
|
||||||
|
#
|
||||||
if not selected_agent_info:
|
# if not selected_agent_info:
|
||||||
selected_agent_info = task_analysis["sub_agents"][0]
|
selected_agent_info = task_analysis["sub_agents"][0]
|
||||||
logger.info("未匹配到路由规则,使用默认 Agent")
|
logger.info("未匹配到路由规则,使用默认 Agent")
|
||||||
|
|
||||||
agent_id = selected_agent_info["agent_id"]
|
agent_id = selected_agent_info["agent_id"]
|
||||||
|
|
||||||
@@ -1334,11 +1337,11 @@ class MultiAgentOrchestrator:
|
|||||||
"""
|
"""
|
||||||
strategy = self.config.aggregation_strategy
|
strategy = self.config.aggregation_strategy
|
||||||
|
|
||||||
if strategy == "merge":
|
if strategy == AggregationStrategy.MERGE:
|
||||||
return self._merge_results(results)
|
return self._merge_results(results)
|
||||||
elif strategy == "vote":
|
elif strategy == AggregationStrategy.VOTE:
|
||||||
return self._vote_results(results)
|
return self._vote_results(results)
|
||||||
elif strategy == "priority":
|
elif strategy == AggregationStrategy.PRIORITY:
|
||||||
return self._priority_results(results)
|
return self._priority_results(results)
|
||||||
else:
|
else:
|
||||||
return self._merge_results(results)
|
return self._merge_results(results)
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
"""多 Agent 配置管理服务"""
|
"""多 Agent 配置管理服务"""
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Optional, List, Tuple, Any
|
from typing import Optional, List, Tuple, Any, Annotated
|
||||||
|
|
||||||
|
from fastapi import Depends
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from sqlalchemy import select, desc
|
from sqlalchemy import select, desc
|
||||||
|
|
||||||
|
from app.db import get_db
|
||||||
from app.models import MultiAgentConfig, App, AgentConfig
|
from app.models import MultiAgentConfig, App, AgentConfig
|
||||||
from app.schemas.multi_agent_schema import (
|
from app.schemas.multi_agent_schema import (
|
||||||
MultiAgentConfigCreate,
|
MultiAgentConfigCreate,
|
||||||
MultiAgentConfigUpdate,
|
MultiAgentConfigUpdate,
|
||||||
MultiAgentRunRequest
|
MultiAgentRunRequest
|
||||||
)
|
)
|
||||||
|
from app.services.model_service import ModelApiKeyService
|
||||||
from app.services.multi_agent_orchestrator import MultiAgentOrchestrator
|
from app.services.multi_agent_orchestrator import MultiAgentOrchestrator
|
||||||
from app.core.exceptions import ResourceNotFoundException, BusinessException
|
from app.core.exceptions import ResourceNotFoundException, BusinessException
|
||||||
from app.core.error_codes import BizCode
|
from app.core.error_codes import BizCode
|
||||||
@@ -158,9 +162,10 @@ class MultiAgentService:
|
|||||||
if not config:
|
if not config:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 转换 master_agent_id (release_id) 为 app_id
|
#兼容代码
|
||||||
master_release = self.db.get(AppRelease, config.master_agent_id)
|
if not config.default_model_config_id:
|
||||||
master_app_id = master_release.app_id if master_release else config.master_agent_id
|
master_release = self.db.get(AppRelease, config.master_agent_id)
|
||||||
|
config.default_model_config_id = master_release.default_model_config_id if master_release else None
|
||||||
|
|
||||||
# 转换 sub_agents 中的 agent_id (release_id) 为 app_id
|
# 转换 sub_agents 中的 agent_id (release_id) 为 app_id
|
||||||
converted_sub_agents = []
|
converted_sub_agents = []
|
||||||
@@ -181,8 +186,8 @@ class MultiAgentService:
|
|||||||
return {
|
return {
|
||||||
"id": config.id,
|
"id": config.id,
|
||||||
"app_id": config.app_id,
|
"app_id": config.app_id,
|
||||||
"master_agent_id": master_app_id,
|
"default_model_config_id": config.default_model_config_id,
|
||||||
"master_agent_name": config.master_agent_name,
|
"model_parameters": config.model_parameters,
|
||||||
"orchestration_mode": config.orchestration_mode,
|
"orchestration_mode": config.orchestration_mode,
|
||||||
"sub_agents": converted_sub_agents,
|
"sub_agents": converted_sub_agents,
|
||||||
"routing_rules": config.routing_rules,
|
"routing_rules": config.routing_rules,
|
||||||
@@ -253,6 +258,52 @@ class MultiAgentService:
|
|||||||
return None
|
return None
|
||||||
return release
|
return release
|
||||||
|
|
||||||
|
def check_config_data(self,app_id: uuid.UUID, data: MultiAgentConfigUpdate) -> MultiAgentConfig:
|
||||||
|
# 1. 验证应用存在
|
||||||
|
app = self.db.get(App, app_id)
|
||||||
|
if not app:
|
||||||
|
raise ResourceNotFoundException("应用", str(app_id))
|
||||||
|
|
||||||
|
# 2. 验证模型配置
|
||||||
|
model_api_key = ModelApiKeyService.get_a_api_key(self.db,data.default_model_config_id)
|
||||||
|
if not model_api_key:
|
||||||
|
raise ResourceNotFoundException("模型配置", str(data.default_model_config_id))
|
||||||
|
|
||||||
|
# 3. 验证子 Agent 存在并获取发布版本 ID
|
||||||
|
for sub_agent in data.sub_agents:
|
||||||
|
agent_app_release = self.get_published_by_agent_id(sub_agent.agent_id)
|
||||||
|
if not agent_app_release:
|
||||||
|
raise ResourceNotFoundException("子 Agent 未发布或不存在", str(sub_agent.agent_id))
|
||||||
|
|
||||||
|
# 使用发布版本 ID
|
||||||
|
sub_agent.agent_id = agent_app_release.id
|
||||||
|
|
||||||
|
# 5. 创建配置(转换 UUID 为字符串以支持 JSON 序列化)
|
||||||
|
sub_agents_data = [convert_uuids_to_str(sub_agent.model_dump()) for sub_agent in data.sub_agents]
|
||||||
|
# routing_rules_data = [convert_uuids_to_str(rule.model_dump()) for rule in data.routing_rules] if data.routing_rules else None
|
||||||
|
|
||||||
|
# 处理 execution_config(可能是 None、字典或 Pydantic 模型)
|
||||||
|
if data.execution_config is None:
|
||||||
|
execution_config_data = {}
|
||||||
|
elif isinstance(data.execution_config, dict):
|
||||||
|
execution_config_data = convert_uuids_to_str(data.execution_config)
|
||||||
|
else:
|
||||||
|
execution_config_data = convert_uuids_to_str(data.execution_config.model_dump())
|
||||||
|
|
||||||
|
config = MultiAgentConfig(
|
||||||
|
app_id=app_id,
|
||||||
|
master_agent_id=data.master_agent_id,
|
||||||
|
master_agent_name=data.master_agent_name,
|
||||||
|
default_model_config_id=data.default_model_config_id,
|
||||||
|
model_parameters=data.model_parameters,
|
||||||
|
orchestration_mode=data.orchestration_mode,
|
||||||
|
sub_agents=sub_agents_data,
|
||||||
|
# routing_rules=routing_rules_data,
|
||||||
|
execution_config=execution_config_data,
|
||||||
|
aggregation_strategy=data.aggregation_strategy
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
def update_config(
|
def update_config(
|
||||||
self,
|
self,
|
||||||
app_id: uuid.UUID,
|
app_id: uuid.UUID,
|
||||||
@@ -268,57 +319,12 @@ class MultiAgentService:
|
|||||||
更新后的配置
|
更新后的配置
|
||||||
"""
|
"""
|
||||||
config = self.get_config(app_id)
|
config = self.get_config(app_id)
|
||||||
|
newConfig = self.check_config_data(app_id, data)
|
||||||
if not config:
|
if not config:
|
||||||
# 1. 验证应用存在
|
config = newConfig
|
||||||
app = self.db.get(App, app_id)
|
|
||||||
if not app:
|
|
||||||
raise ResourceNotFoundException("应用", str(app_id))
|
|
||||||
|
|
||||||
# 2. 验证主 Agent 存在并获取发布版本 ID
|
|
||||||
master_app_release = self.get_published_by_agent_id(data.master_agent_id)
|
|
||||||
if not master_app_release:
|
|
||||||
raise ResourceNotFoundException("主 Agent 未发布或不存在", str(data.master_agent_id))
|
|
||||||
|
|
||||||
# 使用发布版本 ID
|
|
||||||
data.master_agent_id = master_app_release.id
|
|
||||||
|
|
||||||
# 3. 验证子 Agent 存在并获取发布版本 ID
|
|
||||||
for sub_agent in data.sub_agents:
|
|
||||||
agent_app_release = self.get_published_by_agent_id(sub_agent.agent_id)
|
|
||||||
if not agent_app_release:
|
|
||||||
raise ResourceNotFoundException("子 Agent 未发布或不存在", str(sub_agent.agent_id))
|
|
||||||
|
|
||||||
# 使用发布版本 ID
|
|
||||||
sub_agent.agent_id = agent_app_release.id
|
|
||||||
|
|
||||||
|
|
||||||
# 5. 创建配置(转换 UUID 为字符串以支持 JSON 序列化)
|
|
||||||
sub_agents_data = [convert_uuids_to_str(sub_agent.model_dump()) for sub_agent in data.sub_agents]
|
|
||||||
# routing_rules_data = [convert_uuids_to_str(rule.model_dump()) for rule in data.routing_rules] if data.routing_rules else None
|
|
||||||
|
|
||||||
# 处理 execution_config(可能是 None、字典或 Pydantic 模型)
|
|
||||||
if data.execution_config is None:
|
|
||||||
execution_config_data = {}
|
|
||||||
elif isinstance(data.execution_config, dict):
|
|
||||||
execution_config_data = convert_uuids_to_str(data.execution_config)
|
|
||||||
else:
|
|
||||||
execution_config_data = convert_uuids_to_str(data.execution_config.model_dump())
|
|
||||||
|
|
||||||
config = MultiAgentConfig(
|
|
||||||
app_id=app_id,
|
|
||||||
master_agent_id=data.master_agent_id,
|
|
||||||
master_agent_name=data.master_agent_name,
|
|
||||||
orchestration_mode=data.orchestration_mode,
|
|
||||||
sub_agents=sub_agents_data,
|
|
||||||
# routing_rules=routing_rules_data,
|
|
||||||
execution_config=execution_config_data,
|
|
||||||
aggregation_strategy=data.aggregation_strategy
|
|
||||||
)
|
|
||||||
|
|
||||||
self.db.add(config)
|
self.db.add(config)
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(config)
|
self.db.refresh(config)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"创建多 Agent 配置成功",
|
"创建多 Agent 配置成功",
|
||||||
extra={
|
extra={
|
||||||
@@ -329,53 +335,14 @@ class MultiAgentService:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return config
|
return config
|
||||||
# raise ResourceNotFoundException("多 Agent 配置", str(app_id))
|
|
||||||
|
|
||||||
# 更新字段
|
|
||||||
if data.master_agent_id is not None:
|
|
||||||
# 验证主 Agent 存在
|
|
||||||
# 3. 验证主 Agent 存在并获取发布配置
|
|
||||||
master_app_release = self.get_published_by_agent_id(data.master_agent_id)
|
|
||||||
if not master_app_release:
|
|
||||||
raise ResourceNotFoundException("主 Agent 未发布或", str(data.master_agent_id))
|
|
||||||
|
|
||||||
config.master_agent_id = master_app_release.id
|
|
||||||
|
|
||||||
if data.master_agent_name is not None:
|
|
||||||
config.master_agent_name = data.master_agent_name
|
|
||||||
|
|
||||||
if data.orchestration_mode is not None:
|
|
||||||
config.orchestration_mode = data.orchestration_mode
|
|
||||||
|
|
||||||
if data.sub_agents is not None:
|
|
||||||
# 验证子 Agent 存在,并获取其发布的 config_id
|
|
||||||
updated_sub_agents = []
|
|
||||||
for sub_agent in data.sub_agents:
|
|
||||||
agent_app_release = self.get_published_by_agent_id(sub_agent.agent_id)
|
|
||||||
if not agent_app_release:
|
|
||||||
raise ResourceNotFoundException("子 Agent 未发布或", str(sub_agent.agent_id))
|
|
||||||
sub_agent.agent_id = agent_app_release.id
|
|
||||||
sub_agent_dict = convert_uuids_to_str(sub_agent.model_dump())
|
|
||||||
updated_sub_agents.append(sub_agent_dict)
|
|
||||||
|
|
||||||
config.sub_agents = updated_sub_agents
|
|
||||||
|
|
||||||
# if data.routing_rules is not None:
|
|
||||||
# config.routing_rules = [convert_uuids_to_str(rule.model_dump()) for rule in data.routing_rules] if data.routing_rules else None
|
|
||||||
|
|
||||||
if data.execution_config is not None:
|
|
||||||
if isinstance(data.execution_config, dict):
|
|
||||||
execution_config_data = convert_uuids_to_str(data.execution_config)
|
|
||||||
else:
|
|
||||||
execution_config_data = convert_uuids_to_str(data.execution_config.model_dump())
|
|
||||||
config.execution_config = execution_config_data
|
|
||||||
|
|
||||||
if data.aggregation_strategy is not None:
|
|
||||||
config.aggregation_strategy = data.aggregation_strategy
|
|
||||||
|
|
||||||
if data.is_active is not None:
|
|
||||||
config.is_active = data.is_active
|
|
||||||
|
|
||||||
|
config.default_model_config_id = newConfig.default_model_config_id
|
||||||
|
config.model_parameters = newConfig.model_parameters
|
||||||
|
config.orchestration_mode = newConfig.orchestration_mode
|
||||||
|
config.sub_agents = newConfig.sub_agents
|
||||||
|
config.routing_rules = newConfig.routing_rules
|
||||||
|
config.execution_config = newConfig.execution_config
|
||||||
|
config.aggregation_strategy = newConfig.aggregation_strategy
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
self.db.refresh(config)
|
self.db.refresh(config)
|
||||||
|
|
||||||
@@ -490,111 +457,111 @@ class MultiAgentService:
|
|||||||
):
|
):
|
||||||
yield event
|
yield event
|
||||||
|
|
||||||
def add_sub_agent(
|
# def add_sub_agent(
|
||||||
self,
|
# self,
|
||||||
app_id: uuid.UUID,
|
# app_id: uuid.UUID,
|
||||||
agent_id: uuid.UUID,
|
# agent_id: uuid.UUID,
|
||||||
name: str,
|
# name: str,
|
||||||
role: Optional[str] = None,
|
# role: Optional[str] = None,
|
||||||
priority: int = 1,
|
# priority: int = 1,
|
||||||
capabilities: Optional[List[str]] = None
|
# capabilities: Optional[List[str]] = None
|
||||||
) -> MultiAgentConfig:
|
# ) -> MultiAgentConfig:
|
||||||
"""添加子 Agent
|
# """添加子 Agent
|
||||||
|
|
||||||
Args:
|
# Args:
|
||||||
app_id: 应用 ID
|
# app_id: 应用 ID
|
||||||
agent_id: Agent ID
|
# agent_id: Agent ID
|
||||||
name: Agent 名称
|
# name: Agent 名称
|
||||||
role: 角色描述
|
# role: 角色描述
|
||||||
priority: 优先级
|
# priority: 优先级
|
||||||
capabilities: 能力列表
|
# capabilities: 能力列表
|
||||||
|
|
||||||
Returns:
|
# Returns:
|
||||||
更新后的配置
|
# 更新后的配置
|
||||||
"""
|
# """
|
||||||
config = self.get_config(app_id)
|
# config = self.get_config(app_id)
|
||||||
if not config:
|
# if not config:
|
||||||
raise ResourceNotFoundException("多 Agent 配置", str(app_id))
|
# raise ResourceNotFoundException("多 Agent 配置", str(app_id))
|
||||||
|
|
||||||
# 验证 Agent 存在
|
# # 验证 Agent 存在
|
||||||
agent = self.db.get(AgentConfig, agent_id)
|
# agent = self.db.get(AgentConfig, agent_id)
|
||||||
if not agent:
|
# if not agent:
|
||||||
raise ResourceNotFoundException("Agent", str(agent_id))
|
# raise ResourceNotFoundException("Agent", str(agent_id))
|
||||||
|
|
||||||
# 检查是否已存在
|
# # 检查是否已存在
|
||||||
for sub_agent in config.sub_agents:
|
# for sub_agent in config.sub_agents:
|
||||||
if sub_agent["agent_id"] == str(agent_id):
|
# if sub_agent["agent_id"] == str(agent_id):
|
||||||
raise BusinessException("Agent 已存在于配置中", BizCode.DUPLICATE_RESOURCE)
|
# raise BusinessException("Agent 已存在于配置中", BizCode.DUPLICATE_RESOURCE)
|
||||||
|
|
||||||
# 添加子 Agent
|
# # 添加子 Agent
|
||||||
new_sub_agent = {
|
# new_sub_agent = {
|
||||||
"agent_id": str(agent_id),
|
# "agent_id": str(agent_id),
|
||||||
"name": name,
|
# "name": name,
|
||||||
"role": role,
|
# "role": role,
|
||||||
"priority": priority,
|
# "priority": priority,
|
||||||
"capabilities": capabilities or []
|
# "capabilities": capabilities or []
|
||||||
}
|
# }
|
||||||
|
|
||||||
config.sub_agents.append(new_sub_agent)
|
# config.sub_agents.append(new_sub_agent)
|
||||||
|
|
||||||
# 标记为已修改
|
# # 标记为已修改
|
||||||
self.db.add(config)
|
# self.db.add(config)
|
||||||
self.db.commit()
|
# self.db.commit()
|
||||||
self.db.refresh(config)
|
# self.db.refresh(config)
|
||||||
|
|
||||||
logger.info(
|
# logger.info(
|
||||||
"添加子 Agent 成功",
|
# "添加子 Agent 成功",
|
||||||
extra={
|
# extra={
|
||||||
"config_id": str(config.id),
|
# "config_id": str(config.id),
|
||||||
"agent_id": str(agent_id),
|
# "agent_id": str(agent_id),
|
||||||
"agent_name": name
|
# "agent_name": name
|
||||||
}
|
# }
|
||||||
)
|
# )
|
||||||
|
|
||||||
return config
|
# return config
|
||||||
|
|
||||||
def remove_sub_agent(
|
# def remove_sub_agent(
|
||||||
self,
|
# self,
|
||||||
app_id: uuid.UUID,
|
# app_id: uuid.UUID,
|
||||||
agent_id: uuid.UUID
|
# agent_id: uuid.UUID
|
||||||
) -> MultiAgentConfig:
|
# ) -> MultiAgentConfig:
|
||||||
"""移除子 Agent
|
# """移除子 Agent
|
||||||
|
|
||||||
Args:
|
# Args:
|
||||||
app_id: 应用 ID
|
# app_id: 应用 ID
|
||||||
agent_id: Agent ID
|
# agent_id: Agent ID
|
||||||
|
|
||||||
Returns:
|
# Returns:
|
||||||
更新后的配置
|
# 更新后的配置
|
||||||
"""
|
# """
|
||||||
config = self.get_config(app_id)
|
# config = self.get_config(app_id)
|
||||||
if not config:
|
# if not config:
|
||||||
raise ResourceNotFoundException("多 Agent 配置", str(app_id))
|
# raise ResourceNotFoundException("多 Agent 配置", str(app_id))
|
||||||
|
|
||||||
# 查找并移除
|
# # 查找并移除
|
||||||
original_count = len(config.sub_agents)
|
# original_count = len(config.sub_agents)
|
||||||
config.sub_agents = [
|
# config.sub_agents = [
|
||||||
sub_agent for sub_agent in config.sub_agents
|
# sub_agent for sub_agent in config.sub_agents
|
||||||
if sub_agent["agent_id"] != str(agent_id)
|
# if sub_agent["agent_id"] != str(agent_id)
|
||||||
]
|
# ]
|
||||||
|
|
||||||
if len(config.sub_agents) == original_count:
|
# if len(config.sub_agents) == original_count:
|
||||||
raise ResourceNotFoundException("子 Agent", str(agent_id))
|
# raise ResourceNotFoundException("子 Agent", str(agent_id))
|
||||||
|
|
||||||
# 标记为已修改
|
# # 标记为已修改
|
||||||
self.db.add(config)
|
# self.db.add(config)
|
||||||
self.db.commit()
|
# self.db.commit()
|
||||||
self.db.refresh(config)
|
# self.db.refresh(config)
|
||||||
|
|
||||||
logger.info(
|
# logger.info(
|
||||||
"移除子 Agent 成功",
|
# "移除子 Agent 成功",
|
||||||
extra={
|
# extra={
|
||||||
"config_id": str(config.id),
|
# "config_id": str(config.id),
|
||||||
"agent_id": str(agent_id)
|
# "agent_id": str(agent_id)
|
||||||
}
|
# }
|
||||||
)
|
# )
|
||||||
|
|
||||||
return config
|
# return config
|
||||||
|
|
||||||
def list_configs(
|
def list_configs(
|
||||||
self,
|
self,
|
||||||
@@ -629,3 +596,11 @@ class MultiAgentService:
|
|||||||
configs = list(self.db.scalars(stmt).all())
|
configs = list(self.db.scalars(stmt).all())
|
||||||
|
|
||||||
return configs, total
|
return configs, total
|
||||||
|
|
||||||
|
# ==================== 依赖注入函数 ====================
|
||||||
|
|
||||||
|
def get_multi_agent_service(
|
||||||
|
db: Annotated[Session, Depends(get_db)]
|
||||||
|
) -> MultiAgentService:
|
||||||
|
"""获取工作流服务(依赖注入)"""
|
||||||
|
return MultiAgentService(db)
|
||||||
|
|||||||
Reference in New Issue
Block a user