电子书 – Spring Cloud 指南 – NPI EA (分类=Spring Cloud)
announcement - icon

让我们开始使用 Spring Cloud 的微服务架构

>> 加入 Pro 并下载电子书

电子书 – Mockito – NPI EA (标签 = Mockito)
announcement - icon

模拟是单元测试的重要组成部分,Mockito 库使编写 清晰直观的单元测试 变得容易,用于您的 Java 代码。

通过我们的 Mockito 指南 开始模拟,并改进您的应用程序测试

下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – 响应式 – NPI EA (分类=响应式)
announcement - icon

Spring 5 增加了对使用 Spring WebFlux 模块进行响应式编程的支持,此支持自那时起不断改进。 开始使用 Reactor 项目基础知识和 Spring Boot 中的响应式编程

>> 加入 Pro 并下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – Jackson – NPI EA (分类=Jackson)
announcement - icon

用 Jackson 正确处理 JSON

下载电子书

电子书 – HTTP 客户端 – NPI EA (分类=Http 客户端)
announcement - icon

充分利用 Apache HTTP 客户端

下载电子书

电子书 – Maven – NPI EA (分类 = Maven)
announcement - icon

开始使用 Apache Maven

下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

电子书 – RwS – NPI EA (分类=Spring MVC)
announcement - icon

使用 Spring 构建 REST API 吗?

下载电子书

课程 – LS – NPI EA (分类=Jackson)
announcement - icon

通过 Learn Spring 课程开始学习 Spring 和 Spring Boot

>> 学习 SPRING
课程 – RWSB – NPI EA (分类=REST)
announcement - icon

通过构建一个完整的 REST API,深入了解 Spring Boot 3 和 Spring 6,使用该框架

>> 全新的“REST With Spring Boot”

课程 – LSS – NPI EA (分类=Spring Security)
announcement - icon

是的,Spring Security 可能很复杂,从核心内的更高级功能到框架中深入的 OAuth 支持。

我将安全材料构建为 两个完整的课程 - 核心和 OAuth,以针对这些更复杂的场景进行实践。 我们探索何时以及如何使用每个功能,并 在后台项目中对其进行编码

您可以在这里探索该课程

>> 学习 Spring Security

课程 – LSD – NPI EA (标签=Spring Data JPA)
announcement - icon

Spring Data JPA 是处理 JPA 复杂性的绝佳方式,它具有 Spring Boot 的强大简洁性

通过引导式参考课程开始使用 Spring Data JPA

>> 查看课程

合作伙伴 – Moderne – NPI EA (类别=Spring Boot)
announcement - icon

使用 OpenRewrite 安全且自动地重构 Java 代码。

手动重构大型代码库既缓慢、有风险,又容易拖延。OpenRewrite 应运而生。这个用于大规模、自动化代码转换的开源框架可以帮助团队安全、一致地进行现代化改造。

每个月,OpenRewrite 的创建者和维护者 Moderne 都会举办现场、实践培训课程——一个面向初学者,一个面向经验丰富的用户。您将了解配方的运作方式、如何将其应用于项目,以及如何自信地进行代码现代化改造。

参加下一次课程,带来您的问题,并学习如何自动化通常会占用您 sprint 时间的工作。

合作伙伴 – LambdaTest – NPI EA (类别=测试)
announcement - icon

回归测试是发布流程中的重要步骤,以确保新代码不会破坏现有功能。随着代码库的不断发展,我们希望频繁运行这些测试,以便尽早发现任何问题。

确保这些测试以自动化的方式频繁运行的最佳方法当然是将其包含在 CI/CD 管道中。 这样,每次向仓库提交代码时,回归测试将自动执行。

在本教程中,我们将学习如何使用 Selenium 创建回归测试,然后使用 GitHub Actions 将它们包含在我们的管道中,在 LambdaTest 云网格上运行

>> 如何使用 GitHub Actions 运行 Selenium 回归测试

课程 – LJB – NPI EA (类别 = Core Java)
announcement - icon

通过编码方式构建 Java 的坚实、实用的基础

>> 学习 Java 基础

1. 概述

