【SpringAIAlibaba新手村系列】(2)Ollama 本地大模型调用

0 阅读9分钟

第二章 Ollama 本地大模型调用

版本标注

  • Spring AI: 1.1.2
  • Spring AI Alibaba: 1.1.2.0

章节定位

  • 本章属于 Spring AI 通用模型接入基础,核心重点仍然有效。
  • 但在 Spring AI Alibaba 1.1.2.x 官方代码中,Ollama 并不是框架主线,主线已经转向 Agent FrameworkGraphReactAgent 与多智能体编排。

s01 > [ s02 ] > s03 > s04 > s05 > s06 > s07 > s08 > s09 > s10 > s11 > s12 > s13 > s14 > s15 > s16 > s17 > s18

"模型跑在本地, 控制权就在自己手里" -- Ollama 解决的是联网依赖、隐私顾虑和实验自由度。


一、为什么要用本地大模型?

1.1 远程调用的问题

在上一章中,我们使用的是阿里云百炼平台的远程 AI 服务。这意味着:

  • 每次调用都需要联网
  • 所有的数据都要经过第三方服务器(隐私问题)
  • 有 API 调用配额和费用
  • 网络延迟影响响应速度

1.2 本地部署的优势

Ollama 是一个让你可以在自己电脑上运行大模型的神器:

对比项阿里云远程调用Ollama 本地调用
网络要求必须联网不需要(局域网即可)
隐私安全数据上传云端完全本地存储
费用有免费额度,超出收费完全免费
响应速度依赖网络延迟本地响应快
模型选择平台提供的模型可选择开源模型

适合场景

  1. 公司内部系统,不方便把数据发送到外部
  2. 个人学习研究,想怎么玩怎么玩
  3. 对响应速度有较高要求的生产环境
  4. 不想花钱买 API 服务

二、Ollama 核心概念

2.1 什么是 Ollama?

Ollama 是一个用于在本地运行大语言模型的工具。它的特点是:

  • 安装简单(Windows/Mac/Linux 都有客户端)
  • 支持的主流模型:Llama、Qwen、DeepSeek、Codellama 等
  • 不用配置显卡驱动,下载就能用(会自动调用本地GPU)
  • 通过简单的命令行就能启动模型服务

2.2 Ollama 工作原理

┌─────────────────────────────────────┐
│         你自己的电脑                │
│  ┌──────────────────────────────┐   │
│  │      Ollama 运行环境          │   │
│  │  ┌────────────────────────┐  │   │
│  │  │   Qwen/Llama 模型文件   │  │   │
│  │  │   (几GB到几十GB不等)    │  │   │
│  │  └────────────────────────┘  │   │
│  │              ↓                │   │
│  │        提供本地 API           │   │
│  │    http://localhost:11434     │   │
│  └──────────────────────────────┘   │
│                                      │
└─────────────────────────────────────┘
  • 模型文件存在本地硬盘
  • Ollama 启动一个本地 API 服务(默认端口 11434)
  • 我们的 Java 程序通过 HTTP 调用这个本地服务
  • 数据完全不需要出去

2.3 Spring AI 的 Ollama 支持

Spring AI 提供了对 Ollama 的原生支持,通过 spring-ai-starter-model-ollama 依赖即可接入。

关键配置项

  • spring.ai.ollama.base-url:Ollama 服务的地址
  • spring.ai.ollama.chat.options.model:要使用的模型名称

三、Ollama 项目详解

3.1 项目结构

SAA-02Ollama/
├── pom.xml
├── src/main/
│   ├── java/com/atguigu/study/
│   │   ├── controller/
│   │   │   └── OllamaController.java    # 控制器
│   │   └── Saa02OllamaApplication.java  # 启动类
│   └── resources/
│       └── application.yml             # 配置

3.2 pom.xml 依赖

<!-- 第一章的依赖,我们继续保留 -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>

<!-- 新增:Ollama 的 Starter -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>

💡 提示:这里同时保留了阿里云和 Ollama 的依赖,意味着我们可以同时使用两种 AI 服务!开发时可以灵活切换。

3.3 application.yml 配置

server:
  port: 8002

# ============ Ollama 配置(本地模型)============
spring:
  ai:
    ollama:
      # 告诉 Spring AI 去哪里找 Ollama 服务
      base-url: http://localhost:11434
      chat:
        # 选择要使用的模型名称(启动 Ollama 时看到的就是这个)
        options:
          model: qwen2.5:0.5b
          # 不验证 SSL 证书(本地开发用)

