1. 引言

当业务问题从“问答”升级到“方案生成、任务拆解、跨角色协同、执行闭环”时,单一智能体往往很快碰到能力边界。

原因并不复杂:

  • • 单 Agent 擅长基于统一上下文做推理,但不擅长同时兼顾多个专业角色
  • • 复杂场景下上下文越来越长,提示词污染、角色混叠、输出不稳定问题会放大
  • • 业务系统真正需要的不只是“一段回答”,而是“可落地、可审计、可扩展、可治理”的结果

因此,多智能体系统的价值不在于“让多个模型一起说话”,而在于把复杂任务拆成可治理的工程单元,让不同角色智能体以受控方式协同完成目标。

本文不再停留在 Demo 层面,而是从企业架构和生产落地视角,完整讲清楚如何基于 Spring AI Alibaba 构建一个用于“活动/营销方案策划”的多智能体系统,并重点回答四个工程问题:

  • • 多智能体为什么比单智能体更适合复杂策划类任务
  • • 如何设计一个具备高并发、可扩展、可观测、可容错的多智能体架构
  • • Spring AI Alibaba 在生产场景中如何组织代码、配置模型、治理调用链路
  • • 如何将样例代码升级成可在线上运行的生产级实现

2. 业务场景与问题拆解

2.1 真实业务背景

以一家大型营销服务公司为例,客户提交一次活动策划需求后,通常需要经过以下几个专业环节:

  • • 创意策划:输出主题、亮点、玩法、传播点
  • • 财务规划:输出预算结构、成本测算、盈亏边界
  • • 执行设计:输出时间排期、资源配置、现场执行流程
  • • 风险控制:输出合规风险、舆情风险、供应链风险
  • • 方案汇总:整合为可交付、可评审、可执行的正式方案

传统方式通常由多个岗位人工串行协作,常见问题包括:

  • • 周期长:专业角色串行作业,交付速度慢
  • • 协同成本高:多轮沟通反复对齐,信息损耗明显
  • • 质量不稳定:高度依赖个人经验,输出标准不统一
  • • 扩展性差:业务峰值到来时很难快速扩容
  • • 知识沉淀弱:经验分散在人和文档中,难以固化为可复用能力

2.2 为什么必须采用多智能体

对于“生成一份完整策划方案”这类任务,本质上不是一个问答问题,而是一个复合型认知工作流,具备以下特征:

  • • 角色异构:创意、财务、执行关注点完全不同
  • • 目标冲突:创意追求新颖,财务追求成本可控,执行追求确定性
  • • 结果需要整合:最终输出必须统一口径而不是多份答案并列
  • • 过程需要审计:必须知道每个子结论从哪里来、谁生成、何时生成

这意味着系统设计不能只是“并发调用几个 Prompt”,而应当具备:

  • • 任务拆解能力
  • • 角色隔离能力
  • • 结果整合能力
  • • 失败恢复能力
  • • 成本控制能力
  • • 可观测与审计能力

3. 多智能体系统的核心原理

3.1 多智能体不只是“多个 Bot”

多智能体系统的本质,是把复杂任务映射成一个受控协同网络。它通常包含四类核心对象:

  • Planner:任务规划者,负责拆解任务与确定执行路径
  • Specialist Agent:专业角色智能体,负责在限定职责内产出结果
  • Orchestrator:编排协调器,负责任务调度、并发控制、超时治理、状态流转
  • Synthesizer/Judge:整合与评审者,负责冲突消解、方案汇总、结果校验

如果从架构角度看,多智能体系统更像“一个 AI 驱动的分布式业务流程引擎”,而不是简单的聊天机器人组合。

3.2 多智能体协作的三种常见模式

模式一:并行分工

适合相互独立的子任务,例如:

  • • 创意方案
  • • 财务测算
  • • 执行流程

优点:

  • • 延迟低
  • • 易扩展
  • • 结构清晰

缺点:

  • • 子结果之间可能互相矛盾
模式二:串行增强

一个智能体的结果作为下一个智能体的输入,例如:

  • • 先生成初版创意
  • • 再让执行 Agent 判断是否可落地
  • • 再让财务 Agent 测算预算是否超限

优点:

  • • 结果更一致

缺点:

  • • 时延更长
  • • 上游错误会向下游传播
模式三:规划 + 执行 + 裁决

先由 Planner 拆解任务,再由多个 Agent 执行,最后由 Judge 进行评分或裁决。

这是企业级最常用的模式,因为它兼顾:

  • • 灵活性
  • • 可治理性
  • • 可观测性
  • • 质量控制

本文的方案策划系统,采用的是“规划弱化版 + 并行执行 + 统一整合”的模式。之所以不引入完全自治式 Planner,是因为在多数企业场景中,任务类型相对稳定,过强的自主规划反而会带来不确定性和成本上升。


