RAG重排序

RAG重排序技术以提高RAG系统中的检索质量。重新排序充当初始检索后的第二个过滤步骤,以确保最相关的内容用于响应生成。

重排序的关键概念

1.初始检索:使用基本相似度搜索的第一遍(准确度较低但速度更快)
2.文档评分:评估每个检索到的文档与查询的相关性
3.重新排序:按相关性分数对文档进行排序
4.选择:仅使用最相关的文档生成响应

具体代码实现

PDF文本处理与分块

PDF文件中提取全部文本
def extract_text_from_pdf(pdf_path: str) -> str:"""从PDF文件中提取全部文本。"""print(f"[PDF提取] 正在提取: {pdf_path}")with open(pdf_path, 'rb') as f:reader = PdfReader(f)text = ""for i, page in enumerate(reader.pages):page_text = page.extract_text()if page_text:text += page_textprint(f"  - 已提取第{i+1}页")print(f"[PDF提取] 完成,总长度: {len(text)} 字符\n")return text
文本分割为带重叠的块
def chunk_text(text: str, n: int = 1000, overlap: int = 200) -> List[str]:"""将文本分割为带重叠的块。"""print(f"[分块] 每块{n}字符,重叠{overlap}字符")chunks = []for i in range(0, len(text), n - overlap):chunks.append(text[i:i + n])print(f"[分块] 完成,共{len(chunks)}块\n")return chunks

向量生成与存储

阿里embedding模型批量生成文本向量
def create_embeddings(texts, model: str = EMBEDDING_MODEL) -> List[np.ndarray]:"""用阿里embedding模型批量生成文本向量。支持单条或多条文本。"""if isinstance(texts, str):texts = [texts]print(f"[嵌入生成] 正在生成{len(texts)}条文本的向量...")try:response = TextEmbedding.call(model=model,input=texts,api_key=ALI_API_KEY)if response.status_code == 200:embeddings = [np.array(item['embedding']) for item in response.output['embeddings']]print(f"[嵌入生成] 成功,返回{len(embeddings)}条向量\n")return embeddings if len(embeddings) > 1 else embeddings[0]else:print(f"[嵌入生成] 失败: {response.message}")return [np.zeros(1536)] * len(texts)except Exception as e:print(f"[嵌入生成] 异常: {e}")return [np.zeros(1536)] * len(texts)
简单的向量存储与检索类
class SimpleVectorStore:"""简单的向量存储与检索类。"""def __init__(self):self.vectors = []self.texts = []self.metadata = []def add_item(self, text, embedding, metadata=None):self.vectors.append(np.array(embedding))self.texts.append(text)self.metadata.append(metadata or {})def similarity_search(self, query_embedding, k=5):if not self.vectors:return []query_vector = np.array(query_embedding)similarities = []for i, vector in enumerate(self.vectors):sim = np.dot(query_vector, vector) / (np.linalg.norm(query_vector) * np.linalg.norm(vector))similarities.append((i, sim))similarities.sort(key=lambda x: x[1], reverse=True)results = []for i in range(min(k, len(similarities))):idx, score = similarities[i]results.append({"text": self.texts[idx],"metadata": self.metadata[idx],"similarity": score})return results

文档处理主流程

处理PDF文档,提取文本、分块、生成向量并构建向量库
def process_document(pdf_path: str, chunk_size: int = 1000, chunk_overlap: int = 200) -> SimpleVectorStore:"""处理PDF文档,提取文本、分块、生成向量并构建向量库。"""print("[主流程] 开始处理文档...")extracted_text = extract_text_from_pdf(pdf_path)text_chunks = chunk_text(extracted_text, chunk_size, chunk_overlap)print("[主流程] 初始化向量库...")vector_store = SimpleVectorStore()print("[主流程] 为每个块生成向量...")chunk_embeddings = create_embeddings(text_chunks)for i, (chunk, embedding) in enumerate(zip(text_chunks, chunk_embeddings)):print(f"[块{i+1}/{len(text_chunks)}] 已生成向量,长度: {len(chunk)} 字符")vector_store.add_item(chunk, embedding, {"type": "chunk", "index": i})print("[主流程] 文档处理完毕,向量库构建完成\n")return vector_store

