大模型应用技术之一篇搞懂Agent

123 阅读17分钟

本期导读

在前三期,我们学习了RAG检索增强、Function Calling工具调用和MCP协议。现在我们要把这些技术组合起来,构建真正"智能"的AI系统——Agent(智能体)。

Agent不是简单的工具调用,而是具备推理能力行动能力的AI系统。它能够:

  • 理解复杂任务
  • 制定执行计划
  • 动态调整策略
  • 从错误中学习

本文将深入讲解Agent的核心架构,特别是ReAct(Reasoning + Acting)模式,以及如何构建多Agent协作系统。

本文内容包括:

  • Agent的核心概念和工作原理
  • 8种Agent模式详解(规划与执行、自我提问、思考与自省、ReAct、ReAct RAG Agent、Agentic RAG、思维树等)
  • 多Agent协作架构设计
  • CrewAI vs AutoGen vs MetaGPT对比
  • Java实战:构建自主Agent系统
  • Agent开源开发框架介绍
  • A2A(Agent-to-Agent)协作模式
  • 生产环境的Agent最佳实践

一、从工具调用到智能体

1.1 什么是Agent?

想象一下人类解决问题的过程:

问题:"帮我分析一下公司上个月的销售数据,找出问题并给出改进建议"

人类思考过程:
1. 理解问题:需要分析销售数据,找出问题,提出建议
2. 制定计划:
   - 先获取销售数据
   - 分析数据趋势
   - 识别异常点
   - 分析原因
   - 提出改进方案
3. 执行计划:
   - 调用数据库查询销售数据
   - 使用Excel或Python分析数据
   - 生成图表可视化
   - 写分析报告
4. 反思调整:
   - 如果数据不够,调整查询条件
   - 如果分析有误,重新分析
   - 如果建议不切实际,修改建议

Agent就是具备这种思考能力的AI系统

1.2 Agent vs 传统AI的区别

维度传统AIAgent
交互方式一问一答多轮对话,持续交互
任务复杂度单一任务复杂多步骤任务
决策能力被动响应主动规划和决策
学习能力静态知识从经验中学习
错误处理简单重试分析原因,调整策略
工具使用固定工具动态选择和组合工具

1.3 Agent的核心组件

┌─────────────────────────────────────────┐
│                Agent                    │
├─────────────────────────────────────────┤
│ 1. 感知层 (Perception)                  │
│    - 理解用户输入                       │
│    - 解析环境状态                       │
├─────────────────────────────────────────┤
│ 2. 推理层 (Reasoning)                   │
│    - 任务分解                           │
│    - 计划制定                           │
│    - 决策逻辑                           │
├─────────────────────────────────────────┤
│ 3. 行动层 (Action)                      │
│    - 工具调用                           │
│    - 环境交互                           │
│    - 结果处理                           │
├─────────────────────────────────────────┤
│ 4. 记忆层 (Memory)                      │
│    - 短期记忆(对话历史)               │
│    - 长期记忆(经验知识)               │
│    - 工作记忆(当前任务状态)           │
├─────────────────────────────────────────┤
│ 5. 学习层 (Learning)                    │
│    - 从成功案例学习                     │
│    - 从失败案例学习                     │
│    - 策略优化                           │
└─────────────────────────────────────────┘

1.4 Agent的工作流程

graph TD
    A[用户输入] --> B[感知层:理解任务]
    B --> C[推理层:制定计划]
    C --> D[行动层:执行步骤]
    D --> E{任务完成?}
    E -->|否| F[反思:分析结果]
    F --> G[调整计划]
    G --> D
    E -->|是| H[生成最终回答]
    H --> I[更新记忆]

二、Agent的8种核心模式详解

Agent有多种工作模式,每种模式都有其特定的应用场景和优势。本节将详细介绍8种主要的Agent模式。

2.1 规划与执行模式(Planning & Execution)

是什么: 规划与执行模式将复杂任务分解为多个子任务,先制定详细计划,再按计划执行。

运行过程:

  1. 任务分解:将复杂任务分解为可执行的子任务
  2. 计划制定:为每个子任务制定执行策略
  3. 顺序执行:按计划顺序执行子任务
  4. 结果整合:将子任务结果整合为最终答案

应用场景:

  • 软件开发项目
  • 数据分析任务
  • 内容创作
  • 复杂问题求解

执行流程图:

graph TD
    A[接收任务] --> B[任务分解]
    B --> C[制定计划]
    C --> D[执行子任务1]
    D --> E[执行子任务2]
    E --> F[执行子任务N]
    F --> G[整合结果]
    G --> H[返回最终答案]
    
    D --> I{子任务成功?}
    I -->|否| J[调整计划]
    J --> D
    I -->|是| E

2.2 自我提问模式(Self-Questioning)

是什么: Agent通过不断向自己提问来深入理解问题,逐步逼近正确答案。

运行过程:

  1. 初始问题:接收用户问题
  2. 自我提问:生成相关问题
  3. 回答问题:逐一回答生成的问题
  4. 综合答案:基于所有回答生成最终答案

