RAG_AIEXP_01 / index_retriever.py
MrSimple07's picture
added the load_table_data function
f9e7c0c
Raw
History Blame
3.15 kB
from llama_index.core import VectorStoreIndex, Settings
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.response_synthesizers import get_response_synthesizer, ResponseMode
from llama_index.core.prompts import PromptTemplate
from llama_index.retrievers.bm25 import BM25Retriever
from llama_index.core.retrievers import QueryFusionRetriever
from my_logging import log_message
from config import CUSTOM_PROMPT, PROMPT_SIMPLE_POISK
def create_vector_index(documents):
log_message("Строю векторный индекс")
return VectorStoreIndex.from_documents(documents)
def create_query_engine(vector_index):
bm25_retriever = BM25Retriever.from_defaults(
docstore=vector_index.docstore,
similarity_top_k=80
)
vector_retriever = VectorIndexRetriever(
index=vector_index,
similarity_top_k=80,
similarity_cutoff=0.45
)
hybrid_retriever = QueryFusionRetriever(
[vector_retriever, bm25_retriever],
similarity_top_k=100,
num_queries=1
)
custom_prompt_template = PromptTemplate(PROMPT_SIMPLE_POISK)
response_synthesizer = get_response_synthesizer(
response_mode=ResponseMode.TREE_SUMMARIZE,
text_qa_template=custom_prompt_template
)
query_engine = RetrieverQueryEngine(
retriever=hybrid_retriever,
response_synthesizer=response_synthesizer
)
return query_engine
def rerank_nodes(query, nodes, reranker, top_k=40, min_score_threshold=0.35, diversity_penalty=0.15):
if not nodes or not reranker:
return nodes[:top_k]
pairs = [[query, node.text] for node in nodes]
scores = reranker.predict(pairs)
scored_nodes = list(zip(nodes, scores))
scored_nodes.sort(key=lambda x: x[1], reverse=True)
if min_score_threshold:
scored_nodes = [(node, score) for node, score in scored_nodes
if score >= min_score_threshold]
if not scored_nodes:
scored_nodes = list(zip(nodes, scores))
scored_nodes.sort(key=lambda x: x[1], reverse=True)
scored_nodes = scored_nodes[:top_k]
selected = []
seen_docs = {}
for node, score in scored_nodes:
if len(selected) >= top_k:
break
meta = node.metadata if hasattr(node, 'metadata') else {}
doc_id = meta.get('document_id', 'unknown')
node_type = meta.get('type', 'text')
table_num = meta.get('table_number', '')
key = f"{doc_id}_{table_num}" if node_type == 'table' else f"{doc_id}_{meta.get('section_id', '')}"
if key in seen_docs:
penalty = diversity_penalty * 0.2 if node_type == 'table' else diversity_penalty
adjusted_score = score * (1 - penalty)
else:
adjusted_score = score
seen_docs[key] = 1
if not selected or adjusted_score >= selected[0][1] * 0.4:
selected.append((node, score))
return [node for node, score in selected]