1. 项目缘起:为什么现在要关注 Spring AI Alibaba?
最近在和一些做企业级应用开发的朋友聊天,发现一个挺有意思的现象:大家一提到AI能力集成,第一反应还是去调OpenAI的API,或者自己吭哧吭哧去部署开源模型。但当问到模型管理、成本控制、私有化部署这些实际生产问题的时候,往往就开始头疼了。这让我想起了大概十年前,当大家刚开始用云服务的时候,也是类似的情况——直到出现了Spring Cloud Alibaba这样一套“开箱即用”的解决方案,才真正把微服务架构在企业里推开了。
现在,AI能力的集成似乎也走到了这个节点。Spring AI Alibaba的出现,在我看来,就是试图扮演这个“破局者”的角色。它不是一个全新的框架,而是Spring AI这个“标准接口”在阿里云生态下的具体实现。简单来说,Spring AI定义了一套统一的编程模型,让你写代码调用AI服务(比如聊天、画图、Embedding)时,不用关心背后到底是通义千问、ChatGPT还是自家的模型。而Spring AI Alibaba则负责把阿里云灵积平台上的各种模型服务,无缝地接入到这套模型里。
所以,如果你正在或者计划在基于Spring Boot的应用里引入AI能力,并且对模型的稳定性、可控性、成本有要求,那么花点时间搞明白Spring AI Alibaba的搭建和用法,很可能是一笔划算的投资。它帮你省去的是和不同AI服务商API打交道的琐碎,以及未来切换模型供应商时的重构成本。
2. 环境准备:从零开始搭建你的第一个AI应用
搭建的第一步,永远是准备好战场。这里我会假设你是一个有一定Spring Boot基础的开发者,从最干净的环境开始。
2.1 基础环境与工具选型
操作系统:推荐Linux(Ubuntu 20.04+ / CentOS 7+)或 macOS,Windows用户建议使用WSL2以获得最佳体验。这不是强制要求,但后续的一些命令行操作和依赖安装在Unix-like环境下更顺畅。
Java:这是基石。必须使用JDK 17 或更高版本。Spring AI 框架本身对JDK版本有要求,低于17将无法运行。我个人的习惯是直接上JDK 21 LTS版本,用Amazon Corretto或OpenJDK官方发行版都可以。安装后,记得检查环境变量:
java -version # 应该看到类似 openjdk version "21.0.3" 2024-04-16 LTS 的输出构建工具:Maven 3.6+或Gradle 7.x+。本文将以Maven为例,因为它的POM文件结构更直观,对于依赖管理一目了然。如果你团队用Gradle,转换配置也不难。
IDE:IntelliJ IDEA(终极版或社区版均可)或 VS Code + Java扩展包。IDEA对Spring Boot的支持是顶级的,特别是自动补全和配置提示,能极大提升效率。
网络:确保你的开发机能够稳定访问Maven中央仓库和阿里云的Maven镜像。后者对于下载Alibaba相关的构件会快很多。你可以在Maven的settings.xml文件中配置镜像。
2.2 创建Spring Boot项目骨架
最快的方式是使用 Spring Initializr 。在页面上进行如下选择:
- Project: Maven Project
- Language: Java
- Spring Boot: 选择当前最新的稳定版(如 3.2.x)。Spring AI Alibaba 通常需要较新的Boot版本。
- Project Metadata:按需填写
Group(如com.example)、Artifact(如ai-demo)。 - Dependencies:这里先只选择最基础的Spring Web。因为Spring AI Alibaba的依赖我们稍后手动添加,这样能更清楚地了解引入了哪些东西。
点击“GENERATE”下载压缩包,解压后用IDE打开。
打开项目后,你会看到一个标准的Spring Boot工程结构。现在,我们来编辑核心的pom.xml文件,引入关键依赖。
2.3 引入Spring AI Alibaba依赖
这是最关键的一步。我们需要添加两个核心依赖:spring-ai-alibaba-spring-boot-starter和spring-ai-alibaba-dashscope-spring-boot-starter。它们有什么区别呢?
spring-ai-alibaba-spring-boot-starter:这是基础启动器。它提供了与阿里云灵积平台交互的核心基础设施,比如通用的客户端、配置属性、健康指示器等。几乎所有场景下你都需要它。spring-ai-alibaba-dashscope-spring-boot-starter:这是模型特定的启动器。DashScope(灵积)是阿里云模型服务的品牌,这个starter包含了调用具体模型(如通义千问、通义万相)的客户端实现。你需要根据想用的模型来选择对应的starter。目前,DashScope是主要支持。
在你的pom.xml的<dependencies>部分,添加如下内容:
<dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-spring-boot-starter</artifactId> <version>${spring-ai-alibaba.version}</version> <!-- 使用最新版本 --> </dependency> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-dashscope-spring-boot-starter</artifactId> <version>${spring-ai-alibaba.version}</version> </dependency>注意这里的${spring-ai-alibaba.version}。你需要去 Maven中央仓库 查看最新稳定版本。在我撰写本文时,最新版本是1.0.0-M2。这是一个里程碑版本,API基本稳定,可用于学习和预生产环境。对于绝对稳定的生产环境,建议关注其GA(正式版)发布。
重要提示:Spring AI Alibaba 的版本命名可能包含
M(里程碑)或RC(候选版)。初期探索建议直接用最新版,以体验全部特性。如果求稳,可以寻找最新的稳定版(不带M/RC后缀的版本,如果有的话)。同时,确保Spring Boot版本与Spring AI Alibaba版本兼容,通常starter的文档或GitHub仓库的README会说明。
添加后,IDE应该会自动下载依赖。如果下载慢,记得检查Maven镜像配置。
3. 核心配置详解:连接阿里云灵积平台
依赖引入后,项目还不能运行,因为它不知道如何去连接阿里云的AI服务。接下来我们需要进行配置,这相当于给我们的应用一把“钥匙”。
3.1 获取阿里云API密钥
Spring AI Alibaba 通过阿里云的API密钥来进行身份认证和计费。你需要一个阿里云账号。
- 登录 阿里云控制台 。
- 在右上角头像处,进入“AccessKey管理”。
- 创建或使用一个已有的AccessKey。你会得到一对AccessKey ID和AccessKey Secret。请像保护密码一样保护它们,特别是Secret,一旦泄露可能造成资源盗用和经济损失。
- 开通灵积平台服务:在控制台搜索“灵积”或“DashScope”,进入服务页面,确保服务已开通。新用户通常有一定量的免费额度,足够用于开发和测试。
3.2 配置application.yml
在Spring Boot中,我们通常在src/main/resources/application.yml(或application.properties)中配置属性。YAML格式更清晰,推荐使用。
打开或创建application.yml,添加以下配置:
spring: application: name: ai-demo # Spring AI Alibaba 核心配置 spring: ai: alibaba: # 基础连接配置 base: # 从阿里云控制台获取 access-key-id: your-access-key-id-here access-key-secret: your-access-key-secret-here # 灵积API的端点,通常不需要改,除非使用特殊区域或私有化部署 endpoint: dashscope.aliyuncs.com # 连接超时和读取超时(毫秒),根据网络情况调整 connection-timeout: 5000 read-timeout: 30000 # DashScope 模型服务配置 dashscope: # 默认使用的聊天模型,例如通义千问系列 chat: options: model: qwen-turbo # 模型名称,例如 qwen-turbo, qwen-plus, qwen-max temperature: 0.8 # 温度参数,控制随机性 (0~1,越高越随机) top-p: 0.8 # 核采样参数,控制生成多样性 max-tokens: 2000 # 生成的最大token数 enable-search: false # 是否启用联网搜索(部分模型支持)配置项逐行解析:
access-key-id&access-key-secret:替换成你从控制台获取的真实密钥。绝对不要将真实的密钥提交到代码仓库!在生产环境中,必须使用环境变量、配置中心(如Nacos)或Kubernetes Secrets来管理。可以在本地开发时使用环境变量:
然后在export SPRING_AI_ALIBABA_BASE_ACCESS_KEY_ID=your-id export SPRING_AI_ALIBABA_BASE_ACCESS_KEY_SECRET=your-secretapplication.yml中这样引用:access-key-id: ${SPRING_AI_ALIBABA_BASE_ACCESS_KEY_ID} access-key-secret: ${SPRING_AI_ALIBABA_BASE_ACCESS_KEY_SECRET}endpoint:一般保持默认即可。如果你使用的是阿里云内部专有云或特定区域的服务,需要修改为此区域对应的端点。connection-timeout&read-timeout:网络超时设置。connection-timeout是建立TCP连接的超时,read-timeout是等待服务器响应的超时。对于AI生成这种可能较慢的任务,read-timeout可以设得长一些(比如30秒)。dashscope.chat.options.model:指定默认使用的聊天模型。qwen-turbo是响应速度最快、成本较低的版本,适合对话和简单任务。qwen-max是能力最强的版本,适合复杂推理和创作。你可以在灵积平台的模型广场查看所有可用模型及其特性。temperature&top-p:这两个参数共同控制生成的“创造性”和“稳定性”。简单理解,temperature越高,输出越随机、越有创意(也可能更胡言乱语);top-p越高,候选词范围越广。通常两者设置一个即可,建议temperature在0.7~0.9之间平衡创意与可控性。max-tokens:限制模型单次回复的最大长度(约等于字数*某个系数)。设置一个合理的值可以控制成本和响应时间。enable-search:部分模型(如qwen-max)支持联网搜索。开启后,模型在回答问题时可以获取实时信息。注意,这可能会增加调用延迟和成本。
4. 编写第一个AI对话服务
配置完成后,我们就可以编写业务代码了。Spring AI Alibaba 的核心是提供了高度抽象的ChatClient和ChatModel接口,让调用AI变得像调用本地方法一样简单。
4.1 创建ChatController
我们先创建一个简单的REST API端点,接收用户消息并返回AI的回复。
在src/main/java/com/example/aiemo/(你的包名)下创建controller包,然后创建ChatController.java:
package com.example.aidemo.controller; import com.alibaba.cloud.ai.dashscope.chat.api.ChatCompletion; import com.alibaba.cloud.ai.dashscope.chat.api.ChatCompletionMessage; import com.alibaba.cloud.ai.dashscope.chat.api.ChatCompletionParam; import org.springframework.ai.alibaba.chat.AlibabaChatClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.Arrays; @RestController @RequestMapping("/api/chat") public class ChatController { // 方式一:使用高级的 AlibabaChatClient (推荐) @Autowired private AlibabaChatClient chatClient; @PostMapping("/simple") public String chatSimple(@RequestBody String userMessage) { // 最简单的调用方式 String aiResponse = chatClient.call(userMessage); return aiResponse; } // 方式二:使用更底层的 DashScope API,进行更精细的控制 @PostMapping("/advanced") public ChatCompletion chatAdvanced(@RequestBody AdvancedChatRequest request) { // 构建消息历史 ChatCompletionMessage userMsg = ChatCompletionMessage.builder() .role(ChatCompletionMessage.Role.USER) .content(request.getMessage()) .build(); // 构建请求参数,可以覆盖application.yml中的默认配置 ChatCompletionParam param = ChatCompletionParam.builder() .model("qwen-plus") // 临时指定另一个模型 .messages(Arrays.asList(userMsg)) .temperature(0.5) // 临时调整温度 .topP(0.9) .maxTokens(1000) .build(); // 执行调用 ChatCompletion response = chatClient.chatCompletion(param); return response; // 返回完整的响应对象,包含更多元数据 } // 请求体定义 public static class AdvancedChatRequest { private String message; // getters and setters public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } } }代码解读与避坑点:
两种调用方式:
chatSimple:这是最快捷的方式。直接注入AlibabaChatClient,调用其call方法,传入用户消息字符串即可。框架会自动使用你在application.yml中配置的默认模型和参数。适合快速原型和简单场景。chatAdvanced:这种方式提供了完整的控制力。我们手动构建ChatCompletionParam,可以临时覆盖全局配置,比如切换模型、调整参数。返回的ChatCompletion对象包含了choices(候选回复列表)、usage(本次调用的token消耗)等丰富信息,对于需要记录成本或分析响应的场景非常有用。
@Autowiredvs 构造器注入:上述代码使用了字段注入@Autowired,简单直观。但在正式的、尤其是需要测试的项目中,更推荐使用构造器注入,因为它明确声明了依赖,且便于单元测试。private final AlibabaChatClient chatClient; public ChatController(AlibabaChatClient chatClient) { this.chatClient = chatClient; }消息角色(Role):在构建
ChatCompletionMessage时,我们指定了Role.USER。灵积的API遵循常见的聊天格式,消息角色还有Role.SYSTEM(系统指令,用于设定AI行为)和Role.ASSISTANT(AI之前的回复)。要实现多轮对话,你需要将历史消息(用户问、AI答)按顺序放入messages列表。错误处理:上面的代码没有处理异常。在实际项目中,AI服务调用可能因为网络、配额不足、模型过载、输入违规等原因失败。务必添加全局或局部的异常处理(
@ControllerAdvice+@ExceptionHandler),对不同类型的异常(如AlibabaApiException)进行友好处理,返回适当的HTTP状态码和错误信息给前端。
4.2 创建System Prompt配置(进阶)
很多时候,我们希望AI扮演一个特定的角色,比如“翻译助手”、“代码专家”、“客服机器人”。这可以通过系统提示词(System Prompt)来实现。
我们可以在配置中定义默认的系统提示词,也可以在每个请求中动态指定。
在application.yml中配置默认系统提示词:
spring: ai: alibaba: dashscope: chat: options: # ... 其他参数同上 system-prompt: | 你是一个专业的Java开发助手,精通Spring Boot和阿里云生态。 你的回答应该简洁、准确,并且提供可执行的代码示例。 如果用户的问题与Java开发无关,请礼貌地拒绝回答。这样配置后,通过AlibabaChatClient发起的每次对话,都会默认带上这个系统指令。
在代码中动态指定系统提示词:
@PostMapping("/translation") public String translate(@RequestBody TranslateRequest request) { ChatCompletionMessage systemMsg = ChatCompletionMessage.builder() .role(ChatCompletionMessage.Role.SYSTEM) .content("你是一个专业的英汉互译助手。只进行翻译工作,不要添加任何解释。") .build(); ChatCompletionMessage userMsg = ChatCompletionMessage.builder() .role(ChatCompletionMessage.Role.USER) .content("Translate the following to Chinese: " + request.getText()) .build(); ChatCompletionParam param = ChatCompletionParam.builder() .messages(Arrays.asList(systemMsg, userMsg)) // 系统消息在前 .build(); ChatCompletion response = chatClient.chatCompletion(param); return response.getChoices().get(0).getMessage().getContent(); }注意,消息列表(messages)的顺序很重要。通常,SYSTEM消息在最前面,然后是交替的USER和ASSISTANT历史消息,最后是当前的USER消息。
5. 运行、测试与问题排查
配置和代码都写好了,让我们把它跑起来,看看效果如何。
5.1 启动应用与健康检查
在IDE中找到主启动类(通常名为AiDemoApplication),运行它。或者在项目根目录下使用Maven命令:
mvn spring-boot:run如果一切顺利,控制台会输出Spring Boot的启动日志,最后看到类似Started AiDemoApplication in 5.123 seconds的信息。
Spring AI Alibaba Starter 会自动注册一个健康检查端点。打开浏览器,访问http://localhost:8080/actuator/health。你应该能看到一个JSON响应,其中包含alibabaAi的状态。如果配置正确,它应该是"UP"。如果状态是"DOWN",通常意味着API密钥错误或网络无法连接到灵积端点,请检查控制台日志中的错误信息。
5.2 使用工具测试API
现在我们来测试刚才写的两个接口。推荐使用Postman或curl命令行工具。
测试/api/chat/simple:
# 使用curl curl -X POST http://localhost:8080/api/chat/simple \ -H "Content-Type: application/json" \ -d '"你好,请介绍一下Spring Boot的核心优势。"' # 预期返回一个包含AI回复的字符串,例如: # "Spring Boot是一个用于简化Spring应用初始搭建和开发过程的框架..."测试/api/chat/advanced:
curl -X POST http://localhost:8080/api/chat/advanced \ -H "Content-Type: application/json" \ -d '{"message": "用Java写一个快速排序算法的示例"}' # 预期返回一个更复杂的JSON对象,包含模型、回复内容、token使用情况等。5.3 常见启动与运行问题排查
即使按照步骤操作,你也可能会遇到一些问题。这里列出几个我踩过的坑和解决方案:
启动报错:
Failed to configure a DataSource- 现象:应用启动失败,日志提示数据源配置错误。
- 原因:Spring Boot的自动配置机制检测到了JDBC相关的依赖(可能是你项目里间接引入的),但没有配置数据库连接信息。
- 解决:检查你的
pom.xml,排除不必要的JDBC或数据相关依赖。如果确实不需要数据库,可以在主启动类上添加排除自动配置的注解:@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
调用API返回
401 Unauthorized或InvalidAccessKeyId- 现象:健康检查
alibabaAi状态为DOWN,或调用接口时返回认证错误。 - 原因:API密钥(AccessKey ID/Secret)错误、失效,或者没有开通灵积服务。
- 解决:
- 仔细核对
application.yml或环境变量中的密钥,确保没有多余空格。 - 登录阿里云控制台,确认该AccessKey处于“启用”状态。
- 在灵积平台控制台,确认服务已开通,并且查看该AccessKey是否有调用权限(通常主账号的AK都有权限)。
- 仔细核对
- 现象:健康检查
调用超时
Read timed out- 现象:接口调用长时间无响应,最终抛出超时异常。
- 原因:网络问题,或者模型处理复杂请求时间过长。
- 解决:
- 首先,适当增加
spring.ai.alibaba.base.read-timeout的值,比如设为60000(60秒)。 - 检查本地网络是否能正常访问
dashscope.aliyuncs.com。 - 简化你的请求内容,或者换用响应更快的模型(如
qwen-turbo)。
- 首先,适当增加
依赖版本冲突
- 现象:启动时抛出
NoSuchMethodError或ClassNotFoundException。 - 原因:Spring AI Alibaba 依赖的某个库的版本,与你项目中其他依赖的版本不兼容。
- 解决:这是Maven/Gradle项目的老大难问题。使用
mvn dependency:tree命令查看完整的依赖树,找到冲突的库。然后可以在pom.xml中通过<exclusions>标签排除冲突的传递性依赖,或者使用<dependencyManagement>统一管理版本。Spring AI Alibaba的BOM(物料清单)尚未广泛提供,因此需要手动处理。
- 现象:启动时抛出
6. 生产级考量与进阶配置
一个玩具级的Demo跑通了,但要上生产环境,还有不少事情需要考虑。这部分内容决定了你的AI应用是否健壮、可维护、成本可控。
6.1 配置管理:告别硬编码
如前所述,API密钥绝不能写在代码或配置文件中提交到Git。在生产环境,你应该:
- 使用环境变量:这是最简单的方式。在Kubernetes Deployment、Docker Compose或服务器启动脚本中设置环境变量。
- 使用配置中心:对于微服务架构,推荐使用Nacos、Apollo等配置中心。将
spring.ai.alibaba.base.access-key-id等敏感信息存储在配置中心,应用启动时拉取。 - 使用云厂商的密钥管理服务:例如阿里云的KMS(密钥管理服务)或RAM角色,实现更安全的动态密钥获取。
6.2 连接池与客户端优化
高并发场景下,频繁创建和销毁HTTP连接会带来巨大开销。Spring AI Alibaba底层使用的HTTP客户端(可能是OkHttp或Apache HttpClient)通常自带连接池,但我们需要优化其参数。
这些配置可能在spring.ai.alibaba.base下,或者通过自定义RestTemplate或WebClientBean来配置。你需要查阅当前版本Spring AI Alibaba的官方文档,寻找关于连接池、最大连接数、存活时间等配置项。一个常见的模式是:
spring: ai: alibaba: base: # ... 其他配置 max-connections: 200 # 连接池最大连接数 connection-ttl: 300000 # 连接存活时间(毫秒) connection-time-to-live: 300000 # 连接最大存活时间如果没有直接配置项,你可能需要自己定义一个ConnectionProvider或HttpClientBean来替换默认实现。
6.3 熔断、降级与重试
AI服务是外部依赖,存在不稳定性风险。必须为AI调用添加弹性能力。
熔断(Circuit Breaker):使用Resilience4j或Sentinel。当调用失败率超过阈值时,快速失败,避免雪崩。
@CircuitBreaker(name = "aiChatService", fallbackMethod = "fallbackResponse") public String callAiWithCircuitBreaker(String prompt) { return chatClient.call(prompt); } public String fallbackResponse(String prompt, Throwable t) { return "AI服务暂时不可用,请稍后再试。"; }降级(Fallback):如上例,当主服务不可用时,返回一个预设的、功能简化的响应,保证核心业务流程不中断。
重试(Retry):对于网络抖动等临时性错误,自动重试可以提高成功率。同样可以用Resilience4j的
@Retry注解。@Retry(name = "aiChatService", fallbackMethod = "fallbackResponse") public String callAiWithRetry(String prompt) { return chatClient.call(prompt); }配置重试策略,如最大重试次数、重试间隔、重试哪些异常等。
6.4 监控与可观测性
你需要知道你的AI应用运行得怎么样。
- 指标(Metrics):Spring Boot Actuator 集成了Micrometer,可以轻松暴露应用指标。Spring AI Alibaba 应该会自动记录一些关键指标,如调用次数、成功/失败次数、延迟分布等。通过配置,可以将这些指标推送到Prometheus、Grafana进行可视化。
- 日志(Logging):确保AI调用的请求和响应(至少是元数据,如模型、token用量、耗时)被记录到日志中。你可以通过实现一个
ClientInterceptor或类似机制,在AlibabaChatClient调用前后打印日志。注意,不要记录完整的请求/响应内容(可能包含用户隐私),只记录摘要信息。 - 链路追踪(Tracing):在微服务环境中,使用SkyWalking、Jaeger等工具,将一次用户请求背后的AI调用也纳入追踪链路,便于排查复杂问题。
6.5 成本控制与用量统计
AI API调用是按token计费的,费用可能快速增长。
- 记录
usage:每次调用返回的ChatCompletion对象里都有usage字段,包含了本次请求消耗的prompt_tokens、completion_tokens和total_tokens。务必在业务代码中捕获并存储这些数据到数据库或监控系统。 - 设置预算与告警:在阿里云费用中心为灵积服务设置预算和消费告警。当月度消费达到预算的80%、90%时,及时收到通知。
- 限流(Rate Limiting):在应用层面,根据用户或API端点实施限流。例如,使用Guava的
RateLimiter或Spring的@ControllerAdvice配合计数器,防止单个用户恶意刷量消耗token。 - 模型选型:根据业务场景选择性价比合适的模型。简单的问答用
qwen-turbo,复杂的分析再用qwen-max。可以在代码中根据请求的复杂度动态选择模型。
7. 扩展探索:超越简单的聊天
Spring AI Alibaba 不仅仅支持聊天。灵积平台提供了多种模型能力,理论上都可以通过相应的Starter或自定义客户端集成。
7.1 多模态:图像生成与理解
除了文本,AI还能处理图像。例如,使用通义万相进行文生图。
你需要引入对应的依赖(如果存在独立的starter),或者研究如何使用基础的AlibabaChatClient配合特定的模型参数来调用图像生成API。通常,这需要构建不同的请求参数体,指定model为图像生成模型(如wanx-v1),并在messages中提供图像生成的描述(prompt)。
// 伪代码,具体API需参考官方文档 ImageGenerationParam param = ImageGenerationParam.builder() .model("wanx-v1") .prompt("一只戴着礼帽、喝着咖啡的卡通猫,数字艺术风格") .size("1024x1024") .n(1) // 生成数量 .build(); ImageGenerationResponse response = imageClient.generate(param); String imageUrl = response.getData().get(0).getUrl(); // 获取生成图片的URL7.2 Embedding与向量检索
这是构建AI知识库、实现智能搜索的基石。Embedding模型可以将文本转换为高维向量。Spring AI 提供了统一的EmbeddingClient接口。
- 引入Embedding Starter:查找是否有
spring-ai-alibaba-dashscope-embedding-spring-boot-starter。 - 配置Embedding模型:在
application.yml中配置Embedding相关参数,如模型text-embedding-v2。 - 注入并使用
EmbeddingClient:@Autowired private EmbeddingClient embeddingClient; public List<Double> getEmbedding(String text) { // 将文本转换为向量 List<Double> vector = embeddingClient.embed(text); return vector; } - 构建向量数据库:将得到的向量存入专业的向量数据库(如Milvus, Weaviate, pgvector等),后续即可进行相似度检索,实现“基于自有知识库的问答”。
7.3 函数调用(Function Calling)
这是让AI与你的业务系统交互的强大功能。你可以定义一系列工具函数(如“查询天气”、“创建订单”),让AI在对话中判断是否需要调用这些函数,并生成结构化的参数。
Spring AI 对函数调用有抽象支持。你需要:
- 定义工具函数(一个普通的Java方法,用
@Tool注解描述)。 - 将这些函数注册到
ChatClient或ChatModel。 - 在对话中,AI会输出一个包含函数调用请求的特殊响应,你的代码需要解析这个响应,执行对应的Java函数,并将结果返回给AI,由AI整合成最终回复给用户。
这涉及到更复杂的消息流处理,是构建智能Agent的关键一步。
7.4 流式响应(Streaming)
对于长文本生成,等待全部生成完毕再返回给用户体验很差。流式响应允许服务器端一边生成,一边以SSE(Server-Sent Events)或WebSocket的形式将片段推送给前端,实现打字机效果。
Spring AI 的ChatClient通常提供了stream方法。你需要调整你的Controller,返回一个Flux(响应式编程)或使用SseEmitter。
@GetMapping(value = "/chat/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> streamChat(@RequestParam String message) { return chatClient.stream(message) .map(chunk -> chunk.getContent()); // 将响应流中的每个片段映射为内容 }前端则需要使用EventSourceAPI来接收这个流。
搭建一个Spring AI Alibaba项目,从引入依赖到写出第一个可用的接口,其实门槛并不高。真正的挑战在于后续的“生产化”:如何管理配置、如何保证稳定性、如何控制成本、如何扩展能力。这篇文章详细走通了从零到一的过程,并指出了从一到一百需要考虑的方向。我的建议是,先从简单的聊天功能入手,快速验证业务场景的可行性。一旦验证通过,立刻着手完善监控、熔断和成本统计。当这些基础设施就位后,再逐步探索Embedding、函数调用等更高级的特性,这样步子迈得稳,也不容易在后期陷入架构混乱的泥潭。