☰
Spring AI Alibaba 从入门到进阶实战:ChatClient 接入与 RAG 检索增强笔记
2026/10/7 7:06:29 网站建设 项目流程

1. 从零跑通 Spring AI Alibaba:ChatClient 接入阿里云百炼模型到底解决什么问题

如果你正在用 Java 写业务系统,又想快速把大模型能力接进来,Spring AI Alibaba 是一个绕不开的选择。它是基于 Spring AI 构建的框架,专门针对阿里云生态做了深度集成,适合国内开发者,尤其是需要快速接入阿里云百炼平台模型能力的场景。简单说,它让你不用手写一堆 HTTP 请求和 JSON 解析,直接用 Spring 的依赖注入和 Fluent API 就能调用通义千问系列模型。

我第一次接触它的时候,最大的感受是:终于不用在 Java 项目里手动拼HttpClient去调大模型接口了。ChatClient 提供了与 AI 模型通信的 Fluent API,支持同步和响应式(Reactive)编程模式。和 ChatModel、Message、ChatMemory 等原子 API 相比,ChatClient 把与 LLM 交互的复杂性隐藏在背后,因为基于 LLM 的应用程序通常要多个组件协同工作——提示词模板、聊天记忆、LLM Model、输出解析器、RAG 组件(嵌入模型和存储),协调它们会让代码变得复杂。ChatClient 类似应用开发中的服务层,为应用程序直接提供 AI 服务。

这篇文章我会带你走两条主线:第一条是用 ChatClient 调用阿里云百炼模型,跑通第一个对话接口;第二条是 RAG 检索增强,让模型能基于你自己的知识库回答问题。两条线都会给出可复制的依赖配置和关键代码片段,并附上本地启动与接口验证动作。你跟着做,能跑通第一个对话与知识库问答示例。

适合谁看?有 Java 和 Spring Boot 基础,想快速把大模型接入业务系统的后端开发者;或者已经在用 Spring AI,但想换成阿里云百炼模型、需要 RAG 能力的同学。不需要你有大模型训练经验,但需要你能跑 Maven 项目、会看日志。

我试过从零搭一个 demo,踩过的坑主要集中在依赖版本和 API Key 配置上,后面会专门讲排查。先看整体路径:加依赖 → 配 Key → 写 ChatClient → 验证对话 → 加 RAG → 验证知识库问答。每一步都有可复制的代码。

2. TaoToken 前置准备:API Key 与 Base URL 怎么配才不报 401

在写代码之前,先把模型访问的凭证准备好。Spring AI Alibaba 默认对接阿里云百炼平台,你需要一个 DashScope 的 API Key。但实际开发中,很多同学会遇到网络环境或者账号权限的问题,这时候可以用 TaoToken 作为统一的模型接入层,它兼容 OpenAI 风格的接口,配置起来更灵活。

TaoToken 的 API 地址是https://taotoken.net/api,注意这个地址不加 UTM 参数,直接用于代码里的 Base URL。你需要先去控制台创建一个 API Key,然后把它填到 Spring Boot 的配置文件里。如果你用的是 Coding Plan 或者需要长期跑 Agent 任务,建议单独申请一个 Key,避免和测试用的混在一起。

具体操作路径:打开https://taotoken.net/console创建 Key,然后在https://taotoken.net/api-keys页面可以管理你的所有 Key。创建完之后,复制那串sk-开头的字符串,后面配置文件里要用。

这里有个关键点:Spring AI Alibaba 默认走的是 DashScope 的 SDK,但如果你用 TaoToken 的兼容接口,需要把 Base URL 指向https://taotoken.net/api,同时把模型名称写成百炼平台支持的模型 ID,比如qwen-plus或qwen-max。这样你的代码不用大改,只改配置就能切换接入层。

我建议你在application.yml里这样写:

spring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} base-url: https://taotoken.net/api chat: options: model: qwen-plus

然后通过环境变量注入 Key,不要硬编码在代码里。本地开发可以用.env文件或者 IDE 的运行配置。如果你用 Maven 多模块,确保spring-ai-alibaba-starter的版本和 Spring Boot 版本匹配,否则启动时会报NoSuchMethodError。

