SpringBoot集成Ollama本地模型

SpringBoot集成Ollama本地模型

目录

  1. 项目准备
  2. 创建Ollama服务客户端
  3. 创建控制器
  4. 配置应用属性
  5. 创建前端界面
  6. 添加静态资源支持
  7. 完整项目结构
  8. 启动应用
  9. 高级功能扩展
  10. 部署注意事项
  11. 性能优化

1. 项目准备

  1. 创建一个SpringBoot项目,可以使用Spring Initializr或IDE创建
  2. 添加必要的依赖到pom.xml:
    <dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- WebClient --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>
    </dependencies>
    

2. 创建Ollama服务客户端

package com.example.ollama.service;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.List;
import java.util.Map;@Slf4j
@Service
public class OllamaService {private final WebClient webClient;public OllamaService(@Value("${ollama.api.url:http://localhost:11434}") String ollamaApiUrl) {this.webClient = WebClient.builder().baseUrl(ollamaApiUrl).build();}/*** 生成文本*/public Mono<String> generateText(String model, String prompt, Double temperature) {Map<String, Object> requestBody = Map.of("model", model,"prompt", prompt,"temperature", temperature != null ? temperature : 0.7);return webClient.post().uri("/api/generate").bodyValue(requestBody).retrieve().bodyToMono(Map.class).map(response -> (String) response.get("response"));}/*** 聊天对话*/public Mono<String> chat(String model, List<Map<String, String>> messages) {Map<String, Object> requestBody = Map.of("model", model,"messages", messages);return webClient.post().uri("/api/chat").bodyValue(requestBody).retrieve().bodyToMono(Map.class).map(response -> {Map<String, Object> message = (Map<String, Object>) response.get("message");return (String) message.get("content");});}/*** 流式生成文本*/public Flux<String> streamGenerateText(String model, String prompt, Double temperature) {Map<String, Object> requestBody = Map.of("model", model,"prompt", prompt,"temperature", temperature != null ? temperature : 0.7,"stream", true);return webClient.post().uri("/api/generate").bodyValue(requestBody).retrieve().bodyToFlux(Map.class).map(response -> (String) response.get("response"));}
}

3. 创建控制器

package com.example.ollama.controller;import com.example.ollama.service.OllamaService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;import java.util.List;
import java.util.Map;@RestController
@RequestMapping("/api/ollama")
@RequiredArgsConstructor
public class OllamaController {private final OllamaService ollamaService;@PostMapping("/generate")public Mono<String> generateText(@RequestParam(defaultValue = "llama2") String model,@RequestParam String prompt,@RequestParam(required = false) Double temperature) {return ollamaService.generateText(model, prompt, temperature);}@PostMapping("/chat")public Mono<String> chat(@RequestParam(defaultValue = "llama2") String model,@RequestBody List<Map<String, String>> messages) {return ollamaService.chat(model, messages);}@PostMapping("/stream")public Flux<String> streamGenerateText(@RequestParam(defaultValue = "llama2") String model,@RequestParam String prompt,@RequestParam(required = false) Double temperature) {return ollamaService.streamGenerateText(model, prompt, temperature);}
}

4. 配置应用属性

application.propertiesapplication.yml中添加配置:

# Ollama API配置
ollama.api.url=http://localhost:11434# 服务器配置
server.port=8080

5. 创建前端界面