应用场景:

  • 复杂推理问题
  • 学术研究
  • 深度分析
  • 创意生成

执行流程图:

graph TD
    A[接收问题] --> B[生成相关问题1]
    B --> C[回答问题1]
    C --> D[生成相关问题2]
    D --> E[回答问题2]
    E --> F[生成相关问题N]
    F --> G[回答问题N]
    G --> H[综合所有答案]
    H --> I[生成最终答案]
    
    C --> J{需要更多问题?}
    J -->|是| D
    J -->|否| H

2.3 思考与自省模式(Reflection & Introspection)

是什么: Agent在执行过程中不断反思自己的行为和结果,通过自我评估来改进表现。

运行过程:

  1. 执行任务:执行当前任务
  2. 结果评估:评估执行结果的质量
  3. 自我反思:分析成功或失败的原因
  4. 策略调整:基于反思结果调整策略
  5. 重新执行:使用新策略重新执行

应用场景:

  • 学习型任务
  • 优化问题
  • 持续改进
  • 自适应系统

执行流程图:

graph TD
    A[接收任务] --> B[执行任务]
    B --> C[评估结果]
    C --> D[自我反思]
    D --> E{结果满意?}
    E -->|否| F[分析失败原因]
    F --> G[调整策略]
    G --> B
    E -->|是| H[完成任务]
    
    D --> I[记录经验]
    I --> J[更新知识库]

2.4 ReAct模式(通用)

是什么: ReAct = Reasoning + Acting,通过思考-行动-观察的循环来解决问题。

运行过程:

  1. Thought:思考当前状态和下一步行动
  2. Action:选择并执行具体行动
  3. Observation:观察行动结果
  4. 循环:重复上述过程直到任务完成

应用场景:

  • 通用问题求解
  • 工具使用
  • 环境交互
  • 复杂推理

执行流程图:

graph TD
    A[接收任务] --> B[Thought: 思考]
    B --> C[Action: 行动]
    C --> D[Observation: 观察]
    D --> E{任务完成?}
    E -->|否| B
    E -->|是| F[返回结果]
    
    C --> G[工具调用]
    G --> H[环境交互]
    H --> D

2.5 ReAct RAG Agent模式

是什么: 结合ReAct模式和RAG技术,Agent能够检索外部知识来辅助推理和行动。

运行过程:

  1. Thought:思考需要什么信息
  2. Retrieval:检索相关文档
  3. Action:基于检索结果执行行动
  4. Observation:观察行动结果
  5. 循环:重复直到任务完成

应用场景:

  • 知识密集型任务
  • 文档问答
  • 研究分析
  • 信息整合

执行流程图:

graph TD
    A[接收任务] --> B[Thought: 思考需要什么信息]
    B --> C[Retrieval: 检索相关文档]
    C --> D[Action: 基于检索结果行动]
    D --> E[Observation: 观察结果]
    E --> F{任务完成?}
    F -->|否| B
    F -->|是| G[返回结果]
    
    C --> H[向量数据库]
    H --> I[文档检索]
    I --> D

2.6 Agentic RAG模式

是什么: Agentic RAG将RAG过程本身作为Agent的任务,Agent能够主动决定检索策略和生成策略。

运行过程:

  1. 任务分析:分析任务类型和需求
  2. 检索策略:决定检索方法和参数
  3. 文档检索:执行检索操作
  4. 内容生成:基于检索结果生成答案
  5. 质量评估:评估生成结果的质量
  6. 迭代优化:根据评估结果优化策略

应用场景:

  • 智能问答系统
  • 文档分析
  • 知识管理
  • 内容生成

执行流程图:

graph TD
    A[接收任务] --> B[任务分析]
    B --> C[制定检索策略]
    C --> D[执行文档检索]
    D --> E[内容生成]
    E --> F[质量评估]
    F --> G{质量满意?}
    G -->|否| H[优化策略]
    H --> C
    G -->|是| I[返回结果]
    
    D --> J[多源检索]
    J --> K[结果融合]
    K --> E

2.7 思维树模式(Tree of Thoughts)

是什么: 思维树模式通过生成多个思考路径,评估每个路径的价值,选择最优路径继续执行。

运行过程:

  1. 初始思考:生成多个初始思考方向
  2. 路径扩展:为每个思考方向生成子路径
  3. 价值评估:评估每个路径的价值
  4. 路径选择:选择最有价值的路径
  5. 深度搜索:在选定路径上继续扩展
  6. 结果生成:基于最优路径生成最终答案

应用场景:

  • 复杂推理问题
  • 创意生成
  • 策略规划
  • 多方案比较

执行流程图:

graph TD
    A[接收任务] --> B[生成初始思考]
    B --> C[扩展思考路径]
    C --> D[评估路径价值]
    D --> E[选择最优路径]
    E --> F{达到目标?}
    F -->|否| C
    F -->|是| G[生成最终答案]
    
    C --> H[路径1]
    C --> I[路径2]
    C --> J[路径N]
    H --> D
    I --> D
    J --> D

