joyagent智能体学习(第2期)智能体核心设计模式

本章导读: 深入解析JoyAgent-JDGenie中的智能体设计模式,从ReAct到Planning,从单体到多体协作,全面掌握现代多智能体系统的核心设计理念与工程实践。


🎯 引言:现代多智能体系统的设计哲学

在人工智能快速发展的时代,单一的AI模型已经难以满足复杂业务场景的需求。多智能体系统通过专业化分工协作执行智能决策,实现了从"单打独斗"到"团队协作"的根本性转变。

JoyAgent-JDGenie作为业界高完成度的轻量化通用多智能体产品,其核心竞争力在于一套经过生产环境验证的智能体设计模式体系。这套体系包含:

🏗️ 核心设计模式架构

graph TD subgraph "智能体设计模式体系" A[BaseAgent\n基础抽象层] --> B[ReActAgent\n思考-行动模式] A --> C[直接继承模式] B --> D[ReactImplAgent\nReAct具体实现] B --> E[PlanningAgent\n规划智能体] B --> F[ExecutorAgent\n执行智能体] C --> G[SummaryAgent\n总结智能体] end subgraph "协作机制" H[Plan-Solve协作模式] --> I[Planning -> Execution -> Summary] H --> J[并行任务执行] H --> K[状态同步机制] end

🎨 设计模式的核心价值

  1. 模式化复用: 通过抽象基类和继承体系,实现智能体能力的模块化复用
  2. 专业化分工: 不同智能体承担不同职责,实现高效的任务分解与执行
  3. 灵活性扩展: 开放的设计架构支持新智能体类型的快速接入
  4. 工程化实践: 经过生产环境验证的设计模式,具备高可靠性和可维护性

🧠 ReAct智能体设计模式:思考与行动的完美融合

2.1 ReAct模式的理论基础

核心理念:思考-行动-观察循环

ReAct (Reasoning and Acting) 模式是现代智能体系统的核心设计模式之一,它将推理能力行动能力有机结合,通过持续的观察反馈形成闭环优化。

graph LR subgraph "ReAct 循环" T[Think\n思考分析] --> A[Act\n执行行动] A --> O[Observe\n观察结果] O --> T O --> D[Done\n任务完成] end subgraph "各阶段详细过程" T1[分析当前状态\n制定行动策略\n选择合适工具] --> A1[调用工具\n执行操作\n获取反馈] A1 --> O1[处理结果\n更新状态
评估进展] end

适用场景分析

最适合的任务类型

  • 动态信息探索: 需要根据中间结果调整策略的任务
  • 错误可恢复任务: 可以通过重试和调整修正错误
  • 多步骤推理: 需要逐步深入分析的复杂问题
  • 交互式任务: 需要与环境持续交互获取信息

相对不适合的场景

  • 已知流程固定: 步骤明确且不需要调整的标准化任务
  • 大规模并行: 需要同时处理多个独立子任务的场景

2.2 ReActAgent抽象基类设计

核心架构实现

java 复制代码
/**
 * ReAct代理 - 基于ReAct模式的智能代理
 */
@Data
@Slf4j
@EqualsAndHashCode(callSuper = true)
public abstract class ReActAgent extends BaseAgent {

    /**
     * 思考过程
     */
    public abstract boolean think();

    /**
     * 执行行动
     */
    public abstract String act();

    /**
     * 执行单个步骤
     */
    @Override
    public String step() {
        boolean shouldAct = think();
        if (!shouldAct) {
            return "Thinking complete - no action needed";
        }
        return act();
    }

    public void generateDigitalEmployee(String task) {
        // 1、参数检查
        if (StringUtils.isEmpty(task)) {
            return;
        }
        try {
            // 2. 构建系统消息(提取为独立方法)
            String formattedPrompt = formatSystemPrompt(task);
            Message userMessage = Message.userMessage(formattedPrompt, null);

            // 3. 调用LLM并处理结果
            CompletableFuture<String> summaryFuture = getLlm().ask(
                    context,
                    Collections.singletonList(userMessage),
                    Collections.emptyList(),
                    false,
                    0.01);

            // 4. 解析响应
            String llmResponse = summaryFuture.get();
            log.info("requestId: {} task:{} generateDigitalEmployee: {}", context.getRequestId(), task, llmResponse);
            JSONObject jsonObject = parseDigitalEmployee(llmResponse);
            if (jsonObject != null) {
                log.info("requestId:{} generateDigitalEmployee: {}", context.getRequestId(), jsonObject);
                context.getToolCollection().updateDigitalEmployee(jsonObject);
                context.getToolCollection().setCurrentTask(task);
                // 更新 availableTools 添加数字员工
                availableTools = context.getToolCollection();
            } else {
                log.error("requestId: {} generateDigitalEmployee failed", context.getRequestId());
            }

        } catch (Exception e) {
            log.error("requestId: {} in generateDigitalEmployee failed,", context.getRequestId(), e);
        }
    }