LLM重排序

LLM对初步检索结果进行重排序
def rerank_with_llm(query: str, results: List[Dict], top_n: int = 3, model: str = LLM_MODEL) -> List[Dict]:"""使用LLM对初步检索结果进行重排序。"""print(f"[重排序] 对{len(results)}个文档进行LLM重排序...")scored_results = []system_prompt = "你是文档相关性评估专家,请根据用户问题对下列文档相关性打分,0-10分,10分最相关。只返回分数,不要输出其他内容。"for i, result in enumerate(results):if i % 5 == 0:print(f"[重排序] 正在评估第{i+1}/{len(results)}个文档...")user_prompt = f"""问题: {query}\n\n文档内容:\n{result['text']}\n\n请对该文档与问题的相关性打分(0-10分):"""try:response = Generation.call(model=model,messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}],api_key=ALI_API_KEY,result_format='message')score_text = response.output.choices[0].message.content.strip()score_match = re.search(r'\b(10|[0-9])\b', score_text)if score_match:score = float(score_match.group(1))else:print(f"[重排序] 警告: 无法提取分数,使用相似度分数代替: '{score_text}'")score = result["similarity"] * 10except Exception as e:print(f"[重排序] LLM调用异常: {e},使用相似度分数代替")score = result["similarity"] * 10scored_results.append({"text": result["text"],"metadata": result["metadata"],"similarity": result["similarity"],"relevance_score": score})reranked_results = sorted(scored_results, key=lambda x: x["relevance_score"], reverse=True)print(f"[重排序] 完成,返回Top{top_n}结果\n")return reranked_results[:top_n]

关键词重排序

关键词匹配对初步检索结果进行简单重排序
def rerank_with_keywords(query: str, results: List[Dict], top_n: int = 3) -> List[Dict]:"""使用关键词匹配对初步检索结果进行简单重排序。"""print(f"[关键词重排序] 对{len(results)}个文档进行关键词重排序...")keywords = [word.lower() for word in query.split() if len(word) > 3]scored_results = []for result in results:document_text = result["text"].lower()base_score = result["similarity"] * 0.5keyword_score = 0for keyword in keywords:if keyword in document_text:keyword_score += 0.1first_position = document_text.find(keyword)if first_position < len(document_text) / 4:keyword_score += 0.1frequency = document_text.count(keyword)keyword_score += min(0.05 * frequency, 0.2)final_score = base_score + keyword_scorescored_results.append({"text": result["text"],"metadata": result["metadata"],"similarity": result["similarity"],"relevance_score": final_score})reranked_results = sorted(scored_results, key=lambda x: x["relevance_score"], reverse=True)print(f"[关键词重排序] 完成,返回Top{top_n}结果\n")return reranked_results[:top_n]
回答生成
def generate_response(query: str, context: str, model: str = LLM_MODEL) -> str:"""用大模型基于上下文生成回答。"""print("[生成] 正在调用大模型生成回答...")system_prompt = "你是一个AI助手,只能基于给定上下文回答问题。如果上下文无法直接回答,请回复:'信息不足,无法回答。'"user_prompt = f"""
上下文:\n{context}\n\n问题:{query}\n\n请只基于上述上下文简明准确作答。"""try:response = Generation.call(model=model,messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}],api_key=ALI_API_KEY,result_format='message')answer = response.output.choices[0].message.content.strip()print(f"[生成] 回答生成成功: {answer}\n")return answerexcept Exception as e:print(f"[生成] 回答生成异常: {e}")return ""

RAG主流程

def rag_with_reranking(query: str, vector_store: SimpleVectorStore, reranking_method: str = "llm", top_n: int = 3, model: str = LLM_MODEL) -> Dict:"""完整RAG流程,包含初步检索、重排序和回答生成。"""print(f"[RAG] 开始RAG流程,检索+重排序方法: {reranking_method}")query_embedding = create_embeddings(query)initial_results = vector_store.similarity_search(query_embedding, k=10)if reranking_method == "llm":reranked_results = rerank_with_llm(query, initial_results, top_n=top_n)elif reranking_method == "keywords":reranked_results = rerank_with_keywords(query, initial_results, top_n=top_n)else:reranked_results = initial_results[:top_n]context = "\n\n===\n\n".join([result["text"] for result in reranked_results])response = generate_response(query, context, model)print(f"[RAG] 流程完成\n")return {"query": query,"reranking_method": reranking_method,"initial_results": initial_results[:top_n],"reranked_results": reranked_results,"context": context,"response": response}

