跳到主要内容
Spring AI 入门指南:从快速搭建到 RAG 实战 | 极客日志
Java AI java 算法
Spring AI 入门指南:从快速搭建到 RAG 实战 Spring AI 是 Spring 官方推出的 AI 工程框架,旨在简化大模型应用开发。本文涵盖 Spring AI 的核心概念、快速入门配置(DeepSeek/Ollama/Alibaba)、聊天模型(ChatClient/ChatModel)使用、函数调用(Function Calling)实现、图像与语音模型集成,以及基于向量数据库的 RAG(检索增强生成)实战案例。通过实际代码示例,展示如何在 Java 项目中无缝集成 AI 能力,解决知识局限性与幻觉问题,构建智能助手。
Spring AI 入门指南
在当今技术快速发展的背景下,人工智能已成为各行各业的标准配置。作为主流的 Java 应用开发框架,Spring 社区紧跟潮流推出了 Spring AI 框架,旨在将 Spring 生态系统的设计原则应用于 AI 领域。
1. Spring AI 简介
1.1 什么是 Spring AI
Spring AI 是一个面向 AI 工程的应用程序框架。它的核心目标是提供开发 AI 大模型应用所需的基本抽象模型,这些抽象拥有多种实现方式,使得开发者可以用很少的代码改动就能实现组件的轻松替换。简言之,它提供了一个友好的 API 和开发 AI 应用的抽象,旨在简化 AI 大模型应用的开发工作。
目前 Spring AI 推出了预览版 (PRE)、快照版 (SNAPSHOT) 以及正式版 (GA)。推荐使用 GA 版本,因为它最为稳定;SNAPSHOT 版本会持续更新;PRE 版本则主要用于测试找 bug。
1.2 主要功能
支持主流 AI 大模型供应商,如 OpenAI、DeepSeek、Microsoft、Ollama、Amazon、Google HuggingFace 等。
支持 AI 大模型类型包括:聊天、文本到图像、文本到声音等。
支持主流的 Embedding Models 和向量数据库,如 Azure Vector Search、Chroma、Milvus、Neo4j、Redis、PineCone、PostgreSQL/PGVector 等。
把 AI 大模型输出映射到简单的 Java 对象(POJOs)上。
支持函数调用 (Function Calling) 功能。
为数据工程提供 ETL 框架。
支持 Spring Boot 自动配置和快速启动。
2. 快速入门
2.1 准备工作
我们以 DeepSeek 为例进行集成。DeepSeek 是一款由深度求索开发的 AI 大模型,基于 Transformer 架构,在中文理解与输出能力上表现优异,且具有极具竞争力的 API 定价。
首先需要在 DeepSeek 开放平台注册账号并创建 API Key。接口文档地址为 https://api-docs.deepseek.com/zh-cn/。
2.2 创建 SpringBoot 工程
在 IDEA 中创建一个 SpringBoot 项目。注意 Spring AI 对 SpringBoot 和 JDK 的版本要求,通常建议使用 JDK 17 及以上。
2.2.1 引入依赖
在父模块的 pom.xml 中添加公共依赖:
<properties >
<maven.compiler.source > 17</maven.compiler.source >
<maven.compiler.target > 17</maven.compiler.target >
<spring-ai.version > 1.0.0-M5</spring-ai.version >
</properties >
<dependencies >
<dependency >
org.springframework.boot
spring-boot-starter-web
org.springframework.ai
spring-ai-openai-spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
1.18.30
org.springframework.ai
spring-ai-bom
${spring-ai.version}
pom
import
<groupId >
</groupId >
<artifactId >
</artifactId >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<scope >
</scope >
</dependency >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<version >
</version >
</dependency >
</dependencies >
<dependencyManagement >
<dependencies >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<version >
</version >
<type >
</type >
<scope >
</scope >
</dependency >
</dependencies >
</dependencyManagement >
2.2.2 配置文件 在 application.properties 中添加如下配置:
server.port=8899
spring.application.name=spring-ai-deepseek-demo
# DeepSeek 的 Api key
spring.ai.openai.api-key=sk-****************
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.options.model=deepseek-chat
spring.ai.openai.chat.options.temperature=0.7
其中 temperature 参数用于控制生成文本的多样性。值越高,生成的文本越多样化;值越低,生成的文本越接近确定性结果。
2.2.3 启动类与 Controller @SpringBootApplication
public class SpringAiHelloApplication {
public static void main (String[] args) {
SpringApplication.run(SpringAiHelloApplication.class, args);
}
}
package com.example.ai.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatDeepSeekController {
@Resource
private OpenAiChatModel chatModel;
@GetMapping("/ai/generate")
public String generate (@RequestParam(value = "message", defaultValue = "hello") String message) {
String response = this .chatModel.call(message);
System.out.println("response: " + response);
return response;
}
}
测试接口 localhost:8899/ai/generate?message=你好,即可看到 AI 返回的结果。
3. 聊天模型详解
3.1 概述 Spring AI 的聊天模型 API 为开发者提供了便捷通道,能够将强大的 AI 驱动的聊天完成功能无缝集成到各类应用中。借助预先训练的语言模型,它能够依据用户输入生成自然流畅的回复。
3.2 ChatClient 接口 ChatClient 是一个接口,定义了一个与聊天服务交互的客户端。它主要用于创建聊天客户端对象,设置请求规范,以及发起聊天请求。
3.2.1 简单对话 需求是用户输入消息,通过 Spring AI 封装的方法向 AI 模型发送请求,以字符串形式返回响应。
package com.example.ai.controller;
import org.springframework.ai.chat.client.ChatClient;
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 ChatClient chatClient;
public ChatController (ChatClient.Builder chatClientBuilder) {
this .chatClient = chatClientBuilder.build();
}
@GetMapping("/chat")
public String chat (@RequestParam(value = "message", defaultValue = "你是谁") String message) {
return this .chatClient.prompt()
.user(message)
.call()
.content();
}
}
3.2.2 角色预设 我们可以配置默认的系统角色,让 AI 保持特定的人设。
package com.example.ai.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AIConfig {
@Bean
public ChatClient chatClient (ChatClient.Builder builder) {
return builder.defaultSystem("你是 Java 开发专家,精通 Spring 框架,名字叫 AI 助手。" ).build();
}
}
package com.example.ai.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ai")
public class ChatAIController {
@Resource
private ChatClient chatClient;
@GetMapping("/chat")
public String chat (@RequestParam(value = "message") String message) {
return chatClient.prompt().user(message).call().content();
}
}
3.2.3 流式响应 非流式输出 (call) 需要等待大模型把回答结果全部生成后输出给用户;而流式输出 (stream) 则是逐个字符输出,符合大模型生成方式的本质,能大大提高用户体验。
@GetMapping(value = "/chat/stream", produces = "text/html;charset=UTF-8")
public Flux<String> chatStream (@RequestParam(value = "message") String message) {
return chatClient.prompt().user(message).stream().content();
}
3.3 ChatModel 接口 ChatModel 接口作为核心,定义了与 AI 模型交互的基本方法。它继承自 Model<Prompt, ChatResponse>。
虽然带有 String 参数的 call() 方法简化了实际使用,但在实际应用程序中,更常见的是使用 ChatResponse call(Prompt prompt) 方法,该方法采用 Prompt 实例并返回 ChatResponse。
package com.example.ai.controller;
import jakarta.annotation.Resource;
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.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/model")
public class ChatModelController {
@Resource
private ChatModel chatModel;
@GetMapping("/chatModel01")
public String chatModel01 (@RequestParam("message") String message) {
return chatModel.call(message);
}
@GetMapping("/chatModel02")
public String chatModel02 (@RequestParam("message") String message) {
ChatResponse call = chatModel.call(new Prompt (
message,
OpenAiChatOptions.builder()
.model("deepseek-chat" )
.temperature(0.8 )
.build()));
return call.getResult().getOutput().getContent();
}
}
3.3.1 提示词模板 Prompt 提示词是与模型交互的一种输入数据组织方式。Spring AI 提供了 Prompt Template 提示词模板管理抽象,开发者可以预先定义好模板,并在运行时替换模板中的关键词。
@GetMapping("/prompt")
public String prompt (@RequestParam("name") String name, @RequestParam("voice") String voice) {
String userText = "给我推荐北京的至少三种美食" ;
UserMessage userMessage = new UserMessage (userText);
String systemText = "你是一个美食咨询助手,可以帮助人们查询美食信息。你的名字是{name},你应该用你的名字和{voice}的饮食习惯回复用户的请求。" ;
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate (systemText);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name" , name, "voice" , voice));
Prompt prompt = new Prompt (List.of(userMessage, systemMessage));
List<Generation> results = chatModel.call(prompt).getResults();
return results.stream().map(x -> x.getOutput().getContent()).collect(Collectors.joining("" ));
}
4. 函数调用 (Function Calling)
4.1 概述 Spring AI 的函数调用功能允许大语言模型在生成回答时触发预定义的外部函数,从而实现动态数据获取或业务逻辑操作。核心流程包括:定义函数、模型交互、执行函数、返回结果。
4.2 实现步骤
4.2.1 创建自定义 Function 定义一个返回 java.util.Function 并用 @Bean 标注的方法。
package com.example.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import java.util.function.Function;
@Slf4j
@Configuration
public class CalculatorService {
public record AddOperation (int a, int b) {}
public record MulOperation (int m, int n) {}
@Bean
@Description("加法运算")
public Function<AddOperation, Integer> addOperation () {
return request -> {
log.info("执行加法运算:{} + {} = {}" , request.a, request.b, request.a + request.b);
return request.a + request.b;
};
}
@Bean
@Description("乘法运算")
public Function<MulOperation, Integer> mulOperation () {
return request -> {
log.info("执行乘法运算:{} * {} = {}" , request.m, request.n, request.m * request.n);
return request.m * request.n;
};
}
}
4.2.2 编写 Controller 为了让模型知道并调用你的自定义函数,需要在 Prompt 请求中启用它。
package com.example.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
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;
@RestController
public class FunctionController {
@Resource
private ChatModel chatModel;
@GetMapping(value = "/function", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public String ragJsonText (@RequestParam(value = "message") String message) {
return ChatClient.builder(chatModel).build()
.prompt()
.system("""
您是算术计算器的代理。您能够支持加法运算、乘法运算等操作。
当用户询问数学计算时,您必须调用相应的函数来处理。
支持的函数:
- addOperation: 加法运算,需要两个数字参数
- mulOperation: 乘法运算,需要两个数字参数
调用函数的条件:
1. 用户明确要求计算
2. 问题涉及加法或乘法
3. 能够从问题中提取出两个数字
请用中文回复,并在适当的时候调用函数。
""" )
.user(message)
.functions("addOperation" , "mulOperation" )
.call()
.content();
}
}
5. 本地部署 Ollama
5.1 安装 Ollama 安装完成后,可以在系统环境变量中设置 OLLAMA_MODELS 指定模型存储路径。重启电脑使配置生效。
ollama pull deepseek-r1:1.5b
启动服务后,默认监听 http://localhost:11434。
5.2 Spring AI 代码测试
5.2.1 引入依赖 <properties >
<maven.compiler.source > 17</maven.compiler.source >
<maven.compiler.target > 17</maven.compiler.target >
<spring-ai.version > 1.0.0-M5</spring-ai.version >
</properties >
<dependencies >
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-ollama-spring-boot-starter</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 >
<repositories >
<repository >
<id > spring-milestones</id >
<name > Spring Milestones</name >
<url > https://repo.spring.io/milestone</url >
<snapshots > <enabled > false</enabled > </snapshots >
</repository >
<repository >
<id > spring-snapshots</id >
<name > Spring Snapshots</name >
<url > https://repo.spring.io/snapshot</url >
<releases > <enabled > false</enabled > </releases >
</repository >
</repositories >
5.2.2 配置与测试 server.port=8892
spring.application.name=spring-ai-deepseek-demo
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=deepseek-r1:1.5b
spring.ai.ollama.chat.options.temperature=0.7
package com.example.ai.ollama.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/ollama")
public class SpringAiOllamaController {
@Resource
private OllamaChatModel ollamaChatModel;
@GetMapping("/test")
public String generate (@RequestParam(value = "message", defaultValue = "hello") String message) {
String response = this .ollamaChatModel.call(message);
System.out.println("response: " + response);
return response;
}
}
6. Spring AI Alibaba
6.1 概述 Spring AI Alibaba 是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,通过提供一种方便的 API 抽象,帮助 Java 开发者加速和简化 Java 智能体应用的开发。
6.2 快速入门
6.2.1 申请 API Key 访问阿里云百炼页面开通服务,获取 API Key。
6.2.2 引入依赖 <properties >
<maven.compiler.source > 17</maven.compiler.source >
<maven.compiler.target > 17</maven.compiler.target >
<spring-ai.version > 1.0.0-M5</spring-ai.version >
</properties >
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > com.alibaba.cloud.ai</groupId >
<artifactId > spring-ai-alibaba-starter</artifactId >
<version > 1.0.0-M5.1</version >
</dependency >
</dependencies >
6.2.3 配置与 Controller server.port=8893
spring.application.name=spring-ai-deepseek-demo
spring.ai.dashscope.api-key=sk-*****cf
spring.autoconfigure.exclude=org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration
package com.example.controller;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SpringAiAlibabaController {
private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!" ;
private ChatClient dashScopeChatClient;
public SpringAiAlibabaController (ChatClient.Builder chatClientBuilder) {
this .dashScopeChatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
.defaultAdvisors(new MessageChatMemoryAdvisor (new InMemoryChatMemory ()))
.defaultAdvisors(new SimpleLoggerAdvisor ())
.defaultOptions(DashScopeChatOptions.builder().withTopP(0.7 ).build())
.build();
}
@GetMapping("/simple/chat")
public String simpleChat (@RequestParam("query") String query) {
return dashScopeChatClient.prompt(query).call().content();
}
}
7. 其他模型:图像与语音
7.1 图像模型 Image Model API 旨在为与专注于图像生成的各种 AI 模型进行交互提供一个简单且可移植的接口。
package com.example.controller;
import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel;
import com.alibaba.cloud.ai.dashscope.image.DashScopeImageOptions;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
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 java.io.InputStream;
import java.net.URI;
import java.net.URL;
@RestController
public class ImageModelController {
@Resource
private DashScopeImageModel imageModel;
@GetMapping("/generate-image")
public void getImage (@RequestParam(value = "msg", defaultValue = "生成一只小猫") String msg, HttpServletResponse res) throws Exception {
ImageResponse response = imageModel.call(new ImagePrompt (
msg,
DashScopeImageOptions.builder()
.withModel(com.alibaba.cloud.ai.dashscope.api.DashScopeImageApi.DEFAULT_IMAGE_MODEL)
.withN(1 )
.withHeight(1024 )
.withWidth(1024 )
.build()));
String imageUrl = response.getResult().getOutput().getUrl();
URL url = URI.create(imageUrl).toURL();
InputStream in = url.openStream();
res.setHeader("Content-Type" , MediaType.IMAGE_PNG_VALUE);
res.getOutputStream().write(in.readAllBytes());
res.getOutputStream().flush();
}
}
7.2 语音模型 Text-to-Speech API 提供了基于 TTS 模型的语音端点,支持朗读文章、生成多语言音频等。
package com.example.controller;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeSpeechSynthesisModel;
import com.alibaba.cloud.ai.dashscope.audio.DashScopeSpeechSynthesisOptions;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisPrompt;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisResponse;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
@RestController
public class AudioModelController {
@Resource
private DashScopeSpeechSynthesisModel speechSynthesisModel;
private static final String TEXT = "床前明月光,疑是地上霜。举头望明月,低头思故乡。" ;
private static final String FILE_PATH = "/tmp/tts/output.mp3" ;
@GetMapping("/tts")
public void tts () throws IOException {
DashScopeSpeechSynthesisOptions options = DashScopeSpeechSynthesisOptions.builder()
.withSpeed(1.0 )
.withPitch(0.9 )
.withVolume(60 )
.build();
SpeechSynthesisResponse response = speechSynthesisModel.call(new SpeechSynthesisPrompt (TEXT, options));
File file = new File (FILE_PATH);
try (FileOutputStream fos = new FileOutputStream (file)) {
ByteBuffer byteBuffer = response.getResult().getOutput().getAudio();
fos.write(byteBuffer.array());
}
}
}
8. 实现 RAG (检索增强生成)
8.1 概述 RAG (Retrieval-Augmented Generation) 是一种结合了检索系统和生成模型的新型技术框架。其主要目的是利用外部知识库,帮助大模型生成更加准确、有依据、最新的回答,解决传统 LLM 存在的知识局限性和幻觉现象。
工作流程大致为:用户输入问题 -> 问题向量化 -> 向量数据库检索 -> 构建上下文 -> 调用 LLM -> 返回最终回答。
8.2 基本流程实现
8.2.1 配置类 package com.example.ai.rag.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class RagConfig {
@Bean
ChatClient chatClient (ChatClient.Builder builder) {
return builder.defaultSystem("你将作为一名 Java 开发语言的专家,对于用户的使用需求作出解答" ).build();
}
@Bean
VectorStore vectorStore (@Qualifier("dashscopeEmbeddingModel") EmbeddingModel embeddingModel) {
SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build();
List<Document> documents = List.of(new Document (
"产品说明:名称:Java 开发语言\n" +
"产品描述:Java 是一种面向对象开发语言。\n" +
"特性:\n" +
"1. 封装\n" +
"2. 继承\n" +
"3. 多态\n" ));
simpleVectorStore.add(documents);
return simpleVectorStore;
}
}
8.2.2 Controller package com.example.ai.rag.controller;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/rag")
public class RagController {
@Resource
private ChatClient dashScopeChatClient;
@Resource
private VectorStore vectorStore;
@GetMapping(value = "/chat", produces = "text/plain; charset=UTF-8")
public String generation (@RequestParam("userInput") String userInput) {
return dashScopeChatClient.prompt().user(userInput)
.advisors(new QuestionAnswerAdvisor (vectorStore))
.call().content();
}
}
9. 综合案例:智能简历筛选助手 该助手借助 Spring AI 的特性结合人工智能技术,为企业提供快速查看应聘候选人的信息及与候选人岗位的匹配度的服务。
9.1 环境搭建
9.2 创建 RAG 知识库 将候选人的简历构建为 txt 文本放入资源目录,并通过配置类加载到向量库。
package com.example.all.config;
import org.springframework.ai.document.Document;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.reader.TextReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class RagConfig {
@Bean
VectorStore vectorStore (@Qualifier("dashscopeEmbeddingModel") EmbeddingModel embeddingModel) {
SimpleVectorStore simpleVectorStore = SimpleVectorStore.builder(embeddingModel).build();
String filePath = "张三简历.txt" ;
TextReader textReader = new TextReader (filePath);
textReader.getCustomMetadata().put("filePath" , filePath);
List<Document> documents = textReader.get();
TokenTextSplitter splitter = new TokenTextSplitter (1200 , 350 , 5 , 100 , true );
splitter.apply(documents);
simpleVectorStore.add(documents);
return simpleVectorStore;
}
}
9.3 创建工具类 package com.example.all.function;
import java.util.function.Function;
public class RecruitServiceFunction implements Function <RecruitServiceFunction.Request, RecruitServiceFunction.Response> {
@Override
public Response apply (Request request) {
String position = "未知" ;
if (request.name.contains("张三" )) {
position = "算法工程师" ;
}
return new Response (position);
}
public record Request (String name) {}
public record Response (String position) {}
}
9.4 编写 Controller package com.example.ai.all.controller;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.Generation;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@RestController
public class ChatController {
@Resource
private ChatModel chatModel;
@Resource
private VectorStore vectorStore;
@GetMapping("/ai/agent")
public String agent (@RequestParam("query") String query) {
List<Document> documents = vectorStore.similaritySearch(query);
String info = "" ;
if (documents.size() > 0 ) {
info = documents.get(0 ).getContent();
}
String systemPrompt = """
角色与目标:你是一个招聘助手,会针对用户的问题,结合候选人经历,岗位匹配度等专业知识,给用户提供指导。
指导原则:你需要确保给出的建议合理科学,不会对候选人的表现有言论侮辱。
限制:在提供建议时,需要强调在个性建议方面用户仍然需要线下寻求专业咨询。
澄清:在与用户交互过程中,你需要明确回答用户关于招聘方面的问题,对于非招聘方面的问题,你的回应是'我只是一个招聘助手,不能回答这个问题哦'。
个性化:在回答时,你需要以专业可靠的预期回答,偶尔可以带点幽默感。调节气氛。
给你提供一个数据参考,并且给你调用岗位投递检索公户
请你跟进数据参考与工具返回结果回复用户的请求。
""" ;
String userPrompt = """
给你提供一些数据参考:{info},请回答我的问题:{query}。
请你跟进数据参考与工具返回结果回复用户的请求。
""" ;
SystemMessage systemMessage = new SystemMessage (systemPrompt);
PromptTemplate promptTemplate = new PromptTemplate (userPrompt);
Message userMessage = promptTemplate.createMessage(Map.of("info" , info, "query" , query));
Prompt prompt = new Prompt (List.of(userMessage, systemMessage), DashScopeChatOptions.builder()
.withFunctions(Set.of("recruitServiceFunction" )).build());
List<Generation> results = chatModel.call(prompt).getResults();
String content = results.stream().map(x -> x.getOutput().getContent()).collect(Collectors.joining());
return content;
}
}
测试接口 localhost:8896/ai/agent?query=java 语言有哪些特性,即可获得基于知识库和工具的精准回答。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online