现代 Web 应用程序越来越多地与 大型语言模型 (LLMs) 集成,以构建解决方案,这些解决方案不仅限于基于通用知识的问答。

为了增强 AI 模型的响应并使其更具上下文感知能力,我们可以将其连接到外部资源,例如搜索引擎、数据库和文件系统。但是,集成和管理具有不同格式和协议的多个数据源是一个挑战。

模型上下文协议 (MCP) 由 Anthropic 引入,解决了这个集成挑战,并提供了一种标准化的方式来将 AI 驱动的应用程序与外部数据源连接起来。通过 MCP,我们可以在原生 LLM 之上构建复杂的代理和工作流程。

在本教程中,我们将通过使用 Spring AI 实际实现其客户端-服务器架构来理解 MCP 的概念。我们将创建一个简单的聊天机器人,并通过 MCP 服务器扩展其功能,以执行 Web 搜索、执行文件系统操作和访问自定义业务逻辑。

2. 模型上下文协议 101

在深入实现之前,让我们更详细地了解 MCP 及其各个组件

Architecture diagram of the model context protocol (MCP) demonstrating the relationship between host, clients, servers, and external sources.

MCP 遵循客户端-服务器架构,围绕几个关键组件展开

  • MCP Host:是我们的主应用程序,它与 LLM 集成,并需要它连接到外部数据源
  • MCP Clients:是建立并维护与 MCP 服务器 1:1 连接的组件
  • MCP Servers:是与外部数据源集成的组件,并暴露功能以与之交互
  • Tools:指的是 MCP 服务器暴露给客户端调用的可执行函数/方法

此外,为了处理客户端和服务器之间的通信,MCP 提供了两个传输通道。

为了通过标准输入和输出流与本地进程和命令行工具实现通信,它提供了标准输入/输出 (stdio) 传输类型。或者,对于客户端和服务器之间的基于 HTTP 的通信,它提供了服务器发送事件 (SSE) 传输类型。

MCP 是一个复杂而广泛的主题,请参考 官方文档 以了解更多信息。

3. 创建 MCP Host

现在我们对 MCP 有了高级了解,让我们开始实际实现 MCP 架构。

我们将使用 Anthropic 的 Claude 模型构建一个聊天机器人,它将充当我们的 MCP host。或者,我们可以通过 Hugging Face 或 Ollama 使用本地 LLM,因为具体的 AI 模型对于此演示来说无关紧要。

3.1. 依赖项

让我们从向项目的 pom.xml 文件添加必要的依赖项开始

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-anthropic</artifactId>
    <version>1.0.1</version>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
    <version>1.0.1</version>
</dependency>

Anthropic starter 依赖项 是围绕 Anthropic Message API 的包装器,我们将使用它在我们的应用程序中与 Claude 模型进行交互。

此外,我们导入了 MCP 客户端启动依赖这将允许我们在 Spring Boot 应用程序中配置客户端,这些客户端与 MCP 服务器保持 1:1 的连接

鉴于我们正在项目中使用了多个 Spring AI 启动器,让我们也在 pom.xml 中包含 Spring AI 物料清单 (BOM)

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

有了这个补充,我们现在可以从我们的两个启动依赖中删除 version 标签。BOM 消除了版本冲突的风险,并确保我们的 Spring AI 依赖项相互兼容

接下来,让我们在 application.yaml 文件中配置我们的 Anthropic API 密钥和聊天模型。

spring:
  ai:
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
      chat:
        options:
          model: claude-opus-4-20250514

我们使用 ${} 属性占位符从 环境变量 加载 API 密钥的值。

此外,我们指定 Anthropic 的 Claude 4 Opus,使用 claude-opus-4-20250514 模型 ID。可以根据需求探索和使用 不同的模型

在配置以上属性后,Spring AI 会自动创建一个类型为 ChatModel 的 bean,从而使我们能够与指定的模型进行交互

3.2. 为 Brave Search 和 Filesystem 服务器配置 MCP 客户端

现在,让我们为两个预构建的 MCP 服务器实现配置 MCP 客户端:Brave SearchFilesystem。这些服务器将使我们的聊天机器人能够执行网络搜索和文件系统操作。