附录

效果展示

===== RAG重排序增强示例 =====[主流程] 开始处理文档...
[PDF提取] 正在提取: data/2888年Java程序员找工作最新场景题.pdf- 已提取第1- 已提取第2- 已提取第3- 已提取第4- 已提取第5- 已提取第6- 已提取第7- 已提取第8- 已提取第9- 已提取第10[PDF提取] 完成,总长度: 6984 字符[分块] 每块1000字符,重叠200字符
[分块] 完成,共9[主流程] 初始化向量库...
[主流程] 为每个块生成向量...
[嵌入生成] 正在生成9条文本的向量...
[嵌入生成] 成功,返回9条向量[1/9] 已生成向量,长度: 1000 字符
[2/9] 已生成向量,长度: 1000 字符
[3/9] 已生成向量,长度: 1000 字符
[4/9] 已生成向量,长度: 1000 字符
[5/9] 已生成向量,长度: 1000 字符
[6/9] 已生成向量,长度: 1000 字符
[7/9] 已生成向量,长度: 1000 字符
[8/9] 已生成向量,长度: 1000 字符
[9/9] 已生成向量,长度: 584 字符
[主流程] 文档处理完毕,向量库构建完成[主流程] 向量库已构建,开始不同重排序方法对比...=== 标准检索(无重排序) ===
[RAG] 开始RAG流程,检索+重排序方法: none
[嵌入生成] 正在生成1条文本的向量...
[嵌入生成] 成功,返回1条向量[生成] 正在调用大模型生成回答...
[生成] 回答生成成功: 根据上下文,Java程序员面试中常见的技术问题包括但不限于:- 分布式架构相关知识:如CAP原则、微服务架构、弹性设计以及Spring Cloud、CloudNative等相关技术框架的理解。
- 网络编程技能:理解TCP/IP协议的三次握手与四次挥手过程,掌握Socket编程基础,了解select、poll、epoll等I/O多路复用技术。
- 项目经验分享:面试官会询问候选人关于他们参与过的项目细节,特别是那些最自豪或最具挑战性的项目经历,以及如何解决遇到的技术难题。此外,还可能要求讲述曾经犯下的最大技术失误及从中学习到的经验教训。这些问题旨在考察求职者的实际工作经验、解决问题的能力和技术深度。[RAG] 流程完成Query: Java程序员面试中常见的技术问题有哪些?Response:
根据上下文,Java程序员面试中常见的技术问题包括但不限于:- 分布式架构相关知识:如CAP原则、微服务架构、弹性设计以及Spring Cloud、CloudNative等相关技术框架的理解。
- 网络编程技能:理解TCP/IP协议的三次握手与四次挥手过程,掌握Socket编程基础,了解select、poll、epoll等I/O多路复用技术。
- 项目经验分享:面试官会询问候选人关于他们参与过的项目细节,特别是那些最自豪或最具挑战性的项目经历,以及如何解决遇到的技术难题。此外,还可能要求讲述曾经犯下的最大技术失误及从中学习到的经验教训。这些问题旨在考察求职者的实际工作经验、解决问题的能力和技术深度。=== LLM重排序 ===
[RAG] 开始RAG流程,检索+重排序方法: llm
[嵌入生成] 正在生成1条文本的向量...
[嵌入生成] 成功,返回1条向量[重排序]9个文档进行LLM重排序...
[重排序] 正在评估第1/9个文档...
[重排序] 正在评估第6/9个文档...
[重排序] 完成,返回Top3结果[生成] 正在调用大模型生成回答...
[生成] 回答生成成功: 根据上下文,Java程序员面试中常见的技术问题涉及以下几个方面:- 并发编程、NIO、JVM等进阶知识。
- Spring、Netty等流行框架的基本原理。
- 对于分布式架构的理解,包括CAP原则、微服务架构(如Spring Cloud)、弹性设计及云原生(Cloud Native)技术。
- 网络编程相关知识,比如TCP/IP协议的三次握手和四次挥手过程,Socket编程基础,以及I/O多路复用技术(select, poll, epoll)。这些问题旨在评估应聘者对于所列技术的实际掌握程度和技术深度。[RAG] 流程完成Query: Java程序员面试中常见的技术问题有哪些?Response:
根据上下文,Java程序员面试中常见的技术问题涉及以下几个方面:- 并发编程、NIO、JVM等进阶知识。
- Spring、Netty等流行框架的基本原理。
- 对于分布式架构的理解,包括CAP原则、微服务架构(如Spring Cloud)、弹性设计及云原生(Cloud Native)技术。
- 网络编程相关知识,比如TCP/IP协议的三次握手和四次挥手过程,Socket编程基础,以及I/O多路复用技术(select, poll, epoll)。这些问题旨在评估应聘者对于所列技术的实际掌握程度和技术深度。=== 关键词重排序 ===
[RAG] 开始RAG流程,检索+重排序方法: keywords
[嵌入生成] 正在生成1条文本的向量...
[嵌入生成] 成功,返回1条向量[关键词重排序]9个文档进行关键词重排序...
[关键词重排序] 完成,返回Top3结果[生成] 正在调用大模型生成回答...
[生成] 回答生成成功: 根据上下文,Java程序员面试中常见的技术问题包括但不限于:- 分布式架构相关:CAP原则的理解、微服务架构的应用、弹性设计的概念以及Spring Cloud和Cloud Native等技术框架的使用。
- 网络编程基础:TCP/IP协议的工作机制(如三次握手、四次挥手),Socket编程的基础知识,还有I/O多路复用技术(select, poll, epoll)的应用。此外,还强调了对项目经验和技术深度思考的考察,比如要求候选人分享他们最自豪或最近完成的项目、解决过的复杂难题、经历过的挑战性项目以及曾经犯下的最大技术失误等。这些问题旨在评估候选人的实际操作能力、解决问题的能力及面对错误的态度。[RAG] 流程完成Query: Java程序员面试中常见的技术问题有哪些?Response:
根据上下文,Java程序员面试中常见的技术问题包括但不限于:- 分布式架构相关:CAP原则的理解、微服务架构的应用、弹性设计的概念以及Spring Cloud和Cloud Native等技术框架的使用。
- 网络编程基础:TCP/IP协议的工作机制(如三次握手、四次挥手),Socket编程的基础知识,还有I/O多路复用技术(select, poll, epoll)的应用。此外,还强调了对项目经验和技术深度思考的考察,比如要求候选人分享他们最自豪或最近完成的项目、解决过的复杂难题、经历过的挑战性项目以及曾经犯下的最大技术失误等。这些问题旨在评估候选人的实际操作能力、解决问题的能力及面对错误的态度。进程已结束,退出代码为 0

