SpringBoot调用本地AI
本文将手把手教你如何用 Spring Boot + Ollama + Spring AI 快速搭建一个支持流式输出的本地 AI 对话系统,无需联网、支持私有部署,还能扩展接入 OpenAI、DeepSeek 等模型。
🧠 第一步:安装 Ollama,开启本地大模型
Ollama 是一个简洁好用的本地大模型运行工具,你可以在自己的电脑上直接部署和运行 LLM。
✅ 安装 Ollama
访问官网下载安装(支持 Windows/Mac/Linux):
👉 https://ollama.com/download
✅ 启动并验证是否成功
打开终端,运行:
ollama run gemma3:1b
浏览器访问:http://localhost:11434/,看到如下页面代表 Ollama 已运行:

🧩 第二步:Spring Boot 调用本地模型
Spring AI 是由 Spring 团队推出的 AI 接口库,集成后调用本地模型就像调用数据库一样简单。目前已经推出1.0正式版。
我们需要创建一个SpringBoot项目,进行如下配置
🧱 添加依赖(Maven)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
<version>1.0.0-M6</version>
</dependency>
⚙️ 配置 application.yml
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
model: gemma3:1b
✅ 模型名需和你本地运行的一致!
✨ 创建一个简单的对话接口
@RequestMapping("/ollama")
@RestController
public class LocalAIInvokeTest {
@Resource
private OllamaChatModel ollamaChatModel;
/**
* 根据用户提问输出回答
*
* @param prompt
* @return
*/
@GetMapping("/test")
public String testChat(String prompt) {
ChatResponse chatResponse = ollamaChatModel
.call(new Prompt(prompt,
OllamaOptions.builder()
.model("gemma3:1b")
.build()));
return chatResponse.getResult().getOutput().getText();
}
}
效果示例:
http://localhost:8080/test?prompt=你好
🖼️ 接口返回效果:

💬 第三步:实现流式对话(像 ChatGPT 一样输出)
相比普通一次性输出,流式输出体验更丝滑,可以边生成边展示内容。
Spring Boot 使用 Flux + TEXT_EVENT_STREAM_VALUE
即可实现:
@GetMapping(value = "/testStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ChatResponse> testChatStream(String prompt) {
return ollamaChatModel.stream(
new Prompt(prompt, OllamaOptions.builder().model("gemma3:1b").build()));
}
📸 效果图:

💻 第四步:用原生 HTML 打造可交互前端
无需 Vue/React,只用 HTML + JS 实现一个支持实时流式展示的聊天界面👇
👉 功能包含:
- 自动滚动
- 支持 Markdown 渲染
- 支持 Enter 发送、Shift+Enter 换行
- 自动伸缩输入框
🔧 代码如下
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>本地 AI 对话系统</title>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.5/dist/purify.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
font-family: "Helvetica Neue", Arial, sans-serif;
background: #f4f4f4;
margin: 0;
padding: 48px;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.chat-wrapper {
display: flex;
flex-direction: column;
width: 100%;
max-width: 1200px;
height: 100%;
background: #fff;
border-radius: 16px;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.chat-container {
flex: 1;
overflow-y: auto;
padding: 24px;
display: flex;
flex-direction: column;
}
.message {
max-width: 70%;
padding: 12px 16px;
margin: 8px 0;
border-radius: 16px;
word-break: break-word;
line-height: 1.5;
}
.user {
align-self: flex-end;
background-color: #dcfce7;
color: #0f5132;
border: 1px solid #badbcc;
}
.ai {
align-self: flex-start;
background-color: #f8f9fa;
border: 1px solid #dee2e6;
}
.input-bar {
display: flex;
padding: 16px 24px;
border-top: 1px solid #ddd;
background-color: #ffffff;
}
#promptInput {
flex: 1;
padding: 12px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 8px;
resize: none;
height: 48px;
line-height: 1.5;
}
#sendBtn {
margin-left: 12px;
padding: 12px 20px;
font-size: 16px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
transition: background-color 0.2s ease;
}
#sendBtn:hover {
background-color: #45a049;
}
pre code {
background: #f6f8fa;
padding: 8px;
border-radius: 6px;
display: block;
overflow-x: auto;
}
</style>
</head>
<body>
<div class="chat-wrapper">
<div class="chat-container" id="chatContainer"></div>
<div class="input-bar">
<textarea id="promptInput" placeholder="请输入你的问题..." rows="3"></textarea>
<button id="sendBtn">发送</button>
</div>
</div>
<script>
const chatContainer = document.getElementById('chatContainer');
const input = document.getElementById('promptInput');
const button = document.getElementById('sendBtn');
function appendMessage(className) {
const div = document.createElement('div');
div.className = `message ${className}`;
chatContainer.appendChild(div);
chatContainer.scrollTop = chatContainer.scrollHeight;
return div;
}
function sendMessage() {
const prompt = input.value.trim();
if (!prompt) return;
const userDiv = document.createElement('div');
userDiv.className = 'message user';
userDiv.textContent = prompt;
chatContainer.appendChild(userDiv);
input.value = '';
input.style.height = '48px'; // 重置高度
const aiDiv = appendMessage('ai');
let markdownBuffer = '';
const eventSource = new EventSource(`http://localhost:8090/ollama/testStream?prompt=${encodeURIComponent(prompt)}`);
eventSource.onmessage = (event) => {
const json = JSON.parse(event.data);
const text = json.result.output.text;
markdownBuffer += text;
aiDiv.innerHTML = DOMPurify.sanitize(marked.parse(markdownBuffer));
chatContainer.scrollTop = chatContainer.scrollHeight;
};
eventSource.onerror = () => {
eventSource.close();
};
}
// 点击发送按钮
button.onclick = sendMessage;
// 按回车键发送(Shift+Enter换行)
input.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendMessage();
}
});
// 自动调整 textarea 高度
input.addEventListener('input', () => {
input.style.height = 'auto';
input.style.height = input.scrollHeight + 'px';
});
</script>
</body>
</html>
页面效果如下:

🌐 第五步:接入 OpenAI、DeepSeek 等云模型(可选)
如需调用云端大模型(如 GPT-4、DeepSeek),只需:
✅ 申请对应的key
✅ 引入依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
✅ 配置 API Key
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
若使用国产模型(如通义千问),推荐使用阿里封装的SpringAI Spring AI Alibaba。
📌 小结
通过本文你已经掌握:
✅ 如何安装并运行本地大模型 ✅ 如何用 Spring Boot + Spring AI 调用模型 ✅ 如何实现 ChatGPT 式流式输出接口 ✅ 如何构建一个轻量前端聊天系统
贡献者
flycodeu
版权所有
版权归属:flycodeu