4. 整体架构设计

4.1 总体架构图

基础设施层

客户端 / 管理台 / OpenAPI

API Gateway

Planning Application

Agent Orchestrator

Task Planner

Creative Agent

Finance Agent

Execution Agent

Risk Agent

Result Judge / Integrator

LLM Service

Redis

MySQL / PostgreSQL

Kafka / RocketMQ

Prometheus + Grafana + Tracing

4.2 分层设计

从工程落地角度,建议把系统拆成 5 层:

1. 接入层

负责:

  • • HTTP / OpenAPI 接入
  • • 鉴权
  • • 请求幂等
  • • 流量限制
  • • 灰度控制
2. 编排层

负责:

  • • 任务拆解
  • • 智能体选择
  • • 并发执行
  • • 超时控制
  • • 重试与降级
  • • 状态机流转
3. 智能体层

负责:

  • • 角色提示词管理
  • • 上下文构造
  • • 工具调用
  • • 模型输出结构化
  • • 领域规则约束
4. 领域服务层

负责:

  • • 预算规则
  • • 活动模板
  • • 风险规则
  • • 审批约束
  • • 业务知识库检索
5. 基础设施层

负责:

  • • 模型调用
  • • 缓存
  • • 消息队列
  • • 持久化
  • • 监控告警
  • • 配置中心

4.3 为什么要引入 Orchestrator

很多 Demo 代码会把“并发调用多个 Agent”的逻辑直接写在 Controller 里,这在生产环境中很快会失控。

Orchestrator 的价值在于把 AI 编排从业务接口中剥离出来,成为独立的可治理组件。它至少应承担以下职责:

  • • 建立任务上下文,如 requestId / tenantId / scene / budgetLimit
  • • 根据场景动态选择 Agent 集合
  • • 控制并发度,避免线程池或模型调用被打爆
  • • 对每个 Agent 应用超时、重试、熔断、隔离策略
  • • 聚合结果并记录执行轨迹
  • • 输出统一的结构化结果,供后续整合器消费

5. 关键技术选型

5.1 技术栈建议

类别 技术 用途 选型理由
应用框架 Spring Boot 3.x Web 与服务框架 企业生态成熟,便于治理
AI 集成 Spring AI Alibaba 模型接入、Prompt 编排 与 Spring 体系集成自然
模型服务 通义千问或兼容模型 大模型推理 支持中文场景,易于企业接入
缓存 Redis 请求缓存、幂等、分布式锁 高性能,场景匹配度高
消息队列 Kafka / RocketMQ 异步任务、削峰填谷 解耦与高吞吐
持久化 MySQL / PostgreSQL 任务记录、审计日志 强一致、便于分析
限流熔断 Resilience4j / Sentinel 容错治理 适合高并发生产场景
监控 Micrometer + Prometheus + Grafana 指标监控 Spring 生态标准方案
链路追踪 OpenTelemetry 调用链与耗时分析 便于诊断 Agent 执行路径

5.2 为什么 Spring AI Alibaba 适合这类系统

相比手写 HTTP 调用模型接口,Spring AI Alibaba 的价值主要体现在:

  • • 模型调用抽象统一,便于替换不同模型提供方
  • • 可以更自然地组织 Prompt、Message、Options
  • • 能与 Spring Boot 的配置体系、Bean 生命周期、可观测体系对接
  • • 更容易沉淀出企业内部标准化 AI 开发范式

但需要明确一点:Spring AI Alibaba 解决的是“模型接入和基础 AI 编程抽象”,并不直接解决“多智能体生产编排”。编排、治理、幂等、容错、审计,仍然需要我们在应用层自己设计。


6. 生产级领域建模

如果只是返回一段字符串,很难支撑后续审计、回放、重试、质量分析。因此建议从一开始就做结构化建模。

6.1 核心对象

public enum AgentRole {    CREATIVE,    FINANCE,    EXECUTION,    RISK,    JUDGE}public enum TaskStatus {    PENDING,    RUNNING,    SUCCESS,    PARTIAL_SUCCESS,    FAILED,    TIMEOUT}
``````plaintext
import java.math.BigDecimal;import java.time.Instant;import java.util.List;import java.util.Map;public record PlanningRequest(        String requestId,        String tenantId,        String scene,        String customerName,        String requirement,        BigDecimal budgetUpperLimit,        Instant deadline,        List<String> constraints,        Map<String, Object> ext) {}
``````plaintext
import java.time.Instant;public record AgentTask(        String taskId,        String requestId,        AgentRole role,        String prompt,        Instant createdAt) {}
``````plaintext
import java.time.Instant;import java.util.Map;public record AgentResult(        String taskId,        AgentRole role,        boolean success,        String rawOutput,        Map<String, Object> structuredOutput,        String errorCode,        String errorMessage,        long latencyMs,        Instant finishedAt) {}
``````plaintext
import java.time.Instant;import java.util.List;public record PlanningResponse(        String requestId,        TaskStatus status,        String finalPlan,        List<AgentResult> agentResults,        long totalLatencyMs,        Instant finishedAt) {}

