简介
在大模型浪潮席卷各行各业的今天,Java 作为企业级开发的绝对主力,如何无缝接入 AI 能力成为开发者关注的焦点。Spring AI 的诞生,正是为 Java 生态提供了统一、简洁、面向生产的大模型集成方案。
本文将带你从零开始,基于 Spring Boot 3 + Spring AI + Ollama + MCP Client,搭建一个支持 本地大模型调用 与 工具函数调用(Function Calling) 的完整 AI 应用。
- 如何在本地部署 Ollama 并运行轻量级模型(如 llama3.2:1b、llama3.2:3b)
- 如何使用 Spring AI 集成 Ollama,实现自然语言对话
- 如何通过 MCP(Model Context Protocol)Client 实现模型对工具的动态调用,例如查询天气、访问数据库等
- 无需 GPU、无需联网调用第三方 API、数据完全本地化,真正实现私有化、低延迟、高安全的 AI 能力集成。
Spring Boot
Ollama 模型
# 模型大小 2.0GB
ollama pull llama3.2:3b
# 模型大小 43GB
ollama pull llama3.3:70b
注: 有些小模型是不支持 tools 调用,例如 deepseek-r1:1.5b 小模型;本示例推荐使用 llama3.2:3b 模型在本地PC端尝鲜。但因为 llama3.2:3b 模型太小 工具调用时中文容易 “幻觉” 参数值。生产环境推荐 llama3.3:70b 模型。
llama3.2 聊天示例
- build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
- application.properties
spring.application.name=demo
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.model=llama3.2:3b
- DemoApplication.java
@SpringBootApplication
public class DemoApplication {
@Autowired
private OllamaChatModel chatModel;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ChatResponse runner() {
ChatResponse response = chatModel.call(new Prompt(new UserMessage("介绍下Spring AI")));
System.out.println(response);
return response;
}
}
MCP 客户端示例
- build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.ai:spring-ai-starter-mcp-client'
implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
- application.properties
spring.application.name=demo
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.model=llama3.2:3b
spring.ai.mcp.client.name=spring-ai-mcp-client
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.type=sync
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:9800
spring.ai.mcp.client.toolcallback.enabled=true
- ChatService.java
@Service
public class ChatService {
private final ChatClient chatClient;
public ChatService(OllamaChatModel ollamaChatModel, List<McpSyncClient> mcpSyncClientList) {
ToolCallbackProvider toolCallbackProvider = new SyncMcpToolCallbackProvider(mcpSyncClientList);
ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();
for (ToolCallback toolCallback : toolCallbacks) {
System.out.println("toolCallback:" + toolCallback.getToolDefinition());
}
// chatClient = ChatClient.builder(ollamaChatModel).defaultToolCallbacks(toolCallbacks).build();
chatClient = ChatClient.builder(ollamaChatModel).defaultToolCallbacks(toolCallbackProvider).build();
}
public String askQuestion(Message message) {
return chatClient.prompt().messages(message).call().content();
}
public String askQuestion(SystemMessage systemMessage, UserMessage userMessage) {
return chatClient.prompt().messages(systemMessage, userMessage).call().content();
}
}
- DemoApplication.java
@SpringBootApplication
public class DemoApplication {
@Autowired
private ChatService chatService;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public String runner() {
// String result = chatService.askQuestion(new UserMessage("查询姓名为'林俊杰'的用户信息"));
String result = chatService.askQuestion(
new SystemMessage("你是一个工具调用助手。"),
new UserMessage("查询姓名为'林俊杰'的用户信息")
);
System.out.println(result);
return result;
}
}
注: MCP 服务端接收参数时出现值错误原因,这是因为 小模型(llama3.2:3b) 对中文人名、实体的理解和拼写非常不稳,尤其是生僻字/专有名词时,容易产生乱码或替换成别的字。这不是 Spring AI/MCP 框架的问题,而是小模型自己在工具调用时 “幻觉” 了参数值。