    // 解析数据员工大模型响应
    private JSONObject parseDigitalEmployee(String response) {
        /**
         * 格式一:
         *      ```json
         *      {
         *          "file_tool": "市场洞察专员"
         *      }
         *      ```
         * 格式二:
         *      {
         *          "file_tool": "市场洞察专员"
         *      }
         */
        if (StringUtils.isBlank(response)) {
            return null;
        }
        String jsonString = response;
        String regex = "```\\s*json([\\d\\D]+?)```";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(response);
        if (matcher.find()) {
            String temp = matcher.group(1).trim();
            if (!jsonString.isEmpty()) {
                jsonString = temp;
            }
        }
        try {
            return JSON.parseObject(jsonString);
        } catch (Exception e) {
            log.error("requestId: {} in parseDigitalEmployee error:", context.getRequestId(), e);
            return null;
        }
    }

    // 提取系统提示格式化逻辑
    private String formatSystemPrompt(String task) {
        String digitalEmployeePrompt = getDigitalEmployeePrompt();
        if (digitalEmployeePrompt == null) {
            throw new IllegalStateException("System prompt is not configured");
        }

        StringBuilder toolPrompt = new StringBuilder();
        for (BaseTool tool : context.getToolCollection().getToolMap().values()) {
            toolPrompt.append(String.format("工具名:%s 工具描述:%s\n", tool.getName(), tool.getDescription()));
        }

        // 替换占位符
        return digitalEmployeePrompt
                .replace("{{task}}", task)
                .replace("{{ToolsDesc}}", toolPrompt.toString())
                .replace("{{query}}", context.getQuery());
    }
}

2.3 ReactImplAgent具体实现

思考阶段 (Think) 的实现细节

java 复制代码
@Override
public boolean think() {
    // 获取文件内容
    String filesStr = FileUtil.formatFileInfo(context.getProductFiles(), true);
    setSystemPrompt(getSystemPromptSnapshot().replace("{{files}}", filesStr));
    setNextStepPrompt(getNextStepPromptSnapshot().replace("{{files}}", filesStr));

    if (!getMemory().getLastMessage().getRole().equals(RoleType.USER)) {
        Message userMsg = Message.userMessage(getNextStepPrompt(), null);
        getMemory().addMessage(userMsg);
    }
    try {
        // 获取带工具选项的响应
        context.setStreamMessageType("tool_thought");

        CompletableFuture<LLM.ToolCallResponse> future = getLlm().askTool(
                context,
                getMemory().getMessages(),
                Message.systemMessage(getSystemPrompt(), null),
                availableTools,
                ToolChoice.AUTO, null, context.getIsStream(), 300
        );

        LLM.ToolCallResponse response = future.get();

        setToolCalls(response.getToolCalls());

        // 记录响应信息
        if (!context.getIsStream() && response.getContent() != null && !response.getContent().isEmpty()) {
            printer.send("tool_thought", response.getContent());

        }

        // 创建并添加助手消息
        Message assistantMsg = response.getToolCalls() != null && !response.getToolCalls().isEmpty() && !"struct_parse".equals(llm.getFunctionCallType()) ?
                Message.fromToolCalls(response.getContent(), response.getToolCalls()) :
                Message.assistantMessage(response.getContent(), null);
        getMemory().addMessage(assistantMsg);

    } catch (Exception e) {

        log.error("{} react think error", context.getRequestId(), e);
        getMemory().addMessage(Message.assistantMessage(
                "Error encountered while processing: " + e.getMessage(), null));
        setState(AgentState.FINISHED);
        return false;
    }

    return true;
}

