first commit
This commit is contained in:
22
src/agent/__init__.py
Normal file
22
src/agent/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Agent模块初始化文件
|
||||
"""
|
||||
|
||||
from .agent_core import AgentCore, AgentState
|
||||
from .planner import TaskPlanner
|
||||
from .executor import TaskExecutor
|
||||
from .tool_manager import ToolManager
|
||||
from .reasoning_engine import ReasoningEngine
|
||||
from .goal_manager import GoalManager
|
||||
|
||||
__all__ = [
|
||||
'AgentCore',
|
||||
'AgentState',
|
||||
'TaskPlanner',
|
||||
'TaskExecutor',
|
||||
'ToolManager',
|
||||
'ReasoningEngine',
|
||||
'GoalManager'
|
||||
]
|
||||
BIN
src/agent/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/agent_core.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/agent_core.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/executor.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/executor.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/goal_manager.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/goal_manager.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/planner.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/planner.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/reasoning_engine.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/reasoning_engine.cpython-311.pyc
Normal file
Binary file not shown.
BIN
src/agent/__pycache__/tool_manager.cpython-311.pyc
Normal file
BIN
src/agent/__pycache__/tool_manager.cpython-311.pyc
Normal file
Binary file not shown.
312
src/agent/agent_core.py
Normal file
312
src/agent/agent_core.py
Normal file
@@ -0,0 +1,312 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Agent核心模块
|
||||
实现智能体的核心逻辑和决策机制
|
||||
"""
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import Dict, List, Any, Optional, Callable
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
import json
|
||||
|
||||
from ..core.database import db_manager
|
||||
from ..core.llm_client import QwenClient
|
||||
from .planner import TaskPlanner
|
||||
from .executor import TaskExecutor
|
||||
from .tool_manager import ToolManager
|
||||
from .reasoning_engine import ReasoningEngine
|
||||
from .goal_manager import GoalManager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class AgentState(Enum):
|
||||
"""Agent状态枚举"""
|
||||
IDLE = "idle"
|
||||
THINKING = "thinking"
|
||||
PLANNING = "planning"
|
||||
EXECUTING = "executing"
|
||||
LEARNING = "learning"
|
||||
ERROR = "error"
|
||||
|
||||
class AgentCore:
|
||||
"""Agent核心类"""
|
||||
|
||||
def __init__(self):
|
||||
self.state = AgentState.IDLE
|
||||
self.llm_client = QwenClient()
|
||||
self.planner = TaskPlanner()
|
||||
self.executor = TaskExecutor()
|
||||
self.tool_manager = ToolManager()
|
||||
self.reasoning_engine = ReasoningEngine()
|
||||
self.goal_manager = GoalManager()
|
||||
|
||||
# Agent记忆和上下文
|
||||
self.memory = {}
|
||||
self.current_goal = None
|
||||
self.active_tasks = []
|
||||
self.execution_history = []
|
||||
|
||||
# 配置参数
|
||||
self.max_iterations = 10
|
||||
self.confidence_threshold = 0.7
|
||||
|
||||
logger.info("Agent核心初始化完成")
|
||||
|
||||
async def process_request(self, request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""处理用户请求的主入口"""
|
||||
try:
|
||||
self.state = AgentState.THINKING
|
||||
|
||||
# 1. 理解用户意图
|
||||
intent = await self._understand_intent(request)
|
||||
|
||||
# 2. 设定目标
|
||||
goal = await self._set_goal(intent, request)
|
||||
|
||||
# 3. 制定计划
|
||||
plan = await self._create_plan(goal)
|
||||
|
||||
# 4. 执行计划
|
||||
result = await self._execute_plan(plan)
|
||||
|
||||
# 5. 学习和反思
|
||||
await self._learn_from_execution(result)
|
||||
|
||||
self.state = AgentState.IDLE
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理请求失败: {e}")
|
||||
self.state = AgentState.ERROR
|
||||
return {"error": f"处理失败: {str(e)}"}
|
||||
|
||||
async def _understand_intent(self, request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""理解用户意图"""
|
||||
user_message = request.get("message", "")
|
||||
context = request.get("context", {})
|
||||
|
||||
# 使用推理引擎分析意图
|
||||
intent_analysis = await self.reasoning_engine.analyze_intent(
|
||||
message=user_message,
|
||||
context=context,
|
||||
history=self.execution_history[-5:] # 最近5次执行历史
|
||||
)
|
||||
|
||||
return intent_analysis
|
||||
|
||||
async def _set_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""设定目标"""
|
||||
goal = await self.goal_manager.create_goal(
|
||||
intent=intent,
|
||||
request=request,
|
||||
current_state=self.state
|
||||
)
|
||||
|
||||
self.current_goal = goal
|
||||
return goal
|
||||
|
||||
async def _create_plan(self, goal: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""制定执行计划"""
|
||||
self.state = AgentState.PLANNING
|
||||
|
||||
plan = await self.planner.create_plan(
|
||||
goal=goal,
|
||||
available_tools=self.tool_manager.get_available_tools(),
|
||||
constraints=self._get_constraints()
|
||||
)
|
||||
|
||||
return plan
|
||||
|
||||
async def _execute_plan(self, plan: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""执行计划"""
|
||||
self.state = AgentState.EXECUTING
|
||||
|
||||
execution_result = await self.executor.execute_plan(
|
||||
plan=plan,
|
||||
tool_manager=self.tool_manager,
|
||||
context=self.memory
|
||||
)
|
||||
|
||||
# 记录执行历史
|
||||
self.execution_history.append({
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"plan": plan,
|
||||
"result": execution_result
|
||||
})
|
||||
|
||||
return execution_result
|
||||
|
||||
async def _learn_from_execution(self, result: Dict[str, Any]):
|
||||
"""从执行结果中学习"""
|
||||
self.state = AgentState.LEARNING
|
||||
|
||||
# 分析执行效果
|
||||
learning_insights = await self.reasoning_engine.extract_insights(
|
||||
execution_result=result,
|
||||
goal=self.current_goal
|
||||
)
|
||||
|
||||
# 更新记忆
|
||||
self._update_memory(learning_insights)
|
||||
|
||||
# 更新工具使用统计
|
||||
self.tool_manager.update_usage_stats(result.get("tool_usage", []))
|
||||
|
||||
def _get_constraints(self) -> Dict[str, Any]:
|
||||
"""获取执行约束"""
|
||||
return {
|
||||
"max_iterations": self.max_iterations,
|
||||
"confidence_threshold": self.confidence_threshold,
|
||||
"timeout": 300, # 5分钟超时
|
||||
"memory_limit": 1000 # 内存限制
|
||||
}
|
||||
|
||||
def _update_memory(self, insights: Dict[str, Any]):
|
||||
"""更新Agent记忆"""
|
||||
timestamp = datetime.now().isoformat()
|
||||
|
||||
# 更新成功模式
|
||||
if insights.get("success_patterns"):
|
||||
if "success_patterns" not in self.memory:
|
||||
self.memory["success_patterns"] = []
|
||||
self.memory["success_patterns"].extend(insights["success_patterns"])
|
||||
|
||||
# 更新失败模式
|
||||
if insights.get("failure_patterns"):
|
||||
if "failure_patterns" not in self.memory:
|
||||
self.memory["failure_patterns"] = []
|
||||
self.memory["failure_patterns"].extend(insights["failure_patterns"])
|
||||
|
||||
# 更新知识
|
||||
if insights.get("new_knowledge"):
|
||||
if "knowledge" not in self.memory:
|
||||
self.memory["knowledge"] = []
|
||||
self.memory["knowledge"].extend(insights["new_knowledge"])
|
||||
|
||||
# 限制记忆大小
|
||||
for key in self.memory:
|
||||
if isinstance(self.memory[key], list) and len(self.memory[key]) > 100:
|
||||
self.memory[key] = self.memory[key][-100:]
|
||||
|
||||
async def proactive_action(self) -> Optional[Dict[str, Any]]:
|
||||
"""主动行动 - Agent主动发起的行为"""
|
||||
try:
|
||||
# 检查是否有需要主动处理的任务
|
||||
proactive_tasks = await self._identify_proactive_tasks()
|
||||
|
||||
if proactive_tasks:
|
||||
# 选择最重要的任务
|
||||
priority_task = max(proactive_tasks, key=lambda x: x.get("priority", 0))
|
||||
|
||||
# 执行主动任务
|
||||
result = await self.process_request(priority_task)
|
||||
return result
|
||||
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"主动行动失败: {e}")
|
||||
return None
|
||||
|
||||
async def _identify_proactive_tasks(self) -> List[Dict[str, Any]]:
|
||||
"""识别需要主动处理的任务"""
|
||||
tasks = []
|
||||
|
||||
# 检查预警系统
|
||||
alerts = await self._check_alerts()
|
||||
if alerts:
|
||||
tasks.extend([{
|
||||
"type": "alert_response",
|
||||
"message": f"处理预警: {alert['message']}",
|
||||
"priority": self._calculate_alert_priority(alert),
|
||||
"context": {"alert": alert}
|
||||
} for alert in alerts])
|
||||
|
||||
# 检查知识库更新需求
|
||||
knowledge_gaps = await self._identify_knowledge_gaps()
|
||||
if knowledge_gaps:
|
||||
tasks.append({
|
||||
"type": "knowledge_update",
|
||||
"message": "更新知识库",
|
||||
"priority": 0.6,
|
||||
"context": {"gaps": knowledge_gaps}
|
||||
})
|
||||
|
||||
# 检查系统健康状态
|
||||
health_issues = await self._check_system_health()
|
||||
if health_issues:
|
||||
tasks.append({
|
||||
"type": "system_maintenance",
|
||||
"message": "系统维护",
|
||||
"priority": 0.8,
|
||||
"context": {"issues": health_issues}
|
||||
})
|
||||
|
||||
return tasks
|
||||
|
||||
async def _check_alerts(self) -> List[Dict[str, Any]]:
|
||||
"""检查预警"""
|
||||
# 这里可以调用现有的预警系统
|
||||
from ..analytics.alert_system import AlertSystem
|
||||
alert_system = AlertSystem()
|
||||
return alert_system.get_active_alerts()
|
||||
|
||||
def _calculate_alert_priority(self, alert: Dict[str, Any]) -> float:
|
||||
"""计算预警优先级"""
|
||||
severity_map = {
|
||||
"low": 0.3,
|
||||
"medium": 0.6,
|
||||
"high": 0.8,
|
||||
"critical": 1.0
|
||||
}
|
||||
return severity_map.get(alert.get("severity", "medium"), 0.5)
|
||||
|
||||
async def _identify_knowledge_gaps(self) -> List[Dict[str, Any]]:
|
||||
"""识别知识库缺口"""
|
||||
# 分析未解决的问题,识别知识缺口
|
||||
gaps = []
|
||||
|
||||
# 这里可以实现具体的知识缺口识别逻辑
|
||||
# 例如:分析低置信度的回复、未解决的问题等
|
||||
|
||||
return gaps
|
||||
|
||||
async def _check_system_health(self) -> List[Dict[str, Any]]:
|
||||
"""检查系统健康状态"""
|
||||
issues = []
|
||||
|
||||
# 检查各个组件的健康状态
|
||||
if not self.llm_client.test_connection():
|
||||
issues.append({"component": "llm_client", "issue": "连接失败"})
|
||||
|
||||
# 检查内存使用
|
||||
import psutil
|
||||
memory_percent = psutil.virtual_memory().percent
|
||||
if memory_percent > 80:
|
||||
issues.append({"component": "memory", "issue": f"内存使用率过高: {memory_percent}%"})
|
||||
|
||||
return issues
|
||||
|
||||
def get_status(self) -> Dict[str, Any]:
|
||||
"""获取Agent状态"""
|
||||
return {
|
||||
"state": self.state.value,
|
||||
"current_goal": self.current_goal,
|
||||
"active_tasks": len(self.active_tasks),
|
||||
"execution_history_count": len(self.execution_history),
|
||||
"memory_size": len(str(self.memory)),
|
||||
"available_tools": len(self.tool_manager.get_available_tools()),
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
def reset(self):
|
||||
"""重置Agent状态"""
|
||||
self.state = AgentState.IDLE
|
||||
self.current_goal = None
|
||||
self.active_tasks = []
|
||||
self.execution_history = []
|
||||
self.memory = {}
|
||||
logger.info("Agent状态已重置")
|
||||
589
src/agent/executor.py
Normal file
589
src/agent/executor.py
Normal file
@@ -0,0 +1,589 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
任务执行器
|
||||
负责执行计划中的具体任务
|
||||
"""
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import Dict, List, Any, Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class TaskExecutor:
|
||||
"""任务执行器"""
|
||||
|
||||
def __init__(self):
|
||||
self.execution_strategies = {
|
||||
"sequential": self._execute_sequential,
|
||||
"parallel": self._execute_parallel,
|
||||
"conditional": self._execute_conditional,
|
||||
"iterative": self._execute_iterative
|
||||
}
|
||||
self.active_executions = {}
|
||||
|
||||
async def execute_plan(
|
||||
self,
|
||||
plan: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行计划"""
|
||||
try:
|
||||
execution_id = f"exec_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
||||
self.active_executions[execution_id] = {
|
||||
"start_time": datetime.now(),
|
||||
"status": "running",
|
||||
"plan": plan
|
||||
}
|
||||
|
||||
# 根据计划类型选择执行策略
|
||||
execution_strategy = self._determine_execution_strategy(plan)
|
||||
|
||||
# 执行计划
|
||||
result = await self.execution_strategies[execution_strategy](
|
||||
plan=plan,
|
||||
tool_manager=tool_manager,
|
||||
context=context,
|
||||
execution_id=execution_id
|
||||
)
|
||||
|
||||
# 更新执行状态
|
||||
self.active_executions[execution_id]["status"] = "completed"
|
||||
self.active_executions[execution_id]["end_time"] = datetime.now()
|
||||
self.active_executions[execution_id]["result"] = result
|
||||
|
||||
logger.info(f"计划执行完成: {execution_id}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行计划失败: {e}")
|
||||
if execution_id in self.active_executions:
|
||||
self.active_executions[execution_id]["status"] = "failed"
|
||||
self.active_executions[execution_id]["error"] = str(e)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"execution_id": execution_id
|
||||
}
|
||||
|
||||
def _determine_execution_strategy(self, plan: List[Dict[str, Any]]) -> str:
|
||||
"""确定执行策略"""
|
||||
if not plan:
|
||||
return "sequential"
|
||||
|
||||
# 检查计划类型
|
||||
plan_types = [task.get("type") for task in plan]
|
||||
|
||||
if "parallel_group" in plan_types:
|
||||
return "parallel"
|
||||
elif "condition" in plan_types or "branch" in plan_types:
|
||||
return "conditional"
|
||||
elif "iteration_control" in plan_types:
|
||||
return "iterative"
|
||||
else:
|
||||
return "sequential"
|
||||
|
||||
async def _execute_sequential(
|
||||
self,
|
||||
plan: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any],
|
||||
execution_id: str
|
||||
) -> Dict[str, Any]:
|
||||
"""顺序执行计划"""
|
||||
results = []
|
||||
execution_log = []
|
||||
|
||||
for i, task in enumerate(plan):
|
||||
try:
|
||||
logger.info(f"执行任务 {i+1}/{len(plan)}: {task.get('id', 'unknown')}")
|
||||
|
||||
# 检查任务依赖
|
||||
if not await self._check_dependencies(task, results):
|
||||
logger.warning(f"任务 {task.get('id')} 的依赖未满足,跳过执行")
|
||||
continue
|
||||
|
||||
# 执行任务
|
||||
task_result = await self._execute_single_task(task, tool_manager, context)
|
||||
|
||||
results.append({
|
||||
"task_id": task.get("id"),
|
||||
"result": task_result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
execution_log.append({
|
||||
"task_id": task.get("id"),
|
||||
"status": "completed",
|
||||
"duration": task_result.get("duration", 0)
|
||||
})
|
||||
|
||||
# 检查是否满足成功条件
|
||||
if not self._check_success_criteria(task, task_result):
|
||||
logger.warning(f"任务 {task.get('id')} 未满足成功条件")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行任务 {task.get('id')} 失败: {e}")
|
||||
execution_log.append({
|
||||
"task_id": task.get("id"),
|
||||
"status": "failed",
|
||||
"error": str(e)
|
||||
})
|
||||
|
||||
# 根据任务重要性决定是否继续
|
||||
if task.get("critical", False):
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"关键任务失败: {task.get('id')}",
|
||||
"results": results,
|
||||
"execution_log": execution_log
|
||||
}
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"results": results,
|
||||
"execution_log": execution_log,
|
||||
"execution_id": execution_id
|
||||
}
|
||||
|
||||
async def _execute_parallel(
|
||||
self,
|
||||
plan: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any],
|
||||
execution_id: str
|
||||
) -> Dict[str, Any]:
|
||||
"""并行执行计划"""
|
||||
results = []
|
||||
execution_log = []
|
||||
|
||||
# 将计划分组
|
||||
parallel_groups = self._group_tasks_for_parallel_execution(plan)
|
||||
|
||||
for group in parallel_groups:
|
||||
if group["execution_mode"] == "parallel":
|
||||
# 并行执行组内任务
|
||||
group_results = await self._execute_tasks_parallel(
|
||||
group["tasks"], tool_manager, context
|
||||
)
|
||||
results.extend(group_results)
|
||||
else:
|
||||
# 顺序执行组内任务
|
||||
for task in group["tasks"]:
|
||||
task_result = await self._execute_single_task(task, tool_manager, context)
|
||||
results.append({
|
||||
"task_id": task.get("id"),
|
||||
"result": task_result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"results": results,
|
||||
"execution_log": execution_log,
|
||||
"execution_id": execution_id
|
||||
}
|
||||
|
||||
async def _execute_conditional(
|
||||
self,
|
||||
plan: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any],
|
||||
execution_id: str
|
||||
) -> Dict[str, Any]:
|
||||
"""条件执行计划"""
|
||||
results = []
|
||||
execution_log = []
|
||||
|
||||
# 找到条件检查任务
|
||||
condition_task = None
|
||||
branch_tasks = []
|
||||
|
||||
for task in plan:
|
||||
if task.get("type") == "condition":
|
||||
condition_task = task
|
||||
elif task.get("type") == "branch":
|
||||
branch_tasks.append(task)
|
||||
|
||||
if not condition_task:
|
||||
logger.error("条件计划中缺少条件检查任务")
|
||||
return {"success": False, "error": "缺少条件检查任务"}
|
||||
|
||||
# 执行条件检查
|
||||
condition_result = await self._execute_single_task(condition_task, tool_manager, context)
|
||||
results.append({
|
||||
"task_id": condition_task.get("id"),
|
||||
"result": condition_result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
# 根据条件结果选择分支
|
||||
selected_branch = self._select_branch(condition_result, branch_tasks)
|
||||
|
||||
if selected_branch:
|
||||
# 执行选中的分支
|
||||
branch_result = await self._execute_sequential(
|
||||
selected_branch.get("tasks", []),
|
||||
tool_manager,
|
||||
context,
|
||||
execution_id
|
||||
)
|
||||
results.extend(branch_result.get("results", []))
|
||||
execution_log.extend(branch_result.get("execution_log", []))
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"results": results,
|
||||
"execution_log": execution_log,
|
||||
"execution_id": execution_id,
|
||||
"selected_branch": selected_branch.get("id") if selected_branch else None
|
||||
}
|
||||
|
||||
async def _execute_iterative(
|
||||
self,
|
||||
plan: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any],
|
||||
execution_id: str
|
||||
) -> Dict[str, Any]:
|
||||
"""迭代执行计划"""
|
||||
# 找到迭代控制任务
|
||||
iteration_task = None
|
||||
for task in plan:
|
||||
if task.get("type") == "iteration_control":
|
||||
iteration_task = task
|
||||
break
|
||||
|
||||
if not iteration_task:
|
||||
logger.error("迭代计划中缺少迭代控制任务")
|
||||
return {"success": False, "error": "缺少迭代控制任务"}
|
||||
|
||||
max_iterations = iteration_task.get("max_iterations", 10)
|
||||
convergence_criteria = iteration_task.get("convergence_criteria", {})
|
||||
tasks = iteration_task.get("tasks", [])
|
||||
|
||||
results = []
|
||||
execution_log = []
|
||||
iteration_count = 0
|
||||
|
||||
while iteration_count < max_iterations:
|
||||
iteration_count += 1
|
||||
logger.info(f"执行第 {iteration_count} 次迭代")
|
||||
|
||||
# 执行迭代任务
|
||||
iteration_result = await self._execute_sequential(
|
||||
tasks, tool_manager, context, f"{execution_id}_iter_{iteration_count}"
|
||||
)
|
||||
|
||||
results.append({
|
||||
"iteration": iteration_count,
|
||||
"result": iteration_result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
# 检查收敛条件
|
||||
if self._check_convergence(iteration_result, convergence_criteria):
|
||||
logger.info(f"迭代在第 {iteration_count} 次收敛")
|
||||
break
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"results": results,
|
||||
"execution_log": execution_log,
|
||||
"execution_id": execution_id,
|
||||
"iterations": iteration_count,
|
||||
"converged": iteration_count < max_iterations
|
||||
}
|
||||
|
||||
async def _execute_single_task(
|
||||
self,
|
||||
task: Dict[str, Any],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行单个任务"""
|
||||
start_time = datetime.now()
|
||||
|
||||
try:
|
||||
task_id = task.get("id", "unknown")
|
||||
task_type = task.get("type", "action")
|
||||
tool_name = task.get("tool", "")
|
||||
parameters = task.get("parameters", {})
|
||||
|
||||
logger.info(f"执行任务: {task_id}, 类型: {task_type}, 工具: {tool_name}")
|
||||
|
||||
# 根据任务类型执行
|
||||
if task_type == "action":
|
||||
result = await self._execute_action_task(task, tool_manager, context)
|
||||
elif task_type == "condition":
|
||||
result = await self._execute_condition_task(task, tool_manager, context)
|
||||
elif task_type == "control":
|
||||
result = await self._execute_control_task(task, tool_manager, context)
|
||||
else:
|
||||
result = await self._execute_general_task(task, tool_manager, context)
|
||||
|
||||
duration = (datetime.now() - start_time).total_seconds()
|
||||
result["duration"] = duration
|
||||
|
||||
logger.info(f"任务 {task_id} 执行完成,耗时: {duration:.2f}秒")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"执行任务失败: {e}")
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"duration": (datetime.now() - start_time).total_seconds()
|
||||
}
|
||||
|
||||
async def _execute_action_task(
|
||||
self,
|
||||
task: Dict[str, Any],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行动作任务"""
|
||||
tool_name = task.get("tool", "")
|
||||
parameters = task.get("parameters", {})
|
||||
|
||||
# 合并上下文参数
|
||||
full_parameters = {**parameters, **context}
|
||||
|
||||
# 调用工具
|
||||
result = await tool_manager.execute_tool(tool_name, full_parameters)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"tool": tool_name,
|
||||
"parameters": full_parameters,
|
||||
"result": result
|
||||
}
|
||||
|
||||
async def _execute_condition_task(
|
||||
self,
|
||||
task: Dict[str, Any],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行条件任务"""
|
||||
condition = task.get("condition", "")
|
||||
branches = task.get("branches", {})
|
||||
|
||||
# 评估条件
|
||||
condition_result = await self._evaluate_condition(condition, context)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"condition": condition,
|
||||
"result": condition_result,
|
||||
"available_branches": list(branches.keys())
|
||||
}
|
||||
|
||||
async def _execute_control_task(
|
||||
self,
|
||||
task: Dict[str, Any],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行控制任务"""
|
||||
control_type = task.get("control_type", "general")
|
||||
|
||||
if control_type == "iteration":
|
||||
return await self._execute_iteration_control(task, context)
|
||||
elif control_type == "loop":
|
||||
return await self._execute_loop_control(task, context)
|
||||
else:
|
||||
return {
|
||||
"success": True,
|
||||
"control_type": control_type,
|
||||
"message": "控制任务执行完成"
|
||||
}
|
||||
|
||||
async def _execute_general_task(
|
||||
self,
|
||||
task: Dict[str, Any],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""执行通用任务"""
|
||||
description = task.get("description", "")
|
||||
|
||||
# 这里可以实现通用的任务执行逻辑
|
||||
# 例如:调用LLM生成响应、执行数据库操作等
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"description": description,
|
||||
"message": "通用任务执行完成"
|
||||
}
|
||||
|
||||
async def _execute_tasks_parallel(
|
||||
self,
|
||||
tasks: List[Dict[str, Any]],
|
||||
tool_manager: Any,
|
||||
context: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""并行执行多个任务"""
|
||||
async def execute_task(task):
|
||||
return await self._execute_single_task(task, tool_manager, context)
|
||||
|
||||
# 创建并行任务
|
||||
parallel_tasks = [execute_task(task) for task in tasks]
|
||||
|
||||
# 等待所有任务完成
|
||||
results = await asyncio.gather(*parallel_tasks, return_exceptions=True)
|
||||
|
||||
# 处理结果
|
||||
processed_results = []
|
||||
for i, result in enumerate(results):
|
||||
if isinstance(result, Exception):
|
||||
processed_results.append({
|
||||
"task_id": tasks[i].get("id"),
|
||||
"result": {"success": False, "error": str(result)},
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
else:
|
||||
processed_results.append({
|
||||
"task_id": tasks[i].get("id"),
|
||||
"result": result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
return processed_results
|
||||
|
||||
def _group_tasks_for_parallel_execution(self, plan: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||
"""将任务分组以便并行执行"""
|
||||
groups = []
|
||||
current_group = []
|
||||
|
||||
for task in plan:
|
||||
if task.get("type") == "parallel_group":
|
||||
if current_group:
|
||||
groups.append({
|
||||
"execution_mode": "sequential",
|
||||
"tasks": current_group
|
||||
})
|
||||
current_group = []
|
||||
groups.append(task)
|
||||
else:
|
||||
current_group.append(task)
|
||||
|
||||
if current_group:
|
||||
groups.append({
|
||||
"execution_mode": "sequential",
|
||||
"tasks": current_group
|
||||
})
|
||||
|
||||
return groups
|
||||
|
||||
async def _check_dependencies(self, task: Dict[str, Any], results: List[Dict[str, Any]]) -> bool:
|
||||
"""检查任务依赖是否满足"""
|
||||
dependencies = task.get("dependencies", [])
|
||||
|
||||
if not dependencies:
|
||||
return True
|
||||
|
||||
# 检查所有依赖是否已完成
|
||||
completed_task_ids = [r["task_id"] for r in results if r["result"].get("success", False)]
|
||||
|
||||
for dep in dependencies:
|
||||
if dep not in completed_task_ids:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _check_success_criteria(self, task: Dict[str, Any], result: Dict[str, Any]) -> bool:
|
||||
"""检查任务是否满足成功条件"""
|
||||
success_criteria = task.get("success_criteria", {})
|
||||
|
||||
if not success_criteria:
|
||||
return result.get("success", False)
|
||||
|
||||
# 检查每个成功条件
|
||||
for criterion, expected_value in success_criteria.items():
|
||||
actual_value = result.get(criterion)
|
||||
if actual_value != expected_value:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _select_branch(self, condition_result: Dict[str, Any], branch_tasks: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
|
||||
"""根据条件结果选择分支"""
|
||||
condition_value = condition_result.get("result", "")
|
||||
|
||||
for branch_task in branch_tasks:
|
||||
branch_condition = branch_task.get("condition", "")
|
||||
if branch_condition == condition_value:
|
||||
return branch_task
|
||||
|
||||
return None
|
||||
|
||||
def _check_convergence(self, iteration_result: Dict[str, Any], convergence_criteria: Dict[str, Any]) -> bool:
|
||||
"""检查迭代是否收敛"""
|
||||
if not convergence_criteria:
|
||||
return False
|
||||
|
||||
# 检查收敛条件
|
||||
for criterion, threshold in convergence_criteria.items():
|
||||
actual_value = iteration_result.get(criterion)
|
||||
if actual_value is None:
|
||||
continue
|
||||
|
||||
# 这里可以实现更复杂的收敛判断逻辑
|
||||
if isinstance(threshold, dict):
|
||||
if threshold.get("type") == "less_than":
|
||||
if actual_value >= threshold.get("value"):
|
||||
return False
|
||||
elif threshold.get("type") == "greater_than":
|
||||
if actual_value <= threshold.get("value"):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def _evaluate_condition(self, condition: str, context: Dict[str, Any]) -> str:
|
||||
"""评估条件表达式"""
|
||||
# 这里可以实现条件评估逻辑
|
||||
# 例如:解析条件表达式、查询上下文等
|
||||
|
||||
# 简单的条件评估示例
|
||||
if "satisfaction" in condition:
|
||||
return "high" if context.get("satisfaction_score", 0) > 0.7 else "low"
|
||||
elif "priority" in condition:
|
||||
return context.get("priority", "medium")
|
||||
else:
|
||||
return "default"
|
||||
|
||||
async def _execute_iteration_control(self, task: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""执行迭代控制"""
|
||||
max_iterations = task.get("max_iterations", 10)
|
||||
current_iteration = context.get("current_iteration", 0)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"max_iterations": max_iterations,
|
||||
"current_iteration": current_iteration,
|
||||
"continue": current_iteration < max_iterations
|
||||
}
|
||||
|
||||
async def _execute_loop_control(self, task: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""执行循环控制"""
|
||||
loop_condition = task.get("loop_condition", "")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"loop_condition": loop_condition,
|
||||
"continue": True # 这里应该根据实际条件判断
|
||||
}
|
||||
|
||||
def get_execution_status(self, execution_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""获取执行状态"""
|
||||
return self.active_executions.get(execution_id)
|
||||
|
||||
def get_all_executions(self) -> Dict[str, Any]:
|
||||
"""获取所有执行记录"""
|
||||
return self.active_executions
|
||||
573
src/agent/goal_manager.py
Normal file
573
src/agent/goal_manager.py
Normal file
@@ -0,0 +1,573 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
目标管理器
|
||||
负责目标设定、跟踪和评估
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from ..core.llm_client import QwenClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GoalManager:
|
||||
"""目标管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.llm_client = QwenClient()
|
||||
self.active_goals = {}
|
||||
self.goal_history = []
|
||||
self.goal_templates = {
|
||||
"problem_solving": self._create_problem_solving_goal,
|
||||
"information_gathering": self._create_information_gathering_goal,
|
||||
"task_execution": self._create_task_execution_goal,
|
||||
"analysis": self._create_analysis_goal,
|
||||
"communication": self._create_communication_goal
|
||||
}
|
||||
|
||||
async def create_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建目标"""
|
||||
try:
|
||||
goal_type = self._determine_goal_type(intent, request)
|
||||
|
||||
if goal_type in self.goal_templates:
|
||||
goal = await self.goal_templates[goal_type](intent, request, current_state)
|
||||
else:
|
||||
goal = await self._create_general_goal(intent, request, current_state)
|
||||
|
||||
# 生成唯一目标ID
|
||||
goal_id = f"goal_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
||||
goal["id"] = goal_id
|
||||
goal["created_at"] = datetime.now().isoformat()
|
||||
goal["status"] = "active"
|
||||
|
||||
# 添加到活跃目标
|
||||
self.active_goals[goal_id] = goal
|
||||
|
||||
logger.info(f"创建目标: {goal_id}, 类型: {goal_type}")
|
||||
return goal
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创建目标失败: {e}")
|
||||
return self._create_fallback_goal(intent, request)
|
||||
|
||||
def _determine_goal_type(self, intent: Dict[str, Any], request: Dict[str, Any]) -> str:
|
||||
"""确定目标类型"""
|
||||
main_intent = intent.get("main_intent", "general_query")
|
||||
|
||||
goal_type_mapping = {
|
||||
"problem_solving": ["problem_consultation", "issue_resolution", "troubleshooting"],
|
||||
"information_gathering": ["information_query", "data_collection", "research"],
|
||||
"task_execution": ["work_order_creation", "task_assignment", "action_request"],
|
||||
"analysis": ["data_analysis", "report_generation", "performance_review"],
|
||||
"communication": ["notification", "message_delivery", "user_interaction"]
|
||||
}
|
||||
|
||||
for goal_type, intents in goal_type_mapping.items():
|
||||
if main_intent in intents:
|
||||
return goal_type
|
||||
|
||||
return "general"
|
||||
|
||||
async def _create_problem_solving_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建问题解决目标"""
|
||||
prompt = f"""
|
||||
请为以下问题解决请求创建目标:
|
||||
|
||||
用户意图: {json.dumps(intent, ensure_ascii=False)}
|
||||
请求内容: {json.dumps(request, ensure_ascii=False)}
|
||||
|
||||
请定义:
|
||||
1. 目标描述
|
||||
2. 成功标准
|
||||
3. 所需步骤
|
||||
4. 预期结果
|
||||
5. 时间限制
|
||||
6. 资源需求
|
||||
|
||||
请以JSON格式返回目标定义。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个目标设定专家,擅长为问题解决任务设定清晰的目标。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_default_problem_solving_goal(intent, request)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
goal_data = json.loads(json_match.group())
|
||||
goal_data["type"] = "problem_solving"
|
||||
return goal_data
|
||||
else:
|
||||
return self._create_default_problem_solving_goal(intent, request)
|
||||
|
||||
async def _create_information_gathering_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建信息收集目标"""
|
||||
prompt = f"""
|
||||
请为以下信息收集请求创建目标:
|
||||
|
||||
用户意图: {json.dumps(intent, ensure_ascii=False)}
|
||||
请求内容: {json.dumps(request, ensure_ascii=False)}
|
||||
|
||||
请定义:
|
||||
1. 信息收集范围
|
||||
2. 信息质量要求
|
||||
3. 收集方法
|
||||
4. 验证标准
|
||||
5. 整理格式
|
||||
|
||||
请以JSON格式返回目标定义。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个信息收集专家,擅长设定信息收集目标。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_default_information_goal(intent, request)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
goal_data = json.loads(json_match.group())
|
||||
goal_data["type"] = "information_gathering"
|
||||
return goal_data
|
||||
else:
|
||||
return self._create_default_information_goal(intent, request)
|
||||
|
||||
async def _create_task_execution_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建任务执行目标"""
|
||||
prompt = f"""
|
||||
请为以下任务执行请求创建目标:
|
||||
|
||||
用户意图: {json.dumps(intent, ensure_ascii=False)}
|
||||
请求内容: {json.dumps(request, ensure_ascii=False)}
|
||||
|
||||
请定义:
|
||||
1. 任务描述
|
||||
2. 执行步骤
|
||||
3. 完成标准
|
||||
4. 质量要求
|
||||
5. 时间安排
|
||||
|
||||
请以JSON格式返回目标定义。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个任务执行专家,擅长设定任务执行目标。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_default_task_goal(intent, request)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
goal_data = json.loads(json_match.group())
|
||||
goal_data["type"] = "task_execution"
|
||||
return goal_data
|
||||
else:
|
||||
return self._create_default_task_goal(intent, request)
|
||||
|
||||
async def _create_analysis_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建分析目标"""
|
||||
prompt = f"""
|
||||
请为以下分析请求创建目标:
|
||||
|
||||
用户意图: {json.dumps(intent, ensure_ascii=False)}
|
||||
请求内容: {json.dumps(request, ensure_ascii=False)}
|
||||
|
||||
请定义:
|
||||
1. 分析范围
|
||||
2. 分析方法
|
||||
3. 分析深度
|
||||
4. 输出格式
|
||||
5. 质量指标
|
||||
|
||||
请以JSON格式返回目标定义。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个分析专家,擅长设定分析目标。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_default_analysis_goal(intent, request)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
goal_data = json.loads(json_match.group())
|
||||
goal_data["type"] = "analysis"
|
||||
return goal_data
|
||||
else:
|
||||
return self._create_default_analysis_goal(intent, request)
|
||||
|
||||
async def _create_communication_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建沟通目标"""
|
||||
prompt = f"""
|
||||
请为以下沟通请求创建目标:
|
||||
|
||||
用户意图: {json.dumps(intent, ensure_ascii=False)}
|
||||
请求内容: {json.dumps(request, ensure_ascii=False)}
|
||||
|
||||
请定义:
|
||||
1. 沟通对象
|
||||
2. 沟通内容
|
||||
3. 沟通方式
|
||||
4. 预期效果
|
||||
5. 反馈机制
|
||||
|
||||
请以JSON格式返回目标定义。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个沟通专家,擅长设定沟通目标。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_default_communication_goal(intent, request)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
goal_data = json.loads(json_match.group())
|
||||
goal_data["type"] = "communication"
|
||||
return goal_data
|
||||
else:
|
||||
return self._create_default_communication_goal(intent, request)
|
||||
|
||||
async def _create_general_goal(
|
||||
self,
|
||||
intent: Dict[str, Any],
|
||||
request: Dict[str, Any],
|
||||
current_state: Any
|
||||
) -> Dict[str, Any]:
|
||||
"""创建通用目标"""
|
||||
return {
|
||||
"type": "general",
|
||||
"description": intent.get("main_intent", "处理用户请求"),
|
||||
"success_criteria": {
|
||||
"completion": True,
|
||||
"user_satisfaction": 0.7
|
||||
},
|
||||
"steps": ["理解请求", "执行任务", "返回结果"],
|
||||
"expected_result": "用户需求得到满足",
|
||||
"time_limit": 300, # 5分钟
|
||||
"resource_requirements": ["llm_client", "knowledge_base"]
|
||||
}
|
||||
|
||||
def _create_default_problem_solving_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建默认问题解决目标"""
|
||||
return {
|
||||
"type": "problem_solving",
|
||||
"description": "解决用户问题",
|
||||
"success_criteria": {
|
||||
"problem_identified": True,
|
||||
"solution_provided": True,
|
||||
"user_satisfaction": 0.7
|
||||
},
|
||||
"steps": ["分析问题", "寻找解决方案", "提供建议", "验证效果"],
|
||||
"expected_result": "问题得到解决或提供有效建议",
|
||||
"time_limit": 300,
|
||||
"resource_requirements": ["knowledge_base", "llm_client"]
|
||||
}
|
||||
|
||||
def _create_default_information_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建默认信息收集目标"""
|
||||
return {
|
||||
"type": "information_gathering",
|
||||
"description": "收集相关信息",
|
||||
"success_criteria": {
|
||||
"information_complete": True,
|
||||
"information_accurate": True,
|
||||
"information_relevant": True
|
||||
},
|
||||
"steps": ["确定信息需求", "搜索信息源", "收集信息", "整理信息"],
|
||||
"expected_result": "提供准确、完整、相关的信息",
|
||||
"time_limit": 180,
|
||||
"resource_requirements": ["knowledge_base", "search_tools"]
|
||||
}
|
||||
|
||||
def _create_default_task_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建默认任务执行目标"""
|
||||
return {
|
||||
"type": "task_execution",
|
||||
"description": "执行指定任务",
|
||||
"success_criteria": {
|
||||
"task_completed": True,
|
||||
"quality_met": True,
|
||||
"time_met": True
|
||||
},
|
||||
"steps": ["理解任务", "制定计划", "执行任务", "验证结果"],
|
||||
"expected_result": "任务成功完成",
|
||||
"time_limit": 600,
|
||||
"resource_requirements": ["task_tools", "monitoring"]
|
||||
}
|
||||
|
||||
def _create_default_analysis_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建默认分析目标"""
|
||||
return {
|
||||
"type": "analysis",
|
||||
"description": "执行数据分析",
|
||||
"success_criteria": {
|
||||
"analysis_complete": True,
|
||||
"insights_meaningful": True,
|
||||
"report_clear": True
|
||||
},
|
||||
"steps": ["收集数据", "分析数据", "提取洞察", "生成报告"],
|
||||
"expected_result": "提供有价值的分析报告",
|
||||
"time_limit": 900,
|
||||
"resource_requirements": ["analytics_tools", "data_sources"]
|
||||
}
|
||||
|
||||
def _create_default_communication_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建默认沟通目标"""
|
||||
return {
|
||||
"type": "communication",
|
||||
"description": "与用户沟通",
|
||||
"success_criteria": {
|
||||
"message_delivered": True,
|
||||
"response_received": True,
|
||||
"understanding_achieved": True
|
||||
},
|
||||
"steps": ["准备消息", "发送消息", "等待响应", "确认理解"],
|
||||
"expected_result": "成功沟通并达成理解",
|
||||
"time_limit": 120,
|
||||
"resource_requirements": ["communication_tools"]
|
||||
}
|
||||
|
||||
def _create_fallback_goal(self, intent: Dict[str, Any], request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""创建备用目标"""
|
||||
return {
|
||||
"type": "fallback",
|
||||
"description": "处理用户请求",
|
||||
"success_criteria": {"completion": True},
|
||||
"steps": ["处理请求"],
|
||||
"expected_result": "返回响应",
|
||||
"time_limit": 60,
|
||||
"resource_requirements": ["basic_tools"]
|
||||
}
|
||||
|
||||
async def update_goal_progress(self, goal_id: str, progress_data: Dict[str, Any]) -> bool:
|
||||
"""更新目标进度"""
|
||||
try:
|
||||
if goal_id not in self.active_goals:
|
||||
return False
|
||||
|
||||
goal = self.active_goals[goal_id]
|
||||
goal["progress"] = progress_data
|
||||
goal["updated_at"] = datetime.now().isoformat()
|
||||
|
||||
# 检查是否完成
|
||||
if self._check_goal_completion(goal):
|
||||
goal["status"] = "completed"
|
||||
goal["completed_at"] = datetime.now().isoformat()
|
||||
|
||||
# 移动到历史记录
|
||||
self.goal_history.append(goal)
|
||||
del self.active_goals[goal_id]
|
||||
|
||||
logger.info(f"目标 {goal_id} 已完成")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"更新目标进度失败: {e}")
|
||||
return False
|
||||
|
||||
def _check_goal_completion(self, goal: Dict[str, Any]) -> bool:
|
||||
"""检查目标是否完成"""
|
||||
success_criteria = goal.get("success_criteria", {})
|
||||
|
||||
if not success_criteria:
|
||||
return True
|
||||
|
||||
progress = goal.get("progress", {})
|
||||
|
||||
# 检查每个成功标准
|
||||
for criterion, required_value in success_criteria.items():
|
||||
actual_value = progress.get(criterion)
|
||||
if actual_value != required_value:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def evaluate_goal_performance(self, goal_id: str) -> Dict[str, Any]:
|
||||
"""评估目标性能"""
|
||||
try:
|
||||
if goal_id in self.active_goals:
|
||||
goal = self.active_goals[goal_id]
|
||||
elif goal_id in [g["id"] for g in self.goal_history]:
|
||||
goal = next(g for g in self.goal_history if g["id"] == goal_id)
|
||||
else:
|
||||
return {"error": "目标不存在"}
|
||||
|
||||
evaluation = {
|
||||
"goal_id": goal_id,
|
||||
"type": goal.get("type"),
|
||||
"status": goal.get("status"),
|
||||
"created_at": goal.get("created_at"),
|
||||
"completed_at": goal.get("completed_at"),
|
||||
"duration": self._calculate_goal_duration(goal),
|
||||
"success_rate": self._calculate_success_rate(goal),
|
||||
"efficiency": self._calculate_efficiency(goal),
|
||||
"quality_score": self._calculate_quality_score(goal)
|
||||
}
|
||||
|
||||
return evaluation
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"评估目标性能失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
def _calculate_goal_duration(self, goal: Dict[str, Any]) -> float:
|
||||
"""计算目标持续时间"""
|
||||
created_at = datetime.fromisoformat(goal.get("created_at", datetime.now().isoformat()))
|
||||
|
||||
if goal.get("completed_at"):
|
||||
completed_at = datetime.fromisoformat(goal["completed_at"])
|
||||
return (completed_at - created_at).total_seconds()
|
||||
else:
|
||||
return (datetime.now() - created_at).total_seconds()
|
||||
|
||||
def _calculate_success_rate(self, goal: Dict[str, Any]) -> float:
|
||||
"""计算成功率"""
|
||||
if goal.get("status") == "completed":
|
||||
return 1.0
|
||||
elif goal.get("status") == "failed":
|
||||
return 0.0
|
||||
else:
|
||||
# 根据进度计算部分成功率
|
||||
progress = goal.get("progress", {})
|
||||
success_criteria = goal.get("success_criteria", {})
|
||||
|
||||
if not success_criteria:
|
||||
return 0.5
|
||||
|
||||
completed_criteria = 0
|
||||
for criterion in success_criteria:
|
||||
if progress.get(criterion) == success_criteria[criterion]:
|
||||
completed_criteria += 1
|
||||
|
||||
return completed_criteria / len(success_criteria)
|
||||
|
||||
def _calculate_efficiency(self, goal: Dict[str, Any]) -> float:
|
||||
"""计算效率"""
|
||||
duration = self._calculate_goal_duration(goal)
|
||||
time_limit = goal.get("time_limit", 300)
|
||||
|
||||
if duration <= time_limit:
|
||||
return 1.0
|
||||
else:
|
||||
# 超时惩罚
|
||||
return max(0.0, 1.0 - (duration - time_limit) / time_limit)
|
||||
|
||||
def _calculate_quality_score(self, goal: Dict[str, Any]) -> float:
|
||||
"""计算质量分数"""
|
||||
# 这里可以根据具体的目标类型和质量指标计算
|
||||
# 暂时返回一个基于成功率的简单计算
|
||||
success_rate = self._calculate_success_rate(goal)
|
||||
efficiency = self._calculate_efficiency(goal)
|
||||
|
||||
return (success_rate + efficiency) / 2
|
||||
|
||||
def get_active_goals(self) -> List[Dict[str, Any]]:
|
||||
"""获取活跃目标"""
|
||||
return list(self.active_goals.values())
|
||||
|
||||
def get_goal_history(self, limit: int = 10) -> List[Dict[str, Any]]:
|
||||
"""获取目标历史"""
|
||||
return self.goal_history[-limit:] if self.goal_history else []
|
||||
|
||||
def get_goal_statistics(self) -> Dict[str, Any]:
|
||||
"""获取目标统计"""
|
||||
total_goals = len(self.active_goals) + len(self.goal_history)
|
||||
completed_goals = len([g for g in self.goal_history if g.get("status") == "completed"])
|
||||
active_goals = len(self.active_goals)
|
||||
|
||||
return {
|
||||
"total_goals": total_goals,
|
||||
"active_goals": active_goals,
|
||||
"completed_goals": completed_goals,
|
||||
"completion_rate": completed_goals / total_goals if total_goals > 0 else 0,
|
||||
"goal_types": self._get_goal_type_distribution()
|
||||
}
|
||||
|
||||
def _get_goal_type_distribution(self) -> Dict[str, int]:
|
||||
"""获取目标类型分布"""
|
||||
distribution = {}
|
||||
|
||||
# 统计活跃目标
|
||||
for goal in self.active_goals.values():
|
||||
goal_type = goal.get("type", "unknown")
|
||||
distribution[goal_type] = distribution.get(goal_type, 0) + 1
|
||||
|
||||
# 统计历史目标
|
||||
for goal in self.goal_history:
|
||||
goal_type = goal.get("type", "unknown")
|
||||
distribution[goal_type] = distribution.get(goal_type, 0) + 1
|
||||
|
||||
return distribution
|
||||
409
src/agent/planner.py
Normal file
409
src/agent/planner.py
Normal file
@@ -0,0 +1,409 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
任务规划器
|
||||
负责制定执行计划和任务分解
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from ..core.llm_client import QwenClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class TaskPlanner:
|
||||
"""任务规划器"""
|
||||
|
||||
def __init__(self):
|
||||
self.llm_client = QwenClient()
|
||||
self.planning_strategies = {
|
||||
"sequential": self._create_sequential_plan,
|
||||
"parallel": self._create_parallel_plan,
|
||||
"conditional": self._create_conditional_plan,
|
||||
"iterative": self._create_iterative_plan
|
||||
}
|
||||
|
||||
async def create_plan(
|
||||
self,
|
||||
goal: Dict[str, Any],
|
||||
available_tools: List[Dict[str, Any]],
|
||||
constraints: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""创建执行计划"""
|
||||
try:
|
||||
# 1. 分析目标复杂度
|
||||
complexity = await self._analyze_goal_complexity(goal)
|
||||
|
||||
# 2. 选择规划策略
|
||||
strategy = self._select_planning_strategy(complexity, goal)
|
||||
|
||||
# 3. 生成计划
|
||||
plan = await self.planning_strategies[strategy](goal, available_tools, constraints)
|
||||
|
||||
# 4. 优化计划
|
||||
optimized_plan = await self._optimize_plan(plan, constraints)
|
||||
|
||||
logger.info(f"创建计划成功,包含 {len(optimized_plan)} 个任务")
|
||||
return optimized_plan
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创建计划失败: {e}")
|
||||
return []
|
||||
|
||||
async def _analyze_goal_complexity(self, goal: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""分析目标复杂度"""
|
||||
prompt = f"""
|
||||
请分析以下目标的复杂度:
|
||||
|
||||
目标: {goal.get('description', '')}
|
||||
类型: {goal.get('type', '')}
|
||||
上下文: {goal.get('context', {})}
|
||||
|
||||
请从以下维度评估复杂度(1-10分):
|
||||
1. 任务数量
|
||||
2. 依赖关系复杂度
|
||||
3. 所需工具数量
|
||||
4. 时间要求
|
||||
5. 资源需求
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个任务规划专家,擅长分析任务复杂度。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"complexity_score": 5, "strategy": "sequential"}
|
||||
|
||||
try:
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
if json_match:
|
||||
analysis = json.loads(json_match.group())
|
||||
return analysis
|
||||
else:
|
||||
return {"complexity_score": 5, "strategy": "sequential"}
|
||||
except Exception as e:
|
||||
logger.error(f"解析复杂度分析失败: {e}")
|
||||
return {"complexity_score": 5, "strategy": "sequential"}
|
||||
|
||||
def _select_planning_strategy(self, complexity: Dict[str, Any], goal: Dict[str, Any]) -> str:
|
||||
"""选择规划策略"""
|
||||
complexity_score = complexity.get("complexity_score", 5)
|
||||
goal_type = goal.get("type", "general")
|
||||
|
||||
if complexity_score <= 3:
|
||||
return "sequential"
|
||||
elif complexity_score <= 6:
|
||||
if goal_type in ["analysis", "monitoring"]:
|
||||
return "parallel"
|
||||
else:
|
||||
return "conditional"
|
||||
else:
|
||||
return "iterative"
|
||||
|
||||
async def _create_sequential_plan(
|
||||
self,
|
||||
goal: Dict[str, Any],
|
||||
available_tools: List[Dict[str, Any]],
|
||||
constraints: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""创建顺序执行计划"""
|
||||
prompt = f"""
|
||||
请为以下目标创建一个顺序执行计划:
|
||||
|
||||
目标: {goal.get('description', '')}
|
||||
可用工具: {[tool.get('name', '') for tool in available_tools]}
|
||||
|
||||
请将目标分解为具体的执行步骤,每个步骤包含:
|
||||
1. 任务描述
|
||||
2. 所需工具
|
||||
3. 输入参数
|
||||
4. 预期输出
|
||||
5. 成功条件
|
||||
|
||||
请以JSON数组格式返回计划。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个任务规划专家,擅长创建顺序执行计划。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_fallback_plan(goal)
|
||||
|
||||
try:
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\[.*\]', response_content, re.DOTALL)
|
||||
if json_match:
|
||||
plan = json.loads(json_match.group())
|
||||
return self._format_plan_tasks(plan)
|
||||
else:
|
||||
return self._create_fallback_plan(goal)
|
||||
except Exception as e:
|
||||
logger.error(f"解析顺序计划失败: {e}")
|
||||
return self._create_fallback_plan(goal)
|
||||
|
||||
async def _create_parallel_plan(
|
||||
self,
|
||||
goal: Dict[str, Any],
|
||||
available_tools: List[Dict[str, Any]],
|
||||
constraints: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""创建并行执行计划"""
|
||||
# 先创建基础任务
|
||||
base_tasks = await self._create_sequential_plan(goal, available_tools, constraints)
|
||||
|
||||
# 分析任务间的依赖关系
|
||||
parallel_groups = self._group_parallel_tasks(base_tasks)
|
||||
|
||||
return parallel_groups
|
||||
|
||||
async def _create_conditional_plan(
|
||||
self,
|
||||
goal: Dict[str, Any],
|
||||
available_tools: List[Dict[str, Any]],
|
||||
constraints: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""创建条件执行计划"""
|
||||
prompt = f"""
|
||||
请为以下目标创建一个条件执行计划:
|
||||
|
||||
目标: {goal.get('description', '')}
|
||||
上下文: {goal.get('context', {})}
|
||||
|
||||
计划应该包含:
|
||||
1. 初始条件检查
|
||||
2. 分支逻辑
|
||||
3. 每个分支的具体任务
|
||||
4. 合并条件
|
||||
|
||||
请以JSON格式返回计划。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个任务规划专家,擅长创建条件执行计划。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return await self._create_sequential_plan(goal, available_tools, constraints)
|
||||
|
||||
try:
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
if json_match:
|
||||
plan = json.loads(json_match.group())
|
||||
return self._format_conditional_plan(plan)
|
||||
else:
|
||||
return await self._create_sequential_plan(goal, available_tools, constraints)
|
||||
except Exception as e:
|
||||
logger.error(f"解析条件计划失败: {e}")
|
||||
return await self._create_sequential_plan(goal, available_tools, constraints)
|
||||
|
||||
async def _create_iterative_plan(
|
||||
self,
|
||||
goal: Dict[str, Any],
|
||||
available_tools: List[Dict[str, Any]],
|
||||
constraints: Dict[str, Any]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""创建迭代执行计划"""
|
||||
# 创建基础计划
|
||||
base_plan = await self._create_sequential_plan(goal, available_tools, constraints)
|
||||
|
||||
# 添加迭代控制任务
|
||||
iteration_control = {
|
||||
"id": "iteration_control",
|
||||
"type": "control",
|
||||
"description": "迭代控制",
|
||||
"max_iterations": constraints.get("max_iterations", 10),
|
||||
"convergence_criteria": goal.get("success_criteria", {}),
|
||||
"tasks": base_plan
|
||||
}
|
||||
|
||||
return [iteration_control]
|
||||
|
||||
def _group_parallel_tasks(self, tasks: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||
"""将任务分组为可并行执行的任务组"""
|
||||
groups = []
|
||||
current_group = []
|
||||
|
||||
for task in tasks:
|
||||
# 简单的分组逻辑:相同类型的任务可以并行
|
||||
if not current_group or current_group[0].get("type") == task.get("type"):
|
||||
current_group.append(task)
|
||||
else:
|
||||
if current_group:
|
||||
groups.append({
|
||||
"type": "parallel_group",
|
||||
"tasks": current_group,
|
||||
"execution_mode": "parallel"
|
||||
})
|
||||
current_group = [task]
|
||||
|
||||
if current_group:
|
||||
groups.append({
|
||||
"type": "parallel_group",
|
||||
"tasks": current_group,
|
||||
"execution_mode": "parallel"
|
||||
})
|
||||
|
||||
return groups
|
||||
|
||||
def _format_plan_tasks(self, raw_plan: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||
"""格式化计划任务"""
|
||||
formatted_tasks = []
|
||||
|
||||
for i, task in enumerate(raw_plan):
|
||||
formatted_task = {
|
||||
"id": f"task_{i+1}",
|
||||
"type": task.get("type", "action"),
|
||||
"description": task.get("description", ""),
|
||||
"tool": task.get("tool", ""),
|
||||
"parameters": task.get("parameters", {}),
|
||||
"expected_output": task.get("expected_output", ""),
|
||||
"success_criteria": task.get("success_criteria", {}),
|
||||
"dependencies": task.get("dependencies", []),
|
||||
"priority": task.get("priority", 0.5),
|
||||
"timeout": task.get("timeout", 60)
|
||||
}
|
||||
formatted_tasks.append(formatted_task)
|
||||
|
||||
return formatted_tasks
|
||||
|
||||
def _format_conditional_plan(self, raw_plan: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""格式化条件计划"""
|
||||
formatted_tasks = []
|
||||
|
||||
# 添加条件检查任务
|
||||
condition_task = {
|
||||
"id": "condition_check",
|
||||
"type": "condition",
|
||||
"description": "条件检查",
|
||||
"condition": raw_plan.get("condition", ""),
|
||||
"branches": raw_plan.get("branches", {})
|
||||
}
|
||||
formatted_tasks.append(condition_task)
|
||||
|
||||
# 添加分支任务
|
||||
for branch_name, branch_tasks in raw_plan.get("branches", {}).items():
|
||||
branch_task = {
|
||||
"id": f"branch_{branch_name}",
|
||||
"type": "branch",
|
||||
"description": f"执行分支: {branch_name}",
|
||||
"condition": branch_name,
|
||||
"tasks": self._format_plan_tasks(branch_tasks)
|
||||
}
|
||||
formatted_tasks.append(branch_task)
|
||||
|
||||
return formatted_tasks
|
||||
|
||||
async def _optimize_plan(self, plan: List[Dict[str, Any]], constraints: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""优化计划"""
|
||||
optimized_plan = []
|
||||
|
||||
for task in plan:
|
||||
# 检查时间约束
|
||||
if task.get("timeout", 60) > constraints.get("timeout", 300):
|
||||
task["timeout"] = constraints.get("timeout", 300)
|
||||
|
||||
# 检查资源约束
|
||||
if task.get("resource_usage", 0) > constraints.get("memory_limit", 1000):
|
||||
# 分解大任务
|
||||
subtasks = await self._decompose_task(task)
|
||||
optimized_plan.extend(subtasks)
|
||||
else:
|
||||
optimized_plan.append(task)
|
||||
|
||||
return optimized_plan
|
||||
|
||||
async def _decompose_task(self, task: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""分解大任务为小任务"""
|
||||
prompt = f"""
|
||||
请将以下大任务分解为更小的子任务:
|
||||
|
||||
任务: {task.get('description', '')}
|
||||
类型: {task.get('type', '')}
|
||||
参数: {task.get('parameters', {})}
|
||||
|
||||
请返回分解后的子任务列表,每个子任务应该是独立的、可执行的。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个任务分解专家,擅长将复杂任务分解为简单任务。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return [task] # 如果分解失败,返回原任务
|
||||
|
||||
try:
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\[.*\]', response_content, re.DOTALL)
|
||||
if json_match:
|
||||
subtasks = json.loads(json_match.group())
|
||||
return self._format_plan_tasks(subtasks)
|
||||
else:
|
||||
return [task]
|
||||
except Exception as e:
|
||||
logger.error(f"任务分解失败: {e}")
|
||||
return [task]
|
||||
|
||||
def _create_fallback_plan(self, goal: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||
"""创建备用计划"""
|
||||
return [{
|
||||
"id": "fallback_task",
|
||||
"type": "action",
|
||||
"description": goal.get("description", "执行目标"),
|
||||
"tool": "general_response",
|
||||
"parameters": {"goal": goal},
|
||||
"expected_output": "目标完成",
|
||||
"success_criteria": {"completion": True},
|
||||
"priority": 0.5,
|
||||
"timeout": 60
|
||||
}]
|
||||
|
||||
def validate_plan(self, plan: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""验证计划的有效性"""
|
||||
validation_result = {
|
||||
"valid": True,
|
||||
"issues": [],
|
||||
"warnings": []
|
||||
}
|
||||
|
||||
for task in plan:
|
||||
# 检查必要字段
|
||||
if not task.get("id"):
|
||||
validation_result["issues"].append("任务缺少ID")
|
||||
validation_result["valid"] = False
|
||||
|
||||
if not task.get("description"):
|
||||
validation_result["warnings"].append(f"任务 {task.get('id', 'unknown')} 缺少描述")
|
||||
|
||||
# 检查依赖关系
|
||||
dependencies = task.get("dependencies", [])
|
||||
task_ids = [t.get("id") for t in plan]
|
||||
for dep in dependencies:
|
||||
if dep not in task_ids:
|
||||
validation_result["issues"].append(f"任务 {task.get('id')} 的依赖 {dep} 不存在")
|
||||
validation_result["valid"] = False
|
||||
|
||||
return validation_result
|
||||
479
src/agent/reasoning_engine.py
Normal file
479
src/agent/reasoning_engine.py
Normal file
@@ -0,0 +1,479 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
推理引擎
|
||||
负责逻辑推理和决策制定
|
||||
"""
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Any, Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from ..core.llm_client import QwenClient
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ReasoningEngine:
|
||||
"""推理引擎"""
|
||||
|
||||
def __init__(self):
|
||||
self.llm_client = QwenClient()
|
||||
self.reasoning_patterns = {
|
||||
"causal": self._causal_reasoning,
|
||||
"deductive": self._deductive_reasoning,
|
||||
"inductive": self._inductive_reasoning,
|
||||
"abductive": self._abductive_reasoning,
|
||||
"analogical": self._analogical_reasoning
|
||||
}
|
||||
self.reasoning_history = []
|
||||
|
||||
async def analyze_intent(
|
||||
self,
|
||||
message: str,
|
||||
context: Dict[str, Any],
|
||||
history: List[Dict[str, Any]]
|
||||
) -> Dict[str, Any]:
|
||||
"""分析用户意图"""
|
||||
try:
|
||||
prompt = f"""
|
||||
请分析以下用户消息的意图:
|
||||
|
||||
用户消息: {message}
|
||||
上下文: {json.dumps(context, ensure_ascii=False)}
|
||||
历史记录: {json.dumps(history, ensure_ascii=False)}
|
||||
|
||||
请从以下维度分析:
|
||||
1. 主要意图(问题咨询、工单创建、系统查询等)
|
||||
2. 情感倾向(积极、消极、中性)
|
||||
3. 紧急程度(高、中、低)
|
||||
4. 所需工具类型
|
||||
5. 预期响应类型
|
||||
6. 关键信息提取
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个意图分析专家,擅长理解用户需求和意图。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_fallback_intent(message)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
intent_analysis = json.loads(json_match.group())
|
||||
intent_analysis["timestamp"] = datetime.now().isoformat()
|
||||
return intent_analysis
|
||||
else:
|
||||
return self._create_fallback_intent(message)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"意图分析失败: {e}")
|
||||
return self._create_fallback_intent(message)
|
||||
|
||||
async def make_decision(
|
||||
self,
|
||||
situation: Dict[str, Any],
|
||||
options: List[Dict[str, Any]],
|
||||
criteria: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""制定决策"""
|
||||
try:
|
||||
prompt = f"""
|
||||
请根据以下情况制定决策:
|
||||
|
||||
当前情况: {json.dumps(situation, ensure_ascii=False)}
|
||||
可选方案: {json.dumps(options, ensure_ascii=False)}
|
||||
决策标准: {json.dumps(criteria, ensure_ascii=False)}
|
||||
|
||||
请分析每个方案的优缺点,并选择最佳方案。
|
||||
返回格式:
|
||||
{{
|
||||
"selected_option": "方案ID",
|
||||
"reasoning": "选择理由",
|
||||
"confidence": 0.8,
|
||||
"risks": ["风险1", "风险2"],
|
||||
"mitigation": "风险缓解措施"
|
||||
}}
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个决策制定专家,擅长分析情况并做出最优决策。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return self._create_fallback_decision(options)
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
decision = json.loads(json_match.group())
|
||||
decision["timestamp"] = datetime.now().isoformat()
|
||||
return decision
|
||||
else:
|
||||
return self._create_fallback_decision(options)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"决策制定失败: {e}")
|
||||
return self._create_fallback_decision(options)
|
||||
|
||||
async def reason_about_problem(
|
||||
self,
|
||||
problem: str,
|
||||
available_information: Dict[str, Any],
|
||||
reasoning_type: str = "causal"
|
||||
) -> Dict[str, Any]:
|
||||
"""对问题进行推理"""
|
||||
try:
|
||||
if reasoning_type not in self.reasoning_patterns:
|
||||
reasoning_type = "causal"
|
||||
|
||||
reasoning_func = self.reasoning_patterns[reasoning_type]
|
||||
result = await reasoning_func(problem, available_information)
|
||||
|
||||
# 记录推理历史
|
||||
self.reasoning_history.append({
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"problem": problem,
|
||||
"reasoning_type": reasoning_type,
|
||||
"result": result
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"问题推理失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _causal_reasoning(self, problem: str, information: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""因果推理"""
|
||||
prompt = f"""
|
||||
请使用因果推理分析以下问题:
|
||||
|
||||
问题: {problem}
|
||||
可用信息: {json.dumps(information, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 问题的根本原因
|
||||
2. 可能的因果关系链
|
||||
3. 影响因素分析
|
||||
4. 解决方案的预期效果
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个因果推理专家,擅长分析问题的因果关系。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"reasoning_type": "causal", "error": "推理失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
return json.loads(json_match.group())
|
||||
else:
|
||||
return {"reasoning_type": "causal", "analysis": response_content}
|
||||
|
||||
async def _deductive_reasoning(self, problem: str, information: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""演绎推理"""
|
||||
prompt = f"""
|
||||
请使用演绎推理分析以下问题:
|
||||
|
||||
问题: {problem}
|
||||
可用信息: {json.dumps(information, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 一般性规则或原理
|
||||
2. 具体事实或条件
|
||||
3. 逻辑推导过程
|
||||
4. 必然结论
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个演绎推理专家,擅长从一般原理推导具体结论。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"reasoning_type": "deductive", "error": "推理失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
return json.loads(json_match.group())
|
||||
else:
|
||||
return {"reasoning_type": "deductive", "analysis": response_content}
|
||||
|
||||
async def _inductive_reasoning(self, problem: str, information: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""归纳推理"""
|
||||
prompt = f"""
|
||||
请使用归纳推理分析以下问题:
|
||||
|
||||
问题: {problem}
|
||||
可用信息: {json.dumps(information, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 观察到的具体现象
|
||||
2. 寻找共同模式
|
||||
3. 形成一般性假设
|
||||
4. 验证假设的合理性
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个归纳推理专家,擅长从具体现象归纳一般规律。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"reasoning_type": "inductive", "error": "推理失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
return json.loads(json_match.group())
|
||||
else:
|
||||
return {"reasoning_type": "inductive", "analysis": response_content}
|
||||
|
||||
async def _abductive_reasoning(self, problem: str, information: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""溯因推理"""
|
||||
prompt = f"""
|
||||
请使用溯因推理分析以下问题:
|
||||
|
||||
问题: {problem}
|
||||
可用信息: {json.dumps(information, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 观察到的现象
|
||||
2. 可能的最佳解释
|
||||
3. 解释的合理性评估
|
||||
4. 需要进一步验证的假设
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个溯因推理专家,擅长寻找现象的最佳解释。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"reasoning_type": "abductive", "error": "推理失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
return json.loads(json_match.group())
|
||||
else:
|
||||
return {"reasoning_type": "abductive", "analysis": response_content}
|
||||
|
||||
async def _analogical_reasoning(self, problem: str, information: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""类比推理"""
|
||||
prompt = f"""
|
||||
请使用类比推理分析以下问题:
|
||||
|
||||
问题: {problem}
|
||||
可用信息: {json.dumps(information, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 寻找相似的问题或情况
|
||||
2. 识别相似性和差异性
|
||||
3. 应用类比关系
|
||||
4. 调整解决方案以适应当前情况
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个类比推理专家,擅长通过类比解决问题。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"reasoning_type": "analogical", "error": "推理失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
return json.loads(json_match.group())
|
||||
else:
|
||||
return {"reasoning_type": "analogical", "analysis": response_content}
|
||||
|
||||
async def extract_insights(
|
||||
self,
|
||||
execution_result: Dict[str, Any],
|
||||
goal: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""从执行结果中提取洞察"""
|
||||
try:
|
||||
prompt = f"""
|
||||
请从以下执行结果中提取洞察:
|
||||
|
||||
执行结果: {json.dumps(execution_result, ensure_ascii=False)}
|
||||
目标: {json.dumps(goal, ensure_ascii=False)}
|
||||
|
||||
请分析:
|
||||
1. 成功模式(什么导致了成功)
|
||||
2. 失败模式(什么导致了失败)
|
||||
3. 性能指标(效率、准确性等)
|
||||
4. 改进建议
|
||||
5. 新发现的知识
|
||||
|
||||
请以JSON格式返回分析结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个洞察提取专家,擅长从执行结果中提取有价值的洞察。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"error": "洞察提取失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
insights = json.loads(json_match.group())
|
||||
insights["timestamp"] = datetime.now().isoformat()
|
||||
return insights
|
||||
else:
|
||||
return {"analysis": response_content, "timestamp": datetime.now().isoformat()}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"洞察提取失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def evaluate_solution(
|
||||
self,
|
||||
problem: str,
|
||||
solution: Dict[str, Any],
|
||||
criteria: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
"""评估解决方案"""
|
||||
try:
|
||||
prompt = f"""
|
||||
请评估以下解决方案:
|
||||
|
||||
问题: {problem}
|
||||
解决方案: {json.dumps(solution, ensure_ascii=False)}
|
||||
评估标准: {json.dumps(criteria, ensure_ascii=False)}
|
||||
|
||||
请从以下维度评估:
|
||||
1. 有效性(是否能解决问题)
|
||||
2. 效率(资源消耗和时间成本)
|
||||
3. 可行性(实施难度)
|
||||
4. 风险(潜在问题)
|
||||
5. 创新性(新颖程度)
|
||||
|
||||
请以JSON格式返回评估结果。
|
||||
"""
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "你是一个解决方案评估专家,擅长全面评估解决方案的质量。"},
|
||||
{"role": "user", "content": prompt}
|
||||
]
|
||||
|
||||
result = self.llm_client.chat_completion(messages, temperature=0.3)
|
||||
|
||||
if "error" in result:
|
||||
return {"error": "解决方案评估失败"}
|
||||
|
||||
response_content = result["choices"][0]["message"]["content"]
|
||||
import re
|
||||
json_match = re.search(r'\{.*\}', response_content, re.DOTALL)
|
||||
|
||||
if json_match:
|
||||
evaluation = json.loads(json_match.group())
|
||||
evaluation["timestamp"] = datetime.now().isoformat()
|
||||
return evaluation
|
||||
else:
|
||||
return {"evaluation": response_content, "timestamp": datetime.now().isoformat()}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"解决方案评估失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
def _create_fallback_intent(self, message: str) -> Dict[str, Any]:
|
||||
"""创建备用意图分析"""
|
||||
return {
|
||||
"main_intent": "general_query",
|
||||
"emotion": "neutral",
|
||||
"urgency": "medium",
|
||||
"required_tools": ["generate_response"],
|
||||
"expected_response": "text",
|
||||
"key_information": {"message": message},
|
||||
"confidence": 0.5,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
def _create_fallback_decision(self, options: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""创建备用决策"""
|
||||
if not options:
|
||||
return {
|
||||
"selected_option": None,
|
||||
"reasoning": "无可用选项",
|
||||
"confidence": 0.0,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# 选择第一个选项作为默认选择
|
||||
return {
|
||||
"selected_option": options[0].get("id", "option_1"),
|
||||
"reasoning": "默认选择",
|
||||
"confidence": 0.3,
|
||||
"risks": ["决策质量未知"],
|
||||
"mitigation": "需要进一步验证",
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
def get_reasoning_history(self, limit: int = 10) -> List[Dict[str, Any]]:
|
||||
"""获取推理历史"""
|
||||
return self.reasoning_history[-limit:] if self.reasoning_history else []
|
||||
|
||||
def clear_reasoning_history(self):
|
||||
"""清空推理历史"""
|
||||
self.reasoning_history = []
|
||||
logger.info("推理历史已清空")
|
||||
435
src/agent/tool_manager.py
Normal file
435
src/agent/tool_manager.py
Normal file
@@ -0,0 +1,435 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
工具管理器
|
||||
负责管理和执行各种工具
|
||||
"""
|
||||
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import Dict, List, Any, Optional, Callable
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ToolManager:
|
||||
"""工具管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.tools = {}
|
||||
self.tool_usage_stats = {}
|
||||
self.tool_performance = {}
|
||||
self._register_default_tools()
|
||||
|
||||
def _register_default_tools(self):
|
||||
"""注册默认工具"""
|
||||
# 注册基础工具
|
||||
self.register_tool("search_knowledge", self._search_knowledge_tool)
|
||||
self.register_tool("create_work_order", self._create_work_order_tool)
|
||||
self.register_tool("update_work_order", self._update_work_order_tool)
|
||||
self.register_tool("generate_response", self._generate_response_tool)
|
||||
self.register_tool("analyze_data", self._analyze_data_tool)
|
||||
self.register_tool("send_notification", self._send_notification_tool)
|
||||
self.register_tool("schedule_task", self._schedule_task_tool)
|
||||
self.register_tool("web_search", self._web_search_tool)
|
||||
self.register_tool("file_operation", self._file_operation_tool)
|
||||
self.register_tool("database_query", self._database_query_tool)
|
||||
|
||||
logger.info(f"已注册 {len(self.tools)} 个默认工具")
|
||||
|
||||
def register_tool(self, name: str, func: Callable, metadata: Optional[Dict[str, Any]] = None):
|
||||
"""注册工具"""
|
||||
self.tools[name] = {
|
||||
"function": func,
|
||||
"metadata": metadata or {},
|
||||
"usage_count": 0,
|
||||
"last_used": None,
|
||||
"success_rate": 0.0
|
||||
}
|
||||
|
||||
logger.info(f"注册工具: {name}")
|
||||
|
||||
def unregister_tool(self, name: str) -> bool:
|
||||
"""注销工具"""
|
||||
if name in self.tools:
|
||||
del self.tools[name]
|
||||
logger.info(f"注销工具: {name}")
|
||||
return True
|
||||
return False
|
||||
|
||||
async def execute_tool(self, tool_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""执行工具"""
|
||||
if tool_name not in self.tools:
|
||||
return {
|
||||
"success": False,
|
||||
"error": f"工具 '{tool_name}' 不存在"
|
||||
}
|
||||
|
||||
tool = self.tools[tool_name]
|
||||
start_time = datetime.now()
|
||||
|
||||
try:
|
||||
# 更新使用统计
|
||||
tool["usage_count"] += 1
|
||||
tool["last_used"] = start_time
|
||||
|
||||
# 执行工具
|
||||
if asyncio.iscoroutinefunction(tool["function"]):
|
||||
result = await tool["function"](**parameters)
|
||||
else:
|
||||
result = tool["function"](**parameters)
|
||||
|
||||
# 更新性能统计
|
||||
execution_time = (datetime.now() - start_time).total_seconds()
|
||||
self._update_tool_performance(tool_name, True, execution_time)
|
||||
|
||||
logger.info(f"工具 '{tool_name}' 执行成功,耗时: {execution_time:.2f}秒")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"result": result,
|
||||
"execution_time": execution_time,
|
||||
"tool": tool_name
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"工具 '{tool_name}' 执行失败: {e}")
|
||||
|
||||
# 更新性能统计
|
||||
execution_time = (datetime.now() - start_time).total_seconds()
|
||||
self._update_tool_performance(tool_name, False, execution_time)
|
||||
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"execution_time": execution_time,
|
||||
"tool": tool_name
|
||||
}
|
||||
|
||||
def _update_tool_performance(self, tool_name: str, success: bool, execution_time: float):
|
||||
"""更新工具性能统计"""
|
||||
if tool_name not in self.tool_performance:
|
||||
self.tool_performance[tool_name] = {
|
||||
"total_executions": 0,
|
||||
"successful_executions": 0,
|
||||
"total_time": 0.0,
|
||||
"avg_execution_time": 0.0,
|
||||
"success_rate": 0.0
|
||||
}
|
||||
|
||||
perf = self.tool_performance[tool_name]
|
||||
perf["total_executions"] += 1
|
||||
perf["total_time"] += execution_time
|
||||
perf["avg_execution_time"] = perf["total_time"] / perf["total_executions"]
|
||||
|
||||
if success:
|
||||
perf["successful_executions"] += 1
|
||||
|
||||
perf["success_rate"] = perf["successful_executions"] / perf["total_executions"]
|
||||
|
||||
# 更新工具的成功率
|
||||
self.tools[tool_name]["success_rate"] = perf["success_rate"]
|
||||
|
||||
def get_available_tools(self) -> List[Dict[str, Any]]:
|
||||
"""获取可用工具列表"""
|
||||
tools_info = []
|
||||
|
||||
for name, tool in self.tools.items():
|
||||
tool_info = {
|
||||
"name": name,
|
||||
"metadata": tool["metadata"],
|
||||
"usage_count": tool["usage_count"],
|
||||
"last_used": tool["last_used"].isoformat() if tool["last_used"] else None,
|
||||
"success_rate": tool["success_rate"]
|
||||
}
|
||||
|
||||
# 添加性能信息
|
||||
if name in self.tool_performance:
|
||||
perf = self.tool_performance[name]
|
||||
tool_info.update({
|
||||
"avg_execution_time": perf["avg_execution_time"],
|
||||
"total_executions": perf["total_executions"]
|
||||
})
|
||||
|
||||
tools_info.append(tool_info)
|
||||
|
||||
return tools_info
|
||||
|
||||
def get_tool_info(self, tool_name: str) -> Optional[Dict[str, Any]]:
|
||||
"""获取工具信息"""
|
||||
if tool_name not in self.tools:
|
||||
return None
|
||||
|
||||
tool = self.tools[tool_name]
|
||||
info = {
|
||||
"name": tool_name,
|
||||
"metadata": tool["metadata"],
|
||||
"usage_count": tool["usage_count"],
|
||||
"last_used": tool["last_used"].isoformat() if tool["last_used"] else None,
|
||||
"success_rate": tool["success_rate"]
|
||||
}
|
||||
|
||||
if tool_name in self.tool_performance:
|
||||
info.update(self.tool_performance[tool_name])
|
||||
|
||||
return info
|
||||
|
||||
def update_usage_stats(self, tool_usage: List[Dict[str, Any]]):
|
||||
"""更新工具使用统计"""
|
||||
for usage in tool_usage:
|
||||
tool_name = usage.get("tool")
|
||||
if tool_name in self.tools:
|
||||
self.tools[tool_name]["usage_count"] += usage.get("count", 1)
|
||||
|
||||
# 默认工具实现
|
||||
|
||||
async def _search_knowledge_tool(self, query: str, top_k: int = 3, **kwargs) -> Dict[str, Any]:
|
||||
"""搜索知识库工具"""
|
||||
try:
|
||||
from ..knowledge_base.knowledge_manager import KnowledgeManager
|
||||
knowledge_manager = KnowledgeManager()
|
||||
|
||||
results = knowledge_manager.search_knowledge(query, top_k)
|
||||
|
||||
return {
|
||||
"query": query,
|
||||
"results": results,
|
||||
"count": len(results)
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"搜索知识库失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _create_work_order_tool(self, title: str, description: str, category: str, priority: str = "medium", **kwargs) -> Dict[str, Any]:
|
||||
"""创建工单工具"""
|
||||
try:
|
||||
from ..dialogue.dialogue_manager import DialogueManager
|
||||
dialogue_manager = DialogueManager()
|
||||
|
||||
result = dialogue_manager.create_work_order(title, description, category, priority)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"创建工单失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _update_work_order_tool(self, work_order_id: int, **kwargs) -> Dict[str, Any]:
|
||||
"""更新工单工具"""
|
||||
try:
|
||||
from ..dialogue.dialogue_manager import DialogueManager
|
||||
dialogue_manager = DialogueManager()
|
||||
|
||||
success = dialogue_manager.update_work_order(work_order_id, **kwargs)
|
||||
|
||||
return {
|
||||
"success": success,
|
||||
"work_order_id": work_order_id,
|
||||
"updated_fields": list(kwargs.keys())
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"更新工单失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _generate_response_tool(self, message: str, context: str = "", **kwargs) -> Dict[str, Any]:
|
||||
"""生成回复工具"""
|
||||
try:
|
||||
from ..core.llm_client import QwenClient
|
||||
llm_client = QwenClient()
|
||||
|
||||
result = llm_client.generate_response(message, context)
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"生成回复失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _analyze_data_tool(self, data_type: str, date_range: str = "last_7_days", **kwargs) -> Dict[str, Any]:
|
||||
"""数据分析工具"""
|
||||
try:
|
||||
from ..analytics.analytics_manager import AnalyticsManager
|
||||
analytics_manager = AnalyticsManager()
|
||||
|
||||
if data_type == "daily_analytics":
|
||||
result = analytics_manager.generate_daily_analytics()
|
||||
elif data_type == "summary":
|
||||
result = analytics_manager.get_analytics_summary()
|
||||
elif data_type == "category_performance":
|
||||
result = analytics_manager.get_category_performance()
|
||||
else:
|
||||
result = {"error": f"不支持的数据类型: {data_type}"}
|
||||
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"数据分析失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _send_notification_tool(self, message: str, recipients: List[str], notification_type: str = "info", **kwargs) -> Dict[str, Any]:
|
||||
"""发送通知工具"""
|
||||
try:
|
||||
# 这里可以实现具体的通知逻辑
|
||||
# 例如:发送邮件、短信、推送通知等
|
||||
|
||||
notification_data = {
|
||||
"message": message,
|
||||
"recipients": recipients,
|
||||
"type": notification_type,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
# 模拟发送通知
|
||||
logger.info(f"发送通知: {message} 给 {recipients}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"notification_id": f"notif_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
|
||||
"data": notification_data
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"发送通知失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _schedule_task_tool(self, task_name: str, schedule_time: str, task_data: Dict[str, Any], **kwargs) -> Dict[str, Any]:
|
||||
"""调度任务工具"""
|
||||
try:
|
||||
# 这里可以实现任务调度逻辑
|
||||
# 例如:使用APScheduler、Celery等
|
||||
|
||||
schedule_data = {
|
||||
"task_name": task_name,
|
||||
"schedule_time": schedule_time,
|
||||
"task_data": task_data,
|
||||
"created_at": datetime.now().isoformat()
|
||||
}
|
||||
|
||||
logger.info(f"调度任务: {task_name} 在 {schedule_time}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"schedule_id": f"schedule_{datetime.now().strftime('%Y%m%d_%H%M%S')}",
|
||||
"data": schedule_data
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"调度任务失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _web_search_tool(self, query: str, max_results: int = 5, **kwargs) -> Dict[str, Any]:
|
||||
"""网络搜索工具"""
|
||||
try:
|
||||
# 这里可以实现网络搜索逻辑
|
||||
# 例如:使用Google Search API、Bing Search API等
|
||||
|
||||
search_results = [
|
||||
{
|
||||
"title": f"搜索结果 {i+1}",
|
||||
"url": f"https://example.com/result{i+1}",
|
||||
"snippet": f"这是关于 '{query}' 的搜索结果摘要 {i+1}"
|
||||
}
|
||||
for i in range(min(max_results, 3))
|
||||
]
|
||||
|
||||
logger.info(f"网络搜索: {query}")
|
||||
|
||||
return {
|
||||
"query": query,
|
||||
"results": search_results,
|
||||
"count": len(search_results)
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"网络搜索失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _file_operation_tool(self, operation: str, file_path: str, content: str = "", **kwargs) -> Dict[str, Any]:
|
||||
"""文件操作工具"""
|
||||
try:
|
||||
import os
|
||||
|
||||
if operation == "read":
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
return {"success": True, "content": content, "operation": "read"}
|
||||
|
||||
elif operation == "write":
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.write(content)
|
||||
return {"success": True, "operation": "write", "file_path": file_path}
|
||||
|
||||
elif operation == "exists":
|
||||
exists = os.path.exists(file_path)
|
||||
return {"success": True, "exists": exists, "file_path": file_path}
|
||||
|
||||
else:
|
||||
return {"error": f"不支持的文件操作: {operation}"}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"文件操作失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
async def _database_query_tool(self, query: str, query_type: str = "select", **kwargs) -> Dict[str, Any]:
|
||||
"""数据库查询工具"""
|
||||
try:
|
||||
from ..core.database import db_manager
|
||||
|
||||
with db_manager.get_session() as session:
|
||||
if query_type == "select":
|
||||
result = session.execute(query).fetchall()
|
||||
return {
|
||||
"success": True,
|
||||
"result": [dict(row) for row in result],
|
||||
"count": len(result)
|
||||
}
|
||||
else:
|
||||
session.execute(query)
|
||||
session.commit()
|
||||
return {"success": True, "operation": query_type}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"数据库查询失败: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
def get_tool_performance_report(self) -> Dict[str, Any]:
|
||||
"""获取工具性能报告"""
|
||||
report = {
|
||||
"total_tools": len(self.tools),
|
||||
"tool_performance": {},
|
||||
"summary": {
|
||||
"most_used": None,
|
||||
"most_reliable": None,
|
||||
"fastest": None,
|
||||
"slowest": None
|
||||
}
|
||||
}
|
||||
|
||||
if not self.tool_performance:
|
||||
return report
|
||||
|
||||
# 分析性能数据
|
||||
most_used_count = 0
|
||||
most_reliable_rate = 0
|
||||
fastest_time = float('inf')
|
||||
slowest_time = 0
|
||||
|
||||
for tool_name, perf in self.tool_performance.items():
|
||||
report["tool_performance"][tool_name] = perf
|
||||
|
||||
# 找出最常用的工具
|
||||
if perf["total_executions"] > most_used_count:
|
||||
most_used_count = perf["total_executions"]
|
||||
report["summary"]["most_used"] = tool_name
|
||||
|
||||
# 找出最可靠的工具
|
||||
if perf["success_rate"] > most_reliable_rate:
|
||||
most_reliable_rate = perf["success_rate"]
|
||||
report["summary"]["most_reliable"] = tool_name
|
||||
|
||||
# 找出最快的工具
|
||||
if perf["avg_execution_time"] < fastest_time:
|
||||
fastest_time = perf["avg_execution_time"]
|
||||
report["summary"]["fastest"] = tool_name
|
||||
|
||||
# 找出最慢的工具
|
||||
if perf["avg_execution_time"] > slowest_time:
|
||||
slowest_time = perf["avg_execution_time"]
|
||||
report["summary"]["slowest"] = tool_name
|
||||
|
||||
return report
|
||||
Reference in New Issue
Block a user