二:Multi-Agent 协作架构与 MCP 协议实战:Java 企业级 AI 智能体进阶指南

MCP协议实战指南:多智能体协同通信与工程落地 AI Agent已从单体调用迈入多智能体协同阶段,其核心挑战在于跨Agent的可靠通信、状态对齐与故障协同。MCP协议(Multi-agent Coordination Protocol)作为工业界事实标准,通过意图层、执行层、共识层的语义分层设计,解决了‘说什么、怎么说、说给谁、没收到怎么办’等关键问题。它以轻量JSON契约实现跨语言、跨框架兼容,支持强校验、意图锚定、累积超时与ACK驱动的协作流,显著提升多Agent系统的可观测性、可维护性与弹性容错能力。本文聚焦MCP v1.3字段级语义、Spring 阅读详情

Multi-Agent 协作架构与 MCP 协议实战:Java 企业级 AI 智能体进阶指南

前言

上一篇文章中,我们用 LangChain4j 构建了一个具备工具调用、RAG 和记忆能力的单体 Agent。但在真实的企业场景中,一个 Agent 很难包揽所有事情——就像一家公司不可能只有一个"全能员工"。你需要一个 数据分析 Agent、一个 报告撰写 Agent、一个 运维调度 Agent……它们各司其职,又能协同工作。

与此同时,2026 年 AI 领域最大的标准化事件之一——MCP(Model Context Protocol)协议 的成熟,正在重塑 Agent 与外部工具的集成方式。

本文将从架构设计到代码落地,深入讲解这两项关键技术。


一、为什么需要 Multi-Agent?

1.1 单体 Agent 的三大瓶颈

在开始 Multi-Agent 之前,我们先理解:单体 Agent 到底哪里不够用?

瓶颈一:上下文窗口被"撑爆"

一个全能 Agent 需要挂载大量工具——查询能耗的工具、生成报告的工具、发送通知的工具、调用审批流的工具……每注册一个工具,它的 JSON Schema 描述就会占用数百个 Token。当工具数超过 15~20 个时,光是工具描述就可能占据上万 Token,严重挤压实际对话的上下文空间。

瓶颈二:System Prompt 变得臃肿

工具的调用规范、业务流程的规则、安全约束——所有这些都要写进 System Prompt。当一个 Agent 承担了太多职责,Prompt 会长到几千字,模型的注意力被稀释,指令遵循的准确率显著下降。

瓶颈三:职责耦合导致维护困难

所有逻辑塞在一个 Agent 里,修改一个功能可能影响其他功能。测试也变得困难——你无法单独验证"数据分析能力"是否正常,因为它的 Prompt 里混杂着十几个不同领域的指令。

1.2 Multi-Agent 的核心思想:分而治之

Multi-Agent 的架构思想非常朴素:让每个 Agent 只做一件事,做到极致,然后让它们协作。

这本质上与软件工程中的 单一职责原则(SRP) 一脉相承。我们不是造一个"超级大脑",而是组建一个"专家团队":

┌──────────────────────────────────────────────────────┐
│                 Orchestrator Agent                    │
│              (调度中心 / 指挥官)                      │
│                                                      │
│   "理解用户意图,拆解任务,分派给合适的专家Agent"       │
└──────┬──────────────┬──────────────┬─────────────────┘
       │              │              │
  ┌────▼────┐   ┌─────▼─────┐  ┌────▼────┐
  │ 数据    │   │  报告     │  │  运维   │
  │ 分析    │   │  生成     │  │  调度   │
  │ Agent   │   │  Agent    │  │  Agent  │
  └─────────┘   └───────────┘  └─────────┘

每个"专家 Agent"有自己独立的:

  • 精简的 System Prompt:只描述该领域的职责和规则
  • 专用的工具集:只挂载该领域需要的 3~5 个工具
  • 独立的记忆空间:不与其他 Agent 的上下文混淆

1.3 Multi-Agent 的三种协作模式

在架构设计中,Multi-Agent 的协作模式主要有三种,各有优劣:

模式一:中心化调度(Orchestrator Pattern)

一个"调度 Agent"作为中枢,理解用户意图后决定调用哪个专家 Agent。

用户 ──→ Orchestrator ──→ 数据分析Agent ──→ 结果
                │
                └───────→ 报告生成Agent ──→ 结果
                │
                └───────→ 运维调度Agent ──→ 结果
  • 优点:控制流清晰,调度逻辑集中,易于调试。
  • 缺点:调度 Agent 成为瓶颈和单点故障。
  • 适用场景:大多数企业应用,任务流程相对固定。

模式二:流水线(Pipeline Pattern)

多个 Agent 按固定顺序依次处理,前一个的输出是后一个的输入。

用户 ──→ 数据采集Agent ──→ 数据分析Agent ──→ 报告生成Agent ──→ 最终报告
  • 优点:每个阶段可独立优化和替换。
  • 缺点:灵活性低,不支持条件分支。
  • 适用场景:ETL 数据处理、定时报告生成等流程固定的场景。

模式三:协商式(Debate Pattern)

多个 Agent 对同一问题各自给出方案,然后通过"讨论"达成共识。

  • 优点:适合需要多视角判断的复杂决策。
  • 缺点:Token 消耗大,延迟高。
  • 适用场景:风险评估、投资决策等高价值决策场景。

本文重点实现模式一(中心化调度),因为它在企业项目中最实用、落地成本最低。


二、用 LangGraph4j 实现 Multi-Agent 编排

2.1 什么是 LangGraph4j?

LangGraph4j 是 LangChain4j 生态中的 图状态机 框架,专门用于编排多 Agent 的协作流程。它的核心抽象非常简洁:

  • Node(节点):一个执行单元,可以是一个 Agent、一个工具调用、或一段业务逻辑。
  • Edge(边):定义节点之间的流转关系,支持条件分支。
  • State(状态):在节点间流转的共享数据。

用一个类比来理解:如果单体 Agent 是一个"函数",那 LangGraph4j 编排的就是一个"状态机"——多个函数按照条件逻辑组合执行。

2.2 Maven 依赖

<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-core</artifactId>
    <version>1.5.0</version>
</dependency>

<!-- 如果需要可视化调试 -->
<dependency>
    <groupId>org.bsc.langgraph4j</groupId>
    <artifactId>langgraph4j-studio</artifactId>
    <version>1.5.0</version>
</dependency>

2.3 定义共享状态

首先定义在 Agent 之间流转的共享状态对象。它就像一个"公文包",每个 Agent 处理完后往里面放入自己的结果:

import org.bsc.langgraph4j.state.AgentState;
import java.util.Map;

/**
 * Multi-Agent 共享状态
 * 
 * 设计原则:
 * - 每个 Agent 只读取自己需要的字段、写入自己产出的字段
 * - 状态是不可变追加的:通过 Map.copyOf 确保线程安全
 * - 使用 Optional 防御空值
 */
public class EnergyWorkflowState extends AgentState {