思考阶段的关键特性

  1. 动态上下文适配: 根据当前文件状态动态调整提示词
  2. 记忆连续性: 确保对话历史的完整性和连贯性
  3. 工具智能选择: 基于当前状态和可用工具进行最优选择
  4. 错误恢复机制: 异常情况下的优雅降级处理
  5. 流式反馈: 实时向用户展示思考过程

行动阶段 (Act) 的执行机制

java 复制代码
@Override
public String act() {

    if (toolCalls.isEmpty()) {
        setState(AgentState.FINISHED);
        return getMemory().getLastMessage().getContent();
    }

    // action
    Map<String, String> toolResults = executeTools(toolCalls);
    List<String> results = new ArrayList<>();
    for (ToolCall command : toolCalls) {
        String result = toolResults.get(command.getId());
        if (!Arrays.asList("code_interpreter", "report_tool", "file_tool", "deep_search").contains(command.getFunction().getName())) {
            String toolName = command.getFunction().getName();
            printer.send("tool_result", AgentResponse.ToolResult.builder()
                    .toolName(toolName)
                    .toolParam(JSON.parseObject(command.getFunction().getArguments(), Map.class))
                    .toolResult(result)
                    .build(), null);
        }

        if (maxObserve != null) {
            result = result.substring(0, Math.min(result.length(), maxObserve));
        }

        // 添加工具响应到记忆
        if ("struct_parse".equals(llm.getFunctionCallType())) {
            String content = getMemory().getLastMessage().getContent();
            getMemory().getLastMessage().setContent(content + "\n 工具执行结果为:\n" + result);
        } else { // function_call
            Message toolMsg = Message.toolMessage(
                    result,
                    command.getId(),
                    null
            );
            getMemory().addMessage(toolMsg);
        }
        results.add(result);
    }

    return String.join("\n\n", results);
}

行动阶段的核心特征

  1. 并发执行 : 通过executeTools方法同时执行多个工具调用
  2. 结果分类处理: 区分核心工具和辅助工具的结果展示策略
  3. 记忆模式适配: 支持不同的LLM函数调用格式
  4. 输出长度控制: 防止过长的结果影响后续推理
  5. 实时反馈: 向用户实时展示工具执行进展

📋 Planning智能体设计模式:系统化任务规划

3.1 Planning模式的设计理念

核心思想:先规划,后执行

Planning模式采用分而治之的策略,将复杂任务分解为可管理的子任务,然后系统性地执行这些子任务。

graph TD subgraph "Planning 工作流" A[任务分析] --> B[制定计划] B --> C[计划验证] C --> D[执行任务] D --> E[进度跟踪] E --> F{所有任务完成?} F -->|否| G[更新计划] G --> D F -->|是| H[任务总结] end subgraph "计划结构" I[Plan对象\n- title: 计划标题\n- steps: 任务步骤\n- stepStatus: 执行状态\n- currentStep: 当前任务] end

Planning模式的适用场景

最适合的任务类型

  • 复杂多步骤任务: 需要系统性分解和执行的大型任务
  • 资源密集型任务: 需要协调多种资源的复杂场景
  • 长期目标导向: 有明确最终目标的项目式任务
  • 质量要求高: 需要严格按步骤执行以确保质量的任务

设计优势

  • 全局视野: 能够从整体角度制定最优策略
  • 资源优化: 可以提前规划资源使用,避免冲突
  • 进度可控: 明确的里程碑和进度跟踪机制
  • 质量保证: 系统化的执行流程确保输出质量

3.2 Plan数据结构设计

Plan类的核心实现

