{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ๐ RAG Olympics - Building an AI-Powered Q&A System!\n", "\n", "## ๐ฏ Welcome to the RAG Challenge!\n", "\n", "In this hands-on project, you'll build a **Retrieval-Augmented Generation (RAG)** system that can answer questions about the Olympics!\n", "\n", "---\n", "\n", "### ๐ค What is RAG?\n", "\n", "**RAG = Retrieval + Generation**\n", "\n", "Think of it like having a super-smart assistant with access to a library:\n", "\n", "```\n", "User Question โ ๐ Find Relevant Documents โ ๐ค LLM Generates Answer\n", "```\n", "\n", "**The Magic:** Instead of relying only on the LLM's training data, we give it **real-time access to specific information**!\n", "\n", "---\n", "\n", "### ๐ What You'll Learn:\n", "\n", "| Step | What | Why |\n", "|------|------|-----|\n", "| 1๏ธโฃ | **Load Data** | Get Olympics FAQ documents |\n", "| 2๏ธโฃ | **Create Embeddings** | Convert text to vectors |\n", "| 3๏ธโฃ | **Build Vector DB** | Store for fast similarity search |\n", "| 4๏ธโฃ | **Retrieval** | Find relevant documents |\n", "| 5๏ธโฃ | **Prompt Engineering** | Craft effective prompts |\n", "| 6๏ธโฃ | **Generate Answers** | Use LLM with context |\n", "\n", "---\n", "\n", "### ๐ Why RAG is useful ?\n", "\n", "โ **Up-to-date info:** Add new knowledge without retraining \n", "โ **Grounded answers:** Responses based on your documents \n", "โ **Reduced hallucinations:** LLM has concrete context \n", "โ **Transparent sources:** Can cite which documents were used \n", "โ **Cost-effective:** No need to fine-tune large models \n", "\n", "---\n", "\n", "### ๐๏ธ System Architecture:\n", "\n", "```\n", "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n", "โ RAG PIPELINE โ\n", "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค\n", "โ โ\n", "โ 1. INDEXING PHASE (One-time setup) โ\n", "โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ\n", "โ โ Documentsโ -> โEmbeddingsโ -> โ Vector DBโ โ\n", "โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โ\n", "โ โ\n", "โ 2. QUERY PHASE (Real-time) โ\n", "โ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโ โ\n", "โ โ Questionโ ->โ Search DBโ ->โ Context โ ->โ LLM โ โ\n", "โ โโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโ โ\n", "โ โ โ\n", "โ โโโโโโโโโโโ\n", "โ โ Answer โโ\n", "โ โโโโโโโโโโโ\n", "โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n", "```\n", "\n", "Let's build it! ๐" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ Step 1: Loading the Olympics FAQ Data\n", "\n", "We'll work with a JSON file containing frequently asked questions about the Olympics.\n", "\n", "### ๐ Data Structure:\n", "\n", "```json\n", "[\n", " {\n", " \"id\": \"OnlOaClN-fr\",\n", " \"lang\": \"fr\",\n", " \"label\": \"Comment acheter des billets pour...\",\n", " \"body\": \"Des billets pour les Jeux Olympiques...\",\n", " \"topics\": \"Billetterie et Hospitalitรฉ...\", \n", " \"url\": \"https://help.paris2024.org/contents...\"\n", " },\n", " ...\n", "]\n", "```\n", "\n", "Let's load and explore the data!" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "โ Loaded 952 FAQ entries!\n", "\n" ] } ], "source": [ "# Load the FAQ data\n", "import json\n", "from pathlib import Path\n", "\n", "# Get the notebook's directory\n", "notebook_dir = Path.cwd()\n", "data_path = notebook_dir / \"data\" / \"paris-2024-faq.json\"\n", "with Path(data_path).open() as f:\n", " faq_data = json.load(f)\n", "\n", "print(f\"โ Loaded {len(faq_data)} FAQ entries!\\n\")\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'id': '-Bgz0H-g-fr',\n", " 'lang': 'fr',\n", " 'label': 'Existe-t-il des places spรฉcifiques pour les personnes avec un handicap mental/neurologique/psychique ?',\n", " 'body': \"Les personnes avec un handicap mental, neurologique ou psychologique peuvent bรฉnรฉficier des places rรฉservรฉes pour les personnes en situation de handicap qui sont faciles d'accรจs sur prรฉsentation d'une carte d'invaliditรฉ ou d'un รฉquivalent.\\n\\nTous les volontaires seront sensibilisรฉs au handicap mental, neurologique et psychique afin de garantir la meilleure expรฉrience et le meilleur accueil possible.\",\n", " 'topics': 'Spectateurs ;Accessibilitรฉ;Accรจs / services sur site',\n", " 'url': 'https://help.paris2024.org/contents/Existe-t-il-des-places-specifiques-pour-les-personnes-avec-un-handicap-mental-neurologique-psychique--Bgz0H-g'}" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Display first entry\n", "faq_data[0]\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# Filter to keep only English documents\n", "faq_data_en = [item for item in faq_data if item[\"lang\"] == \"en\"]\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ Sample FAQ Entries:\n", "\n", "1. Q: How often will the toilets at the competition venues be cleaned?\n", " A: The toilets will be cleaned regularly during each session....\n", "\n", "2. Q: How do you apply to carry the Flame?\n", " A: The public campaigns for torchbearers have all concluded.\n", "\n", "\n", "\n", "For more information, please visit:\n", "\n", "ht...\n", "\n", "3. Q: Combien y a-t-il de volontaires ?\n", " A: The deadline for applying to the Paris 2024 volunteering programme has already passed.\n", "\n", "However, the...\n", "\n", "๐ก Total entries: 478\n" ] } ], "source": [ "# Display sample entries\n", "print(\"๐ Sample FAQ Entries:\\n\")\n", "for i, entry in enumerate(faq_data_en[:3], 1):\n", " print(f\"{i}. Q: {entry['label']}\")\n", " print(f\" A: {entry['body'][:100]}...\\n\")\n", "\n", "print(f\"๐ก Total entries: {len(faq_data_en)}\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ Step 2: Preprocessing - Creating LangChain Documents\n", "\n", "### Why Create Documents?\n", "\n", "LangChain uses a special `Document` object that:\n", "- ๐ Stores the text content\n", "- ๐ท๏ธ Includes metadata (source, category, etc.)\n", "- ๐ Works seamlessly with vector stores\n", "\n", "First get familiar with this object" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "page_content='Hello, world!' metadata={'source': 'https://example.com'}\n" ] } ], "source": [ "from langchain_core.documents import Document\n", "\n", "# The LangChain Document object contains 2 attributes:\n", "# - a page_content attribute: stores the main text content\n", "# - a metadata attribute: stores additional information about the document\n", "\n", "\n", "# Creating a sample Document object\n", "document = Document(\n", " page_content=\"Hello, world!\", metadata={\"source\": \"https://example.com\"},\n", ")\n", "\n", "# Display the document\n", "print(document)\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Hello, world!'" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "document.page_content\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'source': 'https://example.com'}" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "document.metadata\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Our Strategy:\n", "\n", "We'll combine each Q&A pair into a single document:\n", "```\n", "\"Question: [question]\\nAnswer: [answer]\"\n", "```\n", "\n", "This helps the retrieval system find relevant Q&A pairs based on user questions!" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ Creating LangChain Document objects...\n", "\n", "โ Created 478 Document objects!\n", "\n", "๐ Example Document Structure:\n", "\n", "Content (first 200 chars):\n", "Question: How often will the toilets at the competition venues be cleaned?\n", "Answer: The toilets will be cleaned regularly during each session....\n", "\n", "Metadata:\n", "{'source': 'Olympics FAQ', 'faq_id': 'OnlBYpRa-en', 'question': 'How often will the toilets at the competition venues be cleaned?', 'answer': 'The toilets will be cleaned regularly during each session.', 'topics': 'Other;Environmental commitments;Waste management', 'url': 'https://help.paris2024.org/en-gb/contents/How-often-will-the-toilets-at-the-competition-venues-be-cleaned-OnlBYpRa'}\n", "\n", "๐ก These documents are now ready for embedding!\n" ] } ], "source": [ "print(\"๐ Creating LangChain Document objects...\\n\")\n", "\n", "# Convert FAQ entries to LangChain Documents\n", "documents = []\n", "\n", "for entry in faq_data_en:\n", " # Combine question and answer into one document\n", " content = f\"Question: {entry['label']}\\nAnswer: {entry['body']}\"\n", "\n", " # Create Document with metadata\n", " doc = Document(\n", " page_content=content,\n", " metadata={\n", " \"source\": \"Olympics FAQ\",\n", " \"faq_id\": entry[\"id\"],\n", " \"question\": entry[\"label\"],\n", " \"answer\": entry[\"body\"],\n", " \"topics\": entry[\"topics\"],\n", " \"url\": entry[\"url\"],\n", " },\n", " )\n", "\n", " documents.append(doc)\n", "\n", "print(f\"โ Created {len(documents)} Document objects!\\n\")\n", "\n", "# Show an example document\n", "print(\"๐ Example Document Structure:\\n\")\n", "print(f\"Content (first 200 chars):\\n{documents[0].page_content[:200]}...\\n\")\n", "print(f\"Metadata:\\n{documents[0].metadata}\")\n", "\n", "print(\"\\n๐ก These documents are now ready for embedding!\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ง Step 4: Creating the Vector Database\n", "\n", "This is where the magic happens! We'll:\n", "1. Convert documents to embeddings (vectors)\n", "2. Store them in a Qdrant vector database\n", "3. Enable lightning-fast similarity search\n", "\n", "---\n", "\n", "### ๐ฏ What is Qdrant?\n", "\n", "**Qdrant** (read: quadrant) is a vector similarity search engine and database:\n", "- โก **Fast:** High-performance search with advanced filtering capabilities\n", "- ๐ช **Powerful:** Production-ready with built-in scalability and clustering\n", "- ๐จ **Flexible:** Supports payloads, filtering, and multiple distance metrics\n", "- ๐ **Open Source:** Free to use with both in-memory and persistent storage options\n", "- ๐ณ **Cloud-Native:** Easy deployment with Docker, Kubernetes, or managed cloud service\n", "- ๐ **Versatile Deployment:**\n", " - **In-Memory:** Perfect for development and testing\n", " - **Docker:** Quick local setup with containerization\n", " - **Local:** Run natively on your machine for production\n", " - **Cloud:** Managed service (Qdrant Cloud) for scalability\n", "\n", "---\n", "\n", "### ๐ค Embedding Model:\n", "\n", "We'll use **mistral-embed** (Mistral AI):\n", "- ๐ 1024-dimensional vectors\n", "- Max input: 8192 tokens\n", "- โก Fast encoding speed\n", "- ๐ฏ Great for semantic search\n", "- ๐ Works well in multiple languages\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.\n" ] } ], "source": [ "import os\n", "\n", "os.environ[\"MISTRAL_API_KEY\"] = \"YvbkD5LcIf4GJOiEA1xkjr7ZEjUtZjxN\"\n", "\n", "\n", "# Initialize the embedding model\n", "from langchain_mistralai import MistralAIEmbeddings\n", "\n", "embeddings = MistralAIEmbeddings(\n", " model=\"mistral-embed\",\n", ")\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "from langchain_qdrant import QdrantVectorStore\n", "from qdrant_client import QdrantClient\n", "from qdrant_client.http.models import Distance, VectorParams\n", "\n", "# client = QdrantClient(path=local_output)\n", "# In memory client:\n", "COLLECTION_NAME = \"olympics-2024\"\n", "# VECTOR_NAME = \"sparse-embedding\" # this is to asspciate a name with the embedding\n", "EMBEDDING_SIZE = len(embeddings.embed_query(\"hello\"))\n", "\n", "# instanciate the in memory client\n", "client = QdrantClient(\":memory:\")\n", "client.create_collection(\n", " collection_name=COLLECTION_NAME,\n", " vectors_config=VectorParams(size=EMBEDDING_SIZE, distance=Distance.COSINE),\n", ")\n", "\n", "vector_store = QdrantVectorStore(\n", " client=client,\n", " embedding=embeddings,\n", " collection_name=COLLECTION_NAME,\n", ")\n", "\n", "# See documentation https://reference.langchain.com/python/integrations/langchain_qdrant/\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "============================================================\n", "๐ก What just happened:\n", " 1. Each document was converted to a 1024D vector\n", " 2. Vectors were indexed in Qdrant for fast search\n", " 3. Now we can find similar documents!\n" ] } ], "source": [ "from uuid import uuid4\n", "\n", "ids = [str(uuid4()) for _ in range(len(documents))]\n", "vector_store.add_documents(documents=documents, ids=ids)\n", "\n", "\n", "print(\"\\n\" + \"=\" * 60)\n", "print(\"๐ก What just happened:\")\n", "print(\" 1. Each document was converted to a 1024D vector\")\n", "print(\" 2. Vectors were indexed in Qdrant for fast search\")\n", "print(\" 3. Now we can find similar documents!\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ Step 5: Testing the Retrieval System\n", "\n", "Let's test our vector database by searching for relevant documents!\n", "\n", "### How Retrieval Works:\n", "\n", "```\n", "User Query โ Embed Query โ Find Similar Vectors โ Return Documents\n", "```\n", "\n", "The system uses **cosine similarity** to find the most relevant documents!" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ Testing the Retrieval System\n", "\n", "============================================================\n", "โ User Query: 'How do I get disabled parking spaces?'\n", "\n" ] } ], "source": [ "print(\"๐ Testing the Retrieval System\\n\")\n", "print(\"=\" * 60)\n", "\n", "# Test query\n", "test_query = \"How do I get disabled parking spaces?\"\n", "\n", "print(f\"โ User Query: '{test_query}'\\n\")\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "โ Found 3 relevant documents!\n", "\n", "๐ Retrieved Documents:\n", "\n", "============================================================\n", "Document 1:\n", "============================================================\n", "Content:\n", "Question: Are parking spaces reserved for individuals with disabilities available on-site?\n", "Answer: Each site will have a limited number of parking spaces reserved for wheelchair users.\n", "\n", "Holders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\n", "\n", "\n", "\n", "For countries not issuing either of these two cards, any other official document justifying a disability will be accepted.\n", "\n", "============================================================\n", "Document 2:\n", "============================================================\n", "Content:\n", "Question: What documentary evidence do visitors with disabilities from abroad need?\n", "Answer: Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\n", "\n", "This documentation can be a European parking card or a mobility inclusion card.\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n", "\n", "\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n", "\n", "============================================================\n", "Document 3:\n", "============================================================\n", "Content:\n", "Question: Are there any specific spaces for individuals with mental/neurological/psychological disabilities?\n", "Answer: Individuals with mental, neurological, or psychological disabilities can access reserved spots for people with disabilities that are easily accessible upon presentation of a disability card or equivalent.\n", "\n", "All volunteers will receive training on mental, neurological, and psychological disabilities to ensure the best possible experience and welcome.\n", "\n" ] } ], "source": [ "# Retrieve top 3 most relevant documents\n", "retrieved_docs = vector_store.similarity_search(\n", " query=test_query, k=3, # Return top 3 matches\n", ")\n", "\n", "print(f\"โ Found {len(retrieved_docs)} relevant documents!\\n\")\n", "print(\"๐ Retrieved Documents:\\n\")\n", "\n", "for i, doc in enumerate(retrieved_docs, 1):\n", " print(f\"{'='*60}\")\n", " print(f\"Document {i}:\")\n", " print(f\"{'='*60}\")\n", " print(f\"Content:\\n{doc.page_content}\\n\")\n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'OnlmLzuE-en', 'question': 'Are parking spaces reserved for individuals with disabilities available on-site?', 'answer': 'Each site will have a limited number of parking spaces reserved for wheelchair users.\\n\\nHolders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\\n\\n\\n\\nFor countries not issuing either of these two cards, any other official document justifying a disability will be accepted.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/Are-parking-spaces-reserved-for-individuals-with-disabilities-available-on-site-OnlmLzuE', '_id': 'be6db04a-2902-4ccd-bc29-d2f0d010fff4', '_collection_name': 'olympics-2024'}, page_content='Question: Are parking spaces reserved for individuals with disabilities available on-site?\\nAnswer: Each site will have a limited number of parking spaces reserved for wheelchair users.\\n\\nHolders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\\n\\n\\n\\nFor countries not issuing either of these two cards, any other official document justifying a disability will be accepted.'),\n", " 0.8989433697194552),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'OnllTAmy-en', 'question': 'What documentary evidence do visitors with disabilities from abroad need?', 'answer': 'Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\\n\\nThis documentation can be a European parking card or a mobility inclusion card.\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\\n\\n\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/What-documentary-evidence-do-visitors-with-disabilities-from-abroad-need-OnllTAmy', '_id': 'af36d08e-9cc3-49d2-81e3-d0e15a6825f9', '_collection_name': 'olympics-2024'}, page_content='Question: What documentary evidence do visitors with disabilities from abroad need?\\nAnswer: Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\\n\\nThis documentation can be a European parking card or a mobility inclusion card.\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\\n\\n\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.'),\n", " 0.8880006763829658),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': '-Bgz0H-g-en', 'question': 'Are there any specific spaces for individuals with mental/neurological/psychological disabilities?', 'answer': 'Individuals with mental, neurological, or psychological disabilities can access reserved spots for people with disabilities that are easily accessible upon presentation of a disability card or equivalent.\\n\\nAll volunteers will receive training on mental, neurological, and psychological disabilities to ensure the best possible experience and welcome.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/Are-there-any-specific-spaces-for-individuals-with-mental-neurological-psychological-disabilities--Bgz0H-g', '_id': 'd0248842-155d-4875-a1a2-baaac8e30a27', '_collection_name': 'olympics-2024'}, page_content='Question: Are there any specific spaces for individuals with mental/neurological/psychological disabilities?\\nAnswer: Individuals with mental, neurological, or psychological disabilities can access reserved spots for people with disabilities that are easily accessible upon presentation of a disability card or equivalent.\\n\\nAll volunteers will receive training on mental, neurological, and psychological disabilities to ensure the best possible experience and welcome.'),\n", " 0.8761557912533754)]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# TODO: Try to Enhance retrieval quality\n", "# - Find a way to Retrieve cosine similarity scores [hint: there is a method called \"similarity_search_with_relevance_scores]\n", "# - Experiment with higher k values to return more candidate documents. But remember the more k is high the more\n", "# - you'll have a big system prompt on the next step (generation)\n", "similarity_scores = vector_store.similarity_search_with_relevance_scores(\n", " query=test_query, k=3, # Return top 3 matches\n", ")\n", "similarity_scores\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "Now that we can get similarity scores, notice that even unrelated queries return results.\n", "Can you find a way to filter out results that are too dissimilar from the query?\n", "\n", "Example:\n", "Query: \"How to become an AI Engineer?\"" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(Document(metadata={'source': 'Olympics FAQ', 'faq_id': '3KjcmsfM-en', 'question': 'What are the planned works for the area around the Grand Palais, Pont Alexandre III, and Les Invalides in preparation for the Paris 2024 Olympic and Paralympic Games?', 'answer': 'The schedule for the temporary installations of Paris 2024 in the area of the Grand Palais, Pont Alexandre III, and Les Invalides runs from April to October 2024.\\n\\n\\n\\n * Mid-April: Start of assembly on the southeast lawns of Les Invalides.\\n\\n * From mid-April to mid-June: Progressive expansion of the construction site across all the lawns of Les Invalides and on Avenue du Marรฉchal Gallieni; closure of Cours la Reine between Pont Alexandre III and Les Invalides from April 26 onwards and occupation of Pont Alexandre III and the nearby lower quays from May 17 onwards.\\n\\n * From September to late October: Gradual release of the Champ-de-Mars.\\n\\n\\n\\nFor more information on the assembly and dismantling of the sites:\\n\\nhttps://www.paris2024.org/fr/Montage-Demontage-Sites/%EF%BF%BC', 'topics': 'Spectators;Competition venues', 'url': 'https://help.paris2024.org/en-gb/contents/What-are-the-planned-works-for-the-area-around-the-Grand-Palais-Pont-Alexandre-III-and-Les-Invalides-in-preparation-for-the-Paris-2024-Olympic-and-Paralympic-Games-3KjcmsfM', '_id': '6c3feb47-3d53-4fcb-b9aa-463367fb5e8c', '_collection_name': 'olympics-2024'}, page_content='Question: What are the planned works for the area around the Grand Palais, Pont Alexandre III, and Les Invalides in preparation for the Paris 2024 Olympic and Paralympic Games?\\nAnswer: The schedule for the temporary installations of Paris 2024 in the area of the Grand Palais, Pont Alexandre III, and Les Invalides runs from April to October 2024.\\n\\n\\n\\n * Mid-April: Start of assembly on the southeast lawns of Les Invalides.\\n\\n * From mid-April to mid-June: Progressive expansion of the construction site across all the lawns of Les Invalides and on Avenue du Marรฉchal Gallieni; closure of Cours la Reine between Pont Alexandre III and Les Invalides from April 26 onwards and occupation of Pont Alexandre III and the nearby lower quays from May 17 onwards.\\n\\n * From September to late October: Gradual release of the Champ-de-Mars.\\n\\n\\n\\nFor more information on the assembly and dismantling of the sites:\\n\\nhttps://www.paris2024.org/fr/Montage-Demontage-Sites/%EF%BF%BC'),\n", " 0.8400907480550941),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'v-ZwbOWG-en', 'question': 'What are the objectives of the endowment Fund?', 'answer': 'The Paris 2024 endowment Fund is a platform for social innovation through sports with three main objectives:\\n\\n * Inspire and identify projects with high potential for social innovation through sports\\n\\n * Support project leaders (sports organizations, communities, associations) in the design, implementation, and impact evaluation of these projects\\n\\n * Promote and publicize these projects to encourage their replication', 'topics': 'Other;Impact 2024', 'url': 'https://help.paris2024.org/en-gb/contents/What-are-the-objectives-of-the-endowment-Fund-v-ZwbOWG', '_id': '706433f3-76a8-4252-88a7-26b3c64eeb1f', '_collection_name': 'olympics-2024'}, page_content='Question: What are the objectives of the endowment Fund?\\nAnswer: The Paris 2024 endowment Fund is a platform for social innovation through sports with three main objectives:\\n\\n * Inspire and identify projects with high potential for social innovation through sports\\n\\n * Support project leaders (sports organizations, communities, associations) in the design, implementation, and impact evaluation of these projects\\n\\n * Promote and publicize these projects to encourage their replication'),\n", " 0.8396205061244493),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'OngwUizS-en', 'question': 'Why create an account on the Gรฉnรฉration 2024 platform?', 'answer': 'Once you have created an account on the Gรฉnรฉration 2024 platform:\\n\\n\\n\\n * You will receive all the latest news via the quarterly newsletter\\n\\n * You will have exclusive access to educational resources such as Escape Games, films, colouring books, etc.\\n\\n\\n\\nFor more information, please visit:\\n\\nhttps://generation.paris2024.org/', 'topics': 'Education;Platform Generation 2024', 'url': 'https://help.paris2024.org/en-gb/contents/Why-create-an-account-on-the-Generation-2024-platform-OngwUizS', '_id': '9e124dde-3f7d-4419-b18d-b85ede16099c', '_collection_name': 'olympics-2024'}, page_content='Question: Why create an account on the Gรฉnรฉration 2024 platform?\\nAnswer: Once you have created an account on the Gรฉnรฉration 2024 platform:\\n\\n\\n\\n * You will receive all the latest news via the quarterly newsletter\\n\\n * You will have exclusive access to educational resources such as Escape Games, films, colouring books, etc.\\n\\n\\n\\nFor more information, please visit:\\n\\nhttps://generation.paris2024.org/'),\n", " 0.8395605827531454)]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# TODO: - Implement something to filter low-relevance results\n", "# Use the following query:\n", "query = \"Why did Napoleon Bonaparte invade Egypt ?\"\n", "similarity_scores = vector_store.similarity_search_with_relevance_scores(\n", " query=query, k=3, # Return top 3 matches\n", ")\n", "similarity_scores\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "Now verify that with this new configuration, it does not filter out also relevant results\n", "retest now with the test_query= \"How do I get disabled parking spaces?\"" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'OnlmLzuE-en', 'question': 'Are parking spaces reserved for individuals with disabilities available on-site?', 'answer': 'Each site will have a limited number of parking spaces reserved for wheelchair users.\\n\\nHolders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\\n\\n\\n\\nFor countries not issuing either of these two cards, any other official document justifying a disability will be accepted.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/Are-parking-spaces-reserved-for-individuals-with-disabilities-available-on-site-OnlmLzuE', '_id': 'be6db04a-2902-4ccd-bc29-d2f0d010fff4', '_collection_name': 'olympics-2024'}, page_content='Question: Are parking spaces reserved for individuals with disabilities available on-site?\\nAnswer: Each site will have a limited number of parking spaces reserved for wheelchair users.\\n\\nHolders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\\n\\n\\n\\nFor countries not issuing either of these two cards, any other official document justifying a disability will be accepted.'),\n", " 0.8989433697194552),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': 'OnllTAmy-en', 'question': 'What documentary evidence do visitors with disabilities from abroad need?', 'answer': 'Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\\n\\nThis documentation can be a European parking card or a mobility inclusion card.\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\\n\\n\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/What-documentary-evidence-do-visitors-with-disabilities-from-abroad-need-OnllTAmy', '_id': 'af36d08e-9cc3-49d2-81e3-d0e15a6825f9', '_collection_name': 'olympics-2024'}, page_content='Question: What documentary evidence do visitors with disabilities from abroad need?\\nAnswer: Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\\n\\nThis documentation can be a European parking card or a mobility inclusion card.\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\\n\\n\\n\\nFor countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.'),\n", " 0.8880006763829658),\n", " (Document(metadata={'source': 'Olympics FAQ', 'faq_id': '-Bgz0H-g-en', 'question': 'Are there any specific spaces for individuals with mental/neurological/psychological disabilities?', 'answer': 'Individuals with mental, neurological, or psychological disabilities can access reserved spots for people with disabilities that are easily accessible upon presentation of a disability card or equivalent.\\n\\nAll volunteers will receive training on mental, neurological, and psychological disabilities to ensure the best possible experience and welcome.', 'topics': 'Spectators;Accessibility;On-site access / services', 'url': 'https://help.paris2024.org/en-gb/contents/Are-there-any-specific-spaces-for-individuals-with-mental-neurological-psychological-disabilities--Bgz0H-g', '_id': 'd0248842-155d-4875-a1a2-baaac8e30a27', '_collection_name': 'olympics-2024'}, page_content='Question: Are there any specific spaces for individuals with mental/neurological/psychological disabilities?\\nAnswer: Individuals with mental, neurological, or psychological disabilities can access reserved spots for people with disabilities that are easily accessible upon presentation of a disability card or equivalent.\\n\\nAll volunteers will receive training on mental, neurological, and psychological disabilities to ensure the best possible experience and welcome.'),\n", " 0.8761557912533754)]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Retrieve top 3 most relevant documents\n", "test_query = \"How do I get disabled parking spaces?\"\n", "retrieved_docs = vector_store.similarity_search_with_relevance_scores(\n", " query=test_query, k=3, # Return top 3 matches\n", ")\n", "retrieved_docs\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐จ Step 6: Formatting Documents for the Prompt\n", "\n", "We need to format our retrieved documents as a single string to pass them as context to the LLM prompt.\n", "\n", "### Strategy:\n", "\n", "Format each document as:\n", "```\n", "Document 1:\n", "[content]\n", "\n", "Document 2:\n", "[content]\n", "...\n", "```\n", "\n", "This makes it easy for the LLM to reference specific documents!" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐จ Document Formatting Example:\n", "\n", "============================================================\n", "Document 1:\n", "Question: Are parking spaces reserved for individuals with disabilities available on-site?\n", "Answer: Each site will have a limited number of parking spaces reserved for wheelchair users.\n", "\n", "Holders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\n", "\n", "\n", "\n", "For countries not issuing either of these two cards, any other official document justifying a disability will be accepted.\n", "\n", "Document 2:\n", "Question: What documentary evidence do visitors with disabilities from abroad need?\n", "Answer: Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\n", "\n", "This documentation can be a European parking card or a mobility inclusion card.\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n", "\n", "\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n" ] } ], "source": [ "def format_docs(docs: list[Document]) -> str:\n", " \"\"\"Format retrieved documents for inclusion in prompt.\n", "\n", " Args:\n", " docs: List of Document objects\n", "\n", " Returns:\n", " Formatted string with numbered documents\n", "\n", " \"\"\"\n", " formatted = []\n", "\n", " for i, doc in enumerate(docs, 1):\n", " formatted.append(f\"Document {i}:\\n{doc.page_content}\")\n", "\n", " return \"\\n\\n\".join(formatted)\n", "\n", "\n", "# Test the formatting\n", "print(\"๐จ Document Formatting Example:\\n\")\n", "print(\"=\" * 60)\n", "\n", "docs_to_format = [\n", " item[0] if isinstance(item, tuple) else item for item in retrieved_docs[:2]\n", "]\n", "formatted_context = format_docs(docs_to_format) # Show first 2\n", "print(formatted_context)\n" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐จ Document Formatting Example:\n", "\n", "============================================================\n", "Document 1 (Source: https://help.paris2024.org/en-gb/contents/Are-parking-spaces-reserved-for-individuals-with-disabilities-available-on-site-OnlmLzuE):\n", "Question: Are parking spaces reserved for individuals with disabilities available on-site?\n", "Answer: Each site will have a limited number of parking spaces reserved for wheelchair users.\n", "\n", "Holders of a PFR ticket will be able to access them without reservation and subject to availability, upon presentation of a European parking card, a mobility inclusion card, and a PFR ticket.\n", "\n", "\n", "\n", "For countries not issuing either of these two cards, any other official document justifying a disability will be accepted.\n", "\n", "Document 2 (Source: https://help.paris2024.org/en-gb/contents/What-documentary-evidence-do-visitors-with-disabilities-from-abroad-need-OnllTAmy):\n", "Question: What documentary evidence do visitors with disabilities from abroad need?\n", "Answer: Visitors will need to provide documentation to book PFR (wheelchair spaces) or PSH (easy access seating in the stands).\n", "\n", "This documentation can be a European parking card or a mobility inclusion card.\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n", "\n", "\n", "\n", "For countries that do not issue either of these cards, any other official documentation justifying a disability will be accepted.\n" ] } ], "source": [ "def format_docs_alternative(docs: list[Document]) -> str:\n", " \"\"\"Format retrieved documents for inclusion in prompt.\n", "\n", " Args:\n", " docs: List of Document objects\n", "\n", " Returns:\n", " Formatted string with numbered documents\n", "\n", " \"\"\"\n", " formatted = []\n", "\n", " # TODO: Optimize context format\n", " # - Test answer-only context vs. current question+answer pairs\n", " # Rationale: While questions improve retrieval quality, including both FAQ\n", " # questions and user queries in the prompt may confuse the LLM and increase hallucinations\n", " # - Include source URLs from metadata to enable citation and improve transparency\n", " for i, doc in enumerate(docs, 1):\n", " source_url = doc.metadata.get(\"url\", \"No URL\")\n", " formatted.append(f\"Document {i} (Source: {source_url}):\\n{doc.page_content}\")\n", " return \"\\n\\n\".join(formatted)\n", "\n", "\n", "# Test the formatting\n", "print(\"๐จ Document Formatting Example:\\n\")\n", "print(\"=\" * 60)\n", "\n", "docs_to_format = [\n", " item[0] if isinstance(item, tuple) else item for item in retrieved_docs[:2]\n", "]\n", "formatted_context = format_docs_alternative(docs_to_format) # Show first 2\n", "print(formatted_context)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "๐กNotice how there are repeated lines and multiple line breaks - we should have preprocessed this data as well! \n", "Keep these optimization ideas in mind for improving the RAG system in the next exercise, which will be a bit more challenging! ๐" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ Step 8: Crafting the Prompt\n", "\n", "### Why Prompts Matter:\n", "\n", "A well-crafted prompt is like giving clear instructions to a smart assistant. It should:\n", "- ๐ฏ **Be specific:** Clear about what to do\n", "- ๐ **Provide context:** Give relevant information\n", "- ๐ซ **Set boundaries:** What NOT to do\n", "- โ **Be structured:** Easy for LLM to parse\n", "\n", "---\n", "\n", "### Our Prompt Strategy:\n", "\n", "```\n", "SYSTEM ROLE โ CONTEXT (Documents) โ USER QUESTION โ INSTRUCTIONS\n", "```" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ Creating the RAG Prompt Template\n", "\n", "============================================================\n" ] } ], "source": [ "print(\"๐ Creating the RAG Prompt Template\\n\")\n", "print(\"=\" * 60)\n", "\n", "# Define the prompt template\n", "prompt_template = \"\"\"You are a helpful assistant answering questions about the Olympic Games.\n", "\n", "Use the following context documents to answer the user's question. If the answer is not in the provided documents, say \"I don't have that information in the provided documents.\"\n", "\n", "Context Documents:\n", "{context}\n", "\n", "User Question: {question}\n", "\n", "Instructions:\n", "1. Answer based ONLY on the provided documents\n", "2. Be specific and cite which document(s) you used\n", "3. If information is unclear or missing, say so\n", "4. Keep answers concise but complete\n", "5. Use a friendly, informative tone\n", "Answer:\"\"\"\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ค Step 9: Initialize the LLM\n", "\n", "**Mistral Large** is Mistral AI's most capable model:\n", "\n", "| Feature | Details | Why It Matters for RAG |\n", "|---------|----------|----------------------|\n", "| **Speed** | โก Very fast | Quick responses to user queries |\n", "| **Context Window** | 128K tokens | Fits many retrieved documents |\n", "| **Max Output** | 8K tokens | Detailed answers possible |\n", "| **Cost** | Competitive pricing | Scalable for production use |\n", "| **Strengths** | Reasoning & instruction following | Perfect for synthesizing retrieved context |\n", "\n", "The ideal choice for production RAG systems! ๐ฏ\n" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "MODEL_NAME = \"mistral-large-latest\"\n", "TEMPERATURE = 0\n" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ค Initializing the Language Model\n", "\n", "============================================================\n", "response to hello: Hello! ๐ How can I assist you today? Whether you have a question, need help with something, or just want to chat, I'm here for you!\n" ] } ], "source": [ "print(\"๐ค Initializing the Language Model\\n\")\n", "print(\"=\" * 60)\n", "# Initialize the LLM\n", "from langchain_mistralai import ChatMistralAI\n", "\n", "llm = ChatMistralAI(\n", " model=MODEL_NAME, temperature=TEMPERATURE,\n", ")\n", "\n", "# try an invoke\n", "response = llm.invoke(\"hello\")\n", "print(\"response to hello:\", response.content)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ฏ Step 10: Building the Complete RAG Pipeline\n", "\n", "Now let's put it all together! We'll create a function that:\n", "1. Takes a user question\n", "2. Retrieves relevant documents\n", "3. Formats them into a prompt\n", "4. Gets an answer from the LLM\n", "\n", "This is the **complete RAG pipeline**! ๐" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": [ "def make_rag_prompt(question: str, k: int = 3, score_threshold: float = 0.4) -> str:\n", " \"\"\"Create a RAG prompt by retrieving relevant documents.\n", "\n", " Args:\n", " question: User's question\n", " k: Number of documents to retrieve\n", " score_threshold: Minimum similarity score for retrieved documents\n", "\n", " Returns:\n", " Formatted prompt string with context and question\n", "\n", " \"\"\"\n", " # Step 1: Retrieve relevant documents\n", " retrieved_docs = vector_store.similarity_search(\n", " query=question, k=k, score_threshold=score_threshold,\n", " )\n", "\n", " # Step 2: Format documents\n", " context = format_docs(retrieved_docs)\n", "\n", " # Step 3: Fill in the prompt template\n", " return prompt_template.format(context=context, question=question)\n" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "You are a helpful assistant answering questions about the Olympic Games.\n", "\n", "Use the following context documents to answer the user's question. If the answer is not in the provided documents, say \"I don't have that information in the provided documents.\"\n", "\n", "Context Documents:\n", "Document 1:\n", "Question: I am a traveler with a disability, how can I travel by plane?\n", "Answer: Air France offers specific services to facilitate the travel of people with reduced mobility through the SAPHIR programme (Service dedicated to Assistance for Persons with Handicaps for Information and Reservations).\n", "\n", "This free service is available in France as well as in 20 countries worldwide.\n", "\n", "To be considered, your request must reach us at least 48 hours before the departure of your first flight.\n", "\n", "Air France acknowledges the Sunflower symbol from the \"Hidden disabilities Sunflowerยฎ\" programme as an emblem to facilitate the identification and travel experience of its customers with invisible disabilities.\n", "\n", "\n", "\n", "To learn more, please visit: https://wwws.airfrance.fr/information/passagers/acheter-billet-avion-pmr-autres-handicaps\n", "\n", "Document 2:\n", "Question: I have a disability, can I receive assistance at the train station?\n", "Answer: People with disabilities and reduced mobility can benefit from free assistance at the departure and/or arrival station, from a reception point to their seat on the train.\n", "\n", "This service is called Assist'enGare and is available in over 1,000 stations in France. Assist'enGare can be reached:\n", "\n", " * Online via the reservation form 24/7:\n", " \n", " https://www.garesetconnexions.sncf/en/assistances-psh-pmr\n", "\n", " * By phone every day between 8 a.m. and 8 p.m. at 3212 and at +33 (0)9 72 72 00 92 from abroad (free service + call price).\n", "\n", " * Via Rogervoice, our relay center allowing deaf and hard of hearing people to communicate with our Assist'enGare teleadvisors through a translator operator. This service is available Monday to Friday from 8:30 a.m. to 9 p.m. (excluding holidays) in French Sign Language (LSF), French Spoken Complemented (LfPC), and Real-Time Speech Transcription (TTRP), and 24/7 in Text Transcription (TT).\n", "\n", "During peak periods, it is advisable to book this service as soon as you purchase your train ticket to ensure assistance. Without a reservation, assistance is provided subject to availability.\n", "\n", "Before purchasing the train ticket, it is advisable to check that assistance is available at the desired station and time.\n", "\n", "\n", "\n", "For more information, please visit:\n", "\n", "https://www.paris2024.org/en/practical-information-accessibility/\n", "\n", "Document 3:\n", "Question: How will individuals with disabilities be accommodated at the competition venues?\n", "Answer: Paris 2024 is committed to ensuring accessibility for people with disabilities at every competition venue by implementing the following measures:\n", "\n", " * A drop-off zone near the site entrances for PWD (People With Disabilities).\n", "\n", " * A parking area for PFR (People with Reduced Mobility) and a drop-off zone for IDFM shuttles for PFR.\n", "\n", " * Dedicated assistance available from the drop-off and parking zone.\n", "\n", " * A priority queue for PWD at the site entrances.\n", "\n", " * Dedicated reception staff for people with disabilities.\n", "\n", " * Mobility assistance within the site, with the option to use a wheelchair to reach the seating area.\n", "\n", " * A ticketing offer specifically dedicated to people with disabilities and their companions.\n", "\n", " * A dog relief area at each site.\n", "\n", "\n", "\n", "Find all the services available to PWD and PFR spectators on our dedicated page: https://www.paris2024.org/fr/infos-pratiques-accessibilite/\n", "\n", "User Question: what can I do if I'm disabled ?\n", "\n", "Instructions:\n", "1. Answer based ONLY on the provided documents\n", "2. Be specific and cite which document(s) you used\n", "3. If information is unclear or missing, say so\n", "4. Keep answers concise but complete\n", "5. Use a friendly, informative tone\n", "Answer:\n" ] } ], "source": [ "question = \"what can I do if I'm disabled ?\"\n", "print(make_rag_prompt(question, k=3, score_threshold=0.4))\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "โ RAG Pipeline Functions Created!\n", "\n" ] } ], "source": [ "def rag_assistant(user_question: str, k: int = 3, verbose: bool = False) -> str:\n", " \"\"\"Complete RAG pipeline: question โ retrieval โ generation.\n", "\n", " Args:\n", " user_question: The question to answer\n", " k: Number of documents to retrieve\n", " verbose: Whether to print intermediate steps\n", "\n", " Returns:\n", " LLM's answer string\n", "\n", " \"\"\"\n", " if verbose:\n", " print(\"๐ RAG Pipeline Steps:\\n\")\n", " print(f\"1๏ธโฃ Query: '{user_question}'\")\n", " print(f\"2๏ธโฃ Retrieving top {k} documents...\")\n", "\n", " # Create the prompt with retrieved context\n", " full_prompt = make_rag_prompt(user_question, k=k)\n", "\n", " if verbose:\n", " print(f\"3๏ธโฃ Prompt created ({len(full_prompt)} characters)\")\n", " print(\"4๏ธโฃ Generating answer with LLM...\\n\")\n", "\n", " # Get answer from LLM\n", " response = llm.invoke(full_prompt)\n", " content = response.content\n", "\n", " if isinstance(content, str):\n", " return content\n", "\n", " return \"\\n\".join(\n", " item if isinstance(item, str) else str(item)\n", " for item in content\n", " )\n", "\n", "\n", "print(\"โ RAG Pipeline Functions Created!\\n\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐ฎ Step 11: Testing the RAG System!\n", "\n", "Let's ask some questions and see our RAG system in action! ๐\n", "\n", "### Test Questions:\n", "\n", "We'll test with various types of questions to see how well our system performs." ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "๐ฎ Testing the RAG System\n", "\n", "======================================================================\n", "\n", "โ Question 1: What can I do if i'm disabled?\n", "\n", "๐ค RAG Assistant's Answer:\n", "\n", "Hereโs what you can do if youโre a person with a disability (PWD) or have reduced mobility (PFR) for the Paris 2024 Olympic and Paralympic Games, based on the provided documents:\n", "\n", "### **At Competition Venues (Document 1)**\n", "Youโll have access to:\n", "- **Drop-off zones** near entrances for PWD.\n", "- **Dedicated parking** for PFR and shuttle drop-off zones.\n", "- **Priority queues** at entrances.\n", "- **Assistance staff** to help from arrival to seating.\n", "- **Wheelchair mobility support** within venues.\n", "- **Special ticketing offers** for PWD and companions.\n", "- **Dog relief areas** at each site.\n", "\n", "๐ More details: [Paris 2024 Accessibility Page](https://www.paris2024.org/fr/infos-pratiques-accessibilite/)\n", "\n", "---\n", "\n", "### **Train Travel (Document 2)**\n", "- **Free assistance** (AssistโenGare) at over 1,000 stations in France, from arrival to your train seat.\n", "- **Booking options**:\n", " - Online form (24/7): [SNCF Assistance](https://www.garesetconnexions.sncf/en/assistances-psh-pmr)\n", " - Phone: 3212 (France) or +33 (0)9 72 72 00 92 (abroad).\n", " - **For deaf/hard of hearing**: Rogervoice relay service (LSF, LfPC, TTRP, or text).\n", "- **Book early** during peak periods to guarantee assistance.\n", "\n", "๐ More info: [Paris 2024 Accessibility](https://www.paris2024.org/en/practical-information-accessibility/)\n", "\n", "---\n", "\n", "### **Air Travel (Document 3)**\n", "- **Air Franceโs SAPHIR program** offers free assistance for PWD/PFR.\n", " - Request at least **48 hours before departure**.\n", " - Recognizes the **Sunflower symbol** for invisible disabilities.\n", "๐ Details: [Air France Accessibility](https://wwws.airfrance.fr/information/passagers/acheter-billet-avion-pmr-autres-handicaps)\n", "\n", "---\n", "\n", "### **Tickets (Document 5)**\n", "- **Special seating** for PWD, including wheelchair-accessible spots.\n", "- Purchase through the [official ticketing site](https://tickets.paris2024.org).\n", "๐ FAQ: [Accessible Ticket Categories](https://tickets.paris2024.org/faq/en_en/category/accessibility/what-categories-are-available-for-people-with-disabilities)\n", "\n", "---\n", "\n", "======================================================================\n" ] } ], "source": [ "print(\"๐ฎ Testing the RAG System\\n\")\n", "print(\"=\" * 70)\n", "\n", "# Test Question 1\n", "question1 = \"What can I do if i'm disabled?\"\n", "\n", "print(f\"\\nโ Question 1: {question1}\\n\")\n", "print(\"๐ค RAG Assistant's Answer:\\n\")\n", "print(rag_assistant(question1, verbose=False, k=5))\n", "print(\"\\n\" + \"=\" * 70)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "## ๐จ Step 12: Interactive Q&A Session with Gradio\n", "\n", "Now it's your turn! Ask your own questions about the Olympics!" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "* Running on local URL: http://127.0.0.1:7860\n", "* To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "\"The best RAG system is the one that solves your specific problem.\"
\n", "Go forth and build amazing AI-powered systems! ๐
\n", "