让我们从在 application.yaml 文件中注册 Brave search MCP 服务器的 MCP 客户端开始

spring:
  ai:
    mcp:
      client:
        stdio:
          connections:
            brave-search:
              command: npx
              args:
                - "-y"
                - "@modelcontextprotocol/server-brave-search"
              env:
                BRAVE_API_KEY: ${BRAVE_API_KEY}

这里,我们配置一个使用 stdio 传输的 client我们指定 npx command 来下载并运行基于 TypeScript 的 @modelcontextprotocol/server-brave-search 包,并使用 -y 标志确认所有安装提示

此外,我们提供 BRAVE_API_KEY 作为环境变量。

接下来,让我们配置 Filesystem MCP 服务器的 MCP 客户端

spring:
  ai:
    mcp:
      client:
        stdio:
          connections:
            filesystem:
              command: npx
              args:
                - "-y"
                - "@modelcontextprotocol/server-filesystem"
                - "./"

与之前的配置类似,我们指定运行 Filesystem MCP 服务器包 所需的 command 和参数。此设置允许我们的聊天机器人执行诸如在指定目录中创建、读取和写入文件的操作。

这里,我们仅配置当前目录 (./) 用于文件系统操作,但是,我们可以通过将它们添加到 args 列表中来指定多个目录。

在应用程序启动期间,Spring AI 将扫描我们的配置,创建 MCP 客户端,并与其相应的 MCP 服务器建立连接。它还会创建一个类型为 SyncMcpToolCallbackProvider 的 bean,该 bean 提供所有由配置的 MCP 服务器公开的工具列表

3.3. 构建一个基本的聊天机器人

在配置了我们的 AI 模型和 MCP 客户端之后,让我们构建一个简单的聊天机器人

@Bean
ChatClient chatClient(ChatModel chatModel, SyncMcpToolCallbackProvider toolCallbackProvider) {
    return ChatClient
      .builder(chatModel)
      .defaultToolCallbacks(toolCallbackProvider.getToolCallbacks())
      .build();
}

我们首先使用 ChatModelSyncMcpToolCallbackProvider bean 创建一个类型为 ChatClient 的 bean。ChatClient 类将作为我们与聊天完成模型(即 Claude 4 Opus)交互的主要入口点

接下来,让我们注入 ChatClient bean 以创建一个新的 ChatbotService

String chat(String question) {
    return chatClient
      .prompt()
      .user(question)
      .call()
      .content();
}

我们创建一个 chat() 方法,其中我们将用户的 question 传递给 chat client bean,并简单地返回 AI 模型的响应。

既然我们已经实现了服务层,让我们在其之上暴露一个 REST API

@PostMapping("/chat")
ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest chatRequest) {
    String answer = chatbotService.chat(chatRequest.question());
    return ResponseEntity.ok(new ChatResponse(answer));
}

record ChatRequest(String question) {}

record ChatResponse(String answer) {}

稍后在教程中,我们将使用上述 API 端点与我们的聊天机器人进行交互。

4. 创建自定义 MCP 服务器

除了使用预构建的 MCP 服务器之外,我们可以创建自己的 MCP 服务器,通过我们的业务逻辑扩展聊天机器人的功能

让我们探索如何使用 Spring AI 创建自定义 MCP 服务器。

在本节中,我们将创建一个新的 Spring Boot 应用程序。

4.1. 依赖项

首先,让我们在我们的 pom.xml 文件中包含必要的依赖项

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
    <version>1.0.0</version>
</dependency>

我们导入 Spring AI 的 MCP 服务器依赖项,它提供了创建支持基于 HTTP 的 SSE 传输的自定义 MCP 服务器所需的类。

4.2. 定义和公开自定义工具

接下来,让我们定义一些我们的 MCP 服务器将公开的自定义工具。

我们将创建一个 AuthorRepository 类,该类提供获取作者详细信息的方法

class AuthorRepository {
    @Tool(description = "Get Baeldung author details using an article title")
    Author getAuthorByArticleTitle(String articleTitle) {
        return new Author("John Doe", "[email protected]");
    }

