1.面试题目 #
请详细阐述什么是查询重写(Query Rewriting)?它在RAG系统中有什么作用?如何基于Spring AI框架实现查询重写功能?请结合代码示例说明具体的实现方案。
2.参考答案 #
1. 查询重写的定义 #
查询重写是RAG(检索增强生成)系统中预检索阶段的一种优化技术。它利用大语言模型对用户的原始查询进行重新表述和优化,生成一个更加有效、精确的新查询,用于后续的文档检索过程。
2. 查询重写的作用与价值 #
核心作用 #
- 提升检索准确性:通过优化查询表达,提高与相关文档的匹配度
- 增强检索相关性:使查询更符合知识库的语言风格和表达习惯
- 标准化查询格式:将模糊、口语化、不完整的查询转换为标准化格式
适用场景 #
- 模糊查询:用户查询表达不够明确时
- 口语化表达:用户使用非正式语言进行查询
- 不完整查询:用户查询缺少关键信息
- 语言风格不匹配:用户查询与知识库语言风格不一致
3. Spring AI中的查询重写实现 #
核心接口:QueryTransformer #
Spring AI通过QueryTransformer接口及其实现类来支持查询重写功能。
主要实现类 #
3.1 RewriteQueryTransformer #
用于将简单查询改写为更加具体和专业的查询。
public class RewriteQueryTransformer implements QueryTransformer {
private static final Logger logger = LoggerFactory.getLogger(RewriteQueryTransformer.class);
private static final PromptTemplate DEFAULT_PROMPT_TEMPLATE = new PromptTemplate("""
Given a user query, rewrite it to provide better results when querying a {target}.
Remove any irrelevant information, and ensure the query is concise and specific.
Original query:
{query}
Rewritten query:
""");
private final ChatClient chatClient;
private final PromptTemplate promptTemplate;
public RewriteQueryTransformer(ChatClient chatClient) {
this.chatClient = chatClient;
this.promptTemplate = DEFAULT_PROMPT_TEMPLATE;
}
@Override
public String transform(String query) {
// 实现查询重写逻辑
return chatClient.prompt()
.user(promptTemplate.create(Map.of("query", query, "target", "knowledge base")))
.call()
.content();
}
}3.2 CompressionQueryTransformer #
专门用于多轮对话场景,将对话历史和当前问题压缩为单个上下文完整的新查询。
public class CompressionQueryTransformer implements QueryTransformer {
private final ChatClient chatClient;
private final PromptTemplate compressionTemplate;
public CompressionQueryTransformer(ChatClient chatClient) {
this.chatClient = chatClient;
this.compressionTemplate = new PromptTemplate("""
Given the following conversation history and the current question,
create a standalone question that captures the context and intent.
Conversation History:
{history}
Current Question:
{currentQuery}
Standalone Question:
""");
}
@Override
public String transform(String query) {
// 实现多轮对话压缩逻辑
return chatClient.prompt()
.user(compressionTemplate.create(Map.of(
"history", getConversationHistory(),
"currentQuery", query
)))
.call()
.content();
}
}4. 完整实现方案 #
3.1 配置类 #
@Configuration
@EnableConfigurationProperties(SpringAiProperties.class)
public class QueryRewriteConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel) {
return ChatClient.builder(chatModel).build();
}
@Bean
public RewriteQueryTransformer rewriteQueryTransformer(ChatClient chatClient) {
return new RewriteQueryTransformer(chatClient);
}
@Bean
public CompressionQueryTransformer compressionQueryTransformer(ChatClient chatClient) {
return new CompressionQueryTransformer(chatClient);
}
}3.2 服务层实现 #
@Service
public class QueryRewriteService {
private final RewriteQueryTransformer rewriteTransformer;
private final CompressionQueryTransformer compressionTransformer;
public QueryRewriteService(
RewriteQueryTransformer rewriteTransformer,
CompressionQueryTransformer compressionTransformer) {
this.rewriteTransformer = rewriteTransformer;
this.compressionTransformer = compressionTransformer;
}
public String rewriteQuery(String originalQuery, QueryType type) {
return switch (type) {
case SIMPLE -> rewriteTransformer.transform(originalQuery);
case CONVERSATION -> compressionTransformer.transform(originalQuery);
};
}
public enum QueryType {
SIMPLE, CONVERSATION
}
}3.3 控制器层 #
@RestController
@RequestMapping("/api/query")
public class QueryController {
private final QueryRewriteService queryRewriteService;
@PostMapping("/rewrite")
public ResponseEntity<QueryRewriteResponse> rewriteQuery(
@RequestBody QueryRewriteRequest request) {
String rewrittenQuery = queryRewriteService.rewriteQuery(
request.getOriginalQuery(),
request.getType()
);
return ResponseEntity.ok(new QueryRewriteResponse(
request.getOriginalQuery(),
rewrittenQuery
));
}
}4. 实际应用场景 #
4.1 电商客服系统 #
// 原始查询:用户说"这个手机怎么样?"
// 重写后:"iPhone 15 Pro Max 性能评测、价格对比、用户评价"4.2 技术文档检索 #
// 原始查询:"怎么用Spring?"
// 重写后:"Spring Framework 入门教程、配置方法、最佳实践"4.3 多轮对话场景 #
// 对话历史:用户询问"Spring Boot配置"
// 当前查询:"那数据库连接呢?"
// 压缩后:"Spring Boot 数据库连接配置方法"5. 性能优化建议 #
5.1 缓存机制 #
@Service
public class CachedQueryRewriteService {
@Cacheable(value = "queryRewrite", key = "#originalQuery")
public String rewriteQuery(String originalQuery) {
return queryRewriteService.rewriteQuery(originalQuery, QueryType.SIMPLE);
}
}5.2 异步处理 #
@Async
public CompletableFuture<String> rewriteQueryAsync(String originalQuery) {
return CompletableFuture.completedFuture(
queryRewriteService.rewriteQuery(originalQuery, QueryType.SIMPLE)
);
}6. 总结 #
查询重写技术通过Spring AI框架的QueryTransformer接口,为RAG系统提供了强大的查询优化能力。它不仅能够提升检索的准确性和相关性,还能适应不同的应用场景,是构建高质量RAG系统的重要技术组件。通过合理的架构设计和性能优化,查询重写功能能够显著提升用户体验和系统整体性能。