Spring AI 入门:(3)快速搭建一个简单的问答助手

目录

  • [3.1 环境准备](#3.1 环境准备)
    • [3.1.1 获取通义千问API Key](#3.1.1 获取通义千问API Key)
    • [3.1.2 创建Spring Boot项目](#3.1.2 创建Spring Boot项目)
  • [3.2 添加依赖与配置](#3.2 添加依赖与配置)
    • [3.2.1 添加Maven依赖](#3.2.1 添加Maven依赖)
    • [3.2.2 配置application.yml](#3.2.2 配置application.yml)
    • [3.2.3 关于模型名称的说明](#3.2.3 关于模型名称的说明)
  • [3.3 编写第一个Chat接口](#3.3 编写第一个Chat接口)
    • [3.3.1 创建Controller](#3.3.1 创建Controller)
    • [3.3.2 启动类](#3.3.2 启动类)
    • [3.3.3 ChatModel与ChatClient的选择](#3.3.3 ChatModel与ChatClient的选择)
  • [3.4 测试](#3.4 测试)
  • [3.5 增强版本:加入系统提示词](#3.5 增强版本:加入系统提示词)
  • [3.6 常见问题与调试技巧](#3.6 常见问题与调试技巧)
    • [3.6.1 API Key无效或认证失败](#3.6.1 API Key无效或认证失败)
    • [3.6.2 模型名称或端点错误](#3.6.2 模型名称或端点错误)
  • [3.7 本章小结](#3.7 本章小结)

本章导读:在理解了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):

bash 复制代码
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,以便统一管理各模块的版本:

xml 复制代码
<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:

xml 复制代码
</dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
 </dependency>

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

xml 复制代码
<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兼容端点,即可无缝调用通义千问:

yaml 复制代码
spring:
  application:
    name: spring-ai-tutorial
  ai:
    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: 8080
  servlet:
    encoding:
      charset: UTF-8
      enabled: true
      force: 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实例,我们通过构造器注入即可使用:

java 复制代码
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")
public class HelloController {

    private static final Logger log = LoggerFactory.getLogger(HelloController.class);
    private final ChatClient chatClient;

    // 通过构造器注入ChatClient.Builder,然后构建ChatClient实例
    public HelloController(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,无需额外配置:

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3.3.3 ChatModel与ChatClient的选择

在Spring AI中,与AI模型交互主要有两种方式:ChatModel和ChatClient。

ChatModel是底层模型接口,直接与AI模型进行原始通信,适用于需要精细控制调用细节的场景。例如:

java 复制代码
ChatResponse response = chatModel.call(new Prompt("你好"));
String result = response.getResult().getOutput().getContent();

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

两者各有适用场景:

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

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

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

3.4 测试

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

bash 复制代码
http://localhost:8080/chat?msg=你好,请介绍一下你自己

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

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

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

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

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

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

java 复制代码
@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(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接口,结果如下:

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

注意:

在 Spring MVC 中,@RequestParam 如果不指定 name 或 value 属性,会默认将方法参数名作为请求参数的名称。因此:

@RequestParam(defaultValue = "你是一个医疗问答助手,你叫小依") String system

等价于:

@RequestParam(name = "system", defaultValue = "你是一个医疗问答助手,你叫小依") String system

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

可以在pom文件加上:

xml 复制代码
<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

● 如果使用的是企业内网,可能需要对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配置参考

相关推荐
屋外雨大,惊蛰出没1 小时前
starter的创建与引用
java·stater
高兴高兴张高兴1 小时前
张高兴的 Hailo-10 开发指南:(一)实现离线语音识别
人工智能·语音识别
小同志001 小时前
Spring Boot ⽇志概述(简单了解)
java·java-ee·日志
霸道流氓气质1 小时前
Spring AI Alibaba + Ollama+Embedding向量化项目完整指南
人工智能·spring·embedding
小马爱打代码1 小时前
SpringBoot + 延迟消息 + 时间轮:订单超时、优惠券过期等场景的高效实现方案
java·spring boot·后端
键盘侠伍十七1 小时前
garak 如何探测 LLM 的越狱漏洞
人工智能·大模型·大模型安全·越狱攻击·garak·jailbreaking
就叫_这个吧1 小时前
Java普通类、抽象类、接口的应用和区别
java·开发语言
程序猿阿伟1 小时前
《企业IT系统无缝集成指南》
人工智能
梅孔立1 小时前
解决Nginx缓存不写入响应体问题:浏览器强制不缓存配置教程
java·开发语言·nginx·spring