完整代码示例

# -*- coding: utf-8 -*-
"""
RAG重排序增强脚本(基于阿里云通义千问Qwen)
========================================
本脚本实现了RAG检索增强中的重排序(rerank)流程,所有大模型调用均基于阿里云通义千问Qwen,密钥从api_keys.py读取。
每一步均有详细控制台输出,便于观察效果。
"""
import os
import numpy as np
import json
import re
from typing import List, Dict
from PyPDF2 import PdfReader
from dashscope import Generation, TextEmbedding# ========== 密钥配置 ==========
# try:
#     from test.api_keys import ALI_API_KEY
# except ImportError:
#     raise RuntimeError("未找到test/api_keys.py或未定义ALI_API_KEY,请配置API密钥!")
ALI_API_KEY="sk-148deabc0bcf4fdeaa70a78eaa829c7e"
# =============================LLM_MODEL = "qwen-max"  # 通义千问主力模型
EMBEDDING_MODEL = "text-embedding-v2"  # 阿里云嵌入模型# ========== PDF文本处理与分块 ==========
def extract_text_from_pdf(pdf_path: str) -> str:"""从PDF文件中提取全部文本。"""print(f"[PDF提取] 正在提取: {pdf_path}")with open(pdf_path, 'rb') as f:reader = PdfReader(f)text = ""for i, page in enumerate(reader.pages):page_text = page.extract_text()if page_text:text += page_textprint(f"  - 已提取第{i+1}页")print(f"[PDF提取] 完成,总长度: {len(text)} 字符\n")return textdef chunk_text(text: str, n: int = 1000, overlap: int = 200) -> List[str]:"""将文本分割为带重叠的块。"""print(f"[分块] 每块{n}字符,重叠{overlap}字符")chunks = []for i in range(0, len(text), n - overlap):chunks.append(text[i:i + n])print(f"[分块] 完成,共{len(chunks)}块\n")return chunks# ========== 向量生成与存储 ==========
def create_embeddings(texts, model: str = EMBEDDING_MODEL) -> List[np.ndarray]:"""用阿里embedding模型批量生成文本向量。支持单条或多条文本。"""if isinstance(texts, str):texts = [texts]print(f"[嵌入生成] 正在生成{len(texts)}条文本的向量...")try:response = TextEmbedding.call(model=model,input=texts,api_key=ALI_API_KEY)if response.status_code == 200:embeddings = [np.array(item['embedding']) for item in response.output['embeddings']]print(f"[嵌入生成] 成功,返回{len(embeddings)}条向量\n")return embeddings if len(embeddings) > 1 else embeddings[0]else:print(f"[嵌入生成] 失败: {response.message}")return [np.zeros(1536)] * len(texts)except Exception as e:print(f"[嵌入生成] 异常: {e}")return [np.zeros(1536)] * len(texts)class SimpleVectorStore:"""简单的向量存储与检索类。"""def __init__(self):self.vectors = []self.texts = []self.metadata = []def add_item(self, text, embedding, metadata=None):self.vectors.append(np.array(embedding))self.texts.append(text)self.metadata.append(metadata or {})def similarity_search(self, query_embedding, k=5):if not self.vectors:return []query_vector = np.array(query_embedding)similarities = []for i, vector in enumerate(self.vectors):sim = np.dot(query_vector, vector) / (np.linalg.norm(query_vector) * np.linalg.norm(vector))similarities.append((i, sim))similarities.sort(key=lambda x: x[1], reverse=True)results = []for i in range(min(k, len(similarities))):idx, score = similarities[i]results.append({"text": self.texts[idx],"metadata": self.metadata[idx],"similarity": score})return results# ========== 文档处理主流程 ==========
def process_document(pdf_path: str, chunk_size: int = 1000, chunk_overlap: int = 200) -> SimpleVectorStore:"""处理PDF文档,提取文本、分块、生成向量并构建向量库。"""print("[主流程] 开始处理文档...")extracted_text = extract_text_from_pdf(pdf_path)text_chunks = chunk_text(extracted_text, chunk_size, chunk_overlap)print("[主流程] 初始化向量库...")vector_store = SimpleVectorStore()print("[主流程] 为每个块生成向量...")chunk_embeddings = create_embeddings(text_chunks)for i, (chunk, embedding) in enumerate(zip(text_chunks, chunk_embeddings)):print(f"[块{i+1}/{len(text_chunks)}] 已生成向量,长度: {len(chunk)} 字符")vector_store.add_item(chunk, embedding, {"type": "chunk", "index": i})print("[主流程] 文档处理完毕,向量库构建完成\n")return vector_store# ========== LLM重排序 ==========
def rerank_with_llm(query: str, results: List[Dict], top_n: int = 3, model: str = LLM_MODEL) -> List[Dict]:"""使用LLM对初步检索结果进行重排序。"""print(f"[重排序] 对{len(results)}个文档进行LLM重排序...")scored_results = []system_prompt = "你是文档相关性评估专家,请根据用户问题对下列文档相关性打分,0-10分,10分最相关。只返回分数,不要输出其他内容。"for i, result in enumerate(results):if i % 5 == 0:print(f"[重排序] 正在评估第{i+1}/{len(results)}个文档...")user_prompt = f"""问题: {query}\n\n文档内容:\n{result['text']}\n\n请对该文档与问题的相关性打分(0-10分):"""try:response = Generation.call(model=model,messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}],api_key=ALI_API_KEY,result_format='message')score_text = response.output.choices[0].message.content.strip()score_match = re.search(r'\b(10|[0-9])\b', score_text)if score_match:score = float(score_match.group(1))else:print(f"[重排序] 警告: 无法提取分数,使用相似度分数代替: '{score_text}'")score = result["similarity"] * 10except Exception as e:print(f"[重排序] LLM调用异常: {e},使用相似度分数代替")score = result["similarity"] * 10scored_results.append({"text": result["text"],"metadata": result["metadata"],"similarity": result["similarity"],"relevance_score": score})reranked_results = sorted(scored_results, key=lambda x: x["relevance_score"], reverse=True)print(f"[重排序] 完成,返回Top{top_n}结果\n")return reranked_results[:top_n]# ========== 关键词重排序 ==========
def rerank_with_keywords(query: str, results: List[Dict], top_n: int = 3) -> List[Dict]:"""使用关键词匹配对初步检索结果进行简单重排序。"""print(f"[关键词重排序] 对{len(results)}个文档进行关键词重排序...")keywords = [word.lower() for word in query.split() if len(word) > 3]scored_results = []for result in results:document_text = result["text"].lower()base_score = result["similarity"] * 0.5keyword_score = 0for keyword in keywords:if keyword in document_text:keyword_score += 0.1first_position = document_text.find(keyword)if first_position < len(document_text) / 4:keyword_score += 0.1frequency = document_text.count(keyword)keyword_score += min(0.05 * frequency, 0.2)final_score = base_score + keyword_scorescored_results.append({"text": result["text"],"metadata": result["metadata"],"similarity": result["similarity"],"relevance_score": final_score})reranked_results = sorted(scored_results, key=lambda x: x["relevance_score"], reverse=True)print(f"[关键词重排序] 完成,返回Top{top_n}结果\n")return reranked_results[:top_n]# ========== 回答生成 ==========
def generate_response(query: str, context: str, model: str = LLM_MODEL) -> str:"""用大模型基于上下文生成回答。"""print("[生成] 正在调用大模型生成回答...")system_prompt = "你是一个AI助手,只能基于给定上下文回答问题。如果上下文无法直接回答,请回复:'信息不足,无法回答。'"user_prompt = f"""
上下文:\n{context}\n\n问题:{query}\n\n请只基于上述上下文简明准确作答。"""try:response = Generation.call(model=model,messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}],api_key=ALI_API_KEY,result_format='message')answer = response.output.choices[0].message.content.strip()print(f"[生成] 回答生成成功: {answer}\n")return answerexcept Exception as e:print(f"[生成] 回答生成异常: {e}")return ""# ========== RAG主流程 ==========
def rag_with_reranking(query: str, vector_store: SimpleVectorStore, reranking_method: str = "llm", top_n: int = 3, model: str = LLM_MODEL) -> Dict:"""完整RAG流程,包含初步检索、重排序和回答生成。"""print(f"[RAG] 开始RAG流程,检索+重排序方法: {reranking_method}")query_embedding = create_embeddings(query)initial_results = vector_store.similarity_search(query_embedding, k=10)if reranking_method == "llm":reranked_results = rerank_with_llm(query, initial_results, top_n=top_n)elif reranking_method == "keywords":reranked_results = rerank_with_keywords(query, initial_results, top_n=top_n)else:reranked_results = initial_results[:top_n]context = "\n\n===\n\n".join([result["text"] for result in reranked_results])response = generate_response(query, context, model)print(f"[RAG] 流程完成\n")return {"query": query,"reranking_method": reranking_method,"initial_results": initial_results[:top_n],"reranked_results": reranked_results,"context": context,"response": response}# ========== main方法示例 ==========
if __name__ == "__main__":# 示例PDF路径(请替换为实际文件)pdf_path = "data/2888年Java程序员找工作最新场景题.pdf"# 示例问题query = "Java程序员面试中常见的技术问题有哪些?"print("\n===== RAG重排序增强示例 =====\n")vector_store = process_document(pdf_path)print("[主流程] 向量库已构建,开始不同重排序方法对比...\n")# 1. 标准检索(无重排序)print("\n=== 标准检索(无重排序) ===")standard_results = rag_with_reranking(query, vector_store, reranking_method="none")print(f"\nQuery: {query}")print(f"\nResponse:\n{standard_results['response']}")# 2. LLM重排序print("\n=== LLM重排序 ===")llm_results = rag_with_reranking(query, vector_store, reranking_method="llm")print(f"\nQuery: {query}")print(f"\nResponse:\n{llm_results['response']}")# 3. 关键词重排序print("\n=== 关键词重排序 ===")keyword_results = rag_with_reranking(query, vector_store, reranking_method="keywords")print(f"\nQuery: {query}")print(f"\nResponse:\n{keyword_results['response']}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85655.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85655.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/85655.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 常用注解整理