    @Tool(description = "Get highest rated Baeldung authors")
    List<Author> getTopAuthors() {
        return List.of(
          new Author("John Doe", "[email protected]"),
          new Author("Jane Doe", "[email protected]")
        );
    }

    record Author(String name, String email) {
    }
}

对于我们的演示,我们返回硬编码的作者详细信息,但在实际应用程序中,这些工具通常会与数据库或外部 API 交互。

我们使用 @Tool 注解标注我们的两个方法,并为每个方法提供一个简短的 descriptiondescription 帮助 AI 模型决定何时调用工具,并根据用户输入将结果合并到其响应中

接下来,让我们将我们的作者工具注册到 MCP 服务器

@Bean
ToolCallbackProvider authorTools() {
    return MethodToolCallbackProvider
      .builder()
      .toolObjects(new AuthorRepository())
      .build();
}

我们使用 MethodToolCallbackProviderAuthorRepository 类中定义的工具创建 ToolCallbackProvider bean。带有 @Tool 注解的方法将在应用程序启动时作为 MCP 工具公开

或者,我们可以根据特定条件在运行时动态注册工具

@Bean
CommandLineRunner commandLineRunner(
    McpSyncServer mcpSyncServer,
    @Value("${com.baeldung.author-tools.enabled:false}") boolean authorToolsEnabled
) {
    return args -> {
        if (authorToolsEnabled) {
            ToolCallback[] toolCallbacks = ToolCallbacks.from(new AuthorRepository());
            List<SyncToolSpecification> tools = McpToolUtils.toSyncToolSpecifications(toolCallbacks);
            tools.forEach(tool -> {
                mcpSyncServer.addTool(tool);
                mcpSyncServer.notifyToolsListChanged();
            });
        }
    };
}

这里,我们注入 Spring AI 自动创建的 McpSyncServer bean,以根据配置属性有条件地注册我们的工具。与 addTool() 类似,McpSyncServer 类还提供了 removeTool() 方法来删除某些工具。

对于我们的演示,我们使用的是 CommandLineRunner 接口;但是,我们可以在调用 REST API 时或响应应用程序事件时添加/删除工具。这对于根据用户权限、订阅层级或其他业务逻辑启用或禁用功能而言,尤其 有用

4.3. 配置自定义 MCP 服务器的 MCP 客户端

最后,为了在我们的聊天机器人应用程序中使用我们的自定义 MCP 服务器,我们需要配置一个针对它的 MCP 客户端

spring:
  ai:
    mcp:
      client:
        sse:
          connections:
            author-tools-server:
              url: https://:8081

application.yaml 文件中,我们配置针对我们自定义 MCP 服务器的新客户端。请注意,我们在这里使用 SSE 传输类型。

此配置假定 MCP 服务器正在 https://:8081 运行。如果它在不同的主机或端口上运行,我们需要确保更新 url

此外,如果我们启用了 MCP 服务器在运行时动态添加或删除工具,我们可以注册一个侦听器来检测这些工具的更改

@Bean
McpSyncClientCustomizer mcpSyncClientCustomizer() {
    return (name, mcpClientSpec) -> {
        mcpClientSpec.toolsChangeConsumer(tools -> {
            logger.info("Detected tools changes.");
        });
    };
}

这里,我们定义一个 McpSyncClientCustomizer 类型的 bean,并使用 toolsChangeConsumer() 方法注册一个侦听器。虽然我们为了简单起见而只是在这里进行记录,但在实际应用程序中,我们可以 刷新 ChatClient bean 或 以编程方式重新启动 我们的应用程序。

有了这个配置,我们的 MCP 客户端现在可以调用我们的自定义服务器公开的工具,以及 Brave Search 和 Filesystem MCP 服务器提供的工具

5. 与我们的聊天机器人交互

既然我们已经构建了我们的聊天机器人并将其与各种 MCP 服务器集成,让我们与它交互并对其进行测试。

我们将使用 HTTPie CLI 来调用聊天机器人的 API 端点

http POST :8080/chat question="How much was Elon Musk's initial offer to buy OpenAI in 2025?"

在这里,我们向聊天机器人发送一个简单的问题,询问发生在 LLM 的 知识截止日期之后的事件。让我们看看我们得到的回复