⚠️ 大坑注意

  1. 确保你的电脑上已经安装了 Ollama 并启动了服务
  2. 通过 ollama list 命令查看已下载的模型名称
  3. 如果还没安装,去 ollama.com 下载安装

3.4 控制层代码

package com.atguigu.study.controller;

import jakarta.annotation.Resource;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/**
 * 本章要点:Spring AI 中如何区分不同的 ChatModel 实现
 * 
 * 当项目中注入了多个 ChatModel 时,需要通过 @Qualifier 指定注入哪一个
 */
@RestController
public class OllamaController
{
    // ========== @Qualifier 的作用 ==========
    // 当只有一个 ChatModel 时,Spring 会自动注入
    // 但如果同时有阿里云和 Ollama 两个实现,就需要指定名称
    
    // 使用 @Qualifier("ollamaChatModel") 明确指定注入的是 Ollama 的模型
    @Resource
    @Qualifier("ollamaChatModel")
    private ChatModel chatModel;


    /**
     * 普通调用:发送消息,获取完整回复
     * 
     * 接口地址:http://localhost:8002/ollama/chat?msg=你是谁
     * 
     * @param msg 用户发送的消息
     * @return AI 的回复
     */
    @GetMapping("/ollama/chat")
    public String chat(@RequestParam(name = "msg") String msg)
    {
        // 调用本地 Ollama 模型
        String result = chatModel.call(msg);
        System.out.println("---结果:" + result);
        return result;
    }

    /**
     * 流式调用:逐字返回回答
     * 
     * 接口地址:http://localhost:8002/ollama/streamchat?msg=用Java写个冒泡排序
     */
    @GetMapping("/ollama/streamchat")
    public Flux<String> streamchat(@RequestParam(name = "msg", defaultValue = "你是谁") String msg)
    {
        // 流式调用本地模型,效果和阿里云一模一样
        return chatModel.stream(msg);
    }
}

3.5 @Qualifier 注解详解

这是本章的一个技术重点,让我们详细解释:

// 场景:你的项目中注入了多个 ChatModel 实现
//
// 阿里云百炼 → DashScopeChatModel(bean名称默认是 "dashScopeChatModel")
// Ollama     → OllamaChatModel(bean名称默认是 "ollamaChatModel")
//
// 问题:@Resource 注入时,Spring 不知道你要哪个!
// 解决:使用 @Qualifier 指定具体的 bean 名称

@Resource                        // 不指定?可能报错或注入错误的bean
@Qualifier("ollamaChatModel")    // 明确指定:我就要 Ollama 的这个
private ChatModel chatModel;

Bean 名称的命名规则

  • 类名的首字母小写作为默认名称
  • OllamaChatModelollamaChatModel
  • DashScopeChatModeldashScopeChatModel
3.5.1 如果不写 @Qualifier 会怎样?

这是很多初学者容易产生误解的地方。

如果你这样写:

@Resource
private ChatModel chatModel;

Spring 会尝试从容器里找一个可以注入的 ChatModel Bean。

这时要分三种情况来看:

情况 1:容器里只有一个 ChatModel Bean

比如项目里只有 Ollama 一个模型实现,那么不写 @Qualifier 也没有问题,因为 Spring 只有一个候选对象可以注入。

情况 2:容器里有多个 ChatModel Bean

比如同时存在:

  • ollamaChatModel
  • dashScopeChatModel

这时如果你不指定,Spring 往往会不知道该选哪一个。最常见的结果是:

No qualifying bean of type 'org.springframework.ai.chat.model.ChatModel' available:
expected single matching bean but found 2

也就是说,更常见的情况不是“悄悄注入错了”,而是“因为候选者太多直接报错”

情况 3:多个 ChatModel 中有一个被标记为 @Primary

如果某个 ChatModel Bean 被标记成了主 Bean,例如 DashScope 那个被标记了 @Primary,那在不写 @Qualifier 时,Spring 就会优先选中它。

这时就真的有可能出现这样的情况:

  • 你以为自己在调用 Ollama
  • 实际上注入进去的是 DashScope 的 ChatModel

所以从结果上说:

不写 @Qualifier 时,确实有可能注入到 DashScope,但前提是 Spring 最终能成功选中它;否则更常见的是因为多个候选 Bean 冲突而直接报错。

3.5.2 @Qualifier 到底在干什么?

它的本质作用就是:在多个同类型 Bean 中,明确点名我要哪一个。

@Resource
@Qualifier("ollamaChatModel")
private ChatModel chatModel;