java 复制代码
/**
 * 计划类
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Plan {

    /**
     * 计划标题
     */
    private String title;

    /**
     * 计划步骤列表
     */
    private List<String> steps;

    /**
     * 步骤状态列表
     */
    private List<String> stepStatus;

    /**
     * 步骤备注列表
     */
    private List<String> notes;

    /**
     * 创建新计划
     */
    public static Plan create(String title, List<String> steps) {
        List<String> status = new ArrayList<>();
        List<String> notes = new ArrayList<>();

        for (int i = 0; i < steps.size(); i++) {
            status.add("not_started");
            notes.add("");
        }

        return Plan.builder()
                .title(title)
                .steps(steps)
                .stepStatus(status)
                .notes(notes)
                .build();
    }

    /**
     * 更新当前task为 completed,下一个task为 in_progress
     */
    public void stepPlan() {
        if (steps.isEmpty()) {
            return;
        }
        if (getCurrentStep().isEmpty()) {
            updateStepStatus(0, "in_progress", "");
            return;
        }
        for (int i = 0; i < steps.size(); i++) {
            if ("in_progress".equals(stepStatus.get(i))) {
                updateStepStatus(i, "completed", "");
                if (i + 1 < steps.size()) {
                    updateStepStatus(i + 1, "in_progress", "");
                    break;
                }
            }
        }
    }

    /**
     * 更新步骤状态
     */
    public String getCurrentStep() {
        for (int i = 0; i < steps.size(); i++) {
            if ("in_progress".equals(stepStatus.get(i))) {
                return steps.get(i);
            }
        }
        return "";
    }
}

3.3 PlanningTool工具实现

计划工具的设计架构

java 复制代码
/**
 * 计划工具类
 */
@Data
public class PlanningTool implements BaseTool {

    private AgentContext agentContext;
    private final Map<String, Function<Map<String, Object>, String>> commandHandlers = new HashMap<>();
    private Plan plan;

    public PlanningTool() {
        commandHandlers.put("create", this::createPlan);
        commandHandlers.put("update", this::updatePlan);
        commandHandlers.put("mark_step", this::markStep);
        commandHandlers.put("finish", this::finishPlan);
    }

    @Override
    public String getDescription() {
        String desc = "这是一个计划工具,可让代理创建和管理用于解决复杂任务的计划。\n该工具提供创建计划、更新计划步骤和跟踪进度的功能。\n使用中文回答";
        GenieConfig genieConfig = SpringContextHolder.getApplicationContext().getBean(GenieConfig.class);
        return genieConfig.getPlanToolDesc().isEmpty() ? desc : genieConfig.getPlanToolDesc();
    }

    private String createPlan(Map<String, Object> params) {
        String title = (String) params.get("title");
        List<String> steps = (List<String>) params.get("steps");

        if (title == null || steps == null) {
            throw new IllegalArgumentException("title, and steps are required for create command");
        }

        if (plan != null) {
            throw new IllegalStateException("A plan already exists. Delete the current plan first.");
        }

        plan = Plan.create(title, steps);
        return "我已创建plan";
    }

    public void stepPlan() {
        plan.stepPlan();
    }
}

3.4 PlanningAgent的执行机制

规划智能体的思考逻辑

java 复制代码
@Override
public boolean think() {
    long startTime = System.currentTimeMillis();
    // 获取文件内容
    String filesStr = FileUtil.formatFileInfo(context.getProductFiles(), false);
    setSystemPrompt(getSystemPromptSnapshot().replace("{{files}}", filesStr));
    setNextStepPrompt(getNextStepPromptSnapshot().replace("{{files}}", filesStr));
    log.info("{} planer fileStr {}", context.getRequestId(), filesStr);

    // 关闭了动态更新Plan,直接执行下一个task
    if (isColseUpdate) {
        if (Objects.nonNull(planningTool.getPlan())) {
            planningTool.stepPlan();
            return true;
        }
    }

    try {
        if (!getMemory().getLastMessage().getRole().equals(RoleType.USER)) {
            Message userMsg = Message.userMessage(getNextStepPrompt(), null);
            getMemory().addMessage(userMsg);
        }

        context.setStreamMessageType("plan_thought");
        CompletableFuture<LLM.ToolCallResponse> future = getLlm().askTool(context,
                getMemory().getMessages(),
                Message.systemMessage(getSystemPrompt(), null),
                availableTools,
                ToolChoice.AUTO, null, context.getIsStream(), 300
        );

        LLM.ToolCallResponse response = future.get();
        setToolCalls(response.getToolCalls());

        // 记录响应信息
        if (!context.getIsStream() && response.getContent() != null && !response.getContent().isEmpty()) {
            printer.send("plan_thought", response.getContent());
        }

        // 创建并添加助手消息
        Message assistantMsg = response.getToolCalls() != null && !response.getToolCalls().isEmpty() && !"struct_parse".equals(llm.getFunctionCallType()) ?
                Message.fromToolCalls(response.getContent(), response.getToolCalls()) :
                Message.assistantMessage(response.getContent(), null);

        getMemory().addMessage(assistantMsg);

    } catch (Exception e) {
        log.error("{} think error ", context.getRequestId(), e);
    }

    return true;
}