{
    "answer": "Elon Musk's initial offer to buy OpenAI was $97.4 billion. [Source](https://www.reuters.com/technology/openai-board-rejects-musks-974-billion-offer-2025-02-14/)."
}

正如我们所见,聊天机器人能够使用配置的 Brave Search MCP 服务器执行网络搜索,并提供准确的答案以及来源

接下来,让我们验证聊天机器人是否可以使用文件系统 MCP 服务器执行文件系统操作

http POST :8080/chat question="Create a text file named 'mcp-demo.txt' with content 'This is awesome!'."

我们指示聊天机器人创建一个名为 mcp-demo.txt 的文件,内容为特定内容。让我们看看它是否能够满足请求

{
    "answer": "The text file named 'mcp-demo.txt' has been successfully created with the content you specified."
}

聊天机器人回复了一个成功的响应。我们可以验证该文件是否已在 application.yaml 文件中指定的目录中创建。

最后,让我们验证聊天机器人是否可以调用我们自定义 MCP 服务器暴露的一个工具。我们将通过提及文章标题来询问作者的详细信息

http POST :8080/chat question="Who wrote the article 'Testing CORS in Spring Boot?' on Baeldung, and how can I contact them?"

让我们调用 API 并查看聊天机器人的响应是否包含硬编码的作者详细信息

{
    "answer": "The article 'Testing CORS in Spring Boot' on Baeldung was written by John Doe. You can contact him via email at [[email protected]](mailto:[email protected])."
}

以上响应验证了聊天机器人使用我们自定义 MCP 服务器暴露的 getAuthorByArticleTitle() 工具来获取作者详细信息。

我们强烈建议在本地设置代码库,并使用不同的提示语与聊天机器人进行试验。

6. 结论

在本文中,我们探讨了模型上下文协议并使用 Spring AI 实现了其客户端-服务器架构。

首先,我们使用 Anthropic 的 Claude 4 Opus 模型构建了一个简单的聊天机器人,作为我们的 MCP 主机。

然后,为了为我们的聊天机器人提供网络搜索能力并使其能够执行文件系统操作,我们针对 Brave Search API 和文件系统的预构建 MCP 服务器实现配置了 MCP 客户端。

最后,我们创建了一个自定义 MCP 服务器,并在我们的 MCP 主机应用程序中配置了其相应的 MCP 客户端。

支持本文的代码可在 GitHub 上获取。 一旦你Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。
Baeldung Pro – NPI EA (类别 = Baeldung)
announcement - icon

Baeldung Pro 具有完全无广告以及最终具有深色模式,提供干净的学习体验

>> 探索干净的 Baeldung

一旦早期采用者的席位全部用完,价格将上涨并保持在每年 33 美元。

电子书 – HTTP 客户端 – NPI EA (类别=HTTP 客户端)
announcement - icon

Apache HTTP Client 是一个非常强大的库,适用于简单和高级用例,在测试 HTTP 端点时尤其适用。 查看我们的指南,涵盖基本请求和响应处理,以及安全性、Cookie、超时等。

>> 下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

课程 – LS – NPI EA (类别=REST)

announcement - icon

从 Spring Boot 开始,通过 Learn Spring 课程了解核心 Spring。

>> 查看课程

合作伙伴 – Moderne – NPI EA (标签=重构)
announcement - icon

现代 Java 团队行动迅速——但代码库并不总是跟上。 框架会发生变化,依赖关系会漂移,技术债务会累积,直到它开始拖慢交付速度。 OpenRewrite 就是为此而构建的:一个开源重构引擎,可在保持开发人员意图不变的同时自动化重复的代码更改。

由 Moderne 的 OpenRewrite 创建者和维护者领导的每月培训系列,将介绍实际的迁移和现代化模式。 无论您是重构配方的新手,还是准备编写自己的配方,您都将学习以安全且可扩展的方式进行重构的实用方法。

如果您曾经希望重构感觉像编写代码一样自然——并且一样快速——这是一个很好的起点

电子书 Jackson – NPI EA – 3 (类别 = Jackson)
4 条评论
最早
最新
内联反馈
查看所有评论
© .