基礎RAG實現,最佳入門選擇(八)

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;所以需要消耗大量時間重新調整樹的形態(主要時間用在計算平衡因…