QuestionAnswerAdvisor
implementation "org.springframework.ai:spring-ai-advisors-vector-store"
- vector store에는 llm이 모르는 정보가 들어있다. user query가 들어왔을때,
QuestionAnswerAdvisor는 vector store에 query를 날려서 user query에 관련된 documents를 찾아온다.
- documents는 llm이 답변을 생성하기 위한 context로써 사용된다.
ChatResponse response = ChatClient.builder(chatModel)
.build().prompt()
.advisors(QuestionAnswerAdvisor.builder(vectorStore).build())
.user(userText)
.call()
.chatResponse();
- QuestionAnswerAdvisor는 vector store의 모든 document를 대상으로 유사도 검색을 수행한다.
SearchRequest를 사용해서 SQL 형식의 filtering을 할 수 있다.
var qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder().similarityThreshold(0.8d).topK(6).build()) // 80% 이상 유사한 document 상위 6개로 filtering
.build();
Dynamic Filter Expressions
FILTER_EXPRESSION를 사용해서 runtime이 유연한 filtering을 할 수 있다.
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder().build())
.build())
.build();
// Update filter expression at runtime
String content = this.chatClient.prompt()
.user("Please answer my question XYZ")
.advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Spring'"))
.call()
.content();
Custom Template
- QuestionAnswerAdvisor는 기본 prompt template을 제공하지만
.promptTemplate() 빌더 메서드를 통해서 Custom을 할 수 있다.
- placeholder
query: user query
quersion_answer_context: 검색 결과 documents
PromptTemplate customPromptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
.template("""
<query>
Context information is below.
---------------------
<question_answer_context>
---------------------
Given the context information and no prior knowledge, answer the query.
Follow these rules:
1. If the answer is not in the context, just say that you don't know.
2. Avoid statements like "Based on the context..." or "The provided information...".
""")
.build();
String question = "Where does the adventure of Anacletus and Birba take place?";
QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.promptTemplate(customPromptTemplate)
.build();
String response = ChatClient.builder(chatModel).build()
.prompt(question)
.advisors(qaAdvisor)
.call()
.content();