⚡ ExecutorAgent任务执行机制

4.1 执行智能体的设计定位

ExecutorAgent的核心职责

ExecutorAgent作为任务执行的专门智能体,承担着将抽象的任务描述转化为具体操作的重要职责:

java 复制代码
/**
 * 工具调用代理 - 处理工具/函数调用的基础代理类
 */
@Data
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class ExecutorAgent extends ReActAgent {

    private List<ToolCall> toolCalls;
    private Integer maxObserve;
    private String systemPromptSnapshot;
    private String nextStepPromptSnapshot;

    private Integer taskId;

    public ExecutorAgent(AgentContext context) {
        setName("executor");
        setDescription("an agent that can execute tool calls.");
        ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
        GenieConfig genieConfig = applicationContext.getBean(GenieConfig.class);

        StringBuilder toolPrompt = new StringBuilder();
        for (BaseTool tool : context.getToolCollection().getToolMap().values()) {
            toolPrompt.append(String.format("工具名:%s 工具描述:%s\n", tool.getName(), tool.getDescription()));
        }

        String promptKey = "default";
        String sopPromptKey = "default";
        String nextPromptKey = "default";
        setSystemPrompt(genieConfig.getExecutorSystemPromptMap().getOrDefault(promptKey, ToolCallPrompt.SYSTEM_PROMPT)
                .replace("{{tools}}", toolPrompt.toString())
                .replace("{{query}}", context.getQuery())
                .replace("{{date}}", context.getDateInfo())
                .replace("{{sopPrompt}}", context.getSopPrompt())
                .replace("{{executorSopPrompt}}", genieConfig.getExecutorSopPromptMap().getOrDefault(sopPromptKey, "")));

        // 初始化工具集合
        availableTools = context.getToolCollection();
        setDigitalEmployeePrompt(genieConfig.getDigitalEmployeePrompt());

        setTaskId(0);
    }
}

ExecutorAgent的独特特性

  1. 工具执行专家: 拥有丰富的工具集合,专门负责具体操作
  2. ReAct模式优化: 在ReAct基础上针对执行场景进行优化
  3. 结果观察控制: 通过maxObserve控制结果长度,防止信息过载
  4. 上下文敏感: 能够根据文件和环境信息调整执行策略

4.2 执行智能体的运行机制

数字员工生成与任务预处理

java 复制代码
@Override
public String run(String request) {
    generateDigitalEmployee(request);
    GenieConfig genieConfig = SpringContextHolder.getApplicationContext().getBean(GenieConfig.class);
    request = genieConfig.getTaskPrePrompt() + request;
    // 更新当前task
    context.setTask(request);
    return super.run(request);
}

📊 SummaryAgent结果总结机制

5.1 总结智能体的设计定位

SummaryAgent的核心职责

重要说明 : SummaryAgent 直接继承BaseAgent,而不是ReActAgent,这是因为总结任务相对简单,不需要复杂的思考-行动循环。

java 复制代码
@Data
@Slf4j
@EqualsAndHashCode(callSuper = true)
public class SummaryAgent extends BaseAgent {
    private String requestId;
    private Integer messageSizeLimit;
    public static final String logFlag = "summaryTaskResult";

    public SummaryAgent(AgentContext context) {
        ApplicationContext applicationContext = SpringContextHolder.getApplicationContext();
        GenieConfig genieConfig = applicationContext.getBean(GenieConfig.class);
        setSystemPrompt(genieConfig.getSummarySystemPrompt());

        setContext(context);
        setRequestId(context.getRequestId());
        setLlm(new LLM(context.getAgentType() == 3 ? genieConfig.getPlannerModelName() : genieConfig.getReactModelName(), ""));
        setMessageSizeLimit(genieConfig.getMessageSizeLimit());
    }

    /**
     * 执行单个步骤
     */
    public String step() {
        return "";
    }
}

5.2 核心总结功能实现

任务结果总结方法

