Spring AI Alibaba + Ollama:国产大模型DeepSeek LLM的低成本AI应用开发认知
写在前面
- 官方文档很详细,有开发需求可以直接看文档
- https://java2ai.com/docs/1.0.0-M5.1/get-started/
- 博文内容为一个开发Demo,以及API简单认知
- 理解不足小伙伴帮忙指正 😃,生活加油
我看远山,远山悲悯
持续分享技术干货,感兴趣小伙伴可以关注下 _
AI普惠时代的技术革新
在生成式AI技术快速发展的今天,大模型的高效部署与低成本应用成为企业智能化转型的核心挑战。国产大模型 DeepSeek LLM
凭借其轻量化设计、开源生态和高性价比优势,结合 Spring AI Alibaba
框架与 Ollama
本地化部署能力,为开发者提供了一条“平民化”AI应用的可行路径。
什么是 Spring AI
Spring AI 是由 Spring 官方维护的 AI 开发框架,旨在简化企业级 AI 应用构建。
Spring AI 借鉴了 Python 生态的 LangChain 等工具的设计理念,但并非直接移植,而是专注于解决 Java 开发者面临的 AI 集成核心难题——将企业数据/API 与 AI 模型无缝连接
,突破 Python 生态垄断,推动生成式 AI 应用向多语言生态扩展。
什么是 Spring AI Alibaba?
Spring AI Alibaba
是阿里云
为 Java
开发者打造的开源 AI 开发框架,基于 Spring AI
深度集成通义系列模型,提供标准化接口和高阶抽象能力。
Spring AI Alibaba
简化 AI 应用开发流程,支持以 Spring Boot 开发范式快速接入大模型能力,深度整合阿里云通义系列模型及百炼平台,提供模型部署到运维的最佳实践;
关键能力:
- 统一 API 抽象(支持聊天/多模态模型、同步/流式调用、跨模型无缝切换);
- 智能体开发工具集(函数调用、对话记忆、RAG 全链路支持);
- 工程化增强(结构化输出映射 POJO、向量数据库集成、离线文档处理工具)。
- 相较于原生 API 调用,该框架通过 Fluent API 设计显著降低开发复杂度,使开发者聚焦业务逻辑而非底层模型交互细节。
API认知
在 Spring AI Alibaba
框架中, 提供了 Chat Client
和 Chat Model
两类不同层次的组件,分别对应不同的开发场景需求。
Chat Model(聊天模型)
: 直接与 AI 大模型(比如通义系列模型)打交道的“电话听筒”。你可以把它想象成直接拨通大模型的电话,告诉它你的问题,然后接收它的原始回答。Chat Client(智能体代理客户端)
: 封装好的“智能助手”。它不仅帮你拨通大模型的电话,还会自动帮你处理对话流程、记忆上下文、调用工具函数(比如查机票信息)等复杂操作。
下面我们详细看看
对话模型(Chat Model)
Chat Model 通过标准化 API 抽象,降低多模态大模型集成复杂度,使开发者聚焦业务逻辑,快速实现智能交互功能。
输入/输出形式 支持多模态交互(文本、语音、图片、视频),输入为消息序列(Message
),输出为聊天消息(ChatMessage
)。
角色区分 消息中可标记角色(如 user
、system
、assistant
),帮助模型理解上下文来源(用户指令、系统提示或模型回复)。
特点
模型适配 :集成通义系列大模型服务(如通义千问、通义万象),支持以下功能:
- 文本交互(
ChatModel
):文本输入 → 格式化文本输出 - 文生图(
ImageModel
):文本输入 → 生成图片 - 文生语音(
AudioModel
):文本输入 → 合成语音 - 语音转文本(如语音输入解析)。
开发集成
- 复用 Spring AI 的
Model API
,通过spring-ai-alibaba-starter
自动配置默认实例。 - 支持直接注入
ChatModel
、ImageModel
等 Bean,亦可自定义模型实例。
API 核心逻辑
交互流程:Prompt
(输入) → 模型处理 → ChatResponse
(输出)
- 输入:用户提供的
Prompt
或部分对话上下文。 - 输出:模型生成的自然语言响应,可呈现给用户或用于后续处理。
底层原理 模型基于训练数据解析输入语义,结合上下文生成连贯、符合逻辑的响应。
对话客户端(Chat Client)
Chat Client
通过标准化流程和 Fluent API 提升开发效率,适合需快速落地的通用 AI 场景;
作用:提供与 AI 模型交互的 Fluent API,简化多组件协作流程(如提示词模板、聊天记忆、模型、解析器等)。
定位:类似应用程序的 服务层,封装底层复杂性,快速实现端到端 AI 交互流程。
特点
- 编程模型:支持 同步 与 反应式(Reactive) 调用。
- 开发效率:通过链式调用(Fluent API)减少样板代码,避免手动协调组件(如 RAG、函数调用等)。
- 功能集成:内置输入输出处理、参数配置等通用逻辑,开箱即用。
基础功能
功能 | 说明 |
---|---|
输入定制(Prompt) | 动态组装用户输入,支持模板化参数填充(如变量替换)。 |
结构化输出解析 | 将模型返回的非结构化文本转换为结构化数据(如 JSON、对象)。 |
交互参数调整 | 通过 ChatOptions 动态配置模型参数(如温度、最大 Token 数、Top-P 等)。 |
- 聊天记忆(Chat Memory) 维护多轮对话上下文,支持短期记忆(内存)和长期记忆(持久化存储)。
- 工具/函数调用(Function Calling) 模型根据输入动态调用外部服务或函数(如查询天气、调用 API),并整合结果至响应。
- RAG(检索增强生成) 集成检索组件,通过向量数据库增强模型知识,生成基于业务数据的精准回答。
开发Demo
ollama 运行 deepseek-r1
启动服务
PS C:\Users\liruilong> ollama serve
2025/03/06 10:33:23 routes.go:1186: INFO server config env="map[CUDA_VISIBLE_DEVICES: GPU_DEVICE_ORDINAL:
................................
运行模型测试
PS C:\Users\liruilong> ollama run deepseek-r1
>>> 1+1=?
<think></think>1 + 1 = **2**>>> Send a message (/? for help)
Spring AI Alibaba AI 应用开发
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId></dependency>
配置大模型相关配置
server:port: 10005spring:application:name: spring-ai-alibaba-ollama-demoai:ollama:base-url: http://localhost:11434chat:model: deepseek-r1:latest
克隆项目Demo
git clone --depth=1 https://github.com/springaialibaba/spring-ai-alibaba-examples.git
chat model
@RestController
@RequestMapping("/ollama/chat-model")
public class OllamaChatModelController {private static final String DEFAULT_PROMPT = "你好,介绍下你自己吧。请用中文回答。";private final ChatModel ollamaChatModel;public OllamaChatModelController(ChatModel chatModel) {this.ollamaChatModel = chatModel;}/*** 最简单的使用方式,没有任何 LLMs 参数注入。** @return String types.*/@GetMapping("/simple/chat")public String simpleChat() {return ollamaChatModel.call(new Prompt(DEFAULT_PROMPT)).getResult().getOutput().getContent();}/*** Stream 流式调用。可以使大模型的输出信息实现打字机效果。** @return Flux<String> types.*/@GetMapping("/stream/chat")public Flux<String> streamChat(HttpServletResponse response) {// 避免返回乱码response.setCharacterEncoding("UTF-8");Flux<ChatResponse> stream = ollamaChatModel.stream(new Prompt(DEFAULT_PROMPT));return stream.map(resp -> resp.getResult().getOutput().getContent());}/*** 使用编程方式自定义 LLMs ChatOptions 参数, {@link OllamaOptions}。* 优先级高于在 application.yml 中配置的 LLMs 参数!*/@GetMapping("/custom/chat")public String customChat() {OllamaOptions customOptions = OllamaOptions.builder().topP (0.95D).temperature (0.7D).numPredict (1024).build();return ollamaChatModel.call(new Prompt(DEFAULT_PROMPT, customOptions)).getResult().getOutput().getContent();}}
调用接口测试
PS C:\Users\liruilong> curl http://localhost:10005/ollama/chat-model/simple/chat
<think>
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
</think>您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
PS C:\Users\liruilong> curl http://localhost:10005/ollama/chat-model/stream/chat
<think>
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
</think>您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
下面为自定义模型参数调用
PS C:\Users\liruilong> curl http://localhost:10005/ollama/chat-model/custom/chat
<think>
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
</think>您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
PS C:\Users\liruilong>
chat client
@RestController
@RequestMapping("/ollama/chat-client")
public class OllamaClientController {private static final String DEFAULT_PROMPT = "你好,介绍下你自己!请用中文回答。";private final ChatClient ollamaiChatClient;public OllamaClientController(ChatModel chatModel) {this.ollamaiChatClient = ChatClient.builder(chatModel).defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory())).defaultAdvisors(new SimpleLoggerAdvisor()).defaultOptions(OllamaOptions.builder ().topP (0.95D).temperature (0.7D).numPredict (1024).build()).build();}/*** ChatClient 简单调用*/@GetMapping("/simple/chat")public String simpleChat() {return ollamaiChatClient.prompt(DEFAULT_PROMPT).call().content();}/*** ChatClient 流式调用*/@GetMapping("/stream/chat")public Flux<String> streamChat(HttpServletResponse response) {response.setCharacterEncoding("UTF-8");return ollamaiChatClient.prompt(DEFAULT_PROMPT).stream().content();}}
Demo 代码可以看到 chatModel
都是通过自动装配注入的,不需要显示 new
,client
在 model
的基础上重新构造。
博文部分内容参考
© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃
https://sca.aliyun.com/
https://java2ai.com/docs/1.0.0-M5.1/get-started/
© 2018-至今 liruilonger@gmail.com, 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)
相关文章:
Spring AI Alibaba + Ollama:国产大模型DeepSeek LLM的低成本AI应用开发认知
写在前面 官方文档很详细,有开发需求可以直接看文档https://java2ai.com/docs/1.0.0-M5.1/get-started/博文内容为一个开发Demo,以及API简单认知理解不足小伙伴帮忙指正 😃,生活加油 我看远山,远山悲悯 持续分享技术干货…...
《2025软件测试工程师面试》功能测试篇
什么是功能测试? 功能测试是通过验证产品功能是否满足用户需求的过程,主要关注软件的功能是否符合需求规格说明,包括软件的各种功能、特性、性能、安全性和易用性等。 功能测试的流程包括哪些步骤? 需求分析:明确软件需求,确定测试范围。测试计划:制定详细的测试计划,…...
蓝桥杯2024年第十五届省赛真题-传送阵
题目描述 小蓝在环球旅行时来到了一座古代遗迹,里面并排放置了 n 个传送阵,进入第 i 个传送阵会被传送到第 ai 个传送阵前,并且可以随时选择退出或者继续进入当前传送阵。小蓝为了探寻传送阵中的宝物,需要选择一个传送阵进入&…...

