更新 SpringAI/0_使用SpringAI接入AI模型.md

This commit is contained in:
8ga 2025-03-17 13:41:10 +08:00
parent df203924c3
commit 97b90ff0e2

View File

@ -206,7 +206,7 @@ ChatClient.create(chatModel)
.advisors(new MessageChatMemoryAdvisor(chatMemory, sessionId, 6))
.stream()
.content()
.map(chatResponse -> ServerSentEvent.builder(chatResponse).event("message").build());
.map(chatResponse -> ServerSentEvent.builder(JSONUtil.toJsonStr(chatResponse)).event("message").build());
```
### ETL
@ -395,3 +395,126 @@ vectorStore.add(splitDocuments);
// query可以是用户输入的文本字符串
List<Document> list = vectorStore.similaritySearch(query);
```
### RAG
RAG就是当文档等数据ETL到向量数据库以后用户提问时拿用户的prompt检索向量数据库里的相关资料然后跟用户的prompt合并提交给大模型再让大模型生成答案给用户。
#### QuestionAnswerAdvisor
在SpringAI中QuestionAnswerAdvisor这一组件实现了上述的能力。我们可以定义一个prompt模板来做这件事
```
下面是上下文信息
---------------------
{question_answer_context}
---------------------
给定的上下文和提供的历史信息,而不是事先的知识,回复用户的意见。如果答案不在上下文中,告诉用户你不能回答这个问题。
```
这个模板的内容可以从数据库、Redis、配置文件加载**{question_answer_context}**是一个模板的变量占位符。
```java
ChatClient.create(chatModel)
.prompt()
.user(prompt)
// 会自动从向量数据库查询资料,并替换到 question_answer_context 变量,结合用户的 prompt 一起发送给大模型API
// 假设 promptTemplate 这个字符串就是上面的模板
.advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults(), promptTemplate))
.stream()
.content()
.map(chatResponse -> ServerSentEvent.builder(JSONUtil.toJsonStr(chatResponse)).event("message").build());
```
### FunctionCall
Function Call旨在解决一些复杂场景的需求比如我希望AI读取本机某个文件然后回答文件里面的内容读取文件这个操作就可以通过FunctionCall来实现。
#### 读取文档可以通过tika实现
```xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-tika-document-reader</artifactId>
</dependency>
```
#### 使用JSON描述Function
AI模型是不知道你代码里的Function位置在哪儿的我们需要用JSON声明Function的结构让AI去找并调用简单示例
```json
{
"type": "function",
"function": {
"name": "documentAnalyzer", // 这个是 spring bean 的名称
"description": "文档解析", // 描述函数的用途
"parameters": { // 这个函数要传递的参数
"properties": {
"path": { // 参数的名称
"type": "string", // 参数的类型
"description": "被解析的文档路径" // 参数的描述
},
},
"required":["path"], // 必传的参数
"type": "object"
}
}
}
```
#### 编写函数
我们需要实现**java.util.function.Function**接口里的**apply**方法并将其注入到spring bean中就可以实现自动调用。
```java
@Description("文档解析")
@Service
public class DocumentAnalyzer implements Function<DocumentAnalyzer.Request, DocumentAnalyzer.Response> {
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class Request {
// 这2个jackson注解的目的是让 spring ai 提取参数和描述
@JsonPropertyDescription(value = "需要解析的文档路径")
@JsonProperty(value = "path", required = true)
private String path;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class Response {
private String result;
}
@Override
public Response apply(Request request) {
var resource = new FileSystemResource(request.path);
TikaDocumentReader reader = new TikaDocumentReader(resource);
return new Response(reader.read().get(0).getContent());
}
}
```
#### 使用函数
```java
ChatClient.create(chatModel)
.prompt()
.messages(new UserMessage(prompt))
// spring ai会根据beanName查找fucntion
.functions(functionName)
.stream()
.chatResponse()
.map(chatResponse -> ServerSentEvent.builder(JSONUtil.toJsonStr(chatResponse)).event("message").build());
```
可以用封装一个http接口接收`prompt`和`functionName`完成函数调用。
## 总结
Spring AI框架帮助我们实现了各大主流AI大模型的API封装和常用的一些工具组件依托spring强大的生态各大主流的AI大模型供应商也在积极适配中。它简化了我们的开发工作量同类型的框架还有LangChain4J。