6.2 为什么必须结构化输出

结构化输出至少解决了四个现实问题:

  • • 方便整合器读取关键字段,而不是从自然语言里二次解析
  • • 方便前端分区展示不同 Agent 的贡献结果
  • • 方便离线做质量评估与 A/B 实验
  • • 方便对部分失败场景进行补偿重试

例如财务 Agent 不应该只返回一段“预算说明”,而应该输出:

  • • 总预算
  • • 固定成本
  • • 可变成本
  • • 风险预留金
  • • 成本超限项

7. 生产级代码实现

下面的实现目标不是“最短可运行”,而是“接近企业项目真实写法”。

7.1 Agent 抽象层

import java.time.Duration;import java.util.Map;public interface AgentExecutor {    AgentRole role();    Duration timeout();    AgentResult execute(PlanningRequest request, AgentTask task, Map<String, Object> sharedContext);}
``````plaintext
import org.springframework.ai.chat.messages.SystemMessage;import org.springframework.ai.chat.messages.UserMessage;import org.springframework.ai.chat.prompt.Prompt;import org.springframework.ai.chat.prompt.PromptTemplate;import org.springframework.ai.chat.model.ChatResponse;import org.springframework.ai.chat.client.ChatClient;import java.time.Duration;import java.time.Instant;import java.util.HashMap;import java.util.Map;public abstract class AbstractPlanningAgent implements AgentExecutor {    protected final ChatClient chatClient;    protected AbstractPlanningAgent(ChatClient chatClient) {        this.chatClient = chatClient;    }    protected abstract String systemPrompt();    protected abstract String userPromptTemplate();    protected abstract Map<String, Object> buildVariables(PlanningRequest request, Map<String, Object> sharedContext);    @Override    public AgentResult execute(PlanningRequest request, AgentTask task, Map<String, Object> sharedContext) {        Instant start = Instant.now();        try {            Map<String, Object> variables = new HashMap<>(buildVariables(request, sharedContext));            PromptTemplate template = new PromptTemplate(userPromptTemplate(), variables);            String renderedUserPrompt = template.render();            ChatResponse response = chatClient.prompt(                    new Prompt(                            new SystemMessage(systemPrompt()),                            new UserMessage(renderedUserPrompt)                    )            ).call().chatResponse();            String content = response.getResult().getOutput().getText();            Map<String, Object> structured = Map.of("content", content);            return new AgentResult(                    task.taskId(),                    role(),                    true,                    content,                    structured,                    null,                    null,                    Duration.between(start, Instant.now()).toMillis(),                    Instant.now()            );        } catch (Exception ex) {            return new AgentResult(                    task.taskId(),                    role(),                    false,                    null,                    Map.of(),                    "AGENT_EXECUTION_ERROR",                    ex.getMessage(),                    Duration.between(start, Instant.now()).toMillis(),                    Instant.now()            );        }    }}

7.2 专业智能体实现

