| import google.generativeai as genai |
| from qdrant_client import QdrantClient |
| from groq import Groq |
| from src.core.config import settings |
|
|
| |
| EMBEDDING_MODEL = 'models/gemini-embedding-001' |
| GROQ_MODEL = "llama-3.3-70b-versatile" |
| COLLECTION_NAME = "textbook_content" |
|
|
| class RAGService: |
| """ |
| A service to handle the Retrieval-Augmented Generation pipeline. |
| """ |
| def __init__(self): |
| """ |
| Initializes the RAG service, configuring API clients. |
| """ |
| try: |
| |
| genai.configure(api_key=settings.GEMINI_API_KEY) |
| |
| |
| self.groq_client = Groq( |
| api_key=settings.GROQ_API_KEY, |
| ) |
| |
| self.qdrant_client = QdrantClient(url=settings.QDRANT_URL, api_key=settings.QDRANT_API_KEY) |
| print("RAGService initialized successfully with Groq for generation.") |
| except Exception as e: |
| print(f"Error initializing RAGService: {e}") |
| |
| raise |
|
|
| def get_answer(self, question: str, highlighted_text: str = None) -> str: |
| """ |
| Generates an answer to a question using a RAG pipeline. |
| |
| Args: |
| question: The user's question. |
| highlighted_text: Optional context from text selected by the user. |
| |
| Returns: |
| A generated answer based on the retrieved context. |
| """ |
| if not question: |
| return "Please provide a question." |
|
|
| print(f"Received question: {question}") |
| print(f"Highlighted context: {highlighted_text}") |
|
|
| |
| query_text = f"{highlighted_text}. {question}" if highlighted_text else question |
| try: |
| response = genai.embed_content( |
| model=EMBEDDING_MODEL, |
| content=query_text, |
| task_type="retrieval_query" |
| ) |
| query_embedding = response['embedding'] |
| except Exception as e: |
| print(f"Error generating embedding with Gemini: {e}") |
| return "Sorry, I couldn't process your question at the moment." |
|
|
| |
| try: |
| query_response = self.qdrant_client.query_points( |
| collection_name=COLLECTION_NAME, |
| query=query_embedding, |
| limit=5, |
| ) |
| retrieved_chunks = [result.payload['text'] for result in query_response.points] |
| context_for_prompt = "\n---\ |
| ".join(retrieved_chunks) |
| |
| if not context_for_prompt: |
| print("No relevant context found in the database.") |
| context_for_prompt = "No specific context found." |
|
|
| except Exception as e: |
| print(f"Error querying Qdrant: {e}") |
| return "Sorry, I had trouble searching my knowledge base." |
|
|
| |
| prompt = f""" |
| You are an expert assistant for a textbook on Physical AI and Humanoid Robotics. |
| Your task is to answer the user's question based *only* on the provided context below. |
| If the context does not contain the answer, state that you cannot answer based on the provided information. |
| Do not use any external knowledge. |
| |
| **Provided Context:** |
| --- |
| {context_for_prompt} |
| --- |
| |
| **User's Question:** |
| {question} |
| |
| **Answer:** |
| """ |
|
|
| try: |
| completion = self.groq_client.chat.completions.create( |
| model=GROQ_MODEL, |
| messages=[ |
| {"role": "system", "content": "You are a helpful assistant that answers questions based on provided context."}, |
| {"role": "user", "content": prompt}, |
| ], |
| ) |
| print("Successfully generated answer from Groq.") |
| return completion.choices[0].message.content |
| except Exception as e: |
| print(f"Error generating answer with Groq: {e}") |
| return "Sorry, I was unable to generate an answer." |
|
|
| |
| rag_service = RAGService() |
|
|
|
|