2.8 模式对比总结

模式优势劣势适用场景复杂度
规划与执行结构清晰,易于控制灵活性不足有明确流程的任务中等
自我提问深度思考,全面分析效率较低复杂推理问题
思考与自省持续改进,自适应收敛慢学习型任务
ReAct通用性强,透明性好计算成本高通用问题求解中等
ReAct RAG知识丰富,准确性高检索开销大知识密集型任务
Agentic RAG智能化程度高实现复杂智能问答系统很高
思维树全局最优,创意丰富计算量大复杂推理和创意很高

三、Java实战:构建自主Agent系统

3.1 环境准备

<!-- pom.xml -->
<project>
    <properties>
        <spring-ai.version>1.1.0-M3</spring-ai.version>
    </properties>
    
    <dependencies>
        <!-- Spring AI Starter -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>
        
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Spring Boot Data JPA -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        
        <!-- H2 Database -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
# application.yml
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o-mini
          temperature: 0.0
  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password: password
  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

3.2 核心Agent接口定义

package com.example.agent.core;

import java.util.List;
import java.util.Map;

/**
 * Agent核心接口
 */
public interface Agent {
    
    /**
     * 执行任务
     */
    AgentResult executeTask(String task, Map<String, Object> context);
    
    /**
     * 获取Agent能力
     */
    List<String> getCapabilities();
    
    /**
     * 获取Agent状态
     */
    AgentStatus getStatus();
    
    /**
     * 更新记忆
     */
    void updateMemory(Memory memory);
    
    /**
     * 获取记忆
     */
    List<Memory> getMemories();
}

/**
 * Agent结果
 */
public record AgentResult(
    boolean success,
    String result,
    Map<String, Object> metadata,
    List<String> errors
) {}

/**
 * Agent状态
 */
public enum AgentStatus {
    IDLE, BUSY, ERROR, LEARNING
}

/**
 * 记忆
 */
public record Memory(
    String id,
    String content,
    MemoryType type,
    long timestamp,
    Map<String, Object> metadata
) {}

/**
 * 记忆类型
 */
public enum MemoryType {
    SHORT_TERM, LONG_TERM, WORKING, EPISODIC
}

3.3 ReAct Agent实现

package com.example.agent.react;

import com.example.agent.core.*;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * ReAct Agent实现
 */
@Component
public class ReActAgent implements Agent {
    
    private final ChatClient chatClient;
    private final ToolRegistry toolRegistry;
    private final MemoryManager memoryManager;
    private final PromptTemplate promptTemplate;
    
    private AgentStatus status = AgentStatus.IDLE;
    private final List<Memory> memories = new ArrayList<>();
    
    public ReActAgent(ChatClient.Builder chatClientBuilder, 
                     ToolRegistry toolRegistry,
                     MemoryManager memoryManager,
                     PromptTemplate promptTemplate) {
        this.chatClient = chatClientBuilder.build();
        this.toolRegistry = toolRegistry;
        this.memoryManager = memoryManager;
        this.promptTemplate = promptTemplate;
    }
    
    @Override
    public AgentResult executeTask(String task, Map<String, Object> context) {
        status = AgentStatus.BUSY;
        
        try {
            // 1. 初始化ReAct循环
            List<ReActStep> steps = new ArrayList<>();
            String currentThought = "";
            int maxIterations = 10;
            int iteration = 0;
            
            // 2. ReAct循环
            while (iteration < maxIterations) {
                iteration++;
                
                // Thought: 思考
                String thought = generateThought(task, currentThought, steps);
                steps.add(new ReActStep("Thought", thought, null, null));
                
                // Action: 行动
                Action action = generateAction(thought, steps);
                if (action == null) {
                    break; // 没有更多行动,任务完成
                }
                
                steps.add(new ReActStep("Action", action.name(), action.arguments(), null));
                
                // Observation: 观察
                String observation = executeAction(action);
                steps.add(new ReActStep("Observation", observation, null, null));
                
                // 检查是否完成任务
                if (isTaskComplete(observation, task)) {
                    break;
                }
                
                currentThought = thought;
            }
            
            // 3. 生成最终答案
            String finalAnswer = generateFinalAnswer(task, steps);
            
            // 4. 更新记忆
            updateMemory(new Memory(
                UUID.randomUUID().toString(),
                "Task: " + task + "\nResult: " + finalAnswer,
                MemoryType.EPISODIC,
                System.currentTimeMillis(),
                Map.of("steps", steps.size(), "success", true)
            ));
            
            status = AgentStatus.IDLE;
            return new AgentResult(true, finalAnswer, Map.of("steps", steps), List.of());
            
        } catch (Exception e) {
            status = AgentStatus.ERROR;
            return new AgentResult(false, "", Map.of(), List.of(e.getMessage()));
        }
    }
    
