|
| 1 | +from langchain_core.output_parsers import StrOutputParser |
| 2 | +from langchain.chains.hyde.base import HypotheticalDocumentEmbedder |
| 3 | +from langchain.prompts import PromptTemplate |
| 4 | +from langchain_qdrant import QdrantVectorStore |
| 5 | +from langchain_community.document_loaders import PyMuPDFLoader |
| 6 | +from langchain_ollama import OllamaEmbeddings, ChatOllama |
| 7 | +from langchain_text_splitters import RecursiveCharacterTextSplitter |
| 8 | +from langchain_core.prompts import ChatPromptTemplate |
| 9 | +from langchain_core.runnables import RunnablePassthrough |
| 10 | +from qdrant_client.http.models import Distance, VectorParams |
| 11 | +import qdrant_client |
| 12 | + |
| 13 | + |
| 14 | +class RetrievalAugmentationGenerationUsingHyDE: |
| 15 | + def __init__(self, file_path, collection_name, vector_name, prompt_template, llm_model, embedding_model, qdrant_url, |
| 16 | + qdrant_api_key, base_url): |
| 17 | + self.file_path = file_path |
| 18 | + self.collection_name = collection_name |
| 19 | + self.vector_name = vector_name |
| 20 | + self.prompt_template = prompt_template |
| 21 | + self.qdrant_url = qdrant_url |
| 22 | + self.qdrant_api_key = qdrant_api_key |
| 23 | + self.llm = ChatOllama(model=llm_model, temperature=0.2, base_url=base_url) |
| 24 | + self.base_embeddings = OllamaEmbeddings(model=embedding_model) |
| 25 | + self.client = qdrant_client.QdrantClient(url=qdrant_url, api_key=qdrant_api_key) |
| 26 | + self.vector_store = None |
| 27 | + |
| 28 | + def load_documents(self): |
| 29 | + loader = PyMuPDFLoader(file_path=self.file_path) |
| 30 | + text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder( |
| 31 | + chunk_size=200, chunk_overlap=30 |
| 32 | + ) |
| 33 | + return loader.load_and_split(text_splitter=text_splitter) |
| 34 | + |
| 35 | + def get_embeddings(self): |
| 36 | + prompt = PromptTemplate(input_variables=["question"], template=self.prompt_template) |
| 37 | + llm_chain = self.llm | prompt |
| 38 | + return HypotheticalDocumentEmbedder( |
| 39 | + llm_chain=llm_chain, |
| 40 | + base_embeddings=self.base_embeddings |
| 41 | + ).from_llm(llm=self.llm, base_embeddings=self.base_embeddings, prompt_key="web_search") |
| 42 | + |
| 43 | + def setup_qdrant_collection(self, embeddings, documents): |
| 44 | + if not self.client.collection_exists(collection_name=self.collection_name): |
| 45 | + self.client.create_collection( |
| 46 | + collection_name=self.collection_name, |
| 47 | + vectors_config={ |
| 48 | + "content": VectorParams(size=384, distance=Distance.COSINE) |
| 49 | + } |
| 50 | + ) |
| 51 | + self.vector_store = QdrantVectorStore( |
| 52 | + client=self.client, |
| 53 | + collection_name=self.collection_name, |
| 54 | + embedding=embeddings, |
| 55 | + vector_name=self.vector_name |
| 56 | + ) |
| 57 | + self.vector_store.add_documents(documents=documents) |
| 58 | + else: |
| 59 | + self.vector_store = QdrantVectorStore.from_existing_collection( |
| 60 | + collection_name=self.collection_name, |
| 61 | + url=self.qdrant_url, |
| 62 | + api_key=self.qdrant_api_key, |
| 63 | + vector_name=self.vector_name, |
| 64 | + embedding=embeddings |
| 65 | + ) |
| 66 | + |
| 67 | + def execute_pipeline(self, user_query): |
| 68 | + retriever = self.vector_store.as_retriever( |
| 69 | + search_type="similarity_score_threshold", |
| 70 | + search_kwargs={'score_threshold': 0.8} |
| 71 | + ) |
| 72 | + prompt = ChatPromptTemplate.from_template(self.prompt_template) |
| 73 | + chain = ( |
| 74 | + {"context": retriever, "question": RunnablePassthrough()} |
| 75 | + | prompt |
| 76 | + | self.llm |
| 77 | + | StrOutputParser() |
| 78 | + ) |
| 79 | + return chain.invoke(user_query) |
| 80 | + |
| 81 | + |
| 82 | + |
0 commit comments