非线性优化--NLopt算法(Android版本和Python示例)
通俗一点来说 非线性优化就是求函数的极值。我们想求一个 函数的极值问题的时候,线性函数是最简单的,因为是线性的嘛,单调增或者单调减,那么找到边界就可以求到极值。例如 f(x)=ax+b。 简单的非线性函数也是很容易求得极值的,例如f(x)=x*x.可以通过求导得到极值点,然后求…...
2025-03-06 ffmpeg提取SPS/PPS/SEI ( extradata )
一、需求 在某些情况下,可能需要直接使用H264/H265等原始数据流进行解码,比较常用的udp下的h264/h265。这时需要 av_parser_parse2 来组AVPacket,但对于视频的信息:宽高、格式等,可以根据 AVCodecParserContext 来获取࿰…...

海量数据融合互通丨TiDB 在安徽省住房公积金监管服务平台的应用实践
导读 安徽省住房公积金监管服务平台通过整合全省 17 家公积金中心的数据,致力于实现数据共享、规范化管理与高效数据分析。为了应对海量数据处理需求,安徽省选择 TiDB 作为底层数据库,利用其分布式架构和 HTAP 能力,实现了快速的…...
深入解析 supervision 库:功能、用法与应用案例
1. 引言 在计算机视觉任务中,数据的后处理和可视化是至关重要的环节,尤其是在目标检测、分割、跟踪等任务中。supervision 是一个专门为这些任务提供高效数据处理和可视化支持的 Python 库。本文将深入介绍 supervision 的功能、使用方法,并…...
【DeepSeek问答】访问QStandardItemModel::index(r,c)获取的空索引导致程序崩溃
好的,我现在来仔细思考一下用户的问题。用户在使用QStandardItemModel的setItem方法时,调用了setItem(4,6,item),也就是在第4行第6列的位置设置了一个item。然后他们尝试通过index(3,6)来获取这个位置的项目,想知道会有什么后果。…...

