Appearance
Agent架构设计
好的架构是Agent稳定运行的基础
Agent架构概览
一个完整的Agent系统需要精心设计的架构来支撑复杂任务的执行。良好的架构设计能确保Agent的可靠性、可扩展性和可维护性。
Agent系统架构全景图:
┌─────────────────────────────────────────────────────────────────┐
│ 用户接口层 │
│ (CLI / Web / API / Chat) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Agent核心层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 规划器 │ │ 推理器 │ │ 执行器 │ │ │
│ │ │ Planner │ │ Reasoner │ │ Executor │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 记忆管理层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 短期记忆 │ │ 长期记忆 │ │ 工作记忆 │ │ │
│ │ │ STM │ │ LTM │ │ WM │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 工具服务层 │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │搜索工具│ │数据库 │ │代码执行│ │API调用 │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘核心架构模式
1. 单Agent架构
最简单的架构形式,适合单一任务场景。
单Agent架构:
────────────────────────────
用户输入
↓
┌─────────┐
│ Agent │ ←─── LLM
│ 核心 │
└────┬────┘
↓
┌─────────┐
│ 工具集 │
└────┬────┘
↓
输出结果适用场景:
- 简单问答
- 单一工具调用
- 明确的任务流程
优点:
- 结构简单,易于实现
- 调试方便
- 资源消耗低
缺点:
- 处理复杂任务能力有限
- 难以并行处理
2. 多Agent协作架构
多个专业Agent协同工作,适合复杂任务场景。
多Agent协作架构:
────────────────────────────
用户输入
↓
┌───────────────┐
│ 主控Agent │
│ (Orchestrator)│
└───────┬───────┘
│
┌───────────┼───────────┐
↓ ↓ ↓
┌─────────┐ ┌─────────┐ ┌─────────┐
│研究Agent│ │分析Agent│ │写作Agent│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└───────────┼───────────┘
↓
最终输出适用场景:
- 复杂研究任务
- 多领域协作
- 大规模项目
优点:
- 专业分工,各司其职
- 可并行处理
- 易于扩展
缺点:
- 架构复杂
- 通信开销
- 需要协调机制
3. 层级Agent架构
分层管理,上层Agent负责规划,下层Agent负责执行。
层级Agent架构:
────────────────────────────
┌─────────────┐
│ 管理Agent │ ← 战略层:目标分解
└──────┬──────┘
│
┌──────────┼──────────┐
↓ ↓ ↓
┌───────┐ ┌───────┐ ┌───────┐
│协调器A│ │协调器B│ │协调器C│ ← 战术层:任务协调
└───┬───┘ └───┬───┘ └───┬───┘
│ │ │
┌──┴──┐ ┌──┴──┐ ┌──┴──┐
│执行器│ │执行器│ │执行器│ ← 执行层:具体执行
└─────┘ └─────┘ └─────┘适用场景:
- 大型项目
- 企业级应用
- 需要严格控制的场景
核心组件设计
1. 规划器(Planner)
规划器负责将用户目标分解为可执行的步骤。
规划器设计:
┌─────────────────────────────────────────┐
│ Planner │
├─────────────────────────────────────────┤
│ │
│ 输入:用户目标 + 上下文 │
│ │
│ 处理流程: │
│ 1. 理解目标 │
│ 2. 分析可行性 │
│ 3. 分解子任务 │
│ 4. 确定依赖关系 │
│ 5. 生成执行计划 │
│ │
│ 输出:任务列表 + 执行顺序 │
│ │
└─────────────────────────────────────────┘规划策略:
php
<?php
/**
* 规划器类
* 负责将用户目标分解为可执行的步骤
*/
class Planner
{
// 大语言模型实例
private $llm;
/**
* 构造函数
* @param mixed $llm 大语言模型实例
*/
public function __construct($llm)
{
// 初始化LLM
$this->llm = $llm;
}
/**
* 规划任务
* @param string $goal 用户目标
* @param array $context 上下文信息
* @return array 执行计划
*/
public function plan(string $goal, array $context): array
{
// 构建规划提示词
$planningPrompt = <<<PROMPT
目标:{$goal}
可用工具:{implode(', ', $context['available_tools'])}
请将目标分解为具体步骤,每个步骤包含:
1. 步骤描述
2. 需要使用的工具
3. 预期输出
4. 依赖的其他步骤
以JSON格式输出执行计划。
PROMPT;
// 调用LLM生成计划
$response = $this->llm->generate($planningPrompt);
// 解析并返回计划
return $this->parsePlan($response);
}
/**
* 解析计划响应
* @param string $response LLM响应
* @return array 解析后的计划
*/
private function parsePlan(string $response): array
{
// JSON解码返回数组
return json_decode($response, true);
}
}2. 执行器(Executor)
执行器负责执行具体步骤,调用工具并处理结果。
执行器设计:
┌─────────────────────────────────────────┐
│ Executor │
├─────────────────────────────────────────┤
│ │
│ 核心职责: │
│ • 工具调用 │
│ • 结果处理 │
│ • 错误处理 │
│ • 状态更新 │
│ │
│ 执行流程: │
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │准备参数│→→ │调用工具│→→ │处理结果│ │
│ └───────┘ └───────┘ └───────┘ │
│ ↓ ↓ ↓ │
│ 参数验证 异常捕获 结果验证 │
│ │
└─────────────────────────────────────────┘执行器实现:
php
<?php
/**
* 执行器类
* 负责执行具体步骤,调用工具并处理结果
*/
class Executor
{
// 工具列表
private array $tools;
/**
* 构造函数
* @param array $tools 可用工具列表
*/
public function __construct(array $tools)
{
// 初始化工具列表
$this->tools = $tools;
}
/**
* 执行步骤
* @param array $step 步骤配置
* @return array 执行结果
*/
public function execute(array $step): array
{
// 获取工具名称
$toolName = $step['tool'];
// 获取工具参数,默认为空数组
$params = $step['params'] ?? [];
// 检查工具是否存在
if (!isset($this->tools[$toolName])) {
throw new \InvalidArgumentException("Unknown tool: {$toolName}");
}
// 获取工具实例
$tool = $this->tools[$toolName];
try {
// 执行工具
$result = $tool->execute($params);
// 返回成功结果
return [
'success' => true,
'result' => $result,
'step' => $step
];
} catch (\Exception $e) {
// 返回失败结果
return [
'success' => false,
'error' => $e->getMessage(),
'step' => $step
];
}
}
/**
* 带重试的执行
* @param array $step 步骤配置
* @param int $maxRetries 最大重试次数
* @return array 执行结果
*/
public function executeWithRetry(array $step, int $maxRetries = 3): array
{
// 循环重试
for ($attempt = 0; $attempt < $maxRetries; $attempt++) {
// 执行步骤
$result = $this->execute($step);
// 检查是否成功
if ($result['success']) {
return $result;
}
}
// 返回最后一次结果
return $result;
}
}3. 记忆系统(Memory System)
记忆系统是Agent保持上下文和积累经验的关键。
记忆系统架构:
────────────────────────────
┌─────────────────────────────────────────┐
│ Memory System │
├─────────────────────────────────────────┤
│ │
│ 短期记忆(Short-term Memory) │
│ ├── 当前对话上下文 │
│ ├── 任务执行状态 │
│ └── 临时变量存储 │
│ 存储:内存 │
│ 生命周期:当前会话 │
│ │
│ 工作记忆(Working Memory) │
│ ├── 当前任务相关数据 │
│ ├── 中间计算结果 │
│ └── 活跃的工具状态 │
│ 存储:内存 + 缓存 │
│ 生命周期:任务执行期间 │
│ │
│ 长期记忆(Long-term Memory) │
│ ├── 用户偏好设置 │
│ ├── 历史交互记录 │
│ └── 知识库 │
│ 存储:数据库 / 向量数据库 │
│ 生命周期:持久化 │
│ │
└─────────────────────────────────────────┘记忆系统实现:
php
<?php
/**
* 记忆系统类
* 管理Agent的短期、工作和长期记忆
*/
class MemorySystem
{
// 短期记忆数组
private array $shortTerm = [];
// 工作记忆数组
private array $workingMemory = [];
// 长期记忆向量存储
private VectorStore $longTerm;
/**
* 构造函数
* 初始化长期记忆存储
*/
public function __construct()
{
// 创建向量存储实例
$this->longTerm = new VectorStore();
}
/**
* 添加消息到短期记忆
* @param array $message 消息内容
*/
public function addToShortTerm(array $message): void
{
// 添加消息到数组
$this->shortTerm[] = $message;
// 限制记忆数量,保留最近100条
if (count($this->shortTerm) > 100) {
$this->shortTerm = array_slice($this->shortTerm, -100);
}
}
/**
* 获取上下文内容
* @return string 格式化的上下文字符串
*/
public function getContext(): string
{
// 初始化行数组
$lines = [];
// 遍历短期记忆
foreach ($this->shortTerm as $m) {
// 格式化消息
$lines[] = "{$m['role']}: {$m['content']}";
}
// 返回拼接后的字符串
return implode("\n", $lines);
}
/**
* 存储到长期记忆
* @param string $key 键名
* @param string $value 值
*/
public function storeLongTerm(string $key, string $value): void
{
// 添加到向量存储
$this->longTerm->add($key, $value);
}
/**
* 从长期记忆检索
* @param string $query 查询字符串
* @param int $k 返回结果数量
* @return array 检索结果
*/
public function retrieveLongTerm(string $query, int $k = 5): array
{
// 搜索向量存储
return $this->longTerm->search($query, $k);
}
/**
* 设置工作记忆
* @param string $key 键名
* @param mixed $value 值
*/
public function setWorking(string $key, mixed $value): void
{
// 存储到工作记忆
$this->workingMemory[$key] = $value;
}
public function getWorking(string $key): mixed
{
return $this->workingMemory[$key] ?? null;
}
}执行循环设计
ReAct循环实现
php
<?php
/**
* ReAct Agent类
* 实现思考-行动-观察循环模式
*/
class ReActAgent
{
// 大语言模型实例
private $llm;
// 可用工具列表
private array $tools;
// 记忆系统
private MemorySystem $memory;
// 最大迭代次数
private int $maxIterations = 10;
/**
* 构造函数
* @param mixed $llm 大语言模型实例
* @param array $tools 工具列表
* @param MemorySystem $memory 记忆系统
*/
public function __construct($llm, array $tools, MemorySystem $memory)
{
// 初始化LLM
$this->llm = $llm;
// 初始化工具列表
$this->tools = $tools;
// 初始化记忆系统
$this->memory = $memory;
}
/**
* 运行Agent
* @param string $userInput 用户输入
* @return string 执行结果
*/
public function run(string $userInput): string
{
// 添加用户消息到短期记忆
$this->memory->addToShortTerm([
'role' => 'user',
'content' => $userInput
]);
// 循环执行直到完成或达到最大迭代次数
for ($iteration = 0; $iteration < $this->maxIterations; $iteration++) {
// 思考并获取行动
[$thought, $action] = $this->think();
// 检查是否完成
if (($action['type'] ?? null) === 'finish') {
// 返回最终答案
return $action['answer'];
}
// 执行行动并获取观察结果
$observation = $this->act($action);
// 记录思考、行动和观察结果
$this->memory->addToShortTerm([
'role' => 'assistant',
'content' => "Thought: {$thought}\nAction: " . json_encode($action) . "\nObservation: {$observation}"
]);
}
// 返回超时提示
return "达到最大迭代次数,任务未完成";
}
/**
* 思考过程
* @return array [思考内容, 行动配置]
*/
private function think(): array
{
// 构建提示词
$prompt = $this->buildPrompt();
// 调用LLM生成响应
$response = $this->llm->generate($prompt);
// 解析思考内容和行动
return $this->parseThoughtAction($response);
}
/**
* 执行行动
* @param array $action 行动配置
* @return string 执行结果
*/
private function act(array $action): string
{
// 获取工具名称
$toolName = $action['tool'] ?? '';
// 获取工具参数
$params = $action['params'] ?? [];
// 检查工具是否存在
if (isset($this->tools[$toolName])) {
// 执行工具并返回结果
return $this->tools[$toolName]->execute($params);
}
// 返回未知工具提示
return "Unknown tool: {$toolName}";
}
/**
* 构建提示词
* @return string 完整提示词
*/
private function buildPrompt(): string
{
// 获取工具名称列表
$toolNames = implode(', ', array_keys($this->tools));
// 获取上下文历史
$context = $this->memory->getContext();
// 返回格式化提示词
return <<<PROMPT
你是一个智能Agent,使用ReAct模式完成任务。
可用工具:{$toolNames}
历史记录:
{$context}
请输出:
Thought: 你的思考过程
Action: {"tool": "工具名", "params": {参数}}
或
Action: {"type": "finish", "answer": "最终答案"}
PROMPT;
}
private function parseThoughtAction(string $response): array
{
preg_match('/Thought:\s*(.+)/i', $response, $thoughtMatch);
preg_match('/Action:\s*(\{.+\})/is', $response, $actionMatch);
return [
$thoughtMatch[1] ?? '',
json_decode($actionMatch[1] ?? '{}', true)
];
}
}Plan-and-Execute循环
Plan-and-Execute模式:
────────────────────────────
┌─────────────────────────────────────┐
│ │
│ 1. Planning Phase │
│ ┌─────────┐ │
│ │ 目标输入 │ │
│ └────┬────┘ │
│ ↓ │
│ ┌─────────┐ │
│ │ 规划器 │ → 生成执行计划 │
│ └─────────┘ │
│ │
│ 2. Execution Phase │
│ ┌─────────┐ │
│ │ 步骤列表 │ │
│ └────┬────┘ │
│ ↓ │
│ ┌─────────┐ │
│ │ 执行器 │ → 逐步执行 │
│ └────┬────┘ │
│ ↓ │
│ ┌─────────┐ │
│ │ 结果收集 │ │
│ └─────────┘ │
│ │
│ 3. Review Phase │
│ ┌─────────┐ │
│ │ 结果评估 │ → 是否需要重新规划 │
│ └────┬────┘ │
│ ↓ │
│ ┌─────────┐ │
│ │ 最终输出 │ │
│ └─────────┘ │
│ │
└─────────────────────────────────────┘工具管理设计
工具注册机制
php
<?php
class Tool
{
public string $name;
public string $description;
public array $parameters;
public $execute;
public function __construct(
string $name,
string $description,
array $parameters,
callable $execute
) {
$this->name = $name;
$this->description = $description;
$this->parameters = $parameters;
$this->execute = $execute;
}
public function toOpenAiFormat(): array
{
return [
'type' => 'function',
'function' => [
'name' => $this->name,
'description' => $this->description,
'parameters' => $this->parameters
]
];
}
}
class ToolRegistry
{
private array $tools = [];
public function register(
string $name,
string $description,
array $parameters,
callable $execute
): self {
$this->tools[$name] = new Tool($name, $description, $parameters, $execute);
return $this;
}
public function getTool(string $name): ?Tool
{
return $this->tools[$name] ?? null;
}
public function getAllTools(): array
{
return array_map(fn($tool) => $tool->toOpenAiFormat(), $this->tools);
}
}
$registry = new ToolRegistry();
$registry->register(
name: 'search',
description: '搜索网络获取信息',
parameters: [
'type' => 'object',
'properties' => [
'query' => ['type' => 'string', 'description' => '搜索关键词']
],
'required' => ['query']
],
execute: function (array $params): string {
return "搜索结果:{$params['query']}的相关信息...";
}
);
$registry->register(
name: 'calculate',
description: '执行数学计算',
parameters: [
'type' => 'object',
'properties' => [
'expression' => ['type' => 'string', 'description' => '数学表达式']
],
'required' => ['expression']
],
execute: function (array $params): string {
try {
$result = eval("return {$params['expression']};");
return (string) $result;
} catch (\Exception $e) {
return "计算错误";
}
}
);工具选择策略
工具选择策略:
────────────────────────────
1. 基于描述匹配
• LLM根据工具描述选择
• 简单直接,但可能不准确
2. 基于语义相似度
• 将任务和工具描述向量化
• 计算相似度选择最相关工具
3. 基于历史学习
• 记录历史选择记录
• 学习最优工具选择模式
4. 混合策略
• 结合多种策略
• 加权决策错误处理与恢复
错误处理策略
错误类型与处理:
┌─────────────────────────────────────────┐
│ 错误类型 │ 处理策略 │
├─────────────────────────────────────────┤
│ 工具调用失败 │ 重试 + 备用工具 │
│ 参数错误 │ 自动修正 + 重新调用 │
│ 超时错误 │ 超时重试 + 降级处理 │
│ 资源不可用 │ 等待重试 + 通知用户 │
│ 推理错误 │ 回退 + 重新规划 │
│ 权限错误 │ 请求权限 + 人工介入 │
└─────────────────────────────────────────┘恢复机制实现
php
<?php
class AgentWithRecovery
{
private $agent;
private int $maxRetries = 3;
public function __construct($agent)
{
$this->agent = $agent;
}
public function executeWithRecovery(array $task): array
{
for ($attempt = 0; $attempt < $this->maxRetries; $attempt++) {
try {
$result = $this->agent->execute($task);
if ($result['success']) {
return $result;
}
if ($this->isRecoverable($result['error'])) {
$task = $this->recover($task, $result['error']);
continue;
}
return $result;
} catch (\Exception $e) {
if ($attempt === $this->maxRetries - 1) {
return [
'success' => false,
'error' => $e->getMessage()
];
}
sleep(2 ** $attempt);
}
}
return ['success' => false, 'error' => 'Max retries exceeded'];
}
private function isRecoverable(string $error): bool
{
$recoverableErrors = ['timeout', 'rate_limit', 'temporary_unavailable'];
$errorLower = strtolower($error);
foreach ($recoverableErrors as $e) {
if (str_contains($errorLower, $e)) {
return true;
}
}
return false;
}
private function recover(array $task, string $error): array
{
if (str_contains(strtolower($error), 'timeout')) {
$task['timeout'] = ($task['timeout'] ?? 30) * 2;
} elseif (str_contains(strtolower($error), 'rate_limit')) {
sleep(60);
}
return $task;
}
}性能优化
并行执行
php
<?php
use React\Promise\Promise;
class ParallelExecutor
{
private int $maxWorkers;
public function __construct(int $maxWorkers = 4)
{
$this->maxWorkers = $maxWorkers;
}
public function executeParallel(array $steps): array
{
$results = [];
$chunks = array_chunk($steps, $this->maxWorkers);
foreach ($chunks as $chunk) {
$promises = [];
foreach ($chunk as $index => $step) {
$promises[$index] = $this->executeStepAsync($step);
}
foreach ($promises as $index => $promise) {
$results[$index] = $promise->wait();
}
}
return $results;
}
private function executeStepAsync(array $step): Promise
{
return new Promise(function ($resolve) use ($step) {
$result = $this->executeStep($step);
$resolve($result);
});
}
private function executeStep(array $step): array
{
return ['step' => $step, 'result' => 'executed'];
}
}缓存策略
缓存层次:
────────────────────────────
L1: 内存缓存
• 当前会话的中间结果
• 毫秒级访问
L2: 本地缓存
• 常用工具结果
• 秒级访问
L3: 分布式缓存
• 跨会话共享结果
• 秒级访问
缓存策略:
• LRU淘汰
• TTL过期
• 主动失效监控与可观测性
关键指标
性能指标:
────────────────────────────
• 任务完成率:成功完成的任务比例
• 平均执行时间:任务平均耗时
• 工具调用成功率:工具调用成功比例
• Token消耗:每次任务的Token使用量
• 错误率:各类错误的发生频率
质量指标:
────────────────────────────
• 用户满意度:用户反馈评分
• 任务准确率:结果正确性评估
• 响应相关性:输出与问题的相关性日志设计
php
<?php
use Psr\Log\LoggerInterface;
class AgentLogger
{
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function logStep(int $step, string $thought, array $action, string $observation): void
{
$this->logger->info(json_encode([
'timestamp' => date('c'),
'step' => $step,
'thought' => $thought,
'action' => $action,
'observation' => $observation
], JSON_UNESCAPED_UNICODE));
}
public function logToolCall(string $tool, array $params, string $result, float $duration): void
{
$this->logger->info(json_encode([
'timestamp' => date('c'),
'type' => 'tool_call',
'tool' => $tool,
'params' => $params,
'result' => mb_substr($result, 0, 200),
'duration_ms' => $duration * 1000
], JSON_UNESCAPED_UNICODE));
}
public function logError(string $error, array $context): void
{
$this->logger->error(json_encode([
'timestamp' => date('c'),
'type' => 'error',
'error' => $error,
'context' => $context
], JSON_UNESCAPED_UNICODE));
}
}架构设计最佳实践
设计原则
1. 单一职责原则
────────────────────────────
每个组件只负责一个功能:
• 规划器只负责规划
• 执行器只负责执行
• 记忆系统只负责存储
2. 开闭原则
────────────────────────────
对扩展开放,对修改关闭:
• 新增工具无需修改核心代码
• 新增策略无需修改现有逻辑
3. 依赖倒置原则
────────────────────────────
高层模块不依赖低层模块:
• Agent核心不依赖具体工具实现
• 通过接口/抽象类解耦
4. 最小知识原则
────────────────────────────
组件之间最小化依赖:
• 执行器不需要知道规划细节
• 工具不需要知道调用者是谁常见架构陷阱
避免这些陷阱
- 过度设计:简单任务使用复杂架构
- 状态混乱:没有清晰的状态管理
- 工具爆炸:注册过多不必要工具
- 忽略边界:没有处理异常情况
- 缺乏监控:无法追踪Agent行为
学习检验
概念理解
- Agent的三种主要架构模式各有什么特点?
- 规划器和执行器的职责如何划分?
- 记忆系统的三个层次分别存储什么类型的数据?
实践思考
- 如何为你的业务场景选择合适的Agent架构?
- 如何设计一个可扩展的工具注册机制?
下一步学习
💡 记住:好的架构设计让Agent系统更可靠、更易维护、更易扩展。