    private String generateThought(String task, String previousThought, List<ReActStep> steps) {
        String prompt = promptTemplate.buildReActThoughtPrompt(task, previousThought, steps);
        
        return chatClient.prompt()
            .user(prompt)
            .call()
            .content();
    }
    
    private Action generateAction(String thought, List<ReActStep> steps) {
        String prompt = promptTemplate.buildReActActionPrompt(thought, steps, toolRegistry.getAvailableTools());
        
        String response = chatClient.prompt()
            .user(prompt)
            .call()
            .content();
        
        return parseAction(response);
    }
    
    private String executeAction(Action action) {
        Tool tool = toolRegistry.getTool(action.name());
        if (tool != null) {
            return tool.execute(action.arguments());
        }
        return "Tool not found: " + action.name();
    }
    
    private boolean isTaskComplete(String observation, String originalTask) {
        // 简化的任务完成判断
        return observation.toLowerCase().contains("task completed") ||
               observation.toLowerCase().contains("final answer");
    }
    
    private String generateFinalAnswer(String task, List<ReActStep> steps) {
        String prompt = promptTemplate.buildFinalAnswerPrompt(task, steps);
        
        return chatClient.prompt()
            .user(prompt)
            .call()
            .content();
    }
    
    @Override
    public List<String> getCapabilities() {
        return toolRegistry.getAvailableTools().stream()
            .map(Tool::getName)
            .toList();
    }
    
    @Override
    public AgentStatus getStatus() {
        return status;
    }
    
    @Override
    public void updateMemory(Memory memory) {
        memories.add(memory);
        memoryManager.saveMemory(memory);
    }
    
    @Override
    public List<Memory> getMemories() {
        return new ArrayList<>(memories);
    }
}

/**
 * ReAct步骤
 */
public record ReActStep(
    String type, // Thought, Action, Observation
    String content,
    Map<String, Object> arguments,
    String result
) {}

/**
 * 行动
 */
public record Action(
    String name,
    Map<String, Object> arguments
) {}

3.4 提示词模板

package com.example.agent.prompt;

import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;

/**
 * Agent提示词模板
 */
@Component
public class PromptTemplate {
    
    public String buildReActThoughtPrompt(String task, String previousThought, List<ReActStep> steps) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("你是一个智能助手,正在使用ReAct模式解决问题。\n\n");
        prompt.append("任务:").append(task).append("\n\n");
        
        if (!steps.isEmpty()) {
            prompt.append("之前的步骤:\n");
            for (ReActStep step : steps) {
                prompt.append(step.type()).append(": ").append(step.content()).append("\n");
            }
            prompt.append("\n");
        }
        
        prompt.append("现在请思考下一步应该做什么。\n");
        prompt.append("Thought: ");
        
        return prompt.toString();
    }
    
    public String buildReActActionPrompt(String thought, List<ReActStep> steps, List<Tool> availableTools) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("基于你的思考,请选择下一步行动。\n\n");
        prompt.append("可用工具:\n");
        
        for (Tool tool : availableTools) {
            prompt.append("- ").append(tool.getName()).append(": ").append(tool.getDescription()).append("\n");
        }
        
        prompt.append("\n请按以下格式回答:\n");
        prompt.append("Action: 工具名称\n");
        prompt.append("Action Input: 工具参数\n");
        
        return prompt.toString();
    }
    
    public String buildFinalAnswerPrompt(String task, List<ReActStep> steps) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("基于以下步骤,请生成最终答案:\n\n");
        prompt.append("任务:").append(task).append("\n\n");
        
        prompt.append("执行步骤:\n");
        for (ReActStep step : steps) {
            prompt.append(step.type()).append(": ").append(step.content()).append("\n");
        }
        
        prompt.append("\nFinal Answer: ");
        
        return prompt.toString();
    }
    
    public String buildSelfQuestioningPrompt(String question) {
        return String.format("""
            你是一个善于自我提问的智能助手。对于以下问题,请生成3-5个相关的子问题来帮助深入理解:
            
            原问题:%s
            
            请生成相关问题:
            1. 
            2. 
            3. 
            4. 
            5. 
            
            然后逐一回答这些问题,最后综合所有答案给出最终回答。
            """, question);
    }
    
    public String buildReflectionPrompt(String task, String result, boolean success) {
        return String.format("""
            请对以下任务执行结果进行反思:
            
            任务:%s
            结果:%s
            成功:%s
            
            请分析:
            1. 执行过程中的优点
            2. 存在的问题
            3. 改进建议
            4. 下次如何做得更好
            """, task, result, success);
    }
}

3.5 工具注册表

package com.example.agent.tools;

import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

/**
 * 工具注册表
 */
@Component
public class ToolRegistry {
    
    private final Map<String, Tool> tools = new HashMap<>();
    
    public ToolRegistry() {
        // 注册基础工具
        registerTool(new CalculatorTool());
        registerTool(new SearchTool());
        registerTool(new FileTool());
        registerTool(new DatabaseTool());
    }
    