创意 Agent
import org.springframework.ai.chat.client.ChatClient;import org.springframework.stereotype.Component;import java.time.Duration;import java.util.Map;@Componentpublic class CreativeAgent extends AbstractPlanningAgent {    public CreativeAgent(ChatClient chatClient) {        super(chatClient);    }    @Override    public AgentRole role() {        return AgentRole.CREATIVE;    }    @Override    public Duration timeout() {        return Duration.ofSeconds(12);    }    @Override    protected String systemPrompt() {        return """                你是一名资深创意策划总监。                你的职责是围绕业务目标输出可执行、可传播、具有记忆点的活动创意方案。                输出时必须兼顾品牌调性、目标受众、传播节奏与落地可行性。                不要讨论预算细节,不要越权做财务承诺。                """;    }    @Override    protected String userPromptTemplate() {        return """                请基于以下输入生成创意策划建议:                - 场景:{scene}                - 客户:{customerName}                - 需求:{requirement}                - 预算上限:{budgetUpperLimit}                - 约束:{constraints}                请输出:                1. 活动主题                2. 核心创意亮点                3. 用户参与机制                4. 传播建议                5. 对执行和预算可能产生影响的注意事项                """;    }    @Override    protected Map<String, Object> buildVariables(PlanningRequest request, Map<String, Object> sharedContext) {        return Map.of(                "scene", request.scene(),                "customerName", request.customerName(),                "requirement", request.requirement(),                "budgetUpperLimit", request.budgetUpperLimit(),                "constraints", request.constraints()        );    }}
财务 Agent
import org.springframework.ai.chat.client.ChatClient;import org.springframework.stereotype.Component;import java.time.Duration;import java.util.Map;@Componentpublic class FinanceAgent extends AbstractPlanningAgent {    public FinanceAgent(ChatClient chatClient) {        super(chatClient);    }    @Override    public AgentRole role() {        return AgentRole.FINANCE;    }    @Override    public Duration timeout() {        return Duration.ofSeconds(10);    }    @Override    protected String systemPrompt() {        return """                你是一名企业活动预算规划专家。                你的职责是输出成本结构、预算边界、风险预留和降本建议。                你的目标是保证方案可交付且成本可控。                不要发散讨论创意,不要输出空泛建议。                """;    }    @Override    protected String userPromptTemplate() {        return """                请基于以下输入生成预算方案:                - 需求:{requirement}                - 预算上限:{budgetUpperLimit}                - 约束:{constraints}                - 创意摘要:{creativeSummary}                请输出:                1. 预算分项表                2. 高风险成本项                3. 成本压缩建议                4. 推荐预算区间                5. 是否存在超预算风险                """;    }    @Override    protected Map<String, Object> buildVariables(PlanningRequest request, Map<String, Object> sharedContext) {        return Map.of(                "requirement", request.requirement(),                "budgetUpperLimit", request.budgetUpperLimit(),                "constraints", request.constraints(),                "creativeSummary", sharedContext.getOrDefault("creativeSummary", "暂无")        );    }}
执行 Agent
import org.springframework.ai.chat.client.ChatClient;import org.springframework.stereotype.Component;import java.time.Duration;import java.util.Map;@Componentpublic class ExecutionAgent extends AbstractPlanningAgent {    public ExecutionAgent(ChatClient chatClient) {        super(chatClient);    }    @Override    public AgentRole role() {        return AgentRole.EXECUTION;    }    @Override    public Duration timeout() {        return Duration.ofSeconds(10);    }    @Override    protected String systemPrompt() {        return """                你是一名大型活动执行负责人。                请从时间排期、人员分工、供应商协同、现场流程、应急预案等角度输出执行方案。                输出必须强调落地性和可操作性。                """;    }    @Override    protected String userPromptTemplate() {        return """                请为以下活动需求输出执行方案:                - 场景:{scene}                - 需求:{requirement}                - 截止时间:{deadline}                - 创意摘要:{creativeSummary}                - 约束:{constraints}                请输出:                1. 里程碑排期                2. 人员与角色配置                3. 供应商协作建议                4. 执行风险点                5. 应急处置方案                """;    }    @Override    protected Map<String, Object> buildVariables(PlanningRequest request, Map<String, Object> sharedContext) {        return Map.of(                "scene", request.scene(),                "requirement", request.requirement(),                "deadline", request.deadline(),                "creativeSummary", sharedContext.getOrDefault("creativeSummary", "暂无"),                "constraints", request.constraints()        );    }}

7.3 编排器实现:高并发与容错核心

真正的关键不在 Agent,而在编排器。

下面给出一个生产导向的 AgentOrchestrator 示例,实现了:

  • • 并发执行
  • • 单 Agent 超时控制
  • • 失败隔离
  • • 部分成功返回
  • • 共享上下文注入
import org.springframework.stereotype.Service;import java.time.Instant;import java.util.ArrayList;import java.util.EnumMap;import java.util.List;import java.util.Map;import java.util.UUID;import java.util.concurrent.CompletableFuture;import java.util.concurrent.Executor;import java.util.concurrent.TimeUnit;import java.util.stream.Collectors;@Servicepublic class AgentOrchestrator {    private final Map<AgentRole, AgentExecutor> agentRegistry;    private final Executor agentExecutorPool;    private final ResultIntegrator resultIntegrator;    public AgentOrchestrator(List<AgentExecutor> executors,                             Executor agentExecutorPool,                             ResultIntegrator resultIntegrator) {        this.agentRegistry = executors.stream()                .collect(Collectors.toMap(AgentExecutor::role, it -> it, (a, b) -> a, () -> new EnumMap<>(AgentRole.class)));        this.agentExecutorPool = agentExecutorPool;        this.resultIntegrator = resultIntegrator;    }    public PlanningResponse plan(PlanningRequest request) {        Instant start = Instant.now();        Map<String, Object> sharedContext = new java.util.concurrent.ConcurrentHashMap<>();        List<AgentRole> roles = List.of(AgentRole.CREATIVE, AgentRole.FINANCE, AgentRole.EXECUTION, AgentRole.RISK);        List<CompletableFuture<AgentResult>> futures = new ArrayList<>();        for (AgentRole role : roles) {            AgentExecutor executor = agentRegistry.get(role);            AgentTask task = new AgentTask(                    UUID.randomUUID().toString(),                    request.requestId(),                    role,                    "generated-by-orchestrator",                    Instant.now()            );            CompletableFuture<AgentResult> future = CompletableFuture                    .supplyAsync(() -> executor.execute(request, task, sharedContext), agentExecutorPool)                    .orTimeout(executor.timeout().toMillis(), TimeUnit.MILLISECONDS)                    .exceptionally(ex -> new AgentResult(                            task.taskId(),                            role,                            false,                            null,                            Map.of(),                            "TIMEOUT_OR_FAILURE",                            ex.getMessage(),                            executor.timeout().toMillis(),                            Instant.now()                    ));            future = future.thenApply(result -> {                if (result.success() && role == AgentRole.CREATIVE) {                    sharedContext.put("creativeSummary", result.rawOutput());                }                return result;            });            futures.add(future);        }        List<AgentResult> results = futures.stream().map(CompletableFuture::join).toList();        String finalPlan = resultIntegrator.integrate(request, results);        boolean allSuccess = results.stream().allMatch(AgentResult::success);        boolean anySuccess = results.stream().anyMatch(AgentResult::success);        TaskStatus status = allSuccess ? TaskStatus.SUCCESS :                anySuccess ? TaskStatus.PARTIAL_SUCCESS : TaskStatus.FAILED;        return new PlanningResponse(                request.requestId(),                status,                finalPlan,                results,                java.time.Duration.between(start, Instant.now()).toMillis(),                Instant.now()        );    }}

