
1. 从零跑通 Spring AI AlibabaChatClient 接入阿里云百炼模型到底解决什么问题如果你正在用 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-starterdependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter/artifactId version1.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) MapString, 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 messageuser是用户输入call发起请求content返回字符串。如果你想拿完整的ChatResponse把content()换成chatResponse()就行。如果你要返回实体类比如ActorFilms可以这样写record ActorFilms(String actor, ListString movies) {} GetMapping(/movies) public ActorFilms movies(RequestParam(value input) String input) { return this.chatClient.prompt() .user(input) .call() .entity(ActorFilms.class); }注意.entity()必须传入目标类否则返回的是字符串。如果要返回ListActorFilms用ParameterizedTypeReferenceListActorFilms list this.chatClient.prompt() .user(input) .call() .entity(new ParameterizedTypeReferenceListActorFilms() {});流式输出用stream()GetMapping(value /stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString 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(); ListDocument documents List.of( new Document(产品说明书:产品名称智能机器人\n 产品描述智能机器人是一个智能设备能够自动完成各种任务。\n 功能\n 1. 自动导航机器人能够自动导航到指定位置。\n 2. 自动抓取机器人能够自动抓取物品。\n 3. 自动放置机器人能够自动放置物品。\n)); simpleVectorStore.add(documents); return simpleVectorStore; } }然后写 RAG ControllerRestController RequestMapping(/ai) public class RagController { Autowired private ChatClient chatClient; Autowired private VectorStore vectorStore; GetMapping(value /chat, produces text/plain; charsetUTF-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/apiKey 从控制台拿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 文档开始跑通之后再上复杂场景。