    public void registerTool(Tool tool) {
        tools.put(tool.getName(), tool);
    }
    
    public Tool getTool(String name) {
        return tools.get(name);
    }
    
    public List<Tool> getAvailableTools() {
        return List.copyOf(tools.values());
    }
}

/**
 * 工具接口
 */
public interface Tool {
    String getName();
    String getDescription();
    String execute(Map<String, Object> arguments);
}

/**
 * 计算器工具
 */
@Component
public class CalculatorTool implements Tool {
    
    @Override
    public String getName() {
        return "calculator";
    }
    
    @Override
    public String getDescription() {
        return "执行数学计算";
    }
    
    @Override
    public String execute(Map<String, Object> arguments) {
        String expression = (String) arguments.get("expression");
        try {
            // 简化的计算器实现
            double result = evaluateExpression(expression);
            return "计算结果: " + result;
        } catch (Exception e) {
            return "计算错误: " + e.getMessage();
        }
    }
    
    private double evaluateExpression(String expression) {
        // 这里应该使用更安全的表达式求值器
        // 为了示例,使用简单的实现
        return Double.parseDouble(expression.replaceAll("[^0-9.]", ""));
    }
}

/**
 * 搜索工具
 */
@Component
public class SearchTool implements Tool {
    
    @Override
    public String getName() {
        return "search";
    }
    
    @Override
    public String getDescription() {
        return "搜索网络信息";
    }
    
    @Override
    public String execute(Map<String, Object> arguments) {
        String query = (String) arguments.get("query");
        // 模拟搜索
        return "搜索结果: 关于 '" + query + "' 的信息...";
    }
}

/**
 * 文件工具
 */
@Component
public class FileTool implements Tool {
    
    @Override
    public String getName() {
        return "file";
    }
    
    @Override
    public String getDescription() {
        return "文件操作";
    }
    
    @Override
    public String execute(Map<String, Object> arguments) {
        String operation = (String) arguments.get("operation");
        String filename = (String) arguments.get("filename");
        
        switch (operation) {
            case "read":
                return "读取文件: " + filename;
            case "write":
                return "写入文件: " + filename;
            default:
                return "未知操作: " + operation;
        }
    }
}

/**
 * 数据库工具
 */
@Component
public class DatabaseTool implements Tool {
    
    @Override
    public String getName() {
        return "database";
    }
    
    @Override
    public String getDescription() {
        return "数据库查询";
    }
    
    @Override
    public String execute(Map<String, Object> arguments) {
        String query = (String) arguments.get("query");
        // 模拟数据库查询
        return "查询结果: " + query;
    }
}

3.6 记忆管理器

package com.example.agent.memory;

import com.example.agent.core.Memory;
import com.example.agent.core.MemoryType;
import org.springframework.stereotype.Component;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 记忆管理器
 */
@Component
public class MemoryManager {
    
    private final MemoryRepository memoryRepository;
    private final int maxMemories = 1000;
    
    public MemoryManager(MemoryRepository memoryRepository) {
        this.memoryRepository = memoryRepository;
    }
    
    public void saveMemory(Memory memory) {
        MemoryEntity entity = new MemoryEntity(
            memory.id(),
            memory.content(),
            memory.type().name(),
            memory.timestamp(),
            memory.metadata()
        );
        memoryRepository.save(entity);
        
        // 清理旧记忆
        cleanupOldMemories();
    }
    
    public List<Memory> getMemoriesByType(MemoryType type) {
        return memoryRepository.findByType(type.name())
            .stream()
            .map(this::entityToMemory)
            .collect(Collectors.toList());
    }
    
    public List<Memory> getRecentMemories(int limit) {
        return memoryRepository.findRecentMemories(limit)
            .stream()
            .map(this::entityToMemory)
            .collect(Collectors.toList());
    }
    
    public List<Memory> searchMemories(String query) {
        return memoryRepository.findByContentContaining(query)
            .stream()
            .map(this::entityToMemory)
            .collect(Collectors.toList());
    }
    
    private void cleanupOldMemories() {
        long count = memoryRepository.count();
        if (count > maxMemories) {
            List<MemoryEntity> oldestMemories = memoryRepository.findOldestMemories((int)(count - maxMemories));
            memoryRepository.deleteAll(oldestMemories);
        }
    }
    
    private Memory entityToMemory(MemoryEntity entity) {
        return new Memory(
            entity.getId(),
            entity.getContent(),
            MemoryType.valueOf(entity.getType()),
            entity.getTimestamp(),
            entity.getMetadata()
        );
    }
}

/**
 * 记忆实体
 */
@Entity
@Table(name = "memories")
public class MemoryEntity {
    @Id
    private String id;
    
    @Column(columnDefinition = "TEXT")
    private String content;
    
    private String type;
    private long timestamp;
    
    @Column(columnDefinition = "TEXT")
    private String metadata; // JSON格式
    
    // 构造函数、getter、setter
    public MemoryEntity() {}
    