    public EnergyWorkflowState(Map<String, Object> initData) {
        super(initData);
    }

    // ========== 输入 ==========

    /** 用户原始提问 */
    public String userQuery() {
        return (String) value("userQuery").orElse("");
    }

    // ========== 各 Agent 的产出 ==========

    /** 数据分析 Agent 的分析结果 */
    public String analysisResult() {
        return (String) value("analysisResult").orElse("");
    }

    /** 报告生成 Agent 的报告内容 */
    public String reportContent() {
        return (String) value("reportContent").orElse("");
    }

    /** 运维调度 Agent 的执行结果 */
    public String operationResult() {
        return (String) value("operationResult").orElse("");
    }

    /** 最终汇总回复 */
    public String finalResponse() {
        return (String) value("finalResponse").orElse("");
    }

    /** 路由决策:Orchestrator 判断需要走哪条路径 */
    public String routeDecision() {
        return (String) value("routeDecision").orElse("unknown");
    }
}

2.4 实现各专家 Agent 节点

每个节点是一个函数:接收当前状态,返回更新后的状态。

import org.bsc.langgraph4j.action.NodeAction;
import java.util.Map;

/**
 * 数据分析 Agent 节点
 * 
 * 职责:接收用户的数据查询需求,调用能耗查询工具,返回结构化分析
 */
public class DataAnalysisNode implements NodeAction<EnergyWorkflowState> {

    private final EnergyDataAgent dataAgent;  // 上一篇文章中构建的专用 Agent

    public DataAnalysisNode(EnergyDataAgent dataAgent) {
        this.dataAgent = dataAgent;
    }

    @Override
    public Map<String, Object> apply(EnergyWorkflowState state) throws Exception {
        // 构建包含上下文的任务描述
        String taskPrompt = String.format("""
            请分析以下能耗数据查询需求,给出详细的数据分析结果:
            
            用户需求:%s
            """, state.userQuery());

        String result = dataAgent.chat(taskPrompt);

        // 将分析结果写入共享状态
        return Map.of("analysisResult", result);
    }
}

/**
 * 报告生成 Agent 节点
 * 
 * 职责:基于数据分析结果,生成专业的能耗分析报告
 */
public class ReportGenerationNode implements NodeAction<EnergyWorkflowState> {

    private final ReportAgent reportAgent;

    public ReportGenerationNode(ReportAgent reportAgent) {
        this.reportAgent = reportAgent;
    }

    @Override
    public Map<String, Object> apply(EnergyWorkflowState state) throws Exception {
        String taskPrompt = String.format("""
            请基于以下数据分析结果,生成一份专业的能耗分析报告:
            
            原始需求:%s
            数据分析结果:%s
            """, state.userQuery(), state.analysisResult());

        String report = reportAgent.chat(taskPrompt);

        return Map.of("reportContent", report);
    }
}

/**
 * 运维调度 Agent 节点
 * 
 * 职责:执行具体的运维操作(发送通知、调整参数、触发工单等)
 */
public class OperationNode implements NodeAction<EnergyWorkflowState> {

    private final OperationAgent operationAgent;

    public OperationNode(OperationAgent operationAgent) {
        this.operationAgent = operationAgent;
    }

    @Override
    public Map<String, Object> apply(EnergyWorkflowState state) throws Exception {
        String taskPrompt = String.format("""
            请根据以下情况执行相应的运维操作:
            
            原始需求:%s
            数据分析结果:%s
            """, state.userQuery(), state.analysisResult());

        String result = operationAgent.chat(taskPrompt);

        return Map.of("operationResult", result);
    }
}

2.5 实现 Orchestrator:智能路由

Orchestrator 是整个 Multi-Agent 系统的"大脑"。它的职责是:理解用户意图,决定调用哪些专家 Agent、以什么顺序调用。

/**
 * Orchestrator 节点:意图识别与路由决策
 * 
 * 工作原理:
 * 1. 将用户问题发送给一个轻量级 LLM
 * 2. LLM 返回路由标签:ANALYSIS / REPORT / OPERATION / COMPOSITE
 * 3. 条件边(Conditional Edge)根据标签决定下一步走哪个节点
 */
public class OrchestratorNode implements NodeAction<EnergyWorkflowState> {

    private final ChatLanguageModel routerModel;

    public OrchestratorNode(ChatLanguageModel routerModel) {
        this.routerModel = routerModel;
    }

    @Override
    public Map<String, Object> apply(EnergyWorkflowState state) throws Exception {
        String routePrompt = String.format("""
            你是一个任务路由器。根据用户的问题,判断应该走哪条处理路径。
            
            可选路径:
            - ANALYSIS:纯粹的数据查询和分析(如"A栋今天用了多少电")
            - REPORT:需要生成报告或文档(如"生成本月能耗报告")
            - OPERATION:需要执行运维操作(如"通知张工检修B栋设备")
            - COMPOSITE:需要先分析,再根据结果决定是否生成报告或执行操作
            
            只返回路径标签,不要返回其他内容。
            
            用户问题:%s
            """, state.userQuery());

        AiMessage response = routerModel.generate(
            UserMessage.from(routePrompt)
        ).content();

        String decision = response.text().trim().toUpperCase();

        // 防御性校验:如果 LLM 返回了意外内容,降级为 COMPOSITE
        if (!Set.of("ANALYSIS", "REPORT", "OPERATION", "COMPOSITE").contains(decision)) {
            decision = "COMPOSITE";
        }

        return Map.of("routeDecision", decision);
    }
}

2.6 组装状态图:定义完整的协作流程

这是最核心的部分——用状态图定义节点和边的关系:

import org.bsc.langgraph4j.GraphStateException;
import org.bsc.langgraph4j.StateGraph;
import static org.bsc.langgraph4j.StateGraph.END;
import static org.bsc.langgraph4j.StateGraph.START;

/**
 * 构建 Multi-Agent 协作状态图
 * 
 * 图的拓扑结构:
 * 
 * START ──→ Orchestrator ──┬──(ANALYSIS)──→ DataAnalysis ──→ END
 *                          │
 *                          ├──(REPORT)────→ DataAnalysis ──→ ReportGen ──→ END
 *                          │
 *                          ├──(OPERATION)──→ Operation ──→ END
 *                          │
 *                          └──(COMPOSITE)──→ DataAnalysis ──→ ReportGen ──→ Operation ──→ END
 */
public class EnergyWorkflowBuilder {