java 复制代码
// 总结任务
public TaskSummaryResult summaryTaskResult(List<Message> messages, String query) {
    long startTime = System.currentTimeMillis();
    // 1. 参数校验(可选)
    if (CollectionUtils.isEmpty(messages) || StringUtils.isEmpty(query)) {
        log.warn("requestId: {}  summaryTaskResult messages:{}  or query:{} is empty", requestId, messages, query);
        return TaskSummaryResult.builder().taskSummary("").build();
    }

    try {
        // 2. 构建系统消息(提取为独立方法)
        log.info("requestId: {} summaryTaskResult: messages:{}", requestId, messages.size());
        StringBuilder sb = new StringBuilder();
        for (Message message : messages) {
            String content = message.getContent();
            if (content != null && content.length() > getMessageSizeLimit()) {
                log.info("requestId: {} message truncate,{}", requestId, message);
                content = content.substring(0, getMessageSizeLimit());
            }
            sb.append(String.format("role:%s content:%s\n", message.getRole(), content));
        }
        String formattedPrompt = formatSystemPrompt(sb.toString(), query);
        Message userMessage = createSystemMessage(formattedPrompt);

        // 3. 调用LLM并处理结果
        CompletableFuture<String> summaryFuture = getLlm().ask(
                context,
                Collections.singletonList(userMessage),
                Collections.emptyList(),
                false,
                0.01);

        // 5. 解析响应
        String llmResponse = summaryFuture.get();
        log.info("requestId: {} summaryTaskResult: {}", requestId, llmResponse);

        return parseLlmResponse(llmResponse);
    } catch (Exception e) {
        log.error("requestId: {} in summaryTaskResult failed,", requestId, e);

        return TaskSummaryResult.builder().taskSummary("任务执行失败,请联系管理员!").build();
    }
}

🤝 多智能体协作机制:Plan-Solve协作模式

6.1 三层协作架构

JoyAgent-JDGenie采用三层智能体协作架构,实现了Planning → Execution → Summary的完整工作流:

graph TD subgraph "协作层次结构" A[PlanningAgent\n规划智能体] --> B[ExecutorAgent\n执行智能体] B --> C[SummaryAgent\n总结智能体] end subgraph "协作流程" D[用户查询] --> E[Planning分析任务] E --> F[制定执行计划] F --> G[Executor执行任务] G --> H{任务完成?} H -->|否| I[更新计划] I --> G H -->|是| J[Summary总结结果] J --> K[返回用户] end subgraph "数据流转" L[共享上下文\nAgentContext] --> M[共享记忆\nMemory] M --> N[共享工具\nToolCollection] end

6.2 协作控制器实现

Plan-Solve协作模式的核心控制器

java 复制代码
@Slf4j
@Component
public class PlanSolveHandlerImpl implements AgentHandlerService {

    @Autowired
    private GenieConfig genieConfig;

