我是基于本地大模型,你也可以调用openAI或者deepseek等模型。
1、使用 vLLm 启动模型
python -m vllm.entrypoints.openai.api_server \
--model /code/models/Qwen/Qwen3-8B \
--served-model-name qwen3-8b \
--max-model-len 8k \
--host 0.0.0.0 \
--port 6006 \
--dtype bfloat16 \
--gpu-memory-utilization 0.8 \
--enable-auto-tool-choice \
--tool-call-parser hermes
我的显卡5090 32G显存
2、确认启动
访问地址:IP + 6006/docs 我的地址为:192.168.10.102:6006

启动成功页面
3、编写基于spring AI 代码
所需依赖: springboot 3.5.9 jdk17+ SpringAI 1.1.2
3.1 pom.xml如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>com.shujunjun.spring.ai</groupId>
<artifactId>sjjai</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sjjai</name>
<description>shujunjun ai</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
<spring-ai.version>1.1.2</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- vLLM部署的模型是按照 OpenAI 接口来输出的,因此可以使用该依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 增加历史对话记忆功能 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
</dependency>
<!-- http 请求依赖 -->
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-http</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.2 配置代码如下
application.yml
spring:
application:
name: sjjai
ai:
chat:
memory:
repository:
jdbc:
# 自动初始化数据库
initialize-schema: always
# mysql mariadb
plateform: mysql
openai:
# https://api.deepseek.com
base-url: http://192.168.10.102:6006/
api-key: sk-xxxxxxx
chat:
options:
model: qwen3-8b
datasource:
url: jdbc:mysql://192.168.47.130:3306/sjj-ai?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
server:
port: 8082
config配置
import com.shujunjun.spring.ai.sjjai.tool.ToolService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel, ChatMemory chatMemory, ToolService toolService) {
return ChatClient.builder(chatModel)
.defaultSystem("你作为一名专业的AI助手,请根据用户提示信息回答问题。再根据用户信息,自定判断是否需要调用工具")
.defaultAdvisors(MessageChatMemoryAdvisor
.builder(chatMemory).build())
// 自定义工具类型
.defaultTools(toolService)
.build();
}
/**
* 聊天配置基于jdbc 存储于 MySQL 数据库中
*/
@Bean
public ChatMemory chatMemory(JdbcChatMemoryRepository repository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(repository)
.maxMessages(200)
.build();
}
}
ToolService 工具实现类。该实现类有两个能力,一个是获取天气信息,一个是根据省份获取油价信息
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Component
public class ToolService {
RestTemplate restTemplate = new RestTemplate();
@Tool(name = "getWeather", description = "获取天气信息")
public String getWeather(@ToolParam(description = "要查询的天气的城市名称") String city) {
log.info("调用获取天气工具,城市:{}", city);
return city + "的天气晴朗。气温23摄氏度";
}
@Tool(name = "getLocalOilPrice", description = "根据省份获取当地油价信息")
public String getLocalOilPrice(@ToolParam(description = "要查询的油价的省份名称") String province) {
log.info("调用获取当地油价工具,省份:{}", province);
String format = String.format("https://shanhe.kim/api/youjia/youjia.php?province=%s", province);
return restTemplate.getForObject(format, String.class);
}
}
测试类如下
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping
@RequiredArgsConstructor
public class AiController {
final ChatClient chatClient;
@GetMapping("chat")
public Flux<String> chatAi(String question, String userId, HttpServletResponse response) {
response.setCharacterEncoding("utf-8");
return chatClient.prompt()
.user(question)
.advisors(adv -> adv.param(ChatMemory.CONVERSATION_ID, userId))
.stream()
.content();
}
}
调用接口效果

调用接口展示