    public StateGraph<EnergyWorkflowState> build(
            OrchestratorNode orchestrator,
            DataAnalysisNode dataAnalysis,
            ReportGenerationNode reportGen,
            OperationNode operation) throws GraphStateException {

        return new StateGraph<>(EnergyWorkflowState::new)
            // ===== 注册节点 =====
            .addNode("orchestrator", orchestrator)
            .addNode("data_analysis", dataAnalysis)
            .addNode("report_generation", reportGen)
            .addNode("operation", operation)

            // ===== 定义边 =====

            // 入口:START → Orchestrator
            .addEdge(START, "orchestrator")

            // 条件分支:Orchestrator 的决策决定下一步走向
            .addConditionalEdges("orchestrator",
                state -> state.routeDecision(),
                Map.of(
                    "ANALYSIS",  "data_analysis",
                    "REPORT",    "data_analysis",      // 报告也需要先做数据分析
                    "OPERATION", "operation",
                    "COMPOSITE", "data_analysis"        // 复合路径先走数据分析
                )
            )

            // 纯分析路径:DataAnalysis → END
            // 注意:这里通过状态判断来决定是否继续
            .addConditionalEdges("data_analysis",
                state -> {
                    // 如果路由决策是 ANALYSIS,直接结束
                    // 如果是 REPORT 或 COMPOSITE,继续走报告生成
                    return switch (state.routeDecision()) {
                        case "ANALYSIS" -> "end";
                        default -> "report_generation";
                    };
                },
                Map.of(
                    "end", END,
                    "report_generation", "report_generation"
                )
            )

            // 报告生成后的分支
            .addConditionalEdges("report_generation",
                state -> {
                    // COMPOSITE 路径还需要执行运维操作
                    return "COMPOSITE".equals(state.routeDecision())
                        ? "operation" : "end";
                },
                Map.of(
                    "operation", "operation",
                    "end", END
                )
            )

            // 运维操作完成后结束
            .addEdge("operation", END);
    }
}

2.7 Spring Boot 配置与运行

@Configuration
public class MultiAgentConfig {

    @Bean
    public StateGraph<EnergyWorkflowState> energyWorkflow(
            OrchestratorNode orchestrator,
            DataAnalysisNode dataAnalysis,
            ReportGenerationNode reportGen,
            OperationNode operation) throws GraphStateException {

        return new EnergyWorkflowBuilder()
            .build(orchestrator, dataAnalysis, reportGen, operation);
    }

    @Bean
    public CompiledGraph<EnergyWorkflowState> compiledWorkflow(
            StateGraph<EnergyWorkflowState> workflow) throws GraphStateException {
        return workflow.compile();
    }
}

@Service
public class MultiAgentService {

    @Autowired
    private CompiledGraph<EnergyWorkflowState> workflow;

    /**
     * 执行 Multi-Agent 协作流程
     * 
     * @param userQuery 用户问题
     * @return 各阶段的执行结果(用于调试和展示)
     */
    public Map<String, Object> execute(String userQuery) {
        // 初始化状态
        Map<String, Object> initState = Map.of("userQuery", userQuery);

        // 执行状态图(内部自动按拓扑顺序执行各节点)
        var result = workflow.stream(initState)
            .collect(Collectors.toList());

        // 获取最终状态
        EnergyWorkflowState finalState = result.get(result.size() - 1);

        return Map.of(
            "routeDecision", finalState.routeDecision(),
            "analysis", finalState.analysisResult(),
            "report", finalState.reportContent(),
            "operation", finalState.operationResult()
        );
    }
}

@RestController
@RequestMapping("/api/multi-agent")
public class MultiAgentController {

    @Autowired
    private MultiAgentService multiAgentService;

    @PostMapping("/execute")
    public ResponseEntity<Map<String, Object>> execute(
            @RequestBody ChatRequest request) {
        return ResponseEntity.ok(multiAgentService.execute(request.getMessage()));
    }
}

调用示例:

# 场景1:纯数据查询
curl -X POST http://localhost:8080/api/multi-agent/execute \
  -H "Content-Type: application/json" \
  -d '{"message": "A栋今天用电量是多少"}'
# 路由: ANALYSIS → 只走数据分析节点

# 场景2:生成报告
curl -X POST http://localhost:8080/api/multi-agent/execute \
  -H "Content-Type: application/json" \
  -d '{"message": "帮我生成本月各楼栋的能耗对比报告"}'
# 路由: REPORT → 数据分析 → 报告生成

# 场景3:复合任务
curl -X POST http://localhost:8080/api/multi-agent/execute \
  -H "Content-Type: application/json" \
  -d '{"message": "分析C栋数据中心近一周能耗,如果异常就生成报告并通知运维张工"}'
# 路由: COMPOSITE → 数据分析 → 报告生成 → 运维调度

三、MCP 协议:Agent 工具集成的"USB 标准"

3.1 MCP 是什么?它解决了什么问题?

在 MCP 出现之前,每个 Agent 框架集成外部工具都有自己的方式。LangChain4j 用 @Tool 注解,Spring AI 用 FunctionCallback,Semantic Kernel 用 KernelFunction……这意味着:你为 LangChain4j 写的一个工具,在 Spring AI 中完全不能复用。

这就像 USB 标准出现之前,每个品牌的手机都有自己的充电接口——极其碎片化。

MCP(Model Context Protocol) 由 Anthropic 于 2024 年底提出,目标是成为 Agent 与外部工具/数据源交互的 统一协议标准。到 2026 年,它已经获得了 OpenAI、Google、微软等主要厂商的支持。

MCP 的核心思想是:将"工具"抽象为一个独立的服务(MCP Server),任何 Agent 框架(MCP Client)都可以通过标准协议调用它。

┌─────────────┐         ┌─────────────────┐         ┌──────────────┐
│  Agent 框架  │ ──JSON──→│   MCP Server    │         │   外部系统    │
│ (MCP Client)│ ←──RPC───│  (工具服务)      │────────→│  DB/API/MQ   │
│             │         │                 │         │              │
│ LangChain4j │         │  ┌───────────┐  │         └──────────────┘
│ Spring AI   │         │  │ Tool定义   │  │
│ 其他框架    │         │  │ (JSON Schema)│ │
└─────────────┘         │  └───────────┘  │
                        └─────────────────┘

类比理解:

  • 传统方式:Agent 框架和工具是"硬编码绑定",像焊接在主板上的零件。
  • MCP 方式:工具变成可插拔的"USB 设备",任何支持 MCP 的 Agent 都能即插即用。

3.2 MCP 协议的三大原语

MCP 协议定义了三种核心原语(Primitive),可以理解为"三种能力":

原语含义类比
ToolsAgent 可调用的函数(有输入参数,有执行结果)REST API
ResourcesAgent 可读取的数据源(只读,类似文件)GET 接口
Prompts预定义的提示词模板(Agent 可以检索使用)配置中心

本文重点实现 Tools 原语,因为它在 Agent 场景中使用最广泛。

3.3 MCP 的传输层:Stdio vs SSE

MCP 定义了两种传输方式,适用于不同场景:

Stdio(标准输入输出)

  • MCP Client 以子进程方式启动 MCP Server
  • 通过 stdin/stdout 交换 JSON-RPC 消息
  • 适合:本地开发、单机部署
  • 优点:零网络开销,启动简单

SSE(Server-Sent Events)+ HTTP

  • MCP Server 作为独立 HTTP 服务运行
  • 客户端通过 SSE 接收流式响应,通过 HTTP POST 发送请求
  • 适合:分布式部署、远程服务调用
  • 优点:天然支持网络,可以独立部署和扩展

