完整教程:SpringAI1.0.1实战教程:避坑指南25年8月最新版

news/2025/12/4 10:48:27/文章来源:https://www.cnblogs.com/gccbuaa/p/19305873

Spring AI 1.0.1 使用教程

项目简介

作为一个Java的开发者  听到Java也有ai框架了  很高兴~~~

本来想学一下SpringAI但是网上卖课的一大堆,并且大部分课程都是五月的,到2025年的8月份,SpringAI的版本做了很多更新,所以我本人参考网上示例,很多代码走不通,一些方法被废弃了,搞得有点破防。。。

于是我自行阅读了SpringAI1.0.1的官方教程  

目前应该是全网最新的示例教程 ,欢迎初学者小白git clone  

前人栽树 后人乘凉   给大家避坑的   可以点赞收藏加个绿泡泡不??

作者邮箱:shibaizhelianmeng@163.com  绿泡泡wx@:EonNetWork 

代码仓库:

代码拉取下来就可以跑

github:

Lappercn/SpringAI-examplehttps://github.com/Lappercn/SpringAI-examplegitee:

SpringAI1.0.1教程: 本项目是一个基于 Spring AI 1.0.1 的聊天应用示例,集成了 Ollama 模型,展示了如何使用 Spring AI 的核心功能: - 多模型动态切换 - 聊天记忆管理 - 自定义 Advisor(日志记录、拦截器等) - 用户会话隔离 - 流式响应处理https://gitee.com/Lapper/ChatAI

教程如下:

本项目是一个基于 Spring AI 1.0.1 的聊天应用示例,集成了 Ollama 模型,展示了如何使用 Spring AI 的核心功能:

  • 多模型动态切换
  • 聊天记忆管理
  • 自定义 Advisor(日志记录、拦截器等)
  • 用户会话隔离
  • 流式响应处理

环境要求

  • Java 17+
  • Spring Boot 3.5.4
  • Spring AI 1.0.1
  • Ollama(本地运行)

快速开始

1. 安装 Ollama

# 下载并安装 Ollama
curl -fsSL https://ollama.ai/install.sh | sh
# 拉取模型(示例)
ollama pull deepseek-r1:7b
ollama pull qwen2:7b
ollama pull llama3.2:3b

2. 启动项目

# 克隆项目
git clone 
cd ChatAI
# 启动应用
./mvnw spring-boot:run

3. 测试接口

# 基本聊天
curl "http://localhost:8080/ai/chat?prompt=你好&chatid=1&model=deepseek-r1:7b"
# 切换模型
curl "http://localhost:8080/ai/chat?prompt=讲个笑话&chatid=1&model=qwen2:7b"

核心功能详解

1. ChatClient 配置

文件位置:src/main/java/com/example/chatai/Config/CommonConfigOllama.java

@Configuration
public class CommonConfigOllama {@Beanpublic ChatMemory chatMemory(){return MessageWindowChatMemory.builder().build();}@Beanpublic ChatClient client(OllamaChatModel model){return ChatClient.builder(model).defaultSystem("你是一个可爱的小女孩你的回答语气 非常可爱是一个智能助手").defaultAdvisors(new SimpleLoggerAdvisor(),MessageChatMemoryAdvisor.builder(chatMemory()).build(),new CustomLoggingAdvisor()).build();}
}

核心接口说明:

  • ChatClient.builder(model): 创建聊天客户端构建器
  • .defaultSystem(String): 设置默认系统提示词
  • .defaultAdvisors(...): 注册默认的 Advisor 链

2. 动态模型切换

文件位置:src/main/java/com/example/chatai/Controller/ChatController.java

@GetMapping(value = "/chat", produces = "text/html;charset=utf-8")
public Flux chat(String prompt, int chatid,@RequestParam(defaultValue = "deepseek-r1:7b") String model) {return client.prompt().options(OllamaOptions.builder().model(model).build()).user(prompt).advisors(a -> a.param(CONVERSATION_ID, chatid)).stream().content();
}

接口定义:

  • client.prompt(): 开始构建提示
  • .options(OllamaOptions): 设置模型参数
  • .user(String): 设置用户消息
  • .advisors(...): 配置会话级 Advisor
  • .stream(): 启用流式响应
  • .content(): 获取内容流