从开源大模型工具Ollama存在安全隐患思考企业级大模型应用如何严守安全红线
近日,国家网络安全通报中心通报大模型工具Ollama默认配置存在未授权访问与模型窃取等安全隐患,引发了广泛关注。Ollama作为一款开源的大模型管理工具,在为用户提供便捷的同时,却因缺乏有效的安全管控机制,存在数据泄露…...

Aws batch task 无法拉取ECR 镜像unable to pull secrets or registry auth 问题排查
AWS batch task使用了自定义镜像,在提作业后出现错误 具体错误是ResourceInitializationError: unable to pull secrets or registry auth: The task cannot pull registry auth from Amazon ECR: There is a connection issue between the task and Amazon ECR. C…...

通用信息抽取大模型PP-UIE开源发布,强化零样本学习与长文本抽取能力,全面适配多场景任务
背景与简介 信息抽取(information extraction)是指,从非结构化或半结构化数据(如自然语言文本)中自动识别、提取并组织出结构化信息。通常包含多个子任务,例如:命名实体识别(NER&am…...
基于uniapp的蓝牙打印功能(佳博打印机已测试)
相关步骤 1.蓝牙打印与低功耗打印的区别2.蓝牙打印流程2.1 搜索蓝牙2.2 连接蓝牙 3.连接蓝牙设备4.获取服务5.写入命令源码gbk.jsglobalindex.ts 1.蓝牙打印与低功耗打印的区别 低功耗蓝牙是一种无线、低功耗个人局域网,运行在 2.4 GHz ISM 频段 1、低功耗蓝牙能够…...

【Azure 架构师学习笔记】- Azure Databricks (15) --Delta Lake 和Data Lake
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (14) – 搭建Medallion Architecture part 2 前言 ADB 除了UC 这个概念之外,前面【Azure 架构师学习笔记】- Azure Databricks (1…...

WPF高级 | WPF 应用程序部署与发布:确保顺利交付到用户手中
WPF高级 | WPF 应用程序部署与发布:确保顺利交付到用户手中 一、前言二、部署与发布基础概念2.1 部署的定义与目的2.2 发布的方式与渠道2.3 部署与发布的关键要素 三、WPF 应用程序打包3.1 使用 Visual Studio 自带的打包工具3.2 使用第三方打包工具 四、发布到不同…...

在 IntelliJ IDEA(2024) 中创建 JAR 包步骤
下是在 IntelliJ IDEA 中创建 JAR 包的详细的步骤: 1. 选择File -> Project Structure->Artifacts, (1)点击➕新建,如下图所示: (2)选择JAR->Empty (3)输入jar包名称,确定输出路径 (4&#…...
【C++】5.4.3 范围for语句
范围for语句基本形式: for(声明变量:序列容器) {循环执行语句; } 其中,“序列容器”是指花括号括起来的初始值列表、数组、vector或者string等类型的对象,主要特点是拥有能返回迭代器的 begin() 和 end() 成员; “声明变量”是一个类似声明…...
达梦数据库备份
达梦数据库联机在线备份操作指南 一、基础条件与准备 开启归档模式: 联机备份必须处于归档模式下,否则无法执行。需通过disql工具执行以下操作: alter database mount; alter database ARCHIVELOG; 例子: [dmdbaserver ~]$ cd /op…...

Linux系统基于ARM平台的LVGL移植
软硬件介绍:Ubuntu 20.04 ARM 和(Cortex-A53架构)开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的,如果想要实现在ARM开发板上运行LVGL图形库,那么就需要把LVGL图形库提供的关于帧缓冲设…...
C++ 二叉搜索树代码
C 二叉搜索树代码 #include <iostream> using namespace std;template<typename T> struct TreeNode{T val;TreeNode *left;TreeNode *right;TreeNode():val(0), left(NULL), right(NULL){}TreeNode(T x):val(x), left(NULL), right(NULL){} };template<typena…...

DeepSeek+知识库+鸿蒙,助力鸿蒙高效开发
不知道你们发现没有,就是鸿蒙开发官网,文档也太多太多了,对于新手来说确实头疼,开发者大多是极客,程序的目的是让世界更高效!看文档,挺头疼的,毕竟都是理科生。 遇到问题不要慌&…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

倒装芯片凸点成型工艺
UBM(Under Bump Metallization)与Bump(焊球)形成工艺流程。我们可以将整张流程图分为三大阶段来理解: 🔧 一、UBM(Under Bump Metallization)工艺流程(黄色区域ÿ…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...

麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
FOPLP vs CoWoS
以下是 FOPLP(Fan-out panel-level packaging 扇出型面板级封装)与 CoWoS(Chip on Wafer on Substrate)两种先进封装技术的详细对比分析,涵盖技术原理、性能、成本、应用场景及市场趋势等维度: 一、技术原…...