    public MemoryEntity(String id, String content, String type, long timestamp, Map<String, Object> metadata) {
        this.id = id;
        this.content = content;
        this.type = type;
        this.timestamp = timestamp;
        this.metadata = convertMetadataToString(metadata);
    }
    
    private String convertMetadataToString(Map<String, Object> metadata) {
        // 将Map转换为JSON字符串
        return "{}"; // 简化实现
    }
    
    // getter和setter方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
    
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
    
    public long getTimestamp() { return timestamp; }
    public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
    
    public String getMetadata() { return metadata; }
    public void setMetadata(String metadata) { this.metadata = metadata; }
}

/**
 * 记忆仓库
 */
@Repository
public interface MemoryRepository extends JpaRepository<MemoryEntity, String> {
    
    List<MemoryEntity> findByType(String type);
    
    @Query("SELECT m FROM MemoryEntity m ORDER BY m.timestamp DESC LIMIT ?1")
    List<MemoryEntity> findRecentMemories(int limit);
    
    List<MemoryEntity> findByContentContaining(String query);
    
    @Query("SELECT m FROM MemoryEntity m ORDER BY m.timestamp ASC LIMIT ?1")
    List<MemoryEntity> findOldestMemories(int limit);
}

3.7 多Agent协作系统

package com.example.agent.collaboration;

import com.example.agent.core.Agent;
import com.example.agent.core.AgentResult;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 多Agent协作系统
 */
@Component
public class MultiAgentSystem {
    
    private final Map<String, Agent> agents = new ConcurrentHashMap<>();
    private final MessageBus messageBus;
    private final TaskScheduler taskScheduler;
    
    public MultiAgentSystem(MessageBus messageBus, TaskScheduler taskScheduler) {
        this.messageBus = messageBus;
        this.taskScheduler = taskScheduler;
    }
    
    public void registerAgent(String agentId, Agent agent) {
        agents.put(agentId, agent);
        messageBus.registerAgent(agentId, agent);
    }
    
    public CompletableFuture<AgentResult> executeCollaborativeTask(String task, Map<String, Object> context) {
        return CompletableFuture.supplyAsync(() -> {
            // 1. 任务分解
            List<SubTask> subTasks = decomposeTask(task);
            
            // 2. 分配任务
            Map<String, SubTask> assignments = assignTasks(subTasks);
            
            // 3. 并行执行
            Map<String, CompletableFuture<AgentResult>> futures = new HashMap<>();
            for (Map.Entry<String, SubTask> entry : assignments.entrySet()) {
                String agentId = entry.getKey();
                SubTask subTask = entry.getValue();
                
                futures.put(agentId, CompletableFuture.supplyAsync(() -> {
                    Agent agent = agents.get(agentId);
                    return agent.executeTask(subTask.description(), subTask.context());
                }));
            }
            
            // 4. 等待所有任务完成
            Map<String, AgentResult> results = new HashMap<>();
            for (Map.Entry<String, CompletableFuture<AgentResult>> entry : futures.entrySet()) {
                try {
                    results.put(entry.getKey(), entry.getValue().get());
                } catch (Exception e) {
                    results.put(entry.getKey(), new AgentResult(false, "", Map.of(), List.of(e.getMessage())));
                }
            }
            
            // 5. 整合结果
            return integrateResults(task, results);
        });
    }
    
    private List<SubTask> decomposeTask(String task) {
        // 简化的任务分解逻辑
        List<SubTask> subTasks = new ArrayList<>();
        
        if (task.contains("开发")) {
            subTasks.add(new SubTask("需求分析", "分析用户需求", Map.of()));
            subTasks.add(new SubTask("系统设计", "设计系统架构", Map.of()));
            subTasks.add(new SubTask("编码实现", "实现功能代码", Map.of()));
            subTasks.add(new SubTask("测试验证", "测试系统功能", Map.of()));
        } else if (task.contains("分析")) {
            subTasks.add(new SubTask("数据收集", "收集相关数据", Map.of()));
            subTasks.add(new SubTask("数据处理", "清洗和处理数据", Map.of()));
            subTasks.add(new SubTask("数据分析", "分析数据趋势", Map.of()));
            subTasks.add(new SubTask("结果报告", "生成分析报告", Map.of()));
        } else {
            subTasks.add(new SubTask("任务执行", task, Map.of()));
        }
        
        return subTasks;
    }
    
    private Map<String, SubTask> assignTasks(List<SubTask> subTasks) {
        Map<String, SubTask> assignments = new HashMap<>();
        List<String> availableAgents = new ArrayList<>(agents.keySet());
        
        for (int i = 0; i < subTasks.size() && i < availableAgents.size(); i++) {
            assignments.put(availableAgents.get(i), subTasks.get(i));
        }
        
        return assignments;
    }
    