7.4 结果整合器:从“拼接文本”升级到“冲突消解”

很多文章里的“整合器”只是把多个结果拼在一起,再扔给模型重新总结。这种做法的问题是:

  • • 无法识别预算与创意冲突
  • • 无法识别执行不可落地
  • • 无法识别高风险项是否已被覆盖

生产级整合器应该至少做到两层处理:

第一层:规则整合
  • • 预算是否超过上限
  • • 执行排期是否晚于 deadline
  • • 是否存在被标记的高风险项
第二层:模型整合
  • • 在规则约束下形成完整方案
  • • 显式输出“冲突项与决策理由”
import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.chat.messages.SystemMessage;import org.springframework.ai.chat.messages.UserMessage;import org.springframework.ai.chat.prompt.Prompt;import org.springframework.stereotype.Component;import java.util.List;import java.util.stream.Collectors;@Componentpublic class ResultIntegrator {    private final ChatClient chatClient;    public ResultIntegrator(ChatClient chatClient) {        this.chatClient = chatClient;    }    public String integrate(PlanningRequest request, List<AgentResult> results) {        String agentOutputs = results.stream()                .map(it -> "## " + it.role() + "\n"                        + "success=" + it.success() + "\n"                        + "latencyMs=" + it.latencyMs() + "\n"                        + "content=" + (it.rawOutput() == null ? "N/A" : it.rawOutput()))                .collect(Collectors.joining("\n\n"));        String prompt = """                你是一名资深方案总监,请将多角色智能体结果整合为一份正式交付方案。                整合原则:                1. 优先保证可执行性和预算可控                2. 如果创意与预算冲突,保留创意方向并给出降配方案                3. 如果执行与时间冲突,必须显式指出并调整排期                4. 输出需包含:背景目标、总体方案、预算建议、执行计划、风险控制、结论                原始需求:                %s                各角色输出:                %s                """.formatted(request.requirement(), agentOutputs);        return chatClient.prompt(                new Prompt(                        new SystemMessage("你是一名严谨的企业方案整合专家。"),                        new UserMessage(prompt)                )        ).call().content();    }}

7.5 风险 Agent 示例

import org.springframework.ai.chat.client.ChatClient;import org.springframework.stereotype.Component;import java.time.Duration;import java.util.Map;@Componentpublic class RiskAgent extends AbstractPlanningAgent {    public RiskAgent(ChatClient chatClient) {        super(chatClient);    }    @Override    public AgentRole role() {        return AgentRole.RISK;    }    @Override    public Duration timeout() {        return Duration.ofSeconds(8);    }    @Override    protected String systemPrompt() {        return """                你是一名企业级风控顾问。                请识别活动在合规、舆情、供应链、执行安全上的风险,并给出优先级排序和缓解措施。                """;    }    @Override    protected String userPromptTemplate() {        return """                请基于以下信息输出风险评估:                - 场景:{scene}                - 需求:{requirement}                - 约束:{constraints}                请输出:                1. Top5 风险项                2. 风险等级                3. 触发条件                4. 缓解措施                5. 必须人工复核的部分                """;    }    @Override    protected Map<String, Object> buildVariables(PlanningRequest request, Map<String, Object> sharedContext) {        return Map.of(                "scene", request.scene(),                "requirement", request.requirement(),                "constraints", request.constraints()        );    }}

7.6 控制器与接口设计