这段代码等于在告诉 Spring:

我知道容器里可能有多个 ChatModel,但我不要你猜,我就要名字叫 ollamaChatModel 的那个。

所以它非常适合这种场景:

  • 一个项目同时接入多个模型服务
  • 多个实现类都实现了同一个接口
  • 你希望某个 Controller / Service 明确绑定某一个具体实现
3.5.3 @Resource@Autowired@Qualifier 的关系

这里顺手也补一个很重要的知识点。

@Autowired 默认更偏向按类型注入,所以当容器里有多个 ChatModel 时,通常更容易出现歧义,需要配合 @Qualifier 使用:

@Autowired
@Qualifier("ollamaChatModel")
private ChatModel chatModel;

@Resource 默认会优先按名字找,再按类型找。但为了让语义更清晰、代码更稳定,在多模型场景下依然建议显式写上 @Qualifier,避免 Spring 自动匹配时产生歧义。

3.5.4 一句话总结

当项目里只有一个 ChatModel 时,@Qualifier 可以不写;一旦项目里同时存在 Ollama、DashScope、OpenAI 等多个模型实现,最好显式指定 Bean 名称,否则要么报冲突错误,要么在特殊情况下被注入到并不是你想要的那个实现。


四、Ollama 安装与启动指南

4.1 安装OLLAMA

Windows 用户

  1. 打开 ollama.com
  2. 点击 Download for Windows
  3. 下载并安装 OLLAMASetup.exe

Mac 用户

brew install ollama

Linux 用户

curl -fsSL https://ollama.com/install.sh | sh

4.2 下载模型

安装完成后,在终端(CMD/PowerShell/Terminal)中运行:

# 查看可用的模型列表
ollama list

# 常用的模型(按体积从小到大)
ollama pull qwen2.5:0.5b      # 阿里 Qwen,较小,几百MB
ollama pull qwen2.5:3b        # 中等大小,1-2GB
ollama pull llama3            # Meta Llama 3
ollama pull codellama         # 编程专用模型

4.3 启动服务

# 启动 Ollama 后台服务
ollama serve

# 如果是第一次使用某个模型,它会自动下载
# 启动成功后,默认监听 http://localhost:11434

五、测试验证

5.1 启动项目

  1. 确保 Ollama 已经在运行(ollama serve
  2. 在 IDEA 中运行 Saa02OllamaApplication
  3. 看到启动成功后开始测试

5.2 测试接口

# 普通对话 - 测试本地模型
GET http://localhost:8002/ollama/chat?msg=用Python打印HelloWorld

# 流式对话 - 观察打字效果
GET http://localhost:8002/ollama/streamchat?msg=什么是多线程

5.3 对比测试

如果你同时启动了 SAA-01 项目,可以对比一下:

  • 阿里云响应时间 vs Ollama 响应时间
  • 回答质量有没有明显差异(通常阿里云付费版质量更好)

六、本章小结

概念说明
Ollama本地大模型运行框架
@Qualifier当有多个同名Bean时,用于精确指定注入哪一个
Flux响应式流,用于流式输出效果
本地APIOllama 默认监听 localhost:11434

本章重点

  1. 理解为什么需要本地部署大模型
  2. 掌握 Ollama 的安装和基本使用
  3. 理解 Spring AI 中多 Bean 情况下的注入方式

下章剧透(s03):

了解了两种调用远程/本地模型的方式后,下一章我们将学习 Spring AI 中的两个核心API:ChatModelChatClient 的区别与使用场景。


💡 TIP:Spring AI 原生 vs Spring AI Alibaba 的 Ollama 支持

本章我们使用的是 Spring AI 原生的 Ollama 支持(通过 spring-ai-starter-model-ollama),而不是 Spring AI Alibaba 提供的。

两者对比:

特性Spring AI 原生 OllamaSpring AI Alibaba
依赖spring-ai-starter-model-ollama需自行配置
模型支持Ollama 官方所有模型仅支持部分模型
更新频率跟随 Ollama 官方与阿里云服务同步

为什么课程用 Spring AI 原生?
因为 Ollama 本身是独立项目,使用 Spring AI 原生支持更纯粹。但实际上,你也可以把 Ollama 看作另一个"AI _provider",完全可以共存于同一个项目中(就像我们的 Demo 同时支持阿里云和 Ollama)。


📝 编辑者:Flittly
📅 更新时间:2026年3月
🔗 相关资源Ollama 官网 | Spring AI Ollama 文档