第3章:快速入门SpringAI Alibaba

目录:SpringAI Alibaba

上一节:第2章:Ollama本地部署大模型Qwen3

本节:第3章:快速入门SpringAI Alibaba

下一节:待更新

第3章:快速入门 Spring AI Alibaba

前两章,我们已经分别完成了两件很重要的事情:

  • 先在云端把大模型调用链路跑通
  • 再在本地把 Qwen3 跑起来

到了这一步,一个更贴近 Java 开发者的问题自然就出现了:

如果我要在 Spring Boot 项目里真正接入大模型,到底该怎么做?

很多人第一反应会想到 Spring AI。但当你真正开始接国内模型、接阿里云百炼、接本地 Ollama 时,很快就会发现:光知道 Spring AI 还不够,真正更顺手的,往往是 Spring AI Alibaba

这一章,我们就用一个最小可跑通的例子,快速上手 Spring AI Alibaba,把云端模型、本地模型、同步对话、日志记录和流式输出这几件事串起来。

Spring AI 和 Spring AI Alibaba 到底有什么区别

先说结论:

Spring AI 更像是一套通用的大模型接入标准,而 Spring AI Alibaba 则是在这个基础上,针对阿里云百炼和国内模型生态做了更贴近实战的增强。

官方网站:

https://java2ai.com

如果只用一句话来理解两者的关系,可以这样看:

  • Spring AI:标准能力框架
  • Spring AI Alibaba:更适合国内模型接入场景的落地方案

对很多国内开发者来说,真正的痛点并不是"不会写 Java 代码",而是"接模型的时候总有各种兼容细节"。比如模型配置方式、平台适配、调用体验、生态整合等,这些问题一旦叠加,就会让一个本来很简单的 Demo 变得不再简单。

Spring AI Alibaba 的价值,恰恰就在于它把这些接入成本往下压了一层。

你可以把它的优势理解为三点:

  • 兼容 Spring AI 的整体标准
  • 对阿里云百炼的支持更自然
  • 同时也方便接入本地模型能力,例如 Ollama

这意味着,我们既可以保留 Spring 体系里的开发习惯,又能更顺畅地把国内云模型和本地模型接进同一个项目里。

图1:Spring AI Alibaba 官网首页

第一步:完成项目初始化和依赖准备

真正开始写代码之前,先把基础环境搭好。

这一部分的目标很明确:让 Spring Boot 项目同时具备三类能力:

  • 接入阿里云百炼模型
  • 接入本地 Ollama 模型
  • 具备后续扩展记忆、RAG 等能力的基础依赖

下面是示例依赖配置:

xml 复制代码
<properties>
    <java.version>21</java.version>
    <spring-ai.version>1.0.0</spring-ai.version>
    <spring-ai-alibaba.version>1.0.0.2</spring-ai-alibaba.version>
    <spring-boot.version>3.4.5</spring-boot.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-bom</artifactId>
            <version>${spring-ai-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <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>

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

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

    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

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

    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-memory-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>5.2.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

如果你第一次看这段依赖,不需要一上来就把每个包都研究透。先抓住最关键的几项就够了:

  • spring-ai-alibaba-starter-dashscope:用于接入阿里云百炼
  • spring-ai-starter-model-ollama:用于接入本地 Ollama
  • spring-ai-alibaba-starter-memory-redis:为后续记忆能力预留扩展空间

也就是说,这个工程从一开始就不是只为"跑一个聊天接口"准备的,而是已经具备继续往更复杂 AI 应用演进的基础。

第二步:完成基础配置

依赖准备好之后,下一步就是配置模型连接信息。

这里建议使用 application.yml,而不是把模型相关参数散落在代码里。这样后续切换模型、切换环境、切换云端或本地服务时,都会轻松很多。

示例配置如下:

yaml 复制代码
spring:
  application:
    name: SpringAIAlibaba-RAG-Milvus
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}
      chat:
        model: qwen-plus
        options:
          temperature: 0.7
    ollama:
      enabled: true
      base-url: http://localhost:11434
      chat:
        model: qwen3:1.7b
        options:
          temperature: 0.7

server:
  port: 8080

这里有一个对外发布时必须注意的点:

不要在文章或代码仓库里直接暴露真实 API Key。

所以在正式分享时,更推荐像上面这样写成环境变量形式:

yaml 复制代码
api-key: ${DASHSCOPE_API_KEY}