    private AgentResult integrateResults(String originalTask, Map<String, AgentResult> results) {
        StringBuilder integratedResult = new StringBuilder();
        integratedResult.append("协作任务完成结果:\n\n");
        
        boolean allSuccess = true;
        for (Map.Entry<String, AgentResult> entry : results.entrySet()) {
            String agentId = entry.getKey();
            AgentResult result = entry.getValue();
            
            integratedResult.append("Agent ").append(agentId).append(": ");
            if (result.success()) {
                integratedResult.append("成功 - ").append(result.result()).append("\n");
            } else {
                integratedResult.append("失败 - ").append(result.errors()).append("\n");
                allSuccess = false;
            }
        }
        
        return new AgentResult(allSuccess, integratedResult.toString(), Map.of("collaboration", true), List.of());
    }
}

/**
 * 子任务
 */
public record SubTask(
    String name,
    String description,
    Map<String, Object> context
) {}

/**
 * 消息总线
 */
@Component
public class MessageBus {
    
    private final Map<String, Agent> registeredAgents = new ConcurrentHashMap<>();
    private final Queue<Message> messageQueue = new LinkedList<>();
    
    public void registerAgent(String agentId, Agent agent) {
        registeredAgents.put(agentId, agent);
    }
    
    public void sendMessage(Message message) {
        messageQueue.offer(message);
        processMessage(message);
    }
    
    private void processMessage(Message message) {
        Agent receiver = registeredAgents.get(message.receiver());
        if (receiver != null) {
            // 异步处理消息
            CompletableFuture.runAsync(() -> {
                // 这里应该调用Agent的消息处理方法
                System.out.println("Agent " + message.receiver() + " 收到消息: " + message.content());
            });
        }
    }
    
    public void broadcast(String sender, String content) {
        for (String agentId : registeredAgents.keySet()) {
            if (!agentId.equals(sender)) {
                Message message = new Message(sender, agentId, content, System.currentTimeMillis());
                sendMessage(message);
            }
        }
    }
}

/**
 * 消息
 */
public record Message(
    String sender,
    String receiver,
    String content,
    long timestamp
) {}

/**
 * 任务调度器
 */
@Component
public class TaskScheduler {
    
    public void scheduleTask(String taskId, Runnable task, long delayMs) {
        CompletableFuture.delayedExecutor(delayMs, java.util.concurrent.TimeUnit.MILLISECONDS)
            .execute(task);
    }
    