import jakarta.validation.Valid;import jakarta.validation.constraints.NotBlank;import jakarta.validation.constraints.NotNull;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestHeader;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.math.BigDecimal;import java.time.Instant;import java.util.List;import java.util.Map;import java.util.UUID;@RestController@RequestMapping("/api/planning")public class PlanningController {    private final AgentOrchestrator orchestrator;    public PlanningController(AgentOrchestrator orchestrator) {        this.orchestrator = orchestrator;    }    @PostMapping("/generate")    public ResponseEntity<PlanningResponse> generate(            @RequestHeader(value = "X-Request-Id", required = false) String requestId,            @Valid @RequestBody CreatePlanningCommand command) {        PlanningRequest request = new PlanningRequest(                requestId == null ? UUID.randomUUID().toString() : requestId,                command.tenantId(),                command.scene(),                command.customerName(),                command.requirement(),                command.budgetUpperLimit(),                command.deadline(),                command.constraints(),                Map.of()        );        return ResponseEntity.ok(orchestrator.plan(request));    }    public record CreatePlanningCommand(            @NotBlank String tenantId,            @NotBlank String scene,            @NotBlank String customerName,            @NotBlank String requirement,            @NotNull BigDecimal budgetUpperLimit,            @NotNull Instant deadline,            List<String> constraints    ) {    }}

8. 高并发设计与工程化升级

8.1 并发瓶颈真正在哪里

多智能体系统的瓶颈不只是 CPU,而主要集中在:

  • • 模型调用时延
  • • 外部 API QPS 限制
  • • 上下文组装和序列化开销
  • • 线程池排队
  • • 网络 IO
  • • 结果整合阶段的二次推理

因此,优化方向不能只盯着“线程开大一点”,而应该从系统视角治理整条链路。

8.2 线程池隔离

不要让所有 Agent 共用一个无边界线程池。建议至少做到:

  • • 编排线程池与业务 Web 线程池分离
  • • 高成本 Agent 与低成本 Agent 分池隔离
  • • 为线程池设置有界队列与拒绝策略
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.Executor;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;@Configurationpublic class ExecutorConfig {    @Bean    public Executor agentExecutorPool() {        return new ThreadPoolExecutor(                16,                32,                60,                TimeUnit.SECONDS,                new LinkedBlockingQueue<>(500),                new ThreadPoolExecutor.CallerRunsPolicy()        );    }}

8.3 限流、熔断与重试

生产环境中,最常见的问题不是“代码写错”,而是模型服务不稳定、响应抖动、下游限流。

建议在每个 Agent 调用外层加 Resilience4j:

  • TimeLimiter:限制单次调用时长
  • CircuitBreaker:下游异常率升高时快速失败
  • Bulkhead:限制并发占用
  • Retry:仅对幂等请求做小次数重试

原则上:

  • • 超时优先于重试
  • • 重试次数不宜超过 1 到 2 次
  • • 对长文本推理不应盲目重试

8.4 缓存与幂等

对于方案策划类任务,缓存不能简单基于原始文本,需要考虑:

  • • 租户维度
  • • 场景维度
  • • Prompt 版本
  • • 模型版本
  • • 关键约束是否一致

推荐缓存 Key:

planning:{tenantId}:{scene}:{modelVersion}:{promptVersion}:{requestHash}

幂等建议:

  • • 前端或调用方传入 X-Request-Id
  • • 服务端先查幂等表
  • • 已处理则直接返回历史结果
  • • 处理中则返回“任务进行中”

8.5 异步化与削峰填谷

当请求量提升后,不建议所有请求都同步等待完整方案。

推荐两种模式并存:

同步模式

适用于:

  • • 轻量级方案生成
  • • 内部工具台
  • • 交互式操作
异步模式

适用于:

  • • 大型复杂方案
  • • 峰值流量场景
  • • 批量任务

异步模式流程:

  1. API 接收请求并落库
  2. 投递 MQ
  3. Worker 消费任务并执行 Orchestrator
  4. 结果回写数据库
  5. 通过回调、WebSocket 或轮询获取结果

9. 分布式扩展设计

9.1 从单体到分布式的演进路线

阶段 架构形态 适用阶段 重点问题
阶段一 单体内嵌多 Agent 验证期 快速交付
阶段二 编排与 Agent 逻辑分模块 成长期 代码可维护
阶段三 部分 Agent 独立服务化 峰值增长期 弹性与资源隔离
阶段四 完整分布式编排 企业规模化 治理、审计、成本

9.2 什么情况下需要把 Agent 拆成独立服务

以下场景适合拆服务:

  • • 某个 Agent 调用频率远高于其他 Agent
  • • 某个 Agent 依赖专用知识库或工具链
  • • 某个 Agent 需要独立扩缩容
  • • 不同团队分别负责不同 Agent

