- 新增 Go 语言后端服务(server/),包含用户认证、Agent管理、数据库连接等API - 新增 Python Agent 服务(agent/),实现Agent核心逻辑和工具集 - 前端从原生HTML迁移到Vue.js框架(web/src/) - 添加 Docker Compose 支持(docker-compose.yml) - 添加项目架构文档(docs/ARCHITECTURE.md) - 添加环境变量示例(.env.example)和本地启动脚本(start-local.ps1) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
164 lines
5.0 KiB
Python
164 lines
5.0 KiB
Python
"""
|
||
Agent 执行器 - 负责执行 Agent 的核心逻辑
|
||
"""
|
||
from typing import Any, Optional
|
||
from app.llm.factory import LLMFactory
|
||
from app.agent.tools.registry import ToolRegistry
|
||
from app.agent.memory.session import SessionManager
|
||
from app.security.audit import AuditLogger
|
||
|
||
|
||
class AgentExecutor:
|
||
"""Agent 执行器"""
|
||
|
||
def __init__(
|
||
self,
|
||
agent_id: str,
|
||
llm_factory: LLMFactory,
|
||
tool_registry: ToolRegistry,
|
||
session_manager: SessionManager,
|
||
audit_logger: AuditLogger,
|
||
config: dict
|
||
):
|
||
self.agent_id = agent_id
|
||
self.llm_factory = llm_factory
|
||
self.tool_registry = tool_registry
|
||
self.session_manager = session_manager
|
||
self.audit_logger = audit_logger
|
||
self.config = config
|
||
|
||
# 获取 LLM
|
||
self.llm = self.llm_factory.get_llm()
|
||
|
||
async def run(
|
||
self,
|
||
message: str,
|
||
session_id: str,
|
||
context: dict
|
||
) -> dict[str, Any]:
|
||
"""运行 Agent"""
|
||
tools_used = []
|
||
|
||
# 1. 获取会话历史
|
||
history = self.session_manager.get_history(session_id)
|
||
|
||
# 2. 构建消息列表
|
||
messages = self._build_messages(message, history)
|
||
|
||
# 3. 获取可用工具
|
||
available_tools = self._get_available_tools()
|
||
|
||
# 4. 调用 LLM(带工具)
|
||
try:
|
||
response = await self.llm.agenerate(
|
||
messages=messages,
|
||
tools=available_tools
|
||
)
|
||
|
||
# 检查是否需要调用工具
|
||
response_message = response.generations[0][0]
|
||
|
||
# 如果有工具调用
|
||
if hasattr(response_message, "tool_calls") and response_message.tool_calls:
|
||
for tool_call in response_message.tool_calls:
|
||
tool_name = tool_call.name
|
||
tool_args = tool_call.arguments
|
||
|
||
# 记录工具使用
|
||
tools_used.append(tool_name)
|
||
|
||
# 执行工具
|
||
tool_result = await self._execute_tool(tool_name, tool_args)
|
||
|
||
# 添加工具结果到消息
|
||
messages.append(response_message)
|
||
messages.append({
|
||
"role": "tool",
|
||
"tool_call_id": tool_call.id,
|
||
"content": str(tool_result)
|
||
})
|
||
|
||
# 再次调用 LLM 生成最终响应
|
||
final_response = await self.llm.agenerate(messages=messages)
|
||
final_message = final_response.generations[0][0].text
|
||
|
||
# 保存到历史
|
||
self.session_manager.add_message(session_id, "user", message)
|
||
self.session_manager.add_message(session_id, "assistant", final_message)
|
||
|
||
return {
|
||
"reply": final_message,
|
||
"tools_used": tools_used,
|
||
"metadata": {}
|
||
}
|
||
|
||
# 没有工具调用,直接返回
|
||
reply = response_message.text
|
||
|
||
# 保存到历史
|
||
self.session_manager.add_message(session_id, "user", message)
|
||
self.session_manager.add_message(session_id, "assistant", reply)
|
||
|
||
return {
|
||
"reply": reply,
|
||
"tools_used": tools_used,
|
||
"metadata": {}
|
||
}
|
||
|
||
except Exception as e:
|
||
# 记录错误
|
||
self.audit_logger.log(
|
||
action="agent_error",
|
||
agent_id=self.agent_id,
|
||
session_id=session_id,
|
||
details={"error": str(e)}
|
||
)
|
||
raise
|
||
|
||
def _build_messages(self, message: str, history: list) -> list:
|
||
"""构建消息列表"""
|
||
messages = []
|
||
|
||
# 添加系统提示
|
||
system_prompt = self.config.get("system_prompt", "You are a helpful assistant.")
|
||
messages.append({"role": "system", "content": system_prompt})
|
||
|
||
# 添加历史
|
||
for msg in history:
|
||
messages.append(msg)
|
||
|
||
# 添加当前消息
|
||
messages.append({"role": "user", "content": message})
|
||
|
||
return messages
|
||
|
||
def _get_available_tools(self) -> list:
|
||
"""获取可用工具定义"""
|
||
agent_tools = self.config.get("tools", [])
|
||
tool_defs = []
|
||
|
||
for tool_name in agent_tools:
|
||
tool_def = self.tool_registry.get_tool_definition(tool_name)
|
||
if tool_def:
|
||
tool_defs.append(tool_def)
|
||
|
||
return tool_defs
|
||
|
||
async def _execute_tool(self, tool_name: str, args: dict) -> Any:
|
||
"""执行工具"""
|
||
# 安全检查
|
||
tool_func, metadata = self.tool_registry.get_tool(tool_name)
|
||
|
||
# 如果需要审批,抛出异常
|
||
if metadata.require_approval:
|
||
raise PermissionError(
|
||
f"Tool '{tool_name}' requires approval before execution"
|
||
)
|
||
|
||
# 执行工具
|
||
try:
|
||
result = tool_func(**args)
|
||
return result
|
||
except Exception as e:
|
||
return {"error": str(e)}
|