OllamaOptions 常用配置:

OllamaOptions.builder().model("deepseek-r1:7b")           // 模型名称.temperature(0.7f)                 // 温度参数.topP(0.9f)                       // Top-P 采样.maxTokens(1000)                  // 最大 Token 数.build()

3. 聊天记忆管理

3.1 基础记忆配置
@Bean
public ChatMemory chatMemory(){// 滑动窗口记忆(保留最近 N 条消息)return MessageWindowChatMemory.builder().maxMessages(10)           // 最大消息数.build();
}
3.2 用户会话隔离

通过 CONVERSATION_ID 实现多用户隔离:

.advisors(a -> a.param(CONVERSATION_ID, chatid))

不同用户示例:

# 用户1的对话
curl "http://localhost:8080/ai/chat?prompt=我叫张三&chatid=1"
curl "http://localhost:8080/ai/chat?prompt=我叫什么名字?&chatid=1"
# 用户2的对话
curl "http://localhost:8080/ai/chat?prompt=我叫李四&chatid=2"
curl "http://localhost:8080/ai/chat?prompt=我叫什么名字?&chatid=2"
3.3 持久化记忆(扩展)

自定义持久化记忆实现:

@Component
public class DatabaseChatMemory implements ChatMemory {@Autowiredprivate ChatMessageRepository repository;@Overridepublic void add(String conversationId, List messages) {// 保存到数据库messages.forEach(msg -> {ChatMessageEntity entity = new ChatMessageEntity();entity.setConversationId(conversationId);entity.setContent(msg.getContent());entity.setRole(msg.getMessageType().getValue());entity.setTimestamp(LocalDateTime.now());repository.save(entity);});}@Overridepublic List get(String conversationId, int lastN) {// 从数据库查询return repository.findTopNByConversationIdOrderByTimestampDesc(conversationId, lastN).stream().map(this::toMessage).collect(Collectors.toList());}
}

4. 自定义 Advisor 开发

4.1 日志记录 Advisor

文件位置:src/main/java/com/example/chatai/Config/CustomLoggingAdvisor.java

@Component
public class CustomLoggingAdvisor implements CallAdvisor, StreamAdvisor, Ordered {private static final Logger logger = LoggerFactory.getLogger(CustomLoggingAdvisor.class);@Overridepublic ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {// 请求前处理logger.info("请求开始: {}", request.userText());long startTime = System.currentTimeMillis();// 调用下一个节点ChatClientResponse response = chain.nextCall(request);// 响应后处理long duration = System.currentTimeMillis() - startTime;logger.info("请求完成: 耗时{}ms, 响应长度: {}",duration, response.getResult().getOutput().getContent().length());return response;}@Overridepublic Flux adviseStream(ChatClientRequest request, StreamAdvisorChain chain) {logger.info("流式请求开始: {}", request.userText());return chain.nextStream(request).doOnNext(chunk -> logger.debug("接收到分片: {}",chunk.getResult().getOutput().getContent())).doOnComplete(() -> logger.info("流式响应完成")).doOnError(error -> logger.error("流式响应错误", error));}@Overridepublic int getOrder() {return 100; // 执行顺序,数字越小优先级越高}
}
4.2 权限验证 Advisor
@Component
public class AuthorizationAdvisor implements CallAdvisor {@Overridepublic ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {// 从请求中获取用户信息String userId = request.advisorParams().get("userId");// 验证用户权限if (!hasPermission(userId)) {throw new UnauthorizedException("用户无权限访问");}// 检查敏感词if (containsSensitiveWords(request.userText())) {throw new IllegalArgumentException("包含敏感词汇");}return chain.nextCall(request);}private boolean hasPermission(String userId) {// 实现权限检查逻辑return true;}private boolean containsSensitiveWords(String text) {// 实现敏感词检测逻辑return false;}
}
4.3 速率限制 Advisor
@Component
public class RateLimitAdvisor implements CallAdvisor {private final Map limiters = new ConcurrentHashMap<>();@Overridepublic ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {String userId = request.advisorParams().get("userId");// 获取或创建限流器(每分钟10次请求)RateLimiter limiter = limiters.computeIfAbsent(userId,k -> RateLimiter.create(10.0 / 60.0));if (!limiter.tryAcquire()) {throw new TooManyRequestsException("请求过于频繁,请稍后再试");}return chain.nextCall(request);}
}

5. 配置文件详解

文件位置:src/main/resources/application.yaml

spring:application:name: ChatAIai:ollama:base-url: http://localhost:11434    # Ollama 服务地址chat:model: deepseek-r1:7b             # 默认模型options:temperature: 0.2                # 创造性参数
# 日志配置
logging:level:com.example.chatai.Config.CustomLoggingAdvisor: INFOorg.springframework.ai.chat.client.advisor: DEBUGorg.springframework.ai: INFOpattern:console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

6. 完整的使用示例

6.1 基础聊天示例
@RestController
public class ExampleController {@Autowiredprivate ChatClient chatClient;// 简单聊天@GetMapping("/simple-chat")public String simpleChat(@RequestParam String message) {return chatClient.prompt().user(message).call().content();}// 带系统提示的聊天@GetMapping("/system-chat")public String systemChat(@RequestParam String message) {return chatClient.prompt().system("你是一个专业的代码审查员").user(message).call().content();}// 流式聊天@GetMapping("/stream-chat")public Flux streamChat(@RequestParam String message) {return chatClient.prompt().user(message).stream().content();}
}
6.2 高级功能示例
@RestController
public class AdvancedController {@Autowiredprivate ChatClient chatClient;// 多轮对话与记忆@PostMapping("/conversation")public ResponseEntity conversation(@RequestBody ConversationRequest request) {String response = chatClient.prompt().user(request.getMessage()).advisors(advisor -> advisor.param(CONVERSATION_ID, request.getUserId()).param("userId", request.getUserId())).call().content();return ResponseEntity.ok(response);}// 带选项的聊天@PostMapping("/chat-with-options")public String chatWithOptions(@RequestBody ChatRequest request) {return chatClient.prompt().options(OllamaOptions.builder().model(request.getModel()).temperature(request.getTemperature()).maxTokens(request.getMaxTokens()).build()).user(request.getMessage()).call().content();}// 函数调用示例(如果模型支持)@PostMapping("/function-call")public String functionCall(@RequestParam String query) {return chatClient.prompt().user(query).functions("getCurrentWeather", "searchDatabase").call().content();}
}

最佳实践

1. 错误处理

@RestController
public class ChatController {@GetMapping("/safe-chat")public ResponseEntity safeChat(@RequestParam String message) {try {String response = chatClient.prompt().user(message).call().content();return ResponseEntity.ok(response);} catch (Exception e) {logger.error("聊天请求失败", e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("抱歉,服务暂时不可用");}}
}

2. 性能优化

@Configuration
public class ChatClientConfig {@Bean@Primarypublic ChatClient optimizedChatClient(OllamaChatModel model) {return ChatClient.builder(model).defaultAdvisors(// 缓存 Advisornew CacheAdvisor(),// 限流 Advisornew RateLimitAdvisor(),// 日志 Advisor(低优先级)new SimpleLoggerAdvisor()).build();}
}

3. 监控指标

@Component
public class MetricsAdvisor implements CallAdvisor {private final MeterRegistry meterRegistry;private final Counter requestCounter;private final Timer responseTimer;public MetricsAdvisor(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;this.requestCounter = Counter.builder("ai.requests.total").register(meterRegistry);this.responseTimer = Timer.builder("ai.response.duration").register(meterRegistry);}@Overridepublic ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {return Timer.Sample.start(meterRegistry).stop(responseTimer, () -> {requestCounter.increment();return chain.nextCall(request);});}
}

故障排除

常见问题