    public void scheduleRecurringTask(String taskId, Runnable task, long intervalMs) {
        CompletableFuture.runAsync(() -> {
            while (true) {
                try {
                    task.run();
                    Thread.sleep(intervalMs);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
    }
}

3.8 REST API控制器

package com.example.agent.controller;

import com.example.agent.core.Agent;
import com.example.agent.core.AgentResult;
import com.example.agent.react.ReActAgent;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * Agent REST API控制器
 */
@RestController
@RequestMapping("/api/agent")
public class AgentController {
    
    private final ReActAgent reactAgent;
    private final MultiAgentSystem multiAgentSystem;
    
    public AgentController(ReActAgent reactAgent, MultiAgentSystem multiAgentSystem) {
        this.reactAgent = reactAgent;
        this.multiAgentSystem = multiAgentSystem;
    }
    
    @PostMapping("/execute")
    public AgentResult executeTask(@RequestBody TaskRequest request) {
        return reactAgent.executeTask(request.task(), request.context());
    }
    
    @PostMapping("/collaborate")
    public CompletableFuture<AgentResult> executeCollaborativeTask(@RequestBody TaskRequest request) {
        return multiAgentSystem.executeCollaborativeTask(request.task(), request.context());
    }
    
    @GetMapping("/status")
    public Map<String, Object> getAgentStatus() {
        return Map.of(
            "status", reactAgent.getStatus(),
            "capabilities", reactAgent.getCapabilities(),
            "memoryCount", reactAgent.getMemories().size()
        );
    }
    
    @GetMapping("/memories")
    public List<Memory> getMemories() {
        return reactAgent.getMemories();
    }
}

/**
 * 任务请求
 */
public record TaskRequest(
    String task,
    Map<String, Object> context
) {}

四、Agent开源开发框架

4.1 主流框架对比

框架语言特点适用场景活跃度
LangChainPython生态丰富,组件化快速原型,RAG应用⭐⭐⭐⭐⭐
LangGraphPython状态图,复杂流程复杂Agent系统⭐⭐⭐⭐
CrewAIPython角色驱动,协作内容创作,团队协作⭐⭐⭐⭐
AutoGenPython对话驱动,灵活多Agent对话⭐⭐⭐⭐
MetaGPTPython标准化流程软件开发⭐⭐⭐
Spring AIJava企业级,Spring生态企业应用⭐⭐⭐⭐
Semantic KernelC#微软生态.NET应用⭐⭐⭐
HaystackPython搜索和RAG搜索应用⭐⭐⭐

4.2 框架详细介绍

4.2.1 LangChain

特点:

  • 丰富的组件库
  • 支持多种LLM
  • 强大的工具集成
  • 活跃的社区

核心组件:

from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.tools import Tool
from langchain.prompts import ChatPromptTemplate

适用场景:

  • RAG应用
  • 快速原型开发
  • 工具集成

4.2.2 LangGraph

特点:

  • 基于状态图
  • 支持复杂流程
  • 条件分支
  • 循环控制

核心概念:

from langgraph.graph import StateGraph, END
from langgraph.checkpoint import MemorySaver

适用场景:

  • 复杂工作流
  • 多步骤任务
  • 状态管理

4.2.3 CrewAI

特点:

  • 角色定义清晰
  • 任务流程明确
  • 协作机制完善
  • 适合团队工作

核心组件:

from crewai import Agent, Task, Crew, Process

适用场景:

  • 内容创作
  • 研究分析
  • 团队协作

4.2.4 AutoGen

特点:

  • 对话式协作
  • 高度灵活
  • 支持复杂协商
  • 可定制性强

核心组件:

import autogen
from autogen import ConversableAgent, GroupChat, GroupChatManager

适用场景:

  • 多Agent对话
  • 复杂协商
  • 创意生成

4.2.5 Spring AI

特点:

  • 企业级特性
  • Spring生态集成
  • 类型安全
  • 生产就绪

核心组件:

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;

适用场景:

  • 企业应用
  • 微服务架构
  • Java生态

4.3 框架选择指南

选择标准:

  1. 项目需求

    • 简单任务 → LangChain
    • 复杂流程 → LangGraph
    • 团队协作 → CrewAI
    • 对话系统 → AutoGen
  2. 技术栈

    • Python → LangChain/LangGraph
    • Java → Spring AI
    • C# → Semantic Kernel
  3. 团队经验

    • 新手 → LangChain
    • 有经验 → 根据需求选择
  4. 项目规模

    • 原型 → LangChain
    • 生产 → Spring AI/LangGraph

五、A2A(Agent-to-Agent)协作模式

5.1 A2A基本概念

A2A(Agent-to-Agent)是指Agent之间直接进行协作和通信的模式,不依赖中央协调器。

核心特点:

  • 去中心化协作
  • 直接通信
  • 自主决策
  • 动态适应

5.2 A2A vs 传统协作

维度传统协作A2A协作
架构中心化去中心化
通信通过中央节点直接通信
决策中央协调自主决策
扩展性受限于中央节点水平扩展
容错性单点故障分布式容错

5.3 A2A应用场景

  1. 分布式系统

    • 微服务架构
    • 边缘计算
    • 物联网系统
  2. 智能网络

    • 自动驾驶
    • 智能交通
    • 智慧城市
  3. 协作平台

    • 多Agent游戏
    • 虚拟团队
    • 智能助手网络

5.4 A2A实现要点

通信协议:

  • 消息格式标准化
  • 异步通信
  • 错误处理
  • 超时机制

协调机制:

  • 共识算法
  • 任务分配
  • 冲突解决
  • 负载均衡

安全考虑:

  • 身份认证
  • 权限控制
  • 数据加密
  • 审计日志

5.5 A2A发展趋势

  1. 标准化协议:统一的Agent通信标准
  2. 智能路由:基于AI的消息路由
  3. 自适应协作:动态调整协作策略
  4. 跨域协作:不同系统间的Agent协作
  5. 安全增强:更强的安全机制

六、总结

6.1 常见问题解答

Q1: Agent和传统的聊天机器人有什么区别?

回答:

  • 传统聊天机器人:一问一答,被动响应
  • Agent:主动规划,多步骤执行,具备推理能力

Q2: ReAct模式有什么局限性?

回答:

  1. 计算成本高:每个思考步骤都需要调用LLM
  2. 执行时间长:多轮交互导致响应慢
  3. 错误累积:早期错误会影响后续步骤
  4. 上下文限制:长对话可能超出模型上下文窗口

Q3: 多Agent系统如何避免冲突?

回答:

  • 使用锁机制避免资源冲突
  • 任务去重避免重复执行
  • 状态同步保持一致性

Q4: 如何评估Agent的性能?

回答:

  • 任务完成率
  • 平均执行时间
  • 资源利用率
  • 错误率
  • 用户满意度

6.2 核心要点回顾

  1. Agent是具备推理和行动能力的AI系统
  2. 8种Agent模式:规划与执行、自我提问、思考与自省、ReAct、ReAct RAG Agent、Agentic RAG、思维树等
  3. 多Agent协作:通过角色分工和消息传递实现复杂任务
  4. 主流框架:CrewAI(角色驱动)、AutoGen(对话驱动)、MetaGPT(流程标准化)
  5. Java实现:基于Spring AI的企业级Agent系统
  6. A2A协作:去中心化的Agent间直接通信

6.3 技术选型建议

应用场景          →  推荐方案
─────────────────────────────────
内容创作          →  CrewAI
复杂协商          →  AutoGen
软件开发          →  MetaGPT
研究分析          →  CrewAI + ReAct
创意设计          →  AutoGen
项目管理          →  MetaGPT
企业应用          →  Spring AI