乐于分享
好东西不私藏

Javaer的AI学习之路——Spring AI 入门:(2)快速搭建一个简单的问答

Javaer的AI学习之路——Spring AI 入门:(2)快速搭建一个简单的问答

本章导读:在理解了Spring AI的核心概念之后,现在让我们进入动手实践环节。本章将以阿里云通义千问(Qwen)大模型为例,从零开始搭建一个完整的Spring AI应用,并成功完成第一次AI对话。读完本章,你将拥有一个可运行的智能对话服务,并掌握以下能力:获取并使用通义千问API Key、配置Spring Boot项目集成通义千问、使用ChatClient完成对话请求、处理常见的启动报错与调试问题。

3.1 环境准备

在开始编码之前,我们需要完成两件准备工作:获取阿里云通义千问的API访问凭证,以及创建一个Spring Boot项目。

3.1.1 获取通义千问API Key

API Key是调用通义千问服务的唯一凭证,获取过程分为两步:开通服务、创建并保存密钥。 

第一步:开通DashScope服务

 DashScope(灵积)是阿里云的大模型服务平台,通义千问系列模型的API统一由该平台管理。打开浏览器,访问阿里云DashScope控制台首页,如果尚未登录,请先登录你的阿里云账号(如无账号,需先免费注册)。进入页面后,在“总览”区域单击“去开通”按钮,阅读并勾选《DashScope服务协议》,确认无误后点击“立即开通”,系统会在几秒钟内激活服务。

 第二步:创建并保管API Key

 服务开通后,页面会自动跳转至API-KEY管理页面,你也可以在控制台左侧导航栏手动点击“API-KEY管理”进入。在API-KEY管理页面,点击“创建新的API-KEY”按钮,系统弹窗会显示新生成的API Key字符串(格式以sk-开头)。

新账号创建完,会给一些免费的额度,可以在模型用量查看:

第三步:验证API Key可用性

 创建完成后,可以通过cURL快速测试Key是否有效。打开终端或命令行,执行以下命令(将YOUR_API_KEY替换为实际获取到的Key):

curl -X POST "https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions" \  -H "Authorization: Bearer YOUR_API_KEY" \  -H "Content-Type: application/json" \  -d '{"model": "qwen-plus", "messages": [{"role": "user", "content": "你好"}]}'

如果返回的JSON中包含choices数组及非空的message字段,则说明API Key已激活且具备调用权限。 

补充说明:本章采用Spring AI官方的OpenAI Starter,通过配置base_url指向DashScope提供的OpenAI兼容端点来调用通义千问。这种方式完全基于Spring AI官方框架,不依赖任何Alibaba专用包,Spring AI通过重用现有的OpenAI客户端与兼容OpenAI接口的模型服务进行集成。切换base_url和模型名称即可迁移现有的OpenAI代码至DashScope。

3.1.2 创建Spring Boot项目

使用Spring Initializr创建基础项目,推荐选择以下配置:

 ● 项目构建工具:Maven(本文以此为例) 

● Spring Boot版本:3.2.x 或更高版本 

● Java版本:17 或 21 

● 依赖项选择:先勾选 Spring Web 即可,其他依赖稍后手动添加

 项目创建完成后,打开IDE(如IntelliJ IDEA或VS Code),等待依赖下载完毕。 

JDK版本说明:Spring AI官方要求构建环境Java 21+,运行时兼容Java 17。推荐使用JDK 21以获得更好的性能和虚拟线程支持,但如果你的环境暂时只有JDK 17,也可以正常运行。

3.2 添加依赖与配置

3.2.1 添加Maven依赖

Spring AI提供了官方的OpenAI Starter,这是与AI模型通信的核心依赖。在项目的pom.xml文件中,首先需要添加Spring AI的BOM,以便统一管理各模块的版本:

<properties><java.version>21</java.version><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot.version>3.2.5</spring-boot.version><spring-ai.version>1.1.7</spring-ai.version></properties><dependencyManagement><dependencies><!-- Spring AI BOM --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

然后在节点中添加OpenAI Starter:

</dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency>

如果还需要使用Spring Web能力,可以一并添加:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

完成以上配置后,Maven会自动下载Spring AI相关的依赖包。

3.2.2 配置application.yml

在src/main/resources目录下,创建或编辑application.yml文件,配置通义千问的API Key和模型参数。这里的关键是将base-url指向DashScope的OpenAI兼容端点,即可无缝调用通义千问:

spring:application:name:spring-ai-tutorialai:openai:api-key:${AI_DASHSCOPE_API_KEY}# 复用通义千问的API Key,使用环境变量引用base-url:https://dashscope.aliyuncs.com/compatible-mode# DashScope OpenAI兼容端点chat:options:model:qwen3.6-plus# 通义千问模型名称temperature:0.7# 控制输出随机性,范围0~2,越低越确定性server:port:8080servlet:encoding:charset:UTF-8enabled:trueforce:true