企业项目推荐 SSE 方式,因为它与微服务架构天然契合。

3.4 构建一个 MCP Server:将能耗查询工具标准化

下面我们把上一篇文章中的能耗查询工具改造成一个标准的 MCP Server。

依赖配置
<dependencies>
    <!-- MCP SDK(Java 官方实现) -->
    <dependency>
        <groupId>io.modelcontextprotocol</groupId>
        <artifactId>mcp-sdk-java</artifactId>
        <version>0.9.0</version>
    </dependency>

    <!-- Spring Boot Web(SSE 传输需要) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
定义 MCP 工具

MCP Server 的核心是定义"工具"。每个工具需要声明名称、描述和参数的 JSON Schema:

import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;
import io.modelcontextprotocol.spec.McpSchema.*;
import org.springframework.stereotype.Service;

/**
 * 能源管理 MCP Server
 * 
 * 职责:将能耗查询、趋势分析、通知发送等能力封装为标准 MCP 工具
 * 
 * 设计原则:
 * 1. 工具描述要对 LLM 友好——清晰、准确、有调用场景说明
 * 2. 参数定义要完整——每个字段的类型和含义都要明确
 * 3. 返回值要结构化——方便 LLM 解析和引用
 */
@Service
public class EnergyMcpServer {

    private final EnergyDataService energyDataService;
    private final NotificationService notificationService;

    public EnergyMcpServer(EnergyDataService energyDataService,
                          NotificationService notificationService) {
        this.energyDataService = energyDataService;
        this.notificationService = notificationService;
    }

    /**
     * 构建 MCP Server 实例,注册所有工具
     */
    public McpServer buildServer() {
        return McpServer.builder()
            .serverInfo("energy-mcp-server", "1.0.0")

            // ===== 工具1:实时能耗查询 =====
            .tool(
                "query_realtime_energy",
                "查询指定区域的实时能耗数据。" +
                "当用户询问某个区域'当前用了多少电'、'实时能耗'等问题时使用。" +
                "返回数据包含当前能耗值(kWh)和采集时间。",
                // JSON Schema 定义参数
                """
                {
                  "type": "object",
                  "properties": {
                    "areaName": {
                      "type": "string",
                      "description": "区域名称,如'A栋办公楼'、'B栋研发中心'"
                    }
                  },
                  "required": ["areaName"]
                }
                """,
                this::handleQueryRealtimeEnergy
            )

            // ===== 工具2:能耗趋势分析 =====
            .tool(
                "query_energy_trend",
                "分析指定区域在过去N天内的能耗变化趋势。" +
                "当用户想了解'能耗走势'、'最近用电变化'等问题时使用。" +
                "返回趋势描述和关键指标(均值、峰值、变化率)。",
                """
                {
                  "type": "object",
                  "properties": {
                    "areaName": {
                      "type": "string",
                      "description": "区域名称"
                    },
                    "days": {
                      "type": "integer",
                      "description": "分析天数,通常为7或30"
                    }
                  },
                  "required": ["areaName", "days"]
                }
                """,
                this::handleQueryEnergyTrend
            )

            // ===== 工具3:发送预警通知 =====
            .tool(
                "send_alert",
                "向指定负责人发送能耗预警通知。" +
                "仅在能耗确实异常且用户明确要求通知时使用。" +
                "返回发送结果(成功/失败)。",
                """
                {
                  "type": "object",
                  "properties": {
                    "recipient": {
                      "type": "string",
                      "description": "接收人姓名或工号"
                    },
                    "alertLevel": {
                      "type": "string",
                      "enum": ["INFO", "WARNING", "CRITICAL"],
                      "description": "告警级别"
                    },
                    "message": {
                      "type": "string",
                      "description": "告警消息内容"
                    }
                  },
                  "required": ["recipient", "alertLevel", "message"]
                }
                """,
                this::handleSendAlert
            )

            .build();
    }

    // ==================== 工具处理函数 ====================

    private McpSchema.CallToolResult handleQueryRealtimeEnergy(
            Map<String, Object> arguments) {
        String areaName = (String) arguments.get("areaName");

        // 调用实际业务服务
        EnergyData data = energyDataService.getRealtimeConsumption(areaName);

        // 将结果封装为 JSON 字符串返回给 LLM
        String resultJson = String.format("""
            {
              "areaName": "%s",
              "currentConsumption": %.1f,
              "unit": "kWh",
              "collectTime": "%s",
              "status": "%s"
            }
            """,
            data.getAreaName(),
            data.getConsumption(),
            data.getCollectTime(),
            data.getStatus()
        );

        return new McpSchema.CallToolResult(
            List.of(new McpSchema.TextContent(resultJson)),
            false  // isError = false
        );
    }

    private McpSchema.CallToolResult handleQueryEnergyTrend(
            Map<String, Object> arguments) {
        String areaName = (String) arguments.get("areaName");
        int days = ((Number) arguments.get("days")).intValue();

        TrendAnalysis trend = energyDataService.analyzeTrend(areaName, days);

        String resultJson = String.format("""
            {
              "areaName": "%s",
              "period": "%d天",
              "averageConsumption": %.1f,
              "peakConsumption": %.1f,
              "changeRate": "%.1f%%",
              "trend": "%s"
            }
            """,
            areaName, days,
            trend.getAverage(),
            trend.getPeak(),
            trend.getChangeRate(),
            trend.getTrendDescription()
        );

        return new McpSchema.CallToolResult(
            List.of(new McpSchema.TextContent(resultJson)),
            false
        );
    }

    private McpSchema.CallToolResult handleSendAlert(
            Map<String, Object> arguments) {
        String recipient = (String) arguments.get("recipient");
        String alertLevel = (String) arguments.get("alertLevel");
        String message = (String) arguments.get("message");

        boolean success = notificationService.sendAlert(
            recipient, alertLevel, message);

        String resultJson = String.format("""
            {
              "success": %s,
              "recipient": "%s",
              "alertLevel": "%s",
              "message": "%s"
            }
            """, success, recipient, alertLevel, message);

        return new McpSchema.CallToolResult(
            List.of(new McpSchema.TextContent(resultJson)),
            !success  // 发送失败时标记为错误
        );
    }
}
启动 SSE 传输服务
@Configuration
public class McpTransportConfig {

    @Bean
    public McpSseTransport mcpTransport(EnergyMcpServer energyMcpServer) {
        McpServer server = energyMcpServer.buildServer();

        // 使用 SSE 传输:Agent 通过 HTTP 连接此服务
        McpSseTransport transport = McpSseTransport.builder()
            .server(server)
            .port(8090)                    // MCP Server 独立端口
            .endpointPath("/mcp/sse")      // SSE 连接端点
            .messagePath("/mcp/message")   // 消息发送端点
            .build();

        transport.start();
        log.info("MCP Server 已启动,SSE 端点: http://localhost:8090/mcp/sse");

        return transport;
    }
}