这样既保留了配置结构,也避免把敏感信息直接暴露出去。

如果你从理解配置的角度来读这段内容,可以重点关注三件事:

  • 云端模型这里使用的是 qwen-plus
  • 本地模型这里接的是 qwen3:1.7b
  • 两套模型都被纳入了同一个 Spring Boot 配置体系中

这一步做完,其实就意味着:你的项目已经同时具备了调用"云模型"和"本地模型"的基础能力。

第三步:创建 ChatClient 配置

有了依赖和配置之后,接下来要做的,就是把模型真正封装成项目里可直接使用的 ChatClient

这一步的意义在于:后面的控制器、服务层、工作流逻辑,都不需要直接关心底层模型初始化细节,而是直接面向 ChatClient 编程。

示例配置类如下:

java 复制代码
@Configuration
public class ChatConfig {

    @Bean
    public ChatClient dashscopeChatClient(@Qualifier("dashscopeChatModel") ChatModel dashscopeChatModel) {
        return ChatClient.builder(dashscopeChatModel)
                .build();
    }

    @Bean
    public ChatClient ollamaChatClient(@Qualifier("ollamaChatModel") ChatModel ollamaChatModel) {
        return ChatClient.builder(ollamaChatModel)
                .build();
    }
}

如果你把它翻译成人话,其实就是:

  • 给云端 DashScope 模型创建一个 ChatClient
  • 给本地 Ollama 模型创建一个 ChatClient

这样后面我们就可以像调用普通组件一样,分别去调用云端模型和本地模型,而不需要在业务代码里重复写初始化逻辑。

第四步:先写出第一个同步对话接口

环境和配置都准备好之后,最自然的下一步,就是先把最基础的聊天接口跑起来。

下面是一个最小示例:

java 复制代码
@RestController
@RequestMapping("/api/ai")
public class SimpleAiController {

    @Autowired
    private ChatClient dashscopeChatClient;

    @Autowired
    private ChatClient ollamaChatClient;

    /**
     * 云端模型聊天接口
     */
    @GetMapping("/chat/alibaba")
    public String chat(@RequestParam("question") String question) {
        return dashscopeChatClient.prompt(question).call().content();
    }

    /**
     * 本地模型聊天接口
     */
    @GetMapping("/chat/ollama")
    public String ollamaChat(@RequestParam("question") String question) {
        return ollamaChatClient.prompt(question).call().content();
    }
}

这段代码虽然简单,但它已经完成了一件非常有价值的事情:

同一个 Spring Boot 项目,同时暴露了云端模型和本地模型的调用入口。

从工程视角看,这一步能帮助我们快速回答两个问题:

  • 云端模型能不能正常调用
  • 本地模型能不能在同一套项目结构里正常接入

很多时候,真正的开发节奏不是一开始就追求复杂能力,而是先把最短调用链路跑通。只要这一步通了,后面的上下文管理、日志记录、流式输出和 RAG 才有继续往上叠加的基础。

第五步:用 Advisor 给 AI 对话加日志

当最基础的聊天接口跑通之后,接下来非常值得做的一件事,就是把日志接进来。

因为在 AI 应用开发里,很多问题都不是"接口有没有返回",而是:

  • 请求到底发了什么
  • 模型到底怎么回的
  • 参数是否符合预期
  • Token 消耗是否合理

这时候,Advisor 就很有用了。

你可以把它理解成 AI 对话流程里的"拦截增强器"。在请求发送前后,它可以自动插入额外逻辑,例如日志记录、审查、监控等。

一句话理解:

Advisor 可以看作 AI 调用链路中的拦截器,用来在请求前后自动附加额外逻辑。

示例配置如下:

java 复制代码
@Configuration
public class AIClientConfig {

    /**
     * 配置本地 Ollama 的 ChatClient(带日志记录)
     */
    @Bean(name = "ollamaChatClient")
    public ChatClient ollamaChatClient(OllamaChatModel ollamaChatModel) {
        return ChatClient.builder(ollamaChatModel)
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build();
    }

    /**
     * 配置云端 DashScope 的 ChatClient(带日志记录)
     */
    @Bean(name = "dashscopeChatClient")
    @Primary
    public ChatClient dashscopeChatClient(DashScopeChatModel dashscopeChatModel) {
        return ChatClient.builder(dashscopeChatModel)
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build();
    }
}

这一步做完之后,最大的价值不是"代码更炫了",而是你的 AI 调试能力会明显提升。

