Java开发者别慌用Spring Boot 3.4 Ollama本地模型5分钟搭建一个能调用外部工具的AI助手最近在技术社区看到不少Java开发者抱怨现在AI应用全是Python的天下我们这些写Java的是不是要被淘汰了 作为一个常年混迹在Spring生态的老兵我想说别急着转PythonSpring社区早就为我们准备好了趁手的AI开发工具链。今天我就带大家用Spring Boot 3.4和Ollama本地模型快速搭建一个能调用业务工具的AI助手原型。这个方案最妙的地方在于——完全不需要Python环境所有操作都在你熟悉的Java生态里完成。1. 为什么Java开发者需要关注AI Agents去年参加QCon时我和几个大厂架构师聊到一个有趣的现象虽然Python在AI模型训练领域占据主导但在企业级AI应用落地时Java反而成了更常见的选择。原因很简单——大部分企业的核心业务系统都是Java写的。想象一下这样的场景当你的订单系统需要智能客服功能时是要求所有Java工程师去学Python还是直接在Spring项目里集成AI能力更现实Spring AI项目的出现完美解决了这个痛点。它不像Python的LangChain那样需要处理各种零散的依赖包而是提供了标准化的Spring风格抽象。比如要切换AI模型提供商你只需要换个starter依赖业务代码几乎不用修改。这种设计理念特别适合需要长期维护的企业级应用。2. 环境准备与基础配置2.1 项目初始化先用Spring Initializr创建项目选择这些关键依赖dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-ollama-spring-boot-starter/artifactId /dependency !-- 生产环境建议添加 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency /dependencies记得在pom.xml中添加Spring的snapshot仓库因为Spring AI还在快速迭代期repositories repository idspring-snapshots/id urlhttps://repo.spring.io/snapshot/url /repository /repositories2.2 Ollama模型部署在本地安装Ollama后拉取适合Java生态的中小模型ollama pull qwen2:7b # 7B参数的轻量级模型然后在application.yml中配置模型参数spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen2:7b temperature: 0.7 # 控制生成结果的随机性避坑提示如果遇到模型不支持工具调用的情况可以尝试这些方案检查模型文档是否明确支持function calling降低temperature值获得更稳定的输出换用官方明确支持工具调用的模型版本3. 实现工具调用能力3.1 定义业务工具我们先实现两个典型的企业场景工具订单查询和库存检查。注意使用Tool注解来声明工具元数据public class CommerceTools { Tool(name orderQuery, description 根据订单ID查询订单详情) public OrderDetail queryOrder( Parameter(description 订单编号) String orderId) { // 实际项目中这里会调用订单服务 return mockOrderService.getById(orderId); } Tool(name inventoryCheck, description 检查商品库存情况) public InventoryStatus checkInventory( Parameter(description 商品SKU) String sku, Parameter(description 仓库编码) String warehouse) { // 调用库存系统API return inventoryService.check(sku, warehouse); } }3.2 工具注册与调用创建配置类将工具暴露给AI模型Configuration public class ToolConfig { Bean public ToolCallbackProvider toolProvider() { return ToolCallbackProvider.from( new CommerceTools(), new SystemTools() // 可以继续添加其他工具类 ); } }然后在Controller中只需几行代码就能完成智能调用RestController public class AIController { private final ChatClient chatClient; public AIController(OllamaChatModel model, ToolCallbackProvider tools) { this.chatClient ChatClient.builder(model) .defaultTools(tools) .build(); } GetMapping(/ask) public String ask(RequestParam String question) { return chatClient.prompt(question).call().content(); } }试试这些请求帮我查一下订单ID为12345的详情SKU为IPHONE15的货物在BJ仓库还有多少库存4. 生产环境进阶配置4.1 安全防护措施在企业环境中必须对工具调用添加权限控制。Spring AI提供了优雅的拦截机制Bean public ToolCallbackProvider secureToolProvider() { return new ToolCallbackProvider() { Override public ToolCallbacks getToolCallbacks() { return ToolCallbacks.from(new CommerceTools()) .withFilter((tool, request) - { // 在这里实现权限校验逻辑 if (!securityContext.hasPermission(tool.name())) { throw new AccessDeniedException(工具调用未授权); } return true; }); } }; }4.2 性能优化技巧流式响应对于耗时操作使用Server-Sent Events(SSE)实现流式输出GetMapping(/ask-stream) public FluxString askStream(RequestParam String question) { return chatClient.prompt(question) .stream() .map(ChatResponse::getContent); }对话记忆通过ChatMemory维护上下文Bean public ChatMemory chatMemory() { return new InMemoryChatMemory(50); // 保留最近50条消息 } // 在Controller中注入使用 chatClient.prompt(question) .options(options - options.withMemory(chatMemory)) .call();超时控制在application.yml中配置spring: ai: ollama: client: request-timeout: 30s # 防止长时间阻塞5. 调试与问题排查遇到工具调用失败时可以开启详细日志logging: level: org.springframework.ai: DEBUG com.example.ai: TRACE常见问题解决方案工具未被识别检查Tool的description是否准确描述了功能参数解析失败确保Parameter的name和description清晰明确Nashorn引擎报错Java 15需要额外添加依赖dependency groupIdorg.openjdk.nashorn/groupId artifactIdnashorn-core/artifactId version15.4/version /dependency我在实际项目中发现用qwen2:7b这类中小模型配合清晰的工具描述效果往往比盲目追求大模型更好。有一次我们为客服系统接入AI时经过精心设计的工具描述将准确率从72%提升到了89%。