3.5 在 Agent 中接入 MCP Client

MCP Server 启动后,Agent 端只需配置连接地址,就能自动发现并调用所有注册的工具:

@Configuration
public class AgentWithMcpConfig {

    @Bean
    public EnergyAgent agentWithMcp() {
        // 1. 配置大模型
        OpenAiChatModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("LLM_API_KEY"))
            .baseUrl(System.getenv("LLM_BASE_URL"))
            .modelName("gpt-4o")
            .temperature(0.3)
            .build();

        // 2. 创建 MCP Client,连接到 MCP Server
        McpClient mcpClient = McpClient.builder()
            .transport(McpSseClientTransport.builder()
                .url("http://localhost:8090/mcp/sse")
                .build())
            .build();

        // 3. MCP Client 会自动发现 Server 上注册的所有工具
        //    并将它们转换为 LangChain4j 的 ToolSpec 格式
        List<Object> mcpTools = mcpClient.listTools().stream()
            .map(tool -> new McpToolWrapper(mcpClient, tool))
            .toList();

        // 4. 构建 Agent,传入 MCP 工具
        return AiServices.builder(EnergyAgent.class)
            .chatLanguageModel(model)
            .tools(mcpTools)  // MCP 工具和普通 @Tool 工具一样使用
            .chatMemory(MessageWindowChatMemory.withMaxMessages(20))
            .build();
    }
}

关键优势:Agent 代码中 没有任何对具体工具的硬编码引用。MCP Server 新增或删除工具,Agent 端零改动——这就是协议标准化的价值。


四、MCP + Multi-Agent:强强联合

4.1 每个 Agent 连接不同的 MCP Server

在 Multi-Agent 架构中,不同的专家 Agent 可以连接不同的 MCP Server,各自获取专属的工具能力:

┌────────────────────────────────────────────────────────────────┐
│                        Orchestrator                            │
│                                                               │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────────┐   │
│  │ 数据分析     │  │ 报告生成      │  │ 运维调度            │   │
│  │ Agent       │  │ Agent        │  │ Agent               │   │
│  │             │  │              │  │                     │   │
│  │ MCP Client  │  │ MCP Client   │  │ MCP Client          │   │
│  └──────┬──────┘  └──────┬───────┘  └──────────┬──────────┘   │
│         │                │                     │               │
└─────────┼────────────────┼─────────────────────┼───────────────┘
          │                │                     │
   ┌──────▼──────┐  ┌──────▼───────┐  ┌──────────▼──────────┐
   │ MCP Server  │  │ MCP Server   │  │ MCP Server          │
   │ energy-data │  │ report-gen   │  │ ops-automation      │
   │             │  │              │  │                     │
   │ 工具:       │  │ 工具:        │  │ 工具:               │
   │ · 实时查询   │  │ · 生成PDF    │  │ · 发送通知           │
   │ · 趋势分析   │  │ · 生成Excel  │  │ · 创建工单           │
   │ · 历史对比   │  │ · 邮件发送   │  │ · 调整参数           │
   └─────────────┘  └──────────────┘  └─────────────────────┘

4.2 配置代码

@Configuration
public class MultiAgentMcpConfig {

    /**
     * 数据分析 Agent —— 连接能源数据 MCP Server
     */
    @Bean
    public EnergyDataAgent dataAgent() {
        McpClient dataMcpClient = McpClient.builder()
            .transport(sseTransport("http://energy-data-mcp:8090/mcp/sse"))
            .build();

        return AiServices.builder(EnergyDataAgent.class)
            .chatLanguageModel(chatModel())
            .tools(dataMcpClient.listToolWrappers())
            .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
            .build();
    }

    /**
     * 报告生成 Agent —— 连接报告生成 MCP Server
     */
    @Bean
    public ReportAgent reportAgent() {
        McpClient reportMcpClient = McpClient.builder()
            .transport(sseTransport("http://report-gen-mcp:8091/mcp/sse"))
            .build();

        return AiServices.builder(ReportAgent.class)
            .chatLanguageModel(chatModel())
            .tools(reportMcpClient.listToolWrappers())
            .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
            .build();
    }

    /**
     * 运维调度 Agent —— 连接运维自动化 MCP Server
     */
    @Bean
    public OperationAgent operationAgent() {
        McpClient opsMcpClient = McpClient.builder()
            .transport(sseTransport("http://ops-mcp:8092/mcp/sse"))
            .build();

        return AiServices.builder(OperationAgent.class)
            .chatLanguageModel(chatModel())
            .tools(opsMcpClient.listToolWrappers())
            .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
            .build();
    }

    private ChatLanguageModel chatModel() {
        return OpenAiChatModel.builder()
            .apiKey(System.getenv("LLM_API_KEY"))
            .baseUrl(System.getenv("LLM_BASE_URL"))
            .modelName("gpt-4o")
            .temperature(0.3)
            .timeout(Duration.ofSeconds(60))
            .maxRetries(3)
            .build();
    }

    private McpSseClientTransport sseTransport(String url) {
        return McpSseClientTransport.builder().url(url).build();
    }
}

五、生产环境的深度考量

5.1 MCP Server 的健康检查与容错

MCP Server 作为独立服务,必须具备生产级的可靠性保障:

/**
 * MCP 连接管理器
 * 
 * 解决的问题:
 * 1. MCP Server 宕机时自动重连
 * 2. 工具调用超时时的优雅降级
 * 3. 连接池管理(避免每次调用都建立新连接)
 */
@Component
public class McpConnectionManager {

    private final Map<String, McpClient> clientPool = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler =
        Executors.newScheduledThreadPool(2);

    /**
     * 获取或创建 MCP Client 连接
     */
    public McpClient getClient(String serverUrl) {
        return clientPool.computeIfAbsent(serverUrl, url -> {
            McpClient client = McpClient.builder()
                .transport(McpSseClientTransport.builder()
                    .url(url)
                    .timeout(Duration.ofSeconds(30))
                    .build())
                .build();

            // 启动心跳检测:每 30 秒检查连接状态
            scheduler.scheduleAtFixedRate(() -> {
                if (!client.isHealthy()) {
                    log.warn("MCP Server {} 连接异常,尝试重连...", url);
                    client.reconnect();
                }
            }, 30, 30, TimeUnit.SECONDS);

            return client;
        });
    }

    /**
     * 带超时和降级的工具调用
     */
    public CallToolResult callToolWithFallback(
            String serverUrl, String toolName,
            Map<String, Object> args, Duration timeout) {
        try {
            McpClient client = getClient(serverUrl);
            return client.callTool(toolName, args)
                .orTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS)
                .join();
        } catch (TimeoutException e) {
            log.error("MCP 工具调用超时: server={}, tool={}", serverUrl, toolName);
            // 降级:返回错误提示让 Agent 告知用户
            return createErrorResult("工具服务暂时不可用,请稍后重试");
        }
    }

    @PreDestroy
    public void shutdown() {
        clientPool.values().forEach(McpClient::close);
        scheduler.shutdown();
    }
}