因为从这一刻开始,你不再只是看到一个最终回复,而是能看到:

  • 请求消息内容
  • 模型参数
  • 返回结果结构
  • Token 使用情况

这些信息对于后续做提示词优化、问题排查、性能分析,都会非常有帮助。

第六步:日志结果到底该怎么看

SimpleLoggerAdvisor 生效之后,你会在日志里看到完整的请求和响应信息。

下面是一段典型的返回示例:

json 复制代码
2026-05-02T08:34:36.384+08:00 DEBUG ... request: ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='你是什么模型?', ...}], modelOptions=DashScopeChatOptions: {"model":"qwen-plus","temperature":0.7,...}}, context={}]

2026-05-02T08:34:38.235+08:00 DEBUG ... response: {
  "metadata": {
    "usage": {
      "promptTokens": 12,
      "completionTokens": 67,
      "totalTokens": 79
    }
  },
  "results": [ {
    "output": {
      "text": "我是通义千问(Qwen),由通义实验室研发的超大规模语言模型。..."
    }
  } ]
}

对外写文章时,其实没必要把整段完整日志一股脑贴出来。更适合读者的方式,是告诉他们应该重点看什么:

  • 请求里真正发给模型的内容是什么
  • 本次调用使用的是哪个模型
  • usage 里记录了多少 Token 消耗
  • 返回文本是否符合预期

换句话说,日志最重要的价值不是"展示信息很多",而是帮我们快速定位调用过程中的关键信号。

这也是为什么在 AI 工程实践里,日志常常不是可选项,而是基础能力。

第七步:再补一个流式接口

同步对话跑通之后,下一步通常就是流式输出。

因为很多真实场景里,我们并不希望模型把整段内容生成完再一次性返回,而是更希望它像聊天产品一样边生成边输出。这样用户的体感会更自然,交互也会更流畅。

示例代码如下:

java 复制代码
/**
 * 流式聊天接口
 */
@GetMapping(value = "/stream/chat/ollama", produces = "text/html;charset=utf-8")
public Flux<String> streamChat(@RequestParam("question") String question, HttpServletResponse response) {
    return ollamaChatClient.prompt(question).stream().content();
}

这段代码的核心并不复杂,关键点只有一个:

call() 适合同步结果,stream() 适合流式返回。

也就是说,当你从:

java 复制代码
.call().content()

切换到:

java 复制代码
.stream().content()

你的接口能力就从"一次性返回结果"变成了"持续输出生成内容"。

对于后面做聊天界面、流式问答、长文本生成来说,这一步会非常关键。

写在最后

如果说前两章解决的是"模型能不能用",那么这一章解决的就是:

如何把模型真正接进一个 Spring Boot 工程。

通过 Spring AI Alibaba,我们不仅能更自然地接入阿里云百炼,也能把本地 Ollama 模型一起纳入同一个项目体系中。再往上叠加 Advisor 日志和流式接口之后,一个最基础但已经很有实战味道的 AI 应用骨架,其实就已经搭起来了。

更重要的是,当你亲手把这些代码跑通后,你对 AI Java 开发的理解就会从"知道概念"进入"会搭工程"的阶段。

相关推荐
:mnong1 小时前
打造 AI 级 Agent 架构
人工智能·架构
CS创新实验室1 小时前
CS实验室行业报告:生物医药与生物工程行业就业分析报告
大数据·人工智能·生物医药
新知图书1 小时前
项目资源调配优化建议(使用千问)
人工智能·ai助手·千问·高效办公
久菜盒子工作室1 小时前
时寒冰:第五次产业大转移与未来30年国运:在“双向挤压”中实现惊险一跃
人工智能·学习
chaofan9802 小时前
2026年大模型接入实测:高并发场景下企业级API网关横向对比与选型指南
人工智能·gpt·自动化·api
大尚来也2 小时前
大模型能否替代自媒体创作?真实优缺点拆解
人工智能
He少年2 小时前
【AI 辅助案例分享】
人工智能·c#·编辑器·ai编程
暗夜猎手-大魔王2 小时前
转载--AI Agent 架构设计:目标漂移(OpenClaw、Claude Code、Hermes Agent 对比)
人工智能
老黄编程2 小时前
大型工地实时数据处理与三维重构系统方案
人工智能·ubuntu·信息可视化·重构·入侵检测·大型数据集中处理