配置中使用了环境变量引用(${AI_DASHSCOPE_API_KEY})而不是直接写明文Key——这是一种良好的安全实践,避免API Key被误提交到版本控制系统。

需要在系统环境中配置此变量: 

  • Windows命令行:set AI_DASHSCOPE_API_KEY=你的API-Key 

  • macOS/Linux终端:export AI_DASHSCOPE_API_KEY="你的API-Key" 

另外,还可以选择在IDE的运行配置中直接设置环境变量——以IntelliJ IDEA为例:进入Run → Edit Configurations → 在Environment variables中添加AI_DASHSCOPE_API_KEY=你的API-Key,这样运行Spring Boot应用时就会自动加载。 

当然,如果只是自己写写,可以直接卸载配置文件,但记住生产环境切不可这么做。

3.2.3 关于模型名称的说明

阿里云DashScope平台通过OpenAI兼容接口支持多种通义千问模型供选择:

模型系列
示例名称
特点
适用场景
Qwen-Max系列
qwen-max, qwen3-max
推理能力最强,效果最优
复杂推理、专业任务
Qwen-Plus系列
qwen-plus
平衡性能与成本,能力均衡
日常对话、内容生成
Qwen-Flash系列
qwen-flash
响应速度快,成本低
高频对话、简单问答

新用户通常有免费的额度可供体验,建议先从qwen-plus开始,它兼顾了响应质量和成本效率。如果追求极致速度,可以切换到qwen-flash;如果处理复杂的逻辑推理任务,则可以选择qwen-max。

3.3 编写第一个Chat接口

3.3.1 创建Controller

创建一个RESTful Controller来暴露对话接口。Spring AI的自动配置会自动扫描并注入所需的ChatClient.Builder实例,我们通过构造器注入即可使用:

package com.springai.guide.controller;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.ai.chat.client.ChatClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;/** * 示例控制器 */@RestController@RequestMapping("/api")publicclassHelloController {privatestaticfinalLoggerlog= LoggerFactory.getLogger(HelloController.class);privatefinal ChatClient chatClient;// 通过构造器注入ChatClient.Builder,然后构建ChatClient实例publicHelloController(ChatClient.Builder builder) {        log.info("=== ChatClient 初始化 ===");/**         * hatClient.Builder 已注入,将使用 application.yml 中的配置         * 配置项: spring.ai.openai.api-key, base-url, chat.options.model 等         * 这些配置已由 Spring AI 自动配置类加载并注入到 Builder 中         *         */// 可选:设置默认的系统提示词,定义AI的角色和行为this.chatClient = builder                .defaultSystem("你是一个乐于助人的AI助手,回答要简洁、准确、友好。")                .build();        log.info("ChatClient 构建完成,可以开始使用");        log.info("========================");    }// 同步对话接口:GET方式,接收消息参数,返回AI回答@GetMapping("/chat")public String chat(@RequestParam(value = "msg", defaultValue = "你好") String msg) {return chatClient.prompt()                .user(msg)       // 设置用户输入的内容                .call()          // 发送请求给AI模型,同步等待响应                .content();      // 获取AI返回的回答文本    }}

上述代码的核心是ChatClient的链式调用:

prompt().user(msg).call().content()

是一个流畅的API,让我们可以用一行代码完成构造提示、发送请求、获取响应的全过程。

3.3.2 启动类

确保主启动类存在且包含@SpringBootApplication注解。Spring AI的自动配置会自动扫描并注入所需的Bean,无需额外配置:

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassApplication {publicstaticvoidmain(String[] args) {        SpringApplication.run(Application.class, args);    }}

3.3.3 ChatModel与ChatClient的选择

在Spring AI中,与AI模型交互主要有两种方式:ChatModel和ChatClient。 ChatModel是底层模型接口,直接与AI模型进行原始通信,适用于需要精细控制调用细节的场景。例如:

ChatResponseresponse= chatModel.call(newPrompt("你好"));Stringresult= response.getResult().getOutput().getContent();

ChatClient则是封装了复杂交互流程的高阶API,提供了链式调用语法,功能更丰富。我们本章使用的是ChatClient,它支持系统提示词设置、结构化输出、工具调用等高级功能。

 两者各有适用场景: 

  • 入门学习阶段:两者皆可使用,ChatModel更简单直接,ChatClient则功能更完备,建议从ChatClient开始,后续章节的功能都需要基于它来实现。 

  • 功能扩展阶段:需要聊天记忆、工具调用、RAG等高级功能时,ChatClient是首选。 

  • 性能敏感场景:关注底层响应细节时,可以选择ChatModel配合流式输出。

3.4 测试

启动应用后,打开浏览器或API测试工具(如Postman、Apifox),访问以下地址:

http://localhost:8080/chat?msg=你好,请介绍一下你自己

你也可以使用cURL命令快速测试:

curl "http://localhost:8080/chat?msg=你好,请介绍一下你自己"

预期效果:通义千问模型会返回一段自我介绍的回答,例如:“你好!我是通义千问,是阿里云开发的大语言模型,可以帮你回答问题、生成内容、编写代码……” 。

如果使用的是DeepSeek等模型,返回的内容会是相应模型的自我介绍。

3.5 增强版本:加入系统提示词

除了简单的用户消息,你还可以在构建ChatClient时设置默认的系统提示词,让AI扮演特定角色——系统提示用于设定AI的行为规范和角色定位,用户提示则是具体的提问内容:

@RestControllerpublicclassChatController {privatefinal ChatClient chatClient;publicChatController(ChatClient.Builder builder) {// 在构建ChatClient时设置默认系统提示词this.chatClient = builder                .defaultSystem("你是一个专业的Java技术专家,精通Spring Boot、微服务架构和性能优化。" +"回答要简洁、准确,尽量给出代码示例。如果涉及代码,请使用Java语言。")                .build();    }@GetMapping("/chat")public String chat(@RequestParam(defaultValue = "你好") String msg) {return chatClient.prompt()                .user(msg)                .call()                .content();    }// 需要临时覆盖系统提示词时,可以在调用时指定@GetMapping("/chat/with-system")public String chatWithSystem(@RequestParam(value = "msg", defaultValue = "你是谁?") String msg,@RequestParam(defaultValue = "你是一个医疗问答助手,你叫小依") String system) {return chatClient.prompt()                .system(system)  // 临时覆盖默认系统提示词                .user(msg)                .call()                .content();    }}

这种方式让AI以特定身份回答问题,回复中将包含更多专业术语和代码示例,适合技术问答场景。 再次启动调用/chat/with-system接口,结果如下:

你好!我是小依,你的专属医疗问答助手。如果你有任何关于健康、疾病、用药、检查报告或日常保健的问题,都可以随时告诉我。我会尽力为你提供专业、清晰的参考信息。请问今天有什么可以帮你的吗?

注意: 在 Spring MVC 中,@RequestParam 如果不指定 name 或 value 属性,会默认将方法参数名作为请求参数的名称。因此: @RequestParam(defaultValue = "你是一个医疗问答助手,你叫小依") String system 等价于: @RequestParam(name = "system", defaultValue = "你是一个医疗问答助手,你叫小依") String system。

 需要注意的是:Maven 编译器默认不启用 -parameters 标志,导致运行时无法获取方法参数名。 可以在pom文件加上:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><parameters>true</parameters></configuration></plugin>

这样会让 Java 编译器在生成的 .class 文件中保留方法参数名称,Spring MVC 就能通过反射获取 @RequestParam 的参数名。

3.6 常见问题与调试技巧

3.6.1 API Key无效或认证失败

启动后调用接口时报错类似401 Unauthorized或Invalid API Key时,请确认:

  • API Key是否正确设置,且格式以sk-开头 

  • 如果使用环境变量引用,确认环境变量在启动Shell或IDE配置中已正确导出 

  • API Key对应的DashScope服务是否已成功开通,部分新用户需要等待几分钟服务生效 

  • 检查application.yml中的api-key是否正确地引用了环境变量,注意YAML的缩进格式

3.6.2 模型名称或端点错误

如果报错提示模型不存在(如Model not found)或连接失败(如Connection refused),请检查: 

  • application.yml中model配置的模型名称是否正确——确认使用的是qwen-plus、qwen-max或qwen-flash等官方提供的模型名称,注意大小写和连字符要完全一致 

  • base-url是否配置正确——国内用户使用https://dashscope.aliyuncs.com/compatible-mode/v1,海外用户可能需要切换到https://dashscope-intl.aliyuncs.com/compatible-mode/v1 [2] ● 如果使用的是企业内网,可能需要对DashScope的域名配置代理或DNS解析

3.7 本章小结

在本章中,我们: 

  • 获取了阿里云通义千问的API Key,完成了Spring Boot项目的依赖配置

  • 通过OpenAI兼容模式将DashScope服务接入Spring AI,理解了base-url配置的关键作用 

  • 编写了一个基于ChatClient的Controller,成功发起了第一次AI对话 

  • 测试了带系统提示词的增强版本,了解了如何让AI扮演特定角色 

  • 探讨了常见启动报错的排查方法 

第一个Spring AI应用已经跑通了——虽然现在它只是一个简单的问答接口,但已经掌握了Spring AI集成的核心模式。后面,将深入探讨ChatClient API的更多能力,学习如何更灵活地构造提示词、处理结构化输出,让AI回答真正为你的业务服务。

参考来源 

● Spring AI官方ChatClient文档 

● 阿里云DashScope OpenAI兼容模式指南 

● Spring AI OpenAI Starter配置参考

相关学习资料