但不要过早拆分。对于大多数团队,第一阶段先保持单体编排、模块隔离,是性价比最高的路线。

9.3 分布式编排关注点

真正进入分布式后,要重点解决以下问题:

  • • 任务唯一性:避免同一请求被重复消费
  • • 分布式锁:避免同一任务多次执行
  • • 状态一致性:部分 Agent 成功、部分失败时如何标记
  • • 补偿机制:失败后如何重试或人工介入
  • • Trace 透传:跨服务链路如何完整可见

9.4 状态机设计建议

建议对方案任务定义清晰状态机:

INIT -> DISPATCHED -> RUNNING -> PARTIAL_SUCCESS / SUCCESS / FAILED -> ARCHIVED

每个 Agent 子任务也要有独立状态:

PENDING -> RUNNING -> SUCCESS / FAILED / TIMEOUT

这样才能支持:

  • • 部分重跑
  • • 失败回放
  • • SLA 统计
  • • 运营分析

10. 可观测性与生产治理

10.1 指标体系

多智能体系统至少要监控以下指标:

  • • 请求总量
  • • 方案成功率
  • • 部分成功率
  • • 平均响应时间 / P95 / P99
  • • 各 Agent 成功率与耗时
  • • 模型 Token 消耗
  • • 重试次数
  • • 超时次数
  • • 缓存命中率
  • • 单租户调用量与成本

10.2 Micrometer 埋点示例

import io.micrometer.core.instrument.Counter;import io.micrometer.core.instrument.MeterRegistry;import io.micrometer.core.instrument.Timer;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic class AgentMetrics {    private final MeterRegistry registry;    public AgentMetrics(MeterRegistry registry) {        this.registry = registry;    }    public void recordSuccess(AgentRole role, long latencyMs) {        Timer.builder("agent.execution.latency")                .tag("role", role.name())                .register(registry)                .record(latencyMs, TimeUnit.MILLISECONDS);        Counter.builder("agent.execution.success")                .tag("role", role.name())                .register(registry)                .increment();    }    public void recordFailure(AgentRole role, String errorCode) {        Counter.builder("agent.execution.failure")                .tag("role", role.name())                .tag("errorCode", errorCode == null ? "UNKNOWN" : errorCode)                .register(registry)                .increment();    }}

10.3 链路追踪

建议把以下字段贯穿全链路:

  • requestId
  • tenantId
  • scene
  • agentRole
  • taskId
  • modelName

这样在问题排查时,能够快速回答:

  • • 哪个租户的问题最多
  • • 哪个 Agent 最慢
  • • 哪个模型版本波动最大
  • • 哪个场景最容易失败

10.4 审计与回放

企业场景常常要求“为什么生成这份方案”。因此必须保留以下审计信息:

  • • 原始请求
  • • Prompt 版本
  • • 模型版本
  • • 各 Agent 输出
  • • 整合结果
  • • 时间戳
  • • 操作人或调用方

这样才能支持:

  • • 合规审计
  • • 线上问题回放
  • • 质量复盘
  • • Prompt 升级效果对比

11. 实战案例:大型新品发布会方案生成

下面给出一个更贴近真实业务的案例。

11.1 输入需求

{  "tenantId": "brand-a",  "scene": "新品发布会",  "customerName": "某消费电子品牌",  "requirement": "为新品耳机设计一场 500 人规模的线下发布会,希望突出年轻化、科技感和社交传播效果。",  "budgetUpperLimit": 800000,  "deadline": "2026-05-20T18:00:00Z",  "constraints": [    "场地必须在上海市区",    "活动周期不能超过 1 天",    "必须预留媒体采访区",    "需要兼顾短视频传播"  ]}

11.2 多 Agent 输出分工

创意 Agent 输出重点
  • • 发布会主题建议
  • • 舞台科技感表达方式
  • • 互动玩法设计
  • • 社交传播钩子
财务 Agent 输出重点
  • • 场地、搭建、设备、传播、嘉宾、物料等成本拆分
  • • 超预算风险识别
  • • 降本方案
执行 Agent 输出重点
  • • 倒排计划
  • • 搭建及彩排节点
  • • 现场岗位分工
  • • 应急预案
风险 Agent 输出重点
  • • 舆情风险
  • • 安全风险
  • • 嘉宾临时变更风险
  • • 供应商交付风险

11.3 最终整合结果应该具备什么特征

一份生产可用的结果不应该只是“文案漂亮”,而应该满足:

  • • 创意与预算匹配
  • • 时间排期可执行
  • • 风险项被显式覆盖
  • • 交付格式适合直接给客户或内部评审

也就是说,多智能体系统的目标不是“生成更多内容”,而是“生成更能被业务消费的内容”。


12. 部署方案

12.1 Dockerfile

