Skip to content

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. 最小知识原则
────────────────────────────
组件之间最小化依赖:
• 执行器不需要知道规划细节
• 工具不需要知道调用者是谁

常见架构陷阱

避免这些陷阱

  1. 过度设计:简单任务使用复杂架构
  2. 状态混乱:没有清晰的状态管理
  3. 工具爆炸:注册过多不必要工具
  4. 忽略边界:没有处理异常情况
  5. 缺乏监控:无法追踪Agent行为

学习检验

概念理解

  1. Agent的三种主要架构模式各有什么特点?
  2. 规划器和执行器的职责如何划分?
  3. 记忆系统的三个层次分别存储什么类型的数据?

实践思考

  1. 如何为你的业务场景选择合适的Agent架构?
  2. 如何设计一个可扩展的工具注册机制?

下一步学习


💡 记住:好的架构设计让Agent系统更可靠、更易维护、更易扩展。