5.2 MCP 工具调用的可观测性

在生产环境中,你需要追踪每一次 MCP 工具调用的完整链路:

/**
 * MCP 工具调用拦截器(AOP 方式)
 * 
 * 记录:调用耗时、参数、返回值、错误信息
 * 上报:Prometheus / Grafana / OpenTelemetry
 */
@Aspect
@Component
public class McpToolCallAspect {

    @Autowired
    private MeterRegistry meterRegistry;

    @Around("@annotation(McpToolCall)")
    public Object monitorToolCall(ProceedingJoinPoint pjp) throws Throwable {
        String toolName = pjp.getSignature().getName();
        long startTime = System.currentTimeMillis();

        try {
            Object result = pjp.proceed();
            long duration = System.currentTimeMillis() - startTime;

            // 记录成功指标
            meterRegistry.timer("mcp.tool.call",
                "tool", toolName, "status", "success")
                .record(duration, TimeUnit.MILLISECONDS);

            log.info("[MCP调用成功] tool={} duration={}ms", toolName, duration);
            return result;

        } catch (Exception e) {
            long duration = System.currentTimeMillis() - startTime;

            // 记录失败指标
            meterRegistry.timer("mcp.tool.call",
                "tool", toolName, "status", "error")
                .record(duration, TimeUnit.MILLISECONDS);

            log.error("[MCP调用失败] tool={} duration={}ms error={}",
                toolName, duration, e.getMessage());
            throw e;
        }
    }
}

5.3 安全:MCP Server 的认证与授权

MCP Server 暴露了系统核心能力,必须做好安全防护:

@Configuration
public class McpSecurityConfig {

    /**
     * MCP Server 端的认证拦截
     * 
     * 方案:API Key + 工具级权限控制
     */
    @Bean
    public McpServerFilter securityFilter() {
        return new McpServerFilter() {

            @Override
            public void beforeToolCall(ToolCallContext context) {
                // 1. 验证 API Key
                String apiKey = context.getHeader("X-API-Key");
                if (!apiKeyValidator.isValid(apiKey)) {
                    throw new McpUnauthorizedException("无效的 API Key");
                }

                // 2. 工具级权限检查
                String toolName = context.getToolName();
                String callerRole = apiKeyValidator.getRole(apiKey);

                if (isWriteOperation(toolName) && !"ADMIN".equals(callerRole)) {
                    throw new McpForbiddenException(
                        "角色 " + callerRole + " 无权调用写入工具: " + toolName);
                }

                // 3. 审计日志
                auditLog.record(callerRole, toolName, context.getArguments());
            }
        };
    }

    private boolean isWriteOperation(String toolName) {
        return Set.of("send_alert", "update_threshold", "delete_data")
            .contains(toolName);
    }
}

六、架构全景:Multi-Agent + MCP 完整拓扑

┌─────────────────────────────────────────────────────────────────────────┐
│                           Spring Boot 应用                               │
│                                                                         │
│  ┌──────────┐    ┌──────────────────────────────────────────────────┐   │
│  │ REST API │───→│              Orchestrator Agent                  │   │
│  └──────────┘    │  (意图识别 → 路由决策 → 调度执行 → 结果汇总)      │   │
│                  └────┬──────────────┬──────────────┬───────────────┘   │
│                       │              │              │                    │
│            ┌──────────▼──┐  ┌───────▼──────┐  ┌───▼────────────┐      │
│            │ 数据分析Agent│  │ 报告生成Agent │  │ 运维调度Agent  │      │
│            │  (MCP Client)│  │ (MCP Client)  │  │ (MCP Client)   │      │
│            └──────┬───────┘  └───────┬───────┘  └───────┬────────┘      │
│                   │                  │                  │                │
└───────────────────┼──────────────────┼──────────────────┼────────────────┘
                    │ SSE              │ SSE              │ SSE
        ┌───────────▼──────┐ ┌────────▼───────┐ ┌────────▼───────────┐
        │ MCP Server       │ │ MCP Server     │ │ MCP Server         │
        │ energy-data      │ │ report-gen     │ │ ops-automation     │
        │ :8090            │ │ :8091          │ │ :8092              │
        │                  │ │                │ │                    │
        │ Tools:           │ │ Tools:         │ │ Tools:             │
        │ · query_realtime │ │ · generate_pdf │ │ · send_alert       │
        │ · query_trend    │ │ · generate_xlsx│ │ · create_ticket    │
        │ · query_history  │ │ · send_email   │ │ · adjust_threshold │
        │                  │ │                │ │ · trigger_inspect  │
        └────────┬─────────┘ └───────┬────────┘ └────────┬───────────┘
                 │                   │                   │
        ┌────────▼───────────────────▼───────────────────▼───────────┐
        │                    基础设施层                                │
        │  ┌────────┐  ┌──────────┐  ┌─────┐  ┌──────────────────┐  │
        │  │ 达梦DB  │  │ClickHouse│  │ MQ  │  │ 短信/邮件网关    │  │
        │  └────────┘  └──────────┘  └─────┘  └──────────────────┘  │
        └────────────────────────────────────────────────────────────┘

七、与上一篇文章的对比总结

维度上篇(单体 Agent)本篇(Multi-Agent + MCP)
架构单一 Agent + 多个 @ToolOrchestrator + 多个专家 Agent
工具集成硬编码在 Agent 内部MCP 协议标准化,可插拔
扩展性加工具需改代码新增 MCP Server 即可,Agent 零改动
工具复用框架绑定,无法跨项目MCP Server 独立部署,任何框架可调用
复杂度低(适合快速验证)中~高(适合生产级系统)
可维护性职责耦合各 Agent 独立开发、测试、部署
故障隔离一个工具出错影响全局故障局限在单个 Agent/MCP Server

八、展望:下一步该关注什么?

  1. Agent 的自动评估体系:如何系统性地测试 Agent 的准确率?目前主流方案是构建"评估数据集 + 自动打分"流水线。
  2. A2A 协议(Agent-to-Agent):Google 2025 年提出的 Agent 间直接通信协议,与 MCP 互补——MCP 解决 Agent 与工具的连接,A2A 解决 Agent 与 Agent 的连接。
  3. 长期记忆 + 向量数据库的进阶用法:将用户画像、历史决策向量化存储,让 Agent 具备"经验积累"能力。

AI编程智能体全栈实战:从LangChain到商业级Agent构建 AI编程智能体是当前人工智能技术的重要应用方向,它基于大语言模型构建能够理解需求并生成代码的自动化系统。其核心原理是通过框架层、协议层、工具层和应用层的协同工作,实现智能决策和工具调用。在技术价值方面,AI编程智能体能够显著提升开发效率,降低编码门槛,实现代码生成的标准化和自动化。典型的应用场景包括自动化代码生成、项目重构、文档问答和系统架构设计等。本文重点探讨了LangChain框架与MCP协议的深度集成,通过完整的实战案例展示了如何构建具备商业级能力的编程智能体,解决实际开发中的复杂问题。 阅读详情