Spring & Spring Boot 常用注解整理 现代的 Spring 与 Spring Boot 应用大量使用注解来简化配置、管理组件和实现各种框架功能。本文系统整理了常用的 Spring/Spring Boot 注解&#xff0c;按照功能分类进行介绍。每个注解都会涵盖其含义、提供来源、应用场景以及代码示例…

深入理解 Cross-Entropy 损失函数:从原理到实践

在深度学习中&#xff0c;损失函数是衡量模型性能的关键指标之一。对于多分类问题&#xff0c;Cross-Entropy 损失函数 是最常用的选择之一。它不仅能够有效衡量模型输出与真实标签之间的差异&#xff0c;还能通过梯度下降法指导模型的优化。本文将深入探讨 Cross-Entropy 损失…

Vim-vimrc保存文件自动移除行末尾空格

Vim-vimrc保存文件自动移除行末尾空格 这段代码通过设置 autocmd 和自定义函数&#xff0c;确保每次保存文件时都自动删除文件中的行尾空格&#xff0c;同时不会影响光标和视图的位置。它适用于所有文件类型&#xff0c;并且删除操作不会引入错误&#xff0c;即使没有行尾空格的…

Occt几何内核快速入门

本文简单介绍 Open Cascade Technology&#xff08;OCCT&#xff09;&#xff0c;提供了下载地址和文档地址。通过OCCT的测试工具Draw&#xff0c;展示了OCCT的一些功能特性。介绍了OCCT集成开发的演示代码&#xff0c;提供了源代码下载地址和编译过程文件。 一、简介 Open C…