    @Override
    public String handle(AgentContext agentContext, AgentRequest request) {

        PlanningAgent planning = new PlanningAgent(agentContext);
        ExecutorAgent executor = new ExecutorAgent(agentContext);
        SummaryAgent summary = new SummaryAgent(agentContext);
        summary.setSystemPrompt(summary.getSystemPrompt().replace("{{query}}", request.getQuery()));

        String planningResult = planning.run(agentContext.getQuery());
        int stepIdx = 0;
        int maxStepNum = genieConfig.getPlannerMaxSteps();
        while (stepIdx <= maxStepNum) {
            List<String> planningResults = Arrays.stream(planningResult.split("<sep>"))
                    .map(task -> "你的任务是:" + task)
                    .collect(Collectors.toList());
            String executorResult;
            agentContext.getTaskProductFiles().clear();
            if (planningResults.size() == 1) {
                executorResult = executor.run(planningResults.get(0));
            } else {
                Map<String, String> tmpTaskResult = new ConcurrentHashMap<>();
                CountDownLatch taskCount = ThreadUtil.getCountDownLatch(planningResults.size());
                int memoryIndex = executor.getMemory().size();
                List<ExecutorAgent> slaveExecutors = new ArrayList<>();
                for (String task : planningResults) {
                    ExecutorAgent slaveExecutor = new ExecutorAgent(agentContext);
                    slaveExecutor.setState(executor.getState());
                    slaveExecutor.getMemory().addMessages(executor.getMemory().getMessages());
                    slaveExecutors.add(slaveExecutor);
                    ThreadUtil.execute(() -> {
                        String taskResult = slaveExecutor.run(task);
                        tmpTaskResult.put(task, taskResult);
                        taskCount.countDown();
                    });
                }
                ThreadUtil.await(taskCount);
                for (ExecutorAgent slaveExecutor : slaveExecutors) {
                    for (int i = memoryIndex; i < slaveExecutor.getMemory().size(); i++) {
                        executor.getMemory().addMessage(slaveExecutor.getMemory().get(i));
                    }
                    slaveExecutor.getMemory().clear();
                    executor.setState(slaveExecutor.getState());
                }
                executorResult = String.join("\n", tmpTaskResult.values());
            }
            planningResult = planning.run(executorResult);
            if ("finish".equals(planningResult)) {
                //任务成功结束,总结任务
                TaskSummaryResult result = summary.summaryTaskResult(executor.getMemory().getMessages(), request.getQuery());

                Map<String, Object> taskResult = new HashMap<>();
                taskResult.put("taskSummary", result.getTaskSummary());

                if (CollectionUtils.isEmpty(result.getFiles())) {
                    if (!CollectionUtils.isEmpty(agentContext.getProductFiles())) {
                        List<File> fileResponses = agentContext.getProductFiles();
                        // 过滤中间搜索结果文件
                        fileResponses.removeIf(file -> Objects.nonNull(file) && file.getIsInternalFile());
                        Collections.reverse(fileResponses);
                        taskResult.put("fileList", fileResponses);
                    }
                } else {
                    taskResult.put("fileList", result.getFiles());
                }

                agentContext.getPrinter().send("result", taskResult);

                break;
            }
            if (planning.getState() == AgentState.IDLE || executor.getState() == AgentState.IDLE) {
                agentContext.getPrinter().send("result", "达到最大迭代次数,任务终止。");
                break;
            }
            if (planning.getState() == AgentState.ERROR || executor.getState() == AgentState.ERROR) {
                agentContext.getPrinter().send("result", "任务执行异常,请联系管理员,任务终止。");
                break;
            }
            stepIdx++;
        }

        return "";
    }

    @Override
    public Boolean support(AgentContext agentContext, AgentRequest request) {
        return AgentType.PLAN_SOLVE.getValue().equals(request.getAgentType());
    }
}

协作机制的关键特性

  1. 状态同步: 每个从执行器都同步主执行器的状态和记忆
  2. 内存管理: 任务完成后及时清理从执行器的内存
  3. 线程安全 : 使用ConcurrentHashMapCountDownLatch确保并发安全
  4. 结果聚合: 所有任务的结果和记忆都会合并到主执行器

6.3 智能体间通信协议

消息传递机制

智能体间通过标准化的消息格式进行通信:

java 复制代码
/**
 * 记忆类 - 管理代理的消息历史
 */
@Data
public class Memory {
    private List<Message> messages = new ArrayList<>();

    /**
     * 添加消息
     */
    public void addMessage(Message message) {
        messages.add(message);
    }

    /**
     * 清空工具执行历史
     */
    public void clearToolContext() {
        Iterator<Message> iterator = messages.iterator();
        while (iterator.hasNext()) {
            Message message = iterator.next();
            if (message.getRole() == RoleType.TOOL) {
                iterator.remove();
            }
            if (message.getRole() == RoleType.ASSISTANT && Objects.nonNull(message.getToolCalls()) && !message.getToolCalls().isEmpty()) {
                iterator.remove();
            }
            if (Objects.nonNull(message.getContent()) && message.getContent().startsWith("根据当前状态和可用工具,确定下一步行动")) {
                iterator.remove();
            }
        }
    }
}

🎯 总结:设计模式的价值与展望

通过本章的深入分析,我们全面掌握了JoyAgent-JDGenie中的核心智能体设计模式体系。这套设计模式的核心价值体现在:

🏆 设计模式的核心价值

1. 模式化复用与扩展性

  • 抽象层设计: BaseAgent和ReActAgent提供了良好的抽象基础
  • 继承体系: 通过继承实现功能的复用和扩展
  • 接口标准: 统一的接口设计支持新智能体的快速接入

2. 专业化分工与协作

  • ReAct模式: 适合动态决策和交互式任务
  • Planning模式: 擅长复杂任务的系统化分解
  • Execution模式: 专注于具体工具的执行
  • Summary模式: 负责结果的整理和总结