相关推荐

MCP协议实战:构建高可靠多智能体协作系统

多智能体系统(Multi-Agent System)的核心挑战在于分布式通信的可靠性与可追溯性,而非大模型能力本身。MCP协议(Multi-agent Communication Protocol)作为开源社区共建的轻量级通信规范,通过标准化消息结构(含intent、context_id、correlation_id)、应用层三段式握手机制及可插拔路由策略,将Agent间通信从‘尽力而为’升级为‘使命必达’。其技术价值体现在金融风控、智能制造、跨境电商等强一致性与高并发场景中,支撑消息投递成功率超99.99

weixin_33991418的博客 454

【必收藏】从Single-Agent到Multi-Agent:大模型智能体架构演进与实战应用指南

Agent(智能体)是能够自主感知环境、分析信息并采取行动以实现特定目标的实体或程序。现在主要分为两个流派:workflows和agents之间有一个架构区分。

大模型教程的博客 783

「企业级智能体」LangChain4j Multi-Agent:角色分离 + 协同编排实战

在大部分 Java 项目里,“接入大模型Controller 收到一个 question调用大模型接口拿到 answer把结果原样丢回前端这种玩法可以叫「高配搜索框模式一个 Agent 要写 Prompt、要查数据库、还要改写文案,太忙了不同角色(创作者、编辑、审稿人)的职责混在一起,难以维护想复用其中一段能力(比如只要润色)也不方便把大任务拆成多个 “角色清晰的 Agent”,再编排它们像流水线一样协同完成任务。CreativeWriter:负责创作故事。

OFFTime_we的博客 1545

【珍藏必备】AI智能体开发全流程:LangChain框架+地图产品实战案例解析,从连接模型到复杂Agent架构

本文详细介绍了AI智能体开发的全流程,从连接大模型、理解工具调用和MCP协议,到构建智能体Agent的多种架构模式(RAG、ReAct、Plan-and-Execute等)。重点分析了LangChain框架的核心能力和LangGraph的三大原理(状态、节点、边),并通过地图产品AI交互的实战案例,展示了如何将理论知识应用到实际项目中。适合想要入门AI智能体开发的开发者阅读收藏。

优快云_430422的博客 1040

低速信号设计之 LPC 篇

摘要:LPC总线作为服务器低速信号设计的关键技术,在BIOS芯片连接、Super I/O芯片控制和嵌入式管理等方面发挥着重要作用。其采用33MHz时钟频率和4位并行传输机制,理论速率达16.5MB/s。设计时需重点关注布线长度(建议<10cm)、信号完整性(45°走线、合理层间隔离)和过孔优化等要点。典型应用案例表明,通过规范设计可确保在工业控制等复杂环境中稳定工作。LPC总线凭借低成本、低引脚数和良好兼容性,仍是服务器低速外设连接的重要解决方案。

qq_16237389的博客 1164

Ubuntu 24.04.3 LTS 安装 OpenClaw 图文版

OpenClow安装指南

qq_17204557的博客 2551

MCP协议:AI智能体通信的通用数据总线解决方案

在分布式系统和AI应用开发中,协议适配和数据格式转换是常见的工程挑战。传统方案如JSON-RPC虽然易于理解,但在性能、跨语言支持和流式处理等方面存在局限。MCP(Multi-agent Communication Protocol)作为一种新型通信协议,通过分层设计、混合序列化和智能路由等机制,显著提升了机器间通信效率。该协议特别适用于需要连接大模型与异构业务系统的场景,例如金融风控、智能客服和物联网数据分析。实际测试表明,MCP相比JSON-RPC可降低80%的协议开销,提升15倍并发能力,同时支持原生

diaohuyi6830的博客 417

Pspice开关电源仿真:从零实现反激式电源设计实战案例

通过Pspice仿真工具,手把手实现反激式开关电源的设计与优化,深入剖析关键参数设置与波形分析,帮助掌握Pspice在电源开发中的实际应用技巧。

weixin_35756690的博客 1155

【收藏必备】AI智能体开发实战:LangChain框架从入门到精通

本文介绍了AI智能体(Agent)开发的入门知识,重点讲解了LangChain框架的应用。文章涵盖了大模型连接、工具调用、MCP协议、Agent架构设计模式(如RAG、ReAct等)以及LangGraph原理。适合初学者理解如何构建基于大语言模型的智能应用,提供了从基础概念到实战应用的完整指南,是入门AI Agent开发的必学内容。

youmaob的博客 1086

告别切换烦恼!用Parallels Desktop的Host-Only网卡,在macOS上直接访问虚拟机里的公司内网

本文详细介绍了如何在macOS上使用Parallels Desktop的Host-Only网卡直接访问虚拟机内的公司内网,告别频繁切换操作系统的烦恼。通过配置Host-Only网络模式,实现主机与虚拟机的安全高效通信,特别适合需要频繁访问内网资源的IT从业者。文章包含分步指南、自动化脚本和常见问题解决方案,帮助用户优化工作流程。

weixin_28739079的博客 363

ADRV9026初始化避坑指南:手把手调试PostMcsInit常见故障

本文详细解析了ADRV9026多片同步初始化过程中的PostMcsInit常见故障,包括时钟校准失败、JESD链路建立问题和ARM核通信异常等。通过实际项目经验,提供了硬件检查清单、软件配置要点和分层诊断方法,帮助工程师快速定位和解决问题,提升系统稳定性。

hadoop5ranger的博客 620

企业级Agent智能体(智能小秘)之MCP服务

.env 文件(通常不提交到 Git,本地存放敏感配置)load_dotenv():会自动查找并加载项目根目录下的 .env 文件,将文件中的键值对注入到系统环境变量中。override=True:如果系统中已存在同名环境变量,会用 .env 文件中的值覆盖(确保配置优先从文件读取)。相当于这个做成一个统一类,想要使用什么模型,就在这里配置什么模型去使用即可。

zouyang920的博客 558

2026年信创系统技术应用专业人才培养基地建设方案(高职、信创新专业、人才培养、专业代码:510221)

响应国家信创产业战略及教育部新增“信创系统技术应用”专业(代码510221)的部署,联合麒麟软件、华为鸿蒙等领军企业,建设高水平信创人才培养基地。方案基于国家政策导向(如2027年央企全面国产化替代目标)和行业人才缺口(2025年缺口超80万人),提出以“产教融合、创新驱动”为核心,构建集教学、实训、认证于一体的综合性培养体系。 建设内容涵盖五大方向: 专业规划:分三阶段(2025-2030年)推进专业申报、课程开发与区域辐射,最终建成区域性信创技术创新平台。 课程体系:围绕运维、云计算、数据库、适配

啊碧根果的博客 1596

A2A 协议详解:让 AI Agent 真正实现跨框架协作