FROM eclipse-temurin:17-jreWORKDIR /appCOPY target/planning-service.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]

12.2 Kubernetes Deployment

apiVersion: apps/v1kind: Deploymentmetadata:  name: planning-servicespec:  replicas: 3  selector:    matchLabels:      app: planning-service  template:    metadata:      labels:        app: planning-service    spec:      containers:        - name: planning-service          image: planning-service:1.0.0          ports:            - containerPort: 8080          env:            - name: SPRING_PROFILES_ACTIVE              value: prod            - name: SPRING_AI_ALIBABA_QWEN_API_KEY              valueFrom:                secretKeyRef:                  name: llm-secret                  key: api-key          resources:            requests:              cpu: "500m"              memory: "1Gi"            limits:              cpu: "2"              memory: "4Gi"          readinessProbe:            httpGet:              path: /actuator/health/readiness              port: 8080          livenessProbe:            httpGet:              path: /actuator/health/liveness              port: 8080

12.3 横向扩缩容建议

扩容策略不建议只看 CPU,建议综合以下信号:

  • • 接口 QPS
  • • MQ backlog
  • • Agent 平均耗时
  • • 模型下游限流情况

如果仅根据 CPU 扩容,常常会出现“应用实例扩了,但模型服务仍然是瓶颈”的假象。


13. 测试策略

13.1 单元测试

关注:

  • • Prompt 变量是否渲染正确
  • • Agent 是否按角色职责输出
  • • 规则整合是否生效

13.2 集成测试

关注:

  • • Orchestrator 并发执行结果是否正确
  • • 单 Agent 超时是否会被隔离
  • • 部分失败时是否仍能返回结果

13.3 压测建议

重点压测以下维度:

  • • 10 / 50 / 100 并发下响应时间变化
  • • 不同 Agent 数量下线程池压力
  • • 缓存开启与关闭的差异
  • • 模型接口故障注入后的失败率

13.4 混沌测试

建议在预发布环境模拟:

  • • 单个 Agent 长时间超时
  • • Redis 短暂不可用
  • • 模型服务返回 429
  • • MQ 消费重复投递

只有经历过这些测试,系统才真的接近生产可用。


14. 常见生产问题与解决思路

14.1 输出质量波动

原因:

  • • Prompt 不稳定
  • • 上下文污染
  • • 模型版本切换

解决建议:

  • • 引入 Prompt 版本管理
  • • 使用结构化输出
  • • 建立离线评测集

14.2 成本过高

原因:

  • • 不必要的多 Agent 并发
  • • 重复请求未缓存
  • • 模型选择过重

解决建议:

  • • 按场景动态裁剪 Agent
  • • 引入缓存和结果复用
  • • 轻重模型分层

14.3 峰值时延过高

原因:

  • • 编排线程池拥塞
  • • 下游模型抖动
  • • 整合器二次推理过慢

解决建议:

  • • 分级线程池
  • • 异步模式削峰
  • • 对整合器进行规则前置裁剪

14.4 部分失败导致用户体验差

解决建议:

  • • 支持 PARTIAL_SUCCESS
  • • 前端展示缺失模块和补算状态
  • • 后台异步补偿生成完整版

15. 演进建议:从“多智能体调用”走向“智能体平台”

当业务继续增长,多智能体系统会从“一个应用功能”演进为“一个平台能力”。届时可以继续建设:

  • • Agent 注册中心:统一管理角色、能力、Prompt、版本
  • • Prompt 配置中心:支持灰度发布和回滚
  • • 评测平台:统一做质量评测、回归测试、人工标注
  • • 工具调用平台:统一封装搜索、知识库、预算规则、流程审批接口
  • • 智能路由:根据场景、租户、成本策略自动选择模型与 Agent 组合

这一步很关键,因为企业最终需要的不是某一篇文章里的 Demo,而是一套可复制、可演进、可规模化复用的 AI 工程体系。


16. 总结

多智能体系统真正的难点,从来不只是“如何并行调用多个模型”,而是如何把不确定的 AI 能力放进确定性的工程框架中。

从实践经验看,一个生产可用的多智能体方案策划系统至少要回答清楚以下问题:

  • • 如何拆任务,避免角色混叠
  • • 如何编排执行,兼顾并发与稳定性
  • • 如何做超时、重试、熔断、降级
  • • 如何保证结果可整合、可审计、可回放
  • • 如何在高并发下保持成本和时延可控

Spring AI Alibaba 为我们提供了良好的模型接入与应用开发基础,但真正决定系统上限的,仍然是架构设计、工程治理和生产经验。

如果把本文浓缩成一句话,那就是:

多智能体不是“多调用几个大模型”,而是“把复杂业务流程重构为一套可治理的 AI 协同系统”。

这也是多智能体在企业场景中真正有价值的地方。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

在这里插入图片描述

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