另外,如果你需要看模型对话的效果,可以直接在https://taotoken.net/models页面测试;需要接文档的话,https://taotoken.net/doc有完整的接口说明。这些前置动作做完,再写代码就顺了。

3. 可复制配置:pom.xml 依赖与 ChatClient 关键代码片段

这一节直接给可复制的配置。先看pom.xml,核心依赖是spring-ai-alibaba-starter:

<dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> <version>1.0.0-M6.1</version> </dependency>

如果你要用 RAG,还需要加上向量存储的依赖,比如spring-ai-alibaba-starter已经包含了SimpleVectorStore,但生产环境建议用 Redis 或者百炼云知识库。这里先用内存版跑通。

接下来是application.yml的完整配置,注意路径和原文一致:

server: port: 8080 spring: application: name: spring-ai-alibaba-demo ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} base-url: https://taotoken.net/api chat: options: model: qwen-plus temperature: 0.7

然后写一个ChatClient的配置类,用ChatClient.Builder创建实例。你可以自动注入 Spring Boot 自动配置创建的默认ChatClient.Builder,也可以自己 new 一个。推荐用自动配置的:

@Configuration public class ChatClientConfig { @Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder .defaultSystem("你是一个友好的聊天机器人,回答问题时使用{voice}的语气") .build(); } }

接着写 Controller,提供一个/ai接口:

@RestController public class AIController { private final ChatClient chatClient; public AIController(ChatClient chatClient) { this.chatClient = chatClient; } @GetMapping("/ai") Map<String, String> completion( @RequestParam(value = "message", defaultValue = "说一个笑话") String message, @RequestParam(value = "voice", defaultValue = "幽默") String voice) { return Map.of( "completion", this.chatClient.prompt() .system(sp -> sp.param("voice", voice)) .user(message) .call() .content()); } }

这段代码里,system方法用来覆盖默认的 system message,user是用户输入,call发起请求,content返回字符串。如果你想拿完整的ChatResponse,把content()换成chatResponse()就行。

如果你要返回实体类,比如ActorFilms,可以这样写:

record ActorFilms(String actor, List<String> movies) {} @GetMapping("/movies") public ActorFilms movies(@RequestParam(value = "input") String input) { return this.chatClient.prompt() .user(input) .call() .entity(ActorFilms.class); }

注意,.entity()必须传入目标类,否则返回的是字符串。如果要返回List<ActorFilms>,用ParameterizedTypeReference:

List<ActorFilms> list = this.chatClient.prompt() .user(input) .call() .entity(new ParameterizedTypeReference<List<ActorFilms>>() {});

流式输出用stream():

@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<String> stream(String input) { return this.chatClient.prompt() .user(input) .stream() .content(); }

这些代码片段可以直接复制到你的项目里,改一下包名就能跑。

4. 验证请求与成功结果:curl 测试对话接口和 RAG 知识库问答

配置写完之后,启动 Spring Boot 应用,看到Started Application in x seconds就说明起来了。然后用 curl 测试第一个对话接口:

curl "http://localhost:8080/ai?message=你好&voice=幽默"

如果返回类似{"completion":"你好呀!..."}的 JSON,说明 ChatClient 接入成功。如果报 401,检查 API Key 是否正确;如果报Connection refused,检查 Base URL 是否写成了https://taotoken.net/api。

接下来验证流式输出:

curl -N "http://localhost:8080/stream?input=讲个笑话"

你会看到 SSE 格式的数据一行行返回,每行以data:开头。这说明stream()方法工作正常。

然后验证 RAG。先写一个RagConfig,创建一个SimpleVectorStore并加载文档:

@Configuration public class RagConfig { @Bean VectorStore vectorStore(EmbeddingModel embeddingModel) { SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build(); List<Document> documents = List.of( new Document("产品说明书:产品名称:智能机器人\n" + "产品描述:智能机器人是一个智能设备,能够自动完成各种任务。\n" + "功能:\n" + "1. 自动导航:机器人能够自动导航到指定位置。\n" + "2. 自动抓取:机器人能够自动抓取物品。\n" + "3. 自动放置:机器人能够自动放置物品。\n")); simpleVectorStore.add(documents); return simpleVectorStore; } }

然后写 RAG Controller:

