基于 Spring AI + Ollama + MCP Client 打造纯本地化大模型应用

发布于:2025-08-16 ⋅ 阅读:(20) ⋅ 点赞:(0)

简介

在大模型浪潮席卷各行各业的今天,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 框架的问题,而是小模型自己在工具调用时 “幻觉” 了参数值。

在这里插入图片描述

MCP 服务端实现


网站公告

今日签到

点亮在社区的每一天
去签到