它是一套用于AI Agent 与 AI Agent 之间通信和协作的开放协议。A2A 最初由 Google 推动,后来进入 Linux Foundation 生态,其核心目标并不是规定 Agent 内部怎么实现,而是规定:一个 Agent 如何向其他 Agent 描述自己,以及两个互不理解内部实现的 Agent 如何协作完成任务。Agent A 不需要知道 Agent B 内部怎么实现。LangGraphCrewAIGoogle ADK自研 Agent Runtime普通 PythonGo。

qq_43655834的博客 585

【数据集】全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

WW、forever的博客 387

【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)

【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)

学无止境、积少成多、厚积薄发 3983

基于MCP协议与多Agent架构的智能工具分配系统实践

在AI驱动的软件开发领域,工具调用与智能体协作是提升开发效率的关键技术。其核心原理在于通过标准化的协议,将离散的工具能力进行抽象与整合,并由一个中央协调器根据任务上下文进行智能调度与分配。这项技术的核心价值在于解决了传统AI助手面临的工具闲置与能力边界模糊问题,通过解耦工具使用与智能体,构建了一个可扩展、高可用的工具生态系统。典型的应用场景包括智能代码审查、自动化测试生成、数据库查询优化等复杂工作流。本文以OpenCode项目为例,深入探讨了如何利用模型上下文协议(MCP)构建多Agent工具管理方案,并详

weixin_34269583的博客 473

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

MCP协议与智能体编排技术解析及实践

分布式系统中的多智能体协作是现代AI架构的核心挑战之一。MCP(Multi-agent Control Protocol)作为一种新型通信协议,通过标准化消息交换机制解决了异构智能体间的动态发现与任务编排问题。其协议栈包含传输层、会话层和业务层,支持gRPC等高效传输方式,在金融风控等场景中能提升40%以上的协作效率。从技术实现来看,MCP采用UUID会话标识和上下文传递机制,配合Protobuf编码和LRU缓存策略,在电商推荐等系统中可实现3500 QPS的高吞吐。该技术特别适合需要实时监控与同步操作并存

weixin_30546189的博客 360

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

测试工程师转型智能体架构师:MCP协议与脚本升维实战

智能体(Agent)作为AI原生时代的核心运行单元,正重塑软件质量保障范式。其本质是基于标准化协议(如MCP)编排可复用能力的自治系统,依赖脚本能力作为底层原子服务,而非替代它。掌握MCP协议意味着具备智能体间可靠通信、错误协商与服务发现的能力;而将Shell/Python脚本升维封装为符合契约的MCP Service,则是构建高可用智能体的关键工程实践。该能力已广泛应用于支付风控、接口验证、大促保障等高敏业务场景,支撑毫秒级响应与自动闭环决策。本文聚焦测试工程师如何以脚本为基座、以MCP为语言、以Dify

weixin_33875564的博客 205

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

AI - Agent智能体

Agent:总指挥,负责思考和规划RAG:提供外部知识库:提供执行能力MCP:统一工具调用协议。

MinggeQingchun的博客 357

AI Agent企业落地实战:从单体架构到多智能体协同的完整指南

在企业级AI应用中,智能体(Agent)的价值不在于“会聊天”,而在于“会干活”。从传统的RAG知识检索到复杂的跨系统操作,AI Agent通过动态规划与环境交互,正在重塑业务流程自动化的边界。本文从智能体架构的核心取舍出发,探讨单体与多智能体(Multi-Agent)的设计差异,深入解析Function Calling、MCP协议等工具调用机制,并结合LangGraph框架给出生产级实现方案。面对模型幻觉、工具误调用、安全策略拦截等工程难题,文章提供了基于实战的调优策略与参数配置经验,帮助企业将AI能力从

weixin_34160277的博客 301

阿里AI Agent一面复盘:反问拿捏面试官(含LangChain/Multi\-Agent/A2A/MCP面试全解)

本文分享了阿里AI Agent面试的核心知识点与实战经验。主要内容包括: LangChain架构解析:三层分层设计(基础抽象层、核心能力层、应用运维层),重点对比LangChain与LangGraph的区别,解释Java技术栈选用LangGraph4j的原因。 Agent开发模式:详细介绍ReAct、Plan-and-Execute、Multi-Agent协作和状态图编排四种方式,结合实际项目说明选择状态图编排的原因。 核心模块与项目实战:深入讲解LangChain六大模块,分享Multi-Agent系统设

IT枫斗者的博客 202

元景万悟:企业级AI智能体平台的5大核心能力与高可用微服务架构实践

在数字化转型浪潮中,企业如何快速构建稳定、高效且可扩展的AI智能体平台?中国联通元景万悟智能体平台以企业级微服务架构为基础,提供从智能体开发到部署运维的一站式解决方案,帮助企业快速实现AI能力落地。作为一款商用license友好的开源平台,万悟不仅解决了技术集成难题,更大幅降低了AI项目交付门槛,让企业能够专注于业务创新而非技术堆叠。 ## 一、企业AI转型面临的三大核心挑战 在引入AI技术时

gitblog_00700的博客 481

2026企业级AI Agent竞争版图与生产级落地全指南

AI Agent正从概念验证走向规模量产,成为重塑企业生产力要素的关键技术。其核心在于构建感知、规划、执行与反馈的自治闭环,让系统不仅能处理固化流程,更能完成需要判断和经验积累的复杂任务。通过编排层、业务记忆与安全审计的完善,以及函数调用准确率的提升,Agent得以从“聊天助手”进化为“硅基员工”。当前,云厂商、垂直厂商与开源社区三方角力,推动技术栈选型、垂直技能封装及多Agent协作逐渐成熟,并已在半导体验证、物流决策、企业知识库等场景中创造显著价值。本文深度拆解2026年企业级AI Agent的竞争格局

weixin_33769125的博客 343

基于Spring Ai的Agent 工程师

Spring AI 是 Spring 生态的 AI 应用开发框架,旨在简化 Java 开发者构建 AI 应用的过程“AI 应用的 Spring Boot”,提供统一的抽象层,让开发者像使用数据库一样简单地使用大模型主要功能:对话模型、嵌入模型、向量存储、提示词模板、RAG、Function Calling、结构化输出等答案:原理:AI 先"百度一下"再回答,从外部知识库检索相关信息后生成答案特点:动态检索,适合知识更新频繁的场景,无需重新训练模型。

weixin_48382359的博客 848

高危工业场景人员定位系统设计:四类场景的架构选型与部署要点

本文由航飞光电一线工程团队整理,重点讨论高危工业场景下人员定位系统的架构选型思路。覆盖危化、矿山、港口、电力四类场景,拆解技术路线分工、融合引擎跨区切换实现,以及私有化/本地化部署中的工程难点,供架构师与技术负责人参考。

HF17513371855的博客 365
上一篇: 一:2026 年了,Java 程序员还不会 AI Agent?从原理到实战,用 LangChain4j 构建企业级智能体
下一篇: 三:Agent 自动评估体系与 A2A 协议实战:让你的 AI 智能体从“能用“走向“可靠“
yychen_java
博客等级 码龄8年 1451粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值