【Docker 08】Compose - 容器编排

&#x1f308; 一、Docker Compose 介绍 ⭐ 1. Docker Compose 是什么 Docker Compose 是由 Docker 官方提供的一个用于定义和运行多容器应用的工具&#xff0c;它让用户可以通过一个 YAML 文件&#xff08;通常是 docker-compose.yml&#xff09;来配置应用所需要的服务&…

CentOS Stream 9平台部署安装MySQL8.4.1

1、在线下载安装包 [rootlocalhost ~]# wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.4.1-1.el9.x86_64.rpm-bundle.tar 2、新建解压文件夹 [rootlocalhost ~]#mkdir /root/sql 3、离线解压安装包安装配置MySQL8 上传安装包到home下 [rootlocalhost ~]#c…

phpstorm无缝切换vscode

要将 PhpStorm 的开发体验无缝迁移到 VS Code&#xff0c;需重点配置插件、快捷键和操作习惯。以下是详细方案&#xff1a; 一、必备插件清单 安装以下插件&#xff08;VS Code 搜索安装&#xff09;&#xff1a; PHP Intelephense&#xff1a;核心插件&#xff08;代码补全、…

雨声_锦程_时年

1 炎凉 飘零于三界。 子铭师傅看了几卷笔记&#xff0c;以为我文笔很好&#xff0c;于是我留在石铭公社。 我每日在公社会议厅&#xff0c;高地吹风&#xff0c;悠然笔记。 我喜欢四处旅行。 穿着鞘翅飞翔&#xff0c;风划过耳边。 我渴求所饮的每一滴水&#xff0c;追忆木履留…