@RestController @RequestMapping("/ai") public class RagController { @Autowired private ChatClient chatClient; @Autowired private VectorStore vectorStore; @GetMapping(value = "/chat", produces = "text/plain; charset=UTF-8") public String generation(String userInput) { return chatClient.prompt() .user(userInput) .advisors(new QuestionAnswerAdvisor(vectorStore)) .call() .content(); } }

启动后测试:

curl "http://localhost:8080/ai/chat?userInput=智能机器人有哪些功能?"

如果返回的内容包含“自动导航、自动抓取、自动放置”,说明 RAG 检索增强生效了。你可以把文档换成自己的业务数据,比如产品手册、FAQ,模型就会基于这些内容回答。

这里有个细节:QuestionAnswerAdvisor会自动把用户问题和向量库里的相似文档拼成 prompt,再发给模型。你不需要手动拼上下文。如果检索不到相关内容,模型会基于自己的知识回答,这时候可以调大topK或者换更好的 Embedding 模型。

5. 本篇常见错排查:401、local proxy failed、reading choices 怎么解

这一节列几个我实际遇到过的报错和排查思路。

401 Unauthorized:最常见。先检查spring.ai.dashscope.api-key是否为空,或者环境变量AI_DASHSCOPE_API_KEY有没有注入成功。如果你用的是 TaoToken 的 Key,确认 Base URL 写的是https://taotoken.net/api,不要多加斜杠或者路径。另外,Key 如果过期或者被删除,也会报 401,去https://taotoken.net/api-keys重新生成一个。

local proxy failed:这个报错通常出现在你本地配了代理,但代理不可用的时候。Spring AI Alibaba 底层走 HTTP 请求,如果系统环境变量里有HTTP_PROXY或者HTTPS_PROXY,会优先走代理。解决办法是检查环境变量,把代理关掉,或者确保代理地址可达。如果你在公司内网,可能需要配no_proxy排除taotoken.net。

reading choices 报错:这个一般出现在响应解析阶段,比如模型返回的 JSON 结构和框架预期的不一致。常见原因是模型名称写错了,比如写成了qwen而不是qwen-plus,或者 Base URL 指向了一个不兼容 OpenAI 格式的接口。检查application.yml里的model字段,确保是百炼平台支持的模型 ID。另外,如果你用了entity()方法但模型返回的不是合法 JSON,也会报解析错误,这时候可以在 prompt 里明确要求“以 JSON 格式输出”。

OAuth 相关报错:如果你用的是百炼平台的企业版,可能需要 OAuth 鉴权。Spring AI Alibaba 默认走 API Key,如果你看到OAuth token expired之类的报错,检查是否误用了企业版鉴权方式。普通开发者用 API Key 就够了。

连接超时:如果报Read timed out,可能是网络问题。先 ping 一下taotoken.net,如果延迟高,可以调大超时时间:

spring: ai: dashscope: chat: options: timeout: 60000

如果以上都排查了还是不行,去https://taotoken.net/doc看最新的接口文档,确认 Base URL 和模型 ID 有没有更新。

6. 语义一致 CTA:从对话到 RAG,下一步怎么走

跑通第一个对话和知识库问答之后,你可以继续往深了做。比如把SimpleVectorStore换成 Redis 或者百炼云知识库,支持更大规模的文档检索;或者加上MessageChatMemoryAdvisor实现多轮对话记忆,让模型记住上下文。

如果你需要长期跑编码任务或者 Agent,建议用 Coding Plan,它提供了更稳定的调用配额和专属通道。配置方式还是那三件套:Base URL 用https://taotoken.net/api,Key 从控制台拿,Model ID 填qwen-plus或qwen-max。如果你要接 Claude Code 或者 Cline 这类工具,Base URL 和 Key 的填法是一样的,Model ID 根据工具要求调整。

验证模型效果可以直接在https://taotoken.net/models页面测试,不用写代码就能看不同模型的输出差异。接入文档在https://taotoken.net/doc,里面有完整的参数说明和示例。

最后提醒一点:RAG 的检索质量取决于文档切分和 Embedding 模型。如果你发现模型答非所问,先检查文档有没有被正确切分,再考虑换 Embedding 模型。我试过把一份 50 页的 PDF 直接扔进去,效果很差,后来按段落切分,准确率明显提升。你可以从简单的 FAQ 文档开始,跑通之后再上复杂场景。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询