
1. 项目概述当Spring AI遇见本地大模型Ollama如果你正在用Spring Boot做Java后端开发同时又对最近火热的本地大模型部署感兴趣那么“Spring AI Ollama”这个组合绝对值得你花时间深入研究。简单来说这就是一套让你能在熟悉的Spring生态里轻松调用运行在自己电脑或服务器上的开源大模型比如Llama、Qwen、DeepSeek等的解决方案。你不用再去申请那些按Token计费、网络还可能受限的云端API也不用操心LangChain那种相对复杂的Python生态在Java的世界里就能玩转AI应用开发。我最初接触这个组合是因为一个内部知识库问答系统的需求。客户对数据隐私要求极高所有数据不能出内网。当时评估了各种方案最终发现Spring AI的Ollama模块几乎是唯一能同时满足“Java技术栈”、“本地化部署”、“开箱即用”这几个苛刻条件的选项。它把调用本地大模型这件事变得像集成一个普通的Spring Boot Starter一样简单。你只需要在pom.xml里加个依赖在application.yml里配个地址然后就能像调用服务一样去让大模型生成文本、分析内容。这对于广大Java开发者而言门槛降低了一大截。接下来我会带你从零开始彻底搞懂如何搭建和用好“Spring AI Ollama API”。我们会涵盖从环境准备、依赖配置、基础调用到高级功能如工具调用Function Calling、思维链Reasoning Mode、结构化输出Structured Outputs的完整实践并分享我在实际项目中踩过的坑和总结的优化技巧。无论你是想快速做个Demo还是计划在生产环境集成这篇文章都能给你提供清晰的路径。2. 环境准备与项目初始化2.1 Ollama的安装与模型部署一切的基础是Ollama。你可以把它理解为一个本地的大模型服务引擎它负责模型的加载、推理和管理并对外提供统一的HTTP API。Spring AI的ollama模块就是通过这个API与模型通信的。安装OllamaOllama支持Windows、macOS和Linux。官方下载通常很慢这里强烈建议使用国内镜像源加速。以Linux/macOS为例最稳妥的方式是使用安装脚本并指定镜像# 对于Linux/macOS使用国内镜像下载安装脚本并安装 curl -fsSL https://ollama.com/install.sh | OLLAMA_HOST0.0.0.0 sh安装完成后Ollama服务会自动启动默认监听11434端口。你可以通过ollama --version验证安装并通过ollama serve启动服务如果未自动运行。拉取模型安装好Ollama后你需要拉取具体的模型。Ollama官方维护了一个模型库包含Llama、Mistral、Qwen、DeepSeek等众多热门模型。首次拉取同样可能很慢解决方法是在运行拉取命令时通过环境变量设置镜像。# 方法一拉取官方库模型如Qwen2.5通过环境变量使用国内镜像 OLLAMA_MODELS_SOURCEhttps://mirror.ghproxy.com/ollama/models ollama pull qwen2.5:7b # 方法二直接拉取Hugging Face上的GGUF格式模型资源更丰富 ollama pull hf.co/bartowski/gemma-2-2b-it-GGUF实操心得模型选择与下载轻量起步初次尝试建议从较小的模型开始如qwen2.5:0.5b或llama3.2:3b下载快对硬件要求低。镜像加速如果ollama pull速度极慢甚至失败大概率是网络问题。除了上述环境变量方法也可以考虑手动下载模型的Modelfile和权重文件然后通过ollama create命令本地创建。不过Spring AI的自动拉取功能后文会讲在配置了镜像后也能解决这个问题。验证模型拉取完成后可以用命令行测试ollama run qwen2.5:7b输入问题看是否能正常回复。这能快速排除Ollama服务本身的问题。2.2 Spring Boot项目创建与依赖引入假设你使用Spring Initializrstart.spring.io创建项目选择最新的Spring Boot 3.x版本并添加Spring AI和Spring Web依赖。更精确的做法是直接编辑pom.xml文件。关键依赖Spring AI的版本管理通过BOMBill of Materials进行这能确保所有Spring AI组件版本一致。首先在dependencyManagement部分引入BOMdependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0-M5/version !-- 请使用当前最新稳定版 -- typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement然后在dependencies中添加Ollama的Starter依赖dependencies !-- Spring AI Ollama 集成 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-ollama/artifactId /dependency !-- Web支持用于创建REST API -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- 可选用于测试 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies注意事项版本兼容性Spring AI版本迭代较快1.0.0-M5是里程碑版本API相对稳定。生产环境建议使用最新的GA正式版版本例如1.0.0或更高。务必查看Spring AI官方文档确认BOM版本与Spring Boot版本的兼容性。一个常见的坑是使用了过新或过旧的Spring AI版本导致自动配置不生效或类找不到。2.3 基础配置详解依赖加好后在application.yml或application.properties中进行最小化配置spring: ai: ollama: # Ollama服务器的地址默认本地11434端口 base-url: http://localhost:11434 chat: options: # 默认使用的模型名称必须与Ollama中拉取的模型名一致 model: qwen2.5:7b # 温度参数控制创造性范围0-2越高越随机 temperature: 0.7这个配置做了两件事告诉Spring AI你的Ollama服务在哪里base-url。为OllamaChatModelBean设置默认选项比如使用哪个模型和温度值。启动你的Spring Boot应用如果控制台没有报错并且能看到类似“OllamaChatModel initialized”的日志日志级别需调整说明集成初步成功。3. 核心API使用与模型调用3.1 注入与同步调用配置完成后你可以在任何Spring管理的Bean中如Service,RestController,Component直接注入ChatModel或OllamaChatModel接口。推荐注入通用的ChatModel以提高代码的可移植性。import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.stereotype.Service; Service public class SimpleChatService { private final ChatModel chatModel; // 通过构造器注入 public SimpleChatService(ChatModel chatModel) { this.chatModel chatModel; } public String generate(String userMessage) { // 1. 构建Prompt对象包含用户消息 Prompt prompt new Prompt(new UserMessage(userMessage)); // 2. 调用模型获取响应 ChatResponse response chatModel.call(prompt); // 3. 从响应中提取文本内容 return response.getResult().getOutput().getContent(); } }然后你可以创建一个简单的REST控制器来暴露这个服务import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; RestController public class ChatController { private final SimpleChatService chatService; public ChatController(SimpleChatService chatService) { this.chatService chatService; } GetMapping(/chat) public String chat(RequestParam(defaultValue 你好请介绍一下你自己) String message) { return chatService.generate(message); } }访问http://localhost:8080/chat?messageJava是什么你应该就能收到来自本地Qwen2.5模型的回答了。3.2 流式响应处理对于需要长时间生成文本或希望实现打字机效果的应用流式响应Streaming至关重要。它允许你逐块chunk接收响应而不是等待整个响应完成。Spring AI通过StreamingChatModel接口支持流式响应。OllamaChatModel同时实现了ChatModel和StreamingChatModel。你可以直接注入StreamingChatModel或者将OllamaChatModel向下转型。import org.springframework.ai.chat.model.StreamingChatModel; import org.springframework.ai.chat.prompt.Prompt; import reactor.core.publisher.Flux; Service public class StreamingChatService { private final StreamingChatModel streamingChatModel; public StreamingChatService(StreamingChatModel streamingChatModel) { this.streamingChatModel streamingChatModel; } public FluxString generateStream(String userMessage) { Prompt prompt new Prompt(new UserMessage(userMessage)); // 调用stream方法返回一个Flux流 return streamingChatModel.stream(prompt) // 从每个响应块中提取文本内容 .map(chunk - chunk.getResult().getOutput().getContent()) // 过滤掉空内容 .filter(content - content ! null !content.isEmpty()); } }在Controller中你可以返回text/event-stream类型的响应这是Server-Sent Events (SSE)的标准前端可以直接用EventSource连接。import org.springframework.http.MediaType; 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; RestController public class StreamingChatController { private final StreamingChatService streamingChatService; public StreamingChatController(StreamingChatService streamingChatService) { this.streamingChatService streamingChatService; } GetMapping(value /chat/stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString streamChat(RequestParam String message) { return streamingChatService.generateStream(message); } }踩坑实录流式响应的连接与超时连接保持流式响应需要保持HTTP连接长时间开放。确保你的Web服务器如Tomcat和前端没有设置过短的超时时间。在Spring Boot中可以通过server.servlet.connection-timeout进行调整但通常对于SSE建议使用WebFlux响应式编程以获得更好的支持不过简单的TomcatFlux也能工作。响应缓存某些网关或代理如Nginx可能会缓冲完整的响应后才发送给客户端这会破坏流式效果。需要在Nginx配置中为/chat/stream这类路径添加proxy_buffering off;和proxy_cache off;指令。前端处理前端使用EventSource时要注意处理onerror事件。连接中断后可能需要重连逻辑。对于更复杂的需求如传递认证信息可以考虑使用WebSocket但SSE更简单且原生支持。3.3 运行时参数覆盖你不可能所有请求都用一样的参数。比如一个创意写作的需求可能需要更高的temperature如1.2而一个代码生成的需求则需要更低的temperature如0.2来保证确定性。Spring AI允许你在每次调用时覆盖默认配置。这是通过Prompt的第二个参数——ChatOptions来实现的。对于Ollama我们使用OllamaChatOptions。import org.springframework.ai.ollama.OllamaChatOptions; public String generateWithOptions(String question, String modelName, double temperature) { // 构建运行时特定的选项 OllamaChatOptions runtimeOptions OllamaChatOptions.builder() .model(modelName) // 覆盖默认模型 .temperature(temperature) // 覆盖默认温度 .topP(0.95) // 设置top-p采样 .numPredict(512) // 限制最大生成长度 .build(); Prompt prompt new Prompt(new UserMessage(question), runtimeOptions); ChatResponse response chatModel.call(prompt); return response.getResult().getOutput().getContent(); }你甚至可以混合使用不同类型的ChatOptions。Spring AI提供了一个便携式的ChatOptionsbuilder但Ollama特有的参数如numPredict,repeatPenalty必须通过OllamaChatOptions设置。4. 高级特性深度解析4.1 工具调用Function Calling实战工具调用是大模型与外部世界交互的核心能力。比如让模型调用一个查询天气的函数或者操作数据库。Spring AI通过ToolCallingAdvisor和ChatClient极大地简化了这个过程。第一步定义你的工具函数你需要定义一个实现了工具逻辑的类。Spring AI会利用Java反射将其信息函数名、描述、参数schema传递给模型。import org.springframework.ai.tool.ToolFunction; import org.springframework.stereotype.Component; import com.fasterxml.jackson.annotation.JsonProperty; Component public class WeatherService { // 这个内部类定义了工具的输入参数结构 public record Request(JsonProperty(required true, value location) String location) {} // ToolFunction 注解标记这是一个可供模型调用的工具 // description 非常重要模型根据它来决定是否以及如何调用此工具 ToolFunction(description 根据城市名称获取当前天气情况温度单位是摄氏度。) public String getCurrentWeather(Request request) { // 这里应该是真实的天气API调用例如调用和风天气、OpenWeatherMap等 // 此处为模拟数据 String[] conditions {晴, 多云, 小雨, 阴天}; int temp (int) (Math.random() * 15) 15; // 15-30度 String condition conditions[(int) (Math.random() * conditions.length)]; return String.format(城市【%s】的当前天气为%s温度 %d°C。, request.location(), condition, temp); } }第二步使用ChatClient进行工具调用ChatClient是一个高级客户端它封装了与模型交互、工具调用循环的复杂性。import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.ToolCallingAdvisor; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.FunctionToolCallback; Service public class ToolCallingService { private final ChatClient chatClient; public ToolCallingService(ChatClient.Builder chatClientBuilder, WeatherService weatherService) { // 1. 将WeatherService中的方法包装成ToolCallback ToolCallback weatherCallback FunctionToolCallback.builder() .name(getCurrentWeather) .function(weatherService::getCurrentWeather) // 方法引用 .description(根据城市名称获取当前天气情况温度单位是摄氏度。) .inputType(WeatherService.Request.class) // 指定输入参数类型 .build(); // 2. 构建ChatClient并注册ToolCallingAdvisor和工具回调 this.chatClient chatClientBuilder .defaultAdvisors(new ToolCallingAdvisor()) // 启用工具调用建议器 .defaultTools(weatherCallback) // 注册工具 .build(); } public String chatWithTools(String userMessage) { // 调用chat方法ChatClient会自动处理“模型思考-调用工具-返回结果”的循环 return chatClient.prompt() .user(userMessage) // 用户输入例如“北京、上海、广州的天气怎么样” .call() // 同步调用 .content(); } public FluxString chatWithToolsStream(String userMessage) { // 流式版本 return chatClient.prompt() .user(userMessage) .stream() // 流式调用 .content(); } }当用户提问“北京、上海、广州的天气怎么样”时ChatClient内部会发生以下几步将用户消息和已注册的工具描述发送给Ollama模型。模型“思考”后决定调用getCurrentWeather工具并生成一个符合Requestschema的JSON参数例如{location: 北京}。ToolCallingAdvisor拦截到这个工具调用请求执行真实的weatherService.getCurrentWeather方法获取结果如“北京晴25°C”。将这个工具执行结果作为新的上下文再次发送给模型让模型整合信息并生成最终的自然语言回复给用户。对于多个地点这个循环可能会执行多次。核心避坑指南工具调用失败排查Ollama版本确保你的Ollama版本在0.2.8以上以支持工具调用0.4.6以上以支持流式工具调用。使用ollama --version检查。模型能力并非所有模型都擅长工具调用。Llama 3、Qwen 2.5、DeepSeek等较新的模型支持较好。如果模型完全不调用工具首先尝试换一个模型。描述清晰ToolFunction的description和ToolCallback的description必须清晰、无歧义地描述工具的功能和输入。这是模型决定是否调用的关键依据。描述模糊是导致工具不被调用的最常见原因。参数Schema匹配模型生成的参数必须严格匹配你定义的Java Record如WeatherService.Request。确保JsonProperty注解使用正确特别是required true的字段。如果模型生成的JSON缺少必需字段反序列化会失败。4.2 思维链Reasoning Mode与结构化输出思维链Reasoning一些先进的模型如Qwen3、DeepSeek R1具备“思维链”能力即它们会先输出内部的推理过程再给出最终答案。这对于调试复杂任务或需要可解释性的场景非常有用。在Spring AI中你可以通过OllamaChatOptions的.enableThinking()或.disableThinking()来控制。对于GPT-OSS这类模型还可以指定思维级别thinkLow(),thinkMedium(),thinkHigh()。public ChatResponse askWithReasoning(String complexQuestion) { OllamaChatOptions options OllamaChatOptions.builder() .model(deepseek-r1) // 使用支持思维链的模型 .enableThinking() // 启用思维链 .build(); Prompt prompt new Prompt(new UserMessage(complexQuestion), options); ChatResponse response chatModel.call(prompt); // 从元数据中获取思维过程 String reasoning response.getResult().getMetadata().get(thinking); String finalAnswer response.getResult().getOutput().getContent(); System.out.println(模型推理过程: reasoning); System.out.println(最终答案: finalAnswer); // 你也可以将思维链和答案一起返回 return response; }结构化输出Structured Outputs这是生产环境中的一个杀手级功能。你不再需要依赖模型的自由文本来解析答案而是可以强制要求模型按照你预定义的JSON Schema格式返回数据。这极大地提升了后端程序处理结果的可靠性。Spring AI提供了两种方式简单JSON模式只要求返回JSON不限制结构。.format(json)。JSON Schema模式强制返回符合特定Schema的JSON。.outputSchema(jsonSchemaString)。强烈推荐使用第二种并与BeanOutputConverter结合实现从JSON到Java对象的自动转换。import org.springframework.ai.converter.BeanOutputConverter; import com.fasterxml.jackson.annotation.JsonProperty; // 1. 定义你期望的数据结构 record ProgrammingSolution( JsonProperty(required true, value problem_analysis) String problemAnalysis, JsonProperty(required true, value solution_code) String solutionCode, JsonProperty(required true, value time_complexity) String timeComplexity, JsonProperty(required true, value space_complexity) String spaceComplexity) { } public ProgrammingSolution solveProblem(String problemStatement) { // 2. 创建输出转换器它会自动生成对应的JSON Schema BeanOutputConverterProgrammingSolution outputConverter new BeanOutputConverter(ProgrammingSolution.class); // 3. 构建Prompt指定输出Schema OllamaChatOptions options OllamaChatOptions.builder() .model(qwen2.5:7b-coder) .outputSchema(outputConverter.getJsonSchema()) // 关键注入Schema .temperature(0.1) // 结构化输出建议使用低温度提高确定性 .build(); String systemPrompt 你是一个专业的算法专家。请分析以下编程问题并以严格的JSON格式回复。; String fullPrompt systemPrompt \n问题 problemStatement \n outputConverter.getFormat(); Prompt prompt new Prompt(new UserMessage(fullPrompt), options); ChatResponse response chatModel.call(prompt); // 4. 获取原始JSON文本并转换 String jsonText response.getResult().getOutput().getContent(); // 5. 自动将JSON反序列化为Java对象 return outputConverter.convert(jsonText); }调用solveProblem(用Java实现一个快速排序算法)模型将返回一个严格符合ProgrammingSolution结构的JSON并自动被转换成对象你可以直接访问solution.getSolutionCode()。经验之谈结构化输出的成功率提升技巧Schema要简单明确初期尽量使用扁平结构避免嵌套过深。字段名用英文蛇形命名snake_case比驼峰命名camelCase更稳定因为有些模型对命名风格敏感。在Prompt中强化指令除了设置outputSchema在用户消息中再次用自然语言强调输出格式例如“请务必严格按照给定的JSON格式输出只输出JSON对象不要有任何额外的解释文字。”使用思维链模型像DeepSeek R1这类具有强推理能力的模型在理解复杂Schema和遵循指令方面表现更佳。后置验证与重试即使使用了结构化输出模型偶尔也可能返回格式错误的JSON。在生产代码中应该用try-catch包裹outputConverter.convert()并在失败时进行重试或降级处理。4.3 多模态与自动模型拉取多模态图像理解如果你的Ollama部署了多模态模型如LLaVASpring AI可以让你轻松实现图文对话。核心是利用Message接口的Media类来附加图像。import org.springframework.core.io.Resource; import org.springframework.core.io.ClassPathResource; import org.springframework.ai.chat.messages.Media; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.util.MimeTypeUtils; public String describeImage(String imagePathOnClasspath, String question) throws IOException { // 1. 从类路径加载图片资源 Resource imageResource new ClassPathResource(imagePathOnClasspath); // 2. 创建Media对象指定MIME类型和资源 Media imageMedia new Media(MimeTypeUtils.IMAGE_PNG, imageResource); // 3. 构建包含文本和图像的用户消息 UserMessage userMessage new UserMessage(question, imageMedia); // 4. 指定多模态模型如llava OllamaChatOptions options OllamaChatOptions.builder() .model(llava:latest) .build(); Prompt prompt new Prompt(userMessage, options); ChatResponse response chatModel.call(prompt); return response.getResult().getOutput().getContent(); }自动模型拉取Auto-pulling这是一个在开发和测试环境中极其方便的功能。你可以在配置中指定模型如果本地Ollama中没有Spring AI会在应用启动时自动帮你拉取。spring: ai: ollama: base-url: http://localhost:11434 init: pull-model-strategy: when_missing # 策略缺失时拉取 timeout: 10m # 拉取超时时间 max-retries: 1 # 最大重试次数 chat: options: model: hf.co/bartowski/gemma-2-2b-it-GGUF # 指定一个Hugging Face模型警告生产环境慎用自动拉取pull-model-strategy: always或when_missing在应用启动时如果遇到网络问题或模型很大会导致启动时间极长甚至失败。生产环境的正确做法是在部署流程中通过脚本或配置管理工具如Ansible预先在目标机器上执行ollama pull your-model确保模型已存在。将配置改为pull-model-strategy: never避免不可控的启动延迟。5. 生产级配置、监控与问题排查5.1 连接池、超时与重试直接使用默认配置连接本地Ollama在开发时没问题但在生产环境尤其是Ollama服务可能部署在另一台机器或容器内时必须配置连接管理。Spring AI的Ollama客户端底层使用Spring的RestClient或WebClient。你可以通过配置RestClient.BuilderBean来定制HTTP行为。import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestClient; Configuration public class OllamaClientConfig { Bean public RestClient.Builder ollamaRestClientBuilder() { return RestClient.builder() .baseUrl(http://your-ollama-host:11434) // 生产环境地址 .requestInterceptor((request, body, execution) - { // 可以在这里添加认证头等如果Ollama有安全配置 // request.getHeaders().add(Authorization, Bearer ...); return execution.execute(request, body); }); } // 如果你需要更细粒度的控制可以自定义RestClient Bean public RestClient ollamaRestClient(RestClient.Builder builder) { return builder .requestFactory(new HttpComponentsClientHttpRequestFactory()) // 使用HttpClient以获得连接池 .build(); } }更重要的是在application.yml中配置合理的超时和重试策略。虽然Spring AI Ollama模块没有直接暴露所有HTTP客户端配置但你可以通过Spring Boot对RestClient的通用属性进行配置或者使用HttpComponentsClientHttpRequestFactory进行底层配置。一个更实用的方法是在应用层面对ChatModel的调用进行包装实现业务级的超时和重试。例如使用Spring Retry或Resilience4j。import org.springframework.retry.annotation.Retryable; import org.springframework.retry.annotation.Backoff; Service public class RobustChatService { private final ChatModel chatModel; Retryable( value {Exception.class}, // 重试的异常类型 maxAttempts 3, backoff Backoff(delay 1000, multiplier 2) // 指数退避 ) org.springframework.retry.annotation.Recover public String generateWithRetry(String message) { // 这里可以添加一个带超时的Callable使用CompletableFuture return chatModel.call(new Prompt(new UserMessage(message))); } }5.2 日志、监控与可观测性清晰的日志是排查问题的第一道防线。确保为Spring AI和Ollama相关类开启DEBUG或TRACE级别日志。logging: level: org.springframework.ai: DEBUG # 查看Spring AI内部流程 org.springframework.ai.ollama: TRACE # 查看详细的HTTP请求/响应对于生产监控你需要关注延迟每个请求的响应时间。可以在调用chatModel.call()前后记录时间或使用Micrometer等指标库。Token使用量Ollama的响应中通常包含prompt_eval_count和eval_count分别代表输入和输出的Token数。这些信息在ChatResponse的Metadata中。监控Token数有助于估算资源消耗和成本如果是按Token计费的模型本地模型则关注显存/内存。错误率监控调用失败如超时、网络错误、模型加载失败的比例。模型负载如果Ollama服务被多个应用共享需要监控其GPU/CPU和内存使用情况。5.3 常见问题排查速查表下表总结了集成Spring AI Ollama时最常见的问题、原因和解决方案问题现象可能原因排查步骤与解决方案启动报错Connection refused1. Ollama服务未启动。2.base-url配置错误。3. 防火墙/网络策略阻止。1. 执行ollama serve或检查服务状态。2. 确认application.yml中spring.ai.ollama.base-url的IP和端口正确。3. 使用curl http://localhost:11434/api/tags测试Ollama API是否可达。调用时报错Model xxx not found1. 模型名称拼写错误。2. 模型未下载到本地。1. 用ollama list确认本地已有模型列表核对名称注意tag如qwen2.5:7b。2. 执行ollama pull model-name拉取模型。工具调用不生效1. Ollama版本过低。2. 模型不支持工具调用。3. 工具描述不清晰。4. Prompt未触发工具场景。1. 升级Ollama至0.2.8。2. 换用Llama 3.1、Qwen2.5等较新模型。3. 检查ToolFunction的description确保清晰描述功能和输入。4. 在用户消息中更明确地要求使用工具例如“请调用天气查询工具获取北京天气。”流式响应中途断开1. HTTP连接超时。2. 代理或网关缓冲。3. 前端EventSource处理不当。1. 调整服务器和客户端的超时设置。2. 检查Nginx等代理配置对SSE路径禁用proxy_buffering。3. 在前端添加EventSource的onerror监听和重连逻辑。响应速度非常慢1. 模型首次加载。2. 硬件资源不足GPU内存不够。3. 使用了过大的模型。1. 首次加载后会有缓存后续调用会快很多。2. 使用ollama ps查看模型运行状态考虑使用量化版本如-q4_K_M的模型。3. 换用更小的模型或调整num_ctx上下文长度等参数。结构化输出返回非JSON1. 模型未理解指令。2. Temperature参数过高导致输出随机。1. 在Prompt中强化指令使用思维链模型如DeepSeek R1。2. 将temperature设为0.1或更低提高输出确定性。内存占用持续增长1. Spring AI或Ollama内存泄漏。2. 未正确清理对话历史如果使用了ChatMemory。1. 监控Java进程和Ollama进程的内存。定期重启可能是临时方案。2. 如果使用了ChatMemory确保会话有合理的过期或清理机制。5.4 性能调优与进阶建议模型选择与量化生产环境优先考虑推理速度和资源占用。7B参数左右的模型如Qwen2.5-7B, Llama3.2-3B在大多数任务上已具备良好效果。务必使用量化版本如GGUF格式的Q4_K_M, Q5_K_M它们能在精度损失极小的情况下大幅降低内存和计算需求。参数调优num_ctx根据你的最大对话长度设置不是越大越好。2048是安全值增长会线性增加显存占用。num_thread设置为物理CPU核心数充分利用CPU进行推理。temperature和top_p根据任务调整。创意写作可调高如temperature1.0, top_p0.95代码生成或事实问答则调低如temperature0.2, top_p0.8。使用GPU加速如果服务器有NVIDIA GPU确保Ollama使用了GPU推理。在启动Ollama前设置环境变量OLLAMA_GPU_LAYERS如export OLLAMA_GPU_LAYERS99或直接在Modelfile中指定。使用ollama run model时观察日志确认是否显示“using GPU”。考虑API兼容模式如果你的应用未来可能需要切换回OpenAI等云端服务可以考虑直接使用Spring AI的OpenAI客户端但将其base-url指向Ollamahttp://localhost:11434/v1。这样大部分代码无需改动只需切换配置。但要注意此模式可能无法使用Ollama的所有特有参数除非通过extraBody传递。安全与部署将Ollama部署在内网并通过反向代理如Nginx暴露API配置身份验证和速率限制。不要在公网直接暴露Ollama的11434端口。