  1. 模型连接失败

    • 检查 Ollama 服务是否启动:ollama list
    • 确认模型已下载:ollama pull model-name
  2. 日志不显示

    • 检查 application.yaml 中的日志级别配置
    • 确认 Advisor 已正确注册
  3. 记忆功能不生效

    • 确认 ChatMemory Bean 正确配置
    • 检查 CONVERSATION_ID 参数传递

调试技巧

# 开启详细日志
logging:level:org.springframework.ai: DEBUGorg.springframework.web: DEBUGcom.example.chatai: DEBUG

扩展开发

自定义模型适配

@Configuration
public class CustomModelConfig {@Bean@ConditionalOnProperty(name = "app.model.provider", havingValue = "custom")public ChatModel customChatModel() {// 实现自定义模型适配return new CustomChatModel();}
}

多租户支持

@Component
public class MultiTenantAdvisor implements CallAdvisor {@Overridepublic ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {String tenantId = request.advisorParams().get("tenantId");// 设置租户上下文TenantContext.setCurrentTenant(tenantId);try {return chain.nextCall(request);} finally {TenantContext.clear();}}
}

参考资源

  • Spring AI 官方文档
  • Ollama 官网
  • Spring Boot 文档

联系方式

  • 作者:胖虎爱java
  • 邮箱:shibaizhelianmeng@163.com
  • CSDN:胖虎爱java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/986549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年导热油加热器厂家实力推荐,看看哪家品牌的质量好

为帮工业企业高效锁定适配生产需求的导热油加热器供应商,避免选型走弯路导致设备故障、能耗超标等问题,我们从产品质量稳定性(如加热均匀性、运行故障率)、定制化能力(含非标场景适配、快速出样效率)、全周期服务…

jenkins上执行某个python代码,日志没有打印,如何处理

在Jenkins中执行Python脚本时日志不显示,通常是因为Jenkins的默认行为中断了进程和输出管道。你可以按照以下流程进行排查和解决。 主要问题解决方案详解 1. 防止Jenkins终止后台进程 这是最常见的原因。Jenkins为每…

沉浸式雨天海岸:用A-Frame打造WebXR互动场景 - 实践

沉浸式雨天海岸:用A-Frame打造WebXR互动场景 - 实践2025-12-04 10:46 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; dis…

游记:NOIP2025 游记

炸完了。lyc:你 T2 复杂度多少。 我:\(\mathcal O(\sum n ^ 2)\) 啊? lyc: (短暂思考)是可以优化到。 我:你不是直接范德蒙德卷积吗,然后……不对我怎么多个 \(\log\)??ei 貌似我开始时想到了但后面忘了这回事…

pdf转png的4个实用方法!看看涨知识

pdf文件转png图片怎么转才能又高清又便捷?面对市面上琳琅满目的转换方法,今天我们就来深入探讨几种实用且高效的PDF转PNG妙招,从最简单直接的截图方式,到专业的第三方工具,希望能为你提供清晰的指引。 1. 直接截图…

齿轮与光阴的叙事:不二越 NACHI 官方认证十大优秀代理商全名单

这份榜单从 93 家申报企业中突围,像用 NACHI 高精度量具校准过般严苛。我们联合《Industrial Distribution》2025 全球分销报告、网易格物致胜数据库,访谈 217 位客户、核查三年财报,最终定下四条不可动摇的标尺,每…

成都地区有实力的石栏杆生产厂家怎么选?求口碑推荐

四川地区有实力的石栏杆生产厂家怎么选?求口碑推荐一、引言:四川地区石栏杆选购,“实力厂家” 是关键四川作为川蜀文化核心地,古镇修复(如平乐古镇、黄龙溪古镇)、公园建设(如浣花溪公园、青龙湖湿地公园)、市…

成都石栏杆厂家十大排名:2025 年权威推荐榜发布

成都石栏杆厂家十大排名:2025 年权威推荐榜发布近日,四川省石材商会联合第三方检测机构,基于 2024-2025 年工商信息、招标中标记录、质量抽检报告及 1200 份用户回访数据,发布 “成都石栏杆厂家十大推荐榜”,资阳…

2025成都出国留学中介公司

2025成都出国留学中介公司一、2025年成都留学中介选择指南作为从事12年国际教育规划师的我,经常被成都的学生和家长询问:2025年如何选择可靠的出国留学中介?在成都这个教育资源丰富的城市,留学中介数量众多,选择时…

Python的终端彩色输出:termcolor库

termcolor是一个能让终端彩色输出的Python库,通过ANSI转义序列操控文本的颜色、背景色以及样式,比如加粗或下划线等。这个库允许你在终端中以彩色形式输出文本。1、安装:pip install termcolor -i https://pypi.mir…

2025比较好的留学机构深圳

2025比较好的留学机构深圳一、如何在深圳选择可靠的留学中介许多深圳学生和家长在搜索"2025比较好的留学机构深圳"时,通常关注三个核心问题:深圳本地哪些留学中介具备真实的成功案例、中介的服务流程是否透…

效果好的眼霜有没有推荐的?25年公认好用抗皱紧致眼霜推荐:淡化黑眼圈眼袋

“加班赶方案到凌晨,眼周黑圈堪比熊猫眼;带娃连轴转,眼尾细纹一笑就显;用惯了厚重眼霜,油皮闷出脂肪粒,干皮却还是越涂越干”——眼周问题从来都是“千人千面”,但盲目护理的后果却惊人地相似:薄嫩的眼周肌肤屏…

2025年宁波同城奢侈品收购公司五大推荐:看哪家信誉好

在宁波这座充满商业活力的城市,闲置的奢侈品如何快速变现?如何找到同城靠谱的奢侈品收购公司?2025年,我们依据口碑、专业度、服务体验等维度,筛选出5家宁波本地可靠的奢侈品回收门店,其中宁波市鄞州钟公庙友鲤珠…

2025年工厂用通风机定制哪家好、厨房用通风机供应商、商场用

本榜单依托全维度市场调研与真实行业口碑,深度筛选出十家标杆企业,为企业选型提供客观依据,助力精准匹配适配的服务伙伴。 TOP1 推荐:广东中电嘉进环境科技有限公司 推荐指数:★★★★★ 口碑评分:国内专业的通风…

2025年品牌认证机构推荐:哪家服务更优?行业数据与口碑分析

随着品牌经济快速发展,2025年品牌认证行业面临标准化不足、服务质量参差不齐等挑战。根据中国市场信息调查业协会数据显示,2024年品牌认证服务市场规模达120亿元,但客户满意度仅68%。本文基于2025年行业公开数据和第…

2025北京留学中介机构十强

2025北京留学中介机构十强一、如何选择北京的留学中介机构许多准备出国深造的学生和家长常提出一个问题:在北京众多留学中介中,如何找到真正靠谱的机构?根据《2025中国留学中介白皮书》的数据显示,北京地区留学咨询…

2025年12月,三螺杆挤出造粒机哪家强?这份推荐榜TOP给你答案!造粒机/塑料/双螺杆/双螺杆挤出/三螺杆/三螺杆挤出/再生料/填充母粒造粒机/母粒造粒机械排行榜!

2025年12月,三螺杆挤出造粒机哪家强?这份推荐榜TOP给你答案!造粒机/塑料/双螺杆/双螺杆挤出/三螺杆/三螺杆挤出/再生料/填充母粒造粒机/母粒造粒机械排行榜! 在改性塑料、色母粒、功能母粒等高附加值材料生产领域,…

2025 geo优化公司排行榜前十推荐:AI搜索时代的流量领航者

当生成式AI重构信息分发逻辑,用户的查询习惯已从“关键词检索”转向“自然语言问答”,geo优化(生成式引擎优化)已成为企业抢占数字流量新高地的核心竞争力。作为AI时代的精准获客技术,geo优化通过语义结构化处理、…

C++ 静态库与动态库

一、核心定义与本质区别 1. 静态库(Static Library)格式:Windows 下后缀为 .lib,Linux/macOS 下为 .a; 本质:编译时将库代码完整复制到可执行文件中,生成独立可执行程序,运行时无需依赖外部库文件; 特点:可执…

2025年销量第一证明机构推荐:哪家合规性更稳?权威排名与选择指南

随着市场竞争日益激烈,企业亟需通过权威数据证明自身市场地位以提升品牌公信力。根据国家市场监督管理总局2024年发布的《广告合规白皮书》,超过60%的企业因缺乏第三方销量证明在宣传中面临合规风险,而具备权威背书…