微信小程序使用rsa 加解密

jsencrypt.min.js !function(t,e){"object"typeof exports&&"undefined"!typeof module?e(exports):"function"typeof define&&define.amd?define(["exports"],e):e(t.JSEncrypt{})}(this,function(t){"use s…

2025北邮软件工程复习

文章目录 废话知识点总结Part1 软件工程概述Part2 软件需求分析需求介绍需求描述方法 Part3 软件设计方法软件设计的概念与原则软件设计的方法 Part4 程序实现方法Part5 软件测试方法白盒测试黑盒测试 练习题北邮2021~2022期末考北邮2018期末考 考后总结 废话 update on 4.24&…

《Whisper模型版本及下载链接》

Whisper模型版本及下载链接 Whisper是OpenAI开发的语音识别模型&#xff0c;以下按模型规模从小到大排列&#xff0c;包含不同语言版本及通用版本&#xff1a; 1. Tiny系列&#xff08;轻量级&#xff09; tiny.en.pt&#xff08;英文专用&#xff09;&#xff1a; https://…

AWS-SAA 第二部份:安全性和权限管理

我们来深入讲解第二部分&#xff1a;安全性和权限管理&#xff0c;依然用通俗易懂的语言解释。 核心服务 1&#xff1a;IAM&#xff08;Identity and Access Management&#xff09; 1. IAM 的核心概念 作用&#xff1a; IAM 是 AWS 的“门卫系统”&#xff0c;用来管理谁可以…

Linux 多种方式实现行转列

目录 一. 前提二. xargs 实现行转列三. paste 实现行转列四. sed 实现行转列 一. 前提 ⏹之前在这下面篇文章中使用sed命令实现了行专列&#xff0c;本篇文章再介绍几种更加简单的方式。 Linux sed案例 &#x1f449; 20231126-2.log 110120 SPLREQUEST 内容1 AAA memberID1…

Hadoop HDFS存储机制与块大小选择权衡

一、HDFS块存储机制核心原理 1.1 逻辑块 vs 物理存储 HDFS中的 块大小(block size) 是一个逻辑概念&#xff0c;而非物理预分配&#xff1a; #mermaid-svg-GzNjegjSgYrnlcme {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mer…

Unity Addressable使用之AddressableAssetSettings

AddressableAssetSettings 是 Unity Addressable Assets System 的核心配置文件 配置 Manage Groups 用来打开Addressables Groups窗口 Profiles配置 Profile In Use&#xff1a;可以在这选择使用的是哪一套配置文件Manage Profiles&#xff1a;点击它会打开Addressables Gr…

从“询”到“单”的智能跃迁:工业品电商复杂交易流程引擎的架构之道

当传统企业客户在“询盘-报价-议价-审批-合同-下单-履约”的复杂迷宫中艰难穿行&#xff0c;反复沟通、层层审批、定制条款、手工录入……每一步都暗藏延迟与差错的风险&#xff0c;工业品电商平台也承受着转化率低、运营成本高、客户满意度下滑的阵痛。流程冗长、定制化依赖人…

【软考高级系统架构论文】论模型驱动架构设计方法及其应用

论文真题 模型驱动架构设计是一种用于应用系统开发的软件设计方法,以模型构造、模型转换和精化为核心,提供了一套软件设计的指导规范。在模型驱动架构环境下,通过创建出机器可读和高度抽象的模型实现对不同问题域的描述,这些模型独立于实现技术,以标准化的方式储存,利用…

【入门】【例18.2】 孔融让梨

| 时间限制&#xff1a;C/C 1000MS&#xff0c;其他语言 2000MS 内存限制&#xff1a;C/C 64MB&#xff0c;其他语言 128MB 难度&#xff1a;中等 分数&#xff1a;100 OI排行榜得分&#xff1a;12(0.1分数2难度) 出题人&#xff1a;root | 描述 孔融小时候聪明好学&#xff0…

【nature review】原子尺度上光与物质的相互作用

2021 年 6 月,马普固态研究所 Rico Gutzler 等人在《Nature Reviews Physics》期刊发表了题为《Light–matter interaction at atomic scales》的文章,基于扫描隧道显微镜(STM)与光子学结合的方法,研究了光与物质在原子尺度上的相互作用,实验和仿真结果表明光可通过多种机…

7.3.3_1红黑树的定义和性质

知识总览&#xff1a; 为什么要发明红黑树&#xff1a; 二叉排序树BST 红黑树RBT的查找、插入和删除效率基本和AVL平衡二叉树的相同&#xff0c;但是平衡二叉树在插入和删除节点操作时容易被破坏平衡&#xff0c;所以需要消耗大量时间重新调整树的形态(主要时间用在计算平衡因…