3. 工程化实践与可靠性

  • 错误处理: 完善的异常处理和恢复机制
  • 状态管理: 清晰的智能体状态转换和同步
  • 资源控制: 合理的内存管理和资源释放
  • 监控日志: 详细的执行日志和性能监控

🚀 技术创新与突破

1. 多模式融合

  • 将ReAct的灵活性与Planning的系统性有机结合
  • 实现了单智能体决策与多智能体协作的完美平衡
  • 支持同步执行和异步并行的灵活切换

2. 工程化落地

  • 从学术概念到生产级系统的成功转化
  • 经过大规模业务场景验证的稳定架构
  • 支持快速迭代和功能扩展的设计理念

3. 生态开放性

  • 基于MCP协议的工具生态建设
  • 支持第三方智能体和工具的无缝集成
  • 面向开发者友好的扩展机制

🔮 未来发展方向

1. 更复杂的协作拓扑

graph TD A[PlanningAgent] --> B[ExecutorAgent1] A --> C[ExecutorAgent2] A --> D[ExecutorAgent3] B --> E[VerificationAgent] C --> E D --> E E --> F[SummaryAgent]

2. 智能化程度提升

  • 基于强化学习的智能体行为优化
  • 自适应的工具选择和参数调优
  • 智能体间的自主协商和决策

3. 跨域应用扩展

  • 垂直行业的定制化智能体
  • 跨语言和跨平台的智能体部署
  • 边缘计算环境下的轻量化智能体

💡 实践建议

对于开发者:

  1. 深入理解: 掌握每种设计模式的适用场景和实现细节
  2. 渐进式学习: 从简单的ReAct智能体开始,逐步理解复杂的协作机制
  3. 实践验证: 通过具体项目验证设计模式的有效性

对于架构师:

  1. 模式选择: 根据业务特点选择合适的智能体设计模式
  2. 扩展规划: 设计支持未来扩展的智能体架构
  3. 性能优化: 关注多智能体协作的性能瓶颈和优化方案

对于产品经理:

  1. 场景匹配: 理解不同模式在业务场景中的应用价值
  2. 用户体验: 关注智能体交互的用户体验设计
  3. 价值评估: 评估多智能体系统带来的业务价值

JoyAgent-JDGenie的智能体设计模式体系,不仅是一套技术实现方案,更是多智能体系统工程化的重要里程碑。它为构建下一代AI应用系统提供了宝贵的经验和参考,值得每一位AI从业者深入学习和实践。

下一章我们将深入探讨工具系统的设计与实现,了解智能体如何通过丰富的工具生态来扩展自身能力。

相关推荐
董厂长10 小时前
SubAgent的“指令漂移 (Instruction Drift)“困境
人工智能·agent·mcp·subagent
镰刀韭菜15 小时前
【AI4S】大语言模型与化学的未来,以及整合外部工具和聊天机器人的潜力
llm·transformer·大语言模型·药物设计·分子发现·chemchat·smiles
数据智能老司机19 小时前
建构 AI Agent 应用——工具调用
架构·llm·agent
aopstudio21 小时前
llms.txt:为大模型打造的“网站说明书”
人工智能·python·llm·开发者工具
大模型真好玩2 天前
深入浅出LangGraph AI Agent智能体开发教程(九)—LangGraph长短期记忆管理
人工智能·python·agent
vv_5012 天前
Langchain+Neo4j+Agent 的结合案例-电商销售
人工智能·langchain·agent·neo4j
AI大模型API向量引擎2 天前
开发者必看:Luma Video API 对接教程 + 电影级视频生成技巧,NeRF 技术落地实践
llm
AndrewHZ2 天前
【3D图像技术讨论】3A游戏场景重建实战指南:从数据采集到实时渲染的开源方案
人工智能·算法·游戏·3d·开源·llm·colmap
马诗剑2 天前
Qwen3-8B 在华为昇腾平台上的保姆级微调与推理教程 (基于AutoDL)
llm
攻城狮7号3 天前
Kimi开源轻量级中间件checkpoint-engine:能20秒内更新万亿参数模型?
人工智能·llm·kimi·moonshotai·checkpoint引擎·开源中间件