创建一个简单的HTML页面用于与Ollama交互:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ollama聊天界面</title><style>body {font-family: Arial, sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;}.chat-container {border: 1px solid #ccc;border-radius: 5px;padding: 20px;margin-bottom: 20px;height: 400px;overflow-y: auto;}.message {margin-bottom: 10px;padding: 10px;border-radius: 5px;}.user-message {background-color: #e6f7ff;margin-left: 20%;}.ai-message {background-color: #f0f0f0;margin-right: 20%;}.input-container {display: flex;}#message-input {flex-grow: 1;padding: 10px;border: 1px solid #ccc;border-radius: 5px;margin-right: 10px;}button {padding: 10px 20px;background-color: #4CAF50;color: white;border: none;border-radius: 5px;cursor: pointer;}button:hover {background-color: #45a049;}</style>
</head>
<body><h1>Ollama聊天界面</h1><div class="chat-container" id="chat-container"></div><div class="input-container"><input type="text" id="message-input" placeholder="输入消息..."><button onclick="sendMessage()">发送</button></div><script>const chatContainer = document.getElementById('chat-container');const messageInput = document.getElementById('message-input');// 按Enter键发送消息messageInput.addEventListener('keypress', function(e) {if (e.key === 'Enter') {sendMessage();}});function sendMessage() {const message = messageInput.value.trim();if (!message) return;// 添加用户消息到聊天界面addMessage(message, 'user');messageInput.value = '';// 发送消息到后端fetch('/api/ollama/chat', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify([{'role': 'user','content': message}])}).then(response => response.text()).then(response => {// 添加AI回复到聊天界面addMessage(response, 'ai');}).catch(error => {console.error('Error:', error);addMessage('发生错误,请稍后重试。', 'ai');});}function addMessage(message, sender) {const messageDiv = document.createElement('div');messageDiv.classList.add('message');messageDiv.classList.add(sender === 'user' ? 'user-message' : 'ai-message');messageDiv.textContent = message;chatContainer.appendChild(messageDiv);chatContainer.scrollTop = chatContainer.scrollHeight;}</script>
</body>
</html>

6. 添加静态资源支持

在SpringBoot应用中添加静态资源支持:

package com.example.ollama.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");}
}

7. 完整项目结构

src/
├── main/
│   ├── java/
│   │   └── com/
│   │       └── example/
│   │           └── ollama/
│   │               ├── OllamaApplication.java
│   │               ├── controller/
│   │               │   └── OllamaController.java
│   │               ├── service/
│   │               │   └── OllamaService.java
│   │               └── config/
│   │                   └── WebConfig.java
│   └── resources/
│       ├── static/
│       │   └── index.html
│       └── application.properties

8. 启动应用

  1. 确保Ollama服务已启动并运行在默认端口(11434)
  2. 运行SpringBoot应用
  3. 访问http://localhost:8080查看聊天界面

9. 高级功能扩展

9.1 添加模型选择功能

@GetMapping("/models")
public Mono<List<String>> listModels() {return webClient.get().uri("/api/tags").retrieve().bodyToMono(Map.class).map(response -> {List<Map<String, Object>> models = (List<Map<String, Object>>) response.get("models");return models.stream().map(model -> (String) model.get("name")).collect(Collectors.toList());});
}

9.2 添加流式响应支持

@GetMapping(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> streamChat(@RequestParam(defaultValue = "llama2") String model,@RequestParam String message) {return ollamaService.streamGenerateText(model, message, 0.7).map(response -> ServerSentEvent.<String>builder().data(response).build());
}

9.3 添加会话管理

@Service
public class ChatSessionService {private final Map<String, List<Map<String, String>>> sessions = new ConcurrentHashMap<>();public List<Map<String, String>> getOrCreateSession(String sessionId) {return sessions.computeIfAbsent(sessionId, k -> new ArrayList<>());}public void addMessage(String sessionId, String role, String content) {List<Map<String, String>> messages = getOrCreateSession(sessionId);messages.add(Map.of("role", role, "content", content));}public void clearSession(String sessionId) {sessions.remove(sessionId);}
}

10. 部署注意事项

  1. 确保服务器上已安装并运行Ollama服务
  2. 配置适当的防火墙规则,允许SpringBoot应用访问Ollama服务
  3. 在生产环境中使用HTTPS保护API通信
  4. 考虑添加身份验证和授权机制
  5. 监控Ollama服务的资源使用情况,避免过载

11. 性能优化

  1. 使用连接池管理WebClient连接
  2. 实现请求缓存,避免重复请求
  3. 使用异步处理提高并发能力
  4. 考虑使用响应式编程模式处理流式响应

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

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

相关文章

ResNet改进(19):基于PyTorch的ResNet改进方案详解:Mish激活+SPP模块+MixUp数据增强

1. 前言 ResNet作为深度学习领域里程碑式的网络架构,在图像分类等计算机视觉任务中表现出色。然而,随着研究的深入和技术的发展,原始的ResNet架构仍有改进空间。本文将详细介绍一种基于PyTorch的ResNet改进方案,该方案融合了Mish激活函数、SPP模块和MixUp数据增强等先进技…

leetcode68.左右文本对齐

思路源自 leetcode-字符串篇 68题 文本左右对齐 难度高的模拟类型题目&#xff0c;关键点在于事先知道有多少单词要放在本行并且还要知道本行是不是最后一行&#xff08;最后一行需要全部单空格右对齐&#xff0c;不是最后一行就空格均摊&#xff09;&#xff0c;非最后一行的空…

深入理解 Spring 的 MethodParameter 类

MethodParameter 是 Spring 框架中一个非常重要的类&#xff0c;它封装了方法参数&#xff08;或返回类型&#xff09;的元数据信息。这个类在 Spring MVC、AOP、数据绑定等多个模块中都有广泛应用。 核心功能 MethodParameter 主要提供以下功能&#xff1a; 获取参数类型信息…

Qt 5.14.2入门(一)写个Hello Qt!程序

目录 参考链接&#xff1a;一、新建项目二、直接运行三、修改代码增加窗口内容1、Qt 显示一个 QLabel 标签控件窗口2、添加按键 参考链接&#xff1a; Qt5教程&#xff08;一&#xff09;&#xff1a;Hello World 程序 Qt 编程指南 一、新建项目 1、新建一个项目&#xff08…

Spring Boot 3.x 集成 MongoDB 的 默认配置项及默认值,以及 常用需要修改的配置项 的详细说明

以下是 Spring Boot 3.x 集成 MongoDB 的 默认配置项及默认值&#xff0c;以及 常用需要修改的配置项 的详细说明&#xff1a; 一、默认配置项及默认值 Spring Boot 对 MongoDB 的默认配置基于 spring.data.mongodb 前缀&#xff0c;以下是核心配置项&#xff1a; 配置项默认…

【QT】 进程

目录 QT 多进程复习 Linux-C 多进程QProcess 进程类常用方法简单示例信号与槽应用场景 跨平台注意事项技巧&#xff1a;使用宏控制平台命令 QProcess 在嵌入式系统中的使用示例&#xff1a;调用 ALSA 播放音频示例&#xff1a;调用 arecord 录音示例&#xff1a;QProcess Shel…

原子操作(cpp atomic)

目录 一.原子操作 1.原子操作的概念 2.原子变量 二.原子性 1.中间状态描述 2.单处理器单核 3.多处理器或多核的情况下 4.cache&#xff08;高速缓冲器的作用&#xff09; 5.在cpu cache基础上,cpu如何读写数据&#xff1f;&#xff1f;&#xff1f; 6.为什么会有缓存…

Unet网络的Pytorch实现和matlab实现

文章目录 一、Unet网络简介1.1 输入图像1.2 编码器部分&#xff08;Contracting Path&#xff09;1.3 解码器部分&#xff08;Expanding Path&#xff09;1.4 最后一层&#xff08;输出&#xff09;1.5 跳跃连接&#xff08;Skip Connections&#xff09; 二、Unet网络的Pytorc…

记录一次JVM调优过程1

如何通过jmap 诊断&#xff0c;服务运行一段时间后内存使用量飙升的问题 通过 jmap 诊断服务运行一段时间后内存使用量飙升的问题&#xff0c;需结合堆转储分析、对象分布统计及工具链配合。以下是具体操作步骤和关键方法&#xff1a; 一、实时监控与初步分析 获取进程 PID 使…

接口自动化学习五:mock工具使用

Moco简介&#xff1a; Mock是一个简单搭建模拟服务器的框架&#xff0c;可以用来模拟http、https、socket等协议。 原理&#xff1a; Mock会根据一些配置&#xff0c;启动一个真正的HTTP服务&#xff08;会监听本地的某个端口&#xff09;,当发起的请求满足某个条件时&#xf…

若依 前后端部署

后端&#xff1a;直接把代码从gitee上拉去到本地目录 (https://gitee.com/y_project/RuoYi-Vue ) 注意下redis连接时password改auth 后端启动成功 前端&#xff1a;运行前首先确保安装了node环境&#xff0c;随后执行&#xff1a; &#xff01;&#xff01;一定要用管理员权限…

Adaptive AUTOSAR 状态管理和转换——ActionItemList

在AUTOSAR的状态转换管理(STM,State Transition Manager) 框架中,ActionItemList 是连接 状态机状态(State Machine State) 与 功能组状态(Function Group States) 的核心配置元素。 以下是其关系与作用的详细解释: 1. 核心概念 状态机状态(State Machine State) 表…

一个基于ragflow的工业文档智能解析和问答系统

工业复杂文档解析系统 一个基于ragflow的工业文档智能解析和问答系统,支持多种文档格式的解析、知识库管理和智能问答功能。 系统功能 1. 文档管理 支持多种格式文档上传(PDF、Word、Excel、PPT、图片等)文档自动解析和分块处理实时处理进度显示文档解析结果预览批量文档…

linux系统下如何提交git和调试

我们默认的ubuntu20.04镜像是没有Git提交的工具&#xff0c;我们需要配置安装包。 安装和更新git的命令 sudo apt update //用于更新软件包索引sudo apt install git //用于安装git版本控制工具 git --version //检查git版本,确认是否安装成功 随便进入linux系统下的一…

轻量级爬虫框架Feapder入门:快速搭建企业级数据管道

一、目标与前置知识 1. 目标概述 本教程的主要目标是&#xff1a; 介绍轻量级爬虫框架 Feapder 的基本使用方式。快速搭建一个采集豆瓣电影数据的爬虫&#xff0c;通过电影名称查找对应的电影详情页并提取相关信息&#xff08;电影名称、导演、演员、剧情简介、评分&#xf…

spring mvc的拦截器HandlerInterceptor 接口详解

HandlerInterceptor 接口详解 1. 接口方法说明 方法作用执行时机返回值/注意事项preHandle请求处理前拦截在控制器方法执行前调用返回 false 中断后续流程&#xff1b;返回 true 继续执行postHandle控制器方法执行后拦截在控制器方法返回结果后&#xff0c;视图渲染前调用无返…

数据可视化 —— 柱形图应用(大全)

一、案例一&#xff1a;单柱形图 1.导入库 import matplotlib.pyplot as plt import pandas as pd import numpy as np 2.给窗口名称和画布大小 plt.figure(num单柱形图, figsize(6, 4), facecolorw) 3.定义x、y轴的数据 # range(0-4) x np.arange(5) # 创建数组 y1 np.a…

apijson 快速上手

apijson是强大的工具&#xff0c;简化了CRUD的操作&#xff0c;只要有数据库表&#xff0c;就能自动生成RESTFUL接口。但初次上手也是摸索了很长时间&#xff0c;尤其是部署与使用上&#xff0c;这里尝试以初学者角度来说下&#xff1a; 一、好处 1、对于简单的应用&#xff…

V4L2杂谈

V4L2的开发手册 在做v4l2的开发的时候&#xff0c; 可以使用v4l2-ctl命令协助调试和软件开发。关于linux多媒体开发可以参考链接&#xff1a;https://www.linuxtv.org/wiki/index.php/Main_Page关于v4l2的api接口开发可以参考&#xff1a;https://linuxtv.org/docs.php在linux…

(五)深入了解AVFoundation-播放:多音轨、字幕、倍速播放与横竖屏切换

引言 在之前的博客中&#xff0c;我们已经实现了一个相对完整的播放器&#xff0c;具备了基本功能&#xff0c;如播放、暂停、播放进度显示和拖拽快进等。这为我们提供了一个坚实的基础。接下来&#xff0c;我们将进一步扩展播放器的功能&#xff0c;使其更具灵活性和实用性&a…