{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "sZVlYSmRjzuk"
   },
   "source": [
    "# Tutorial: Classifying Documents & Queries by Language\n",
    "\n",
    "- **Level**: Beginner\n",
    "- **Time to complete**: 15 minutes\n",
    "- **Components Used**: [`InMemoryDocumentStore`](https://docs.haystack.deepset.ai/docs/inmemorydocumentstore), [`DocumentLanguageClassifier`](https://docs.haystack.deepset.ai/docs/documentlanguageclassifier), [`MetadataRouter`](https://docs.haystack.deepset.ai/docs/metadatarouter), [`DocumentWriter`](https://docs.haystack.deepset.ai/docs/documentwriter), [`TextLanguageRouter`](https://docs.haystack.deepset.ai/docs/textlanguagerouter), [`DocumentJoiner`](https://docs.haystack.deepset.ai/docs/documentjoiner), [`InMemoryBM25Retriever`](https://docs.haystack.deepset.ai/docs/inmemorybm25retriever), [`ChatPromptBuilder`](https://docs.haystack.deepset.ai/docs/chatpromptbuilder), [`OpenAIChatGenerator`](https://docs.haystack.deepset.ai/docs/openaichatgenerator)\n",
    "- **Goal**: After completing this tutorial, you'll have learned how to build a Haystack pipeline to classify documents based on the (human) language they were written in.\n",
    "- Optionally, at the end you'll also incorporate language clasification and query routing into a RAG pipeline, so you can query documents based on the language a question was written in."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "G8qw1k7nf7yH"
   },
   "source": [
    "## Overview\n",
    "\n",
    "In a gobalized society with over 7,000 human languages spoken worldwide today, handling multilingual input is a common use case for NLP applications.\n",
    "\n",
    "Good news: Haystack has a [`DocumentLanguageClassifier`](https://docs.haystack.deepset.ai/docs/documentlanguageclassifier) built in. This component detects the language a document was written in. This functionality lets you create *branches* in your Haystack pipelines, granting the flexibility to add different processing steps for each language. For example, you could use a LLM that performs better in German to answer German queries. Or, you could fetch only French restaurant reviews for your French users.\n",
    "\n",
    "In this tutorial, you'll take a text samples from hotel reviews, written in different languages. The text samples will be made into Haystack documents and classified by language. Then each document will be written to a language-specific `DocumentStore`. To validate that the language detection is working correctly, you'll filter the document stores to display their contents.\n",
    "\n",
    "In the last section, you'll build a multi-lingual RAG pipeline. The language of a question is detected, and only documents in that language are used to generate the answer. For this section, the [`TextLanguageRouter`](https://docs.haystack.deepset.ai/docs/textlanguagerouter) will come in handy.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "oC7ff5x0XTfN"
   },
   "source": [
    "# Installing Haystack\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "lxgAfuxcdftS",
    "outputId": "36339d6b-f7a8-4686-911a-60642a8adbe6"
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "pip install haystack-ai\n",
    "pip install langdetect"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "K0wRwkyvkV3Z"
   },
   "source": [
    "## Write Documents Into `InMemoryDocumentStore`\n",
    "\n",
    "The following indexing pipeline writes French and English documents into their own `InMemoryDocumentStores` based on language.\n",
    "\n",
    "Import the modules you'll need. Then instantiate a list of Haystack `Documents` that are snippets of hotel reviews in various languages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "mN2fFuWWP_8D"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/amna.mubashar/Library/Python/3.9/lib/python/site-packages/pypdf/_crypt_providers/_cryptography.py:32: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from this module in 48.0.0.\n",
      "  from cryptography.hazmat.primitives.ciphers.algorithms import AES, ARC4\n"
     ]
    }
   ],
   "source": [
    "from haystack import Document, Pipeline\n",
    "from haystack.document_stores.in_memory import InMemoryDocumentStore\n",
    "from haystack.components.classifiers import DocumentLanguageClassifier\n",
    "from haystack.components.routers import MetadataRouter\n",
    "from haystack.components.writers import DocumentWriter\n",
    "\n",
    "\n",
    "documents = [\n",
    "    Document(\n",
    "        content=\"Super appartement. Juste au dessus de plusieurs bars qui ferment très tard. A savoir à l'avance. (Bouchons d'oreilles fournis !)\"\n",
    "    ),\n",
    "    Document(\n",
    "        content=\"El apartamento estaba genial y muy céntrico, todo a mano. Al lado de la librería Lello y De la Torre de los clérigos. Está situado en una zona de marcha, así que si vais en fin de semana , habrá ruido, aunque a nosotros no nos molestaba para dormir\"\n",
    "    ),\n",
    "    Document(\n",
    "        content=\"The keypad with a code is convenient and the location is convenient. Basically everything else, very noisy, wi-fi didn't work, check-in person didn't explain anything about facilities, shower head was broken, there's no cleaning and everything else one may need is charged.\"\n",
    "    ),\n",
    "    Document(\n",
    "        content=\"It is very central and appartement has a nice appearance (even though a lot IKEA stuff), *W A R N I N G** the appartement presents itself as a elegant and as a place to relax, very wrong place to relax - you cannot sleep in this appartement, even the beds are vibrating from the bass of the clubs in the same building - you get ear plugs from the hotel -> now I understand why -> I missed a trip as it was so loud and I could not hear the alarm next day due to the ear plugs.- there is a green light indicating 'emergency exit' just above the bed, which shines very bright at night - during the arrival process, you felt the urge of the agent to leave as soon as possible. - try to go to 'RVA clerigos appartements' -> same price, super quiet, beautiful, city center and very nice staff (not an agency)- you are basically sleeping next to the fridge, which makes a lot of noise, when the compressor is running -> had to switch it off - but then had no cool food and drinks. - the bed was somehow broken down - the wooden part behind the bed was almost falling appart and some hooks were broken before- when the neighbour room is cooking you hear the fan very loud. I initially thought that I somehow activated the kitchen fan\"\n",
    "    ),\n",
    "    Document(content=\"Un peu salé surtout le sol. Manque de service et de souplesse\"),\n",
    "    Document(\n",
    "        content=\"Nous avons passé un séjour formidable. Merci aux personnes , le bonjours à Ricardo notre taxi man, très sympathique. Je pense refaire un séjour parmi vous, après le confinement, tout était parfait, surtout leur gentillesse, aucune chaude négative. Je n'ai rien à redire de négative, Ils étaient a notre écoute, un gentil message tout les matins, pour nous demander si nous avions besoins de renseignement et savoir si tout allait bien pendant notre séjour.\"\n",
    "    ),\n",
    "    Document(\n",
    "        content=\"Céntrico. Muy cómodo para moverse y ver Oporto. Edificio con terraza propia en la última planta. Todo reformado y nuevo. Te traen un estupendo desayuno todas las mañanas al apartamento. Solo que se puede escuchar algo de ruido de la calle a primeras horas de la noche. Es un zona de ocio nocturno. Pero respetan los horarios.\"\n",
    "    ),\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "TcZbAvjbRJLA"
   },
   "source": [
    "Each language gets its own `DocumentStore`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "rfC1ZCigQJgI"
   },
   "outputs": [],
   "source": [
    "en_document_store = InMemoryDocumentStore()\n",
    "fr_document_store = InMemoryDocumentStore()\n",
    "es_document_store = InMemoryDocumentStore()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "d9fyP-ThRTue"
   },
   "source": [
    "In this step, we configure the language classification component that will detect and route documents based on their language\n",
    "\n",
    "The `DocumentLanguageClassifier` takes a list of languages. The `MetadataRouter` needs a dictionary of rules.  These rules specify which node to route a document to (in this case, which language-specific `DocumentWriter`), based on the document's metadata.\n",
    "\n",
    "The keys of the dictionary are the names of the output connections, and the values are dictionaries that follow the format of [filtering expressions in Haystack.](https://docs.haystack.deepset.ai/docs/metadata-filtering)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "FlqGdbuxQNKk"
   },
   "outputs": [],
   "source": [
    "language_classifier = DocumentLanguageClassifier(languages=[\"en\", \"fr\", \"es\"])\n",
    "router_rules = {\n",
    "    \"en\": {\"field\": \"meta.language\", \"operator\": \"==\", \"value\": \"en\"},\n",
    "    \"fr\": {\"field\": \"meta.language\", \"operator\": \"==\", \"value\": \"fr\"},\n",
    "    \"es\": {\"field\": \"meta.language\", \"operator\": \"==\", \"value\": \"es\"},\n",
    "}\n",
    "router = MetadataRouter(rules=router_rules)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "FEw5pfmBQRBB"
   },
   "outputs": [],
   "source": [
    "en_writer = DocumentWriter(document_store=en_document_store)\n",
    "fr_writer = DocumentWriter(document_store=fr_document_store)\n",
    "es_writer = DocumentWriter(document_store=es_document_store)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "kAQvRdtESq_J"
   },
   "source": [
    "Now that all the components have been created, instantiate the `Pipeline`. Add the components to the pipeline. Connect the outputs of one component to the input of the following component."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "id": "BdvO_fEfcVAY"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<haystack.core.pipeline.pipeline.Pipeline object at 0x310ac9220>\n",
       "🚅 Components\n",
       "  - language_classifier: DocumentLanguageClassifier\n",
       "  - router: MetadataRouter\n",
       "  - en_writer: DocumentWriter\n",
       "  - fr_writer: DocumentWriter\n",
       "  - es_writer: DocumentWriter\n",
       "🛤️ Connections\n",
       "  - language_classifier.documents -> router.documents (List[Document])\n",
       "  - router.en -> en_writer.documents (List[Document])\n",
       "  - router.fr -> fr_writer.documents (List[Document])\n",
       "  - router.es -> es_writer.documents (List[Document])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "indexing_pipeline = Pipeline()\n",
    "indexing_pipeline.add_component(instance=language_classifier, name=\"language_classifier\")\n",
    "indexing_pipeline.add_component(instance=router, name=\"router\")\n",
    "indexing_pipeline.add_component(instance=en_writer, name=\"en_writer\")\n",
    "indexing_pipeline.add_component(instance=fr_writer, name=\"fr_writer\")\n",
    "indexing_pipeline.add_component(instance=es_writer, name=\"es_writer\")\n",
    "\n",
    "\n",
    "indexing_pipeline.connect(\"language_classifier\", \"router\")\n",
    "indexing_pipeline.connect(\"router.en\", \"en_writer\")\n",
    "indexing_pipeline.connect(\"router.fr\", \"fr_writer\")\n",
    "indexing_pipeline.connect(\"router.es\", \"es_writer\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ulAiCB1vTIbr"
   },
   "source": [
    "Draw a diagram of the pipeline to see what the graph looks like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "598ZTa7RzNeR"
   },
   "outputs": [],
   "source": [
    "# indexing_pipeline.draw(\"indexing_pipeline.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "UzQX7zFLS_Bk"
   },
   "source": [
    "Run the pipeline and it will tell you how many documents were written in each language. Voila!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "lE5XE8cPXN5-",
    "outputId": "43017d9b-65f8-48ad-dadb-66ad0de3af43"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'router': {'unmatched': []},\n",
       " 'en_writer': {'documents_written': 2},\n",
       " 'fr_writer': {'documents_written': 3},\n",
       " 'es_writer': {'documents_written': 2}}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "indexing_pipeline.run(data={\"language_classifier\": {\"documents\": documents}})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "R-Q2SxDnu3v-"
   },
   "source": [
    "### Check the Contents of Your Document Stores\n",
    "\n",
    "You can check the contents of your document stores. Each one should only contain documents in the correct language."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "LNHzxz52uxZV",
    "outputId": "d0459677-73c0-4bb6-f5d3-87c0c00b1552"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "English documents:  [Document(id=8f64ab234c6a5d5652d02bed144d069ec6e988903b071d16fffbf400abfc1047, content: 'The keypad with a code is convenient and the location is convenient. Basically everything else, very...', meta: {'language': 'en'}), Document(id=d4d878288efba5e28a43ae0195e43dadd0298fe36d3d9b3075c5c5120d27763e, content: 'It is very central and appartement has a nice appearance (even though a lot IKEA stuff), *W A R N I ...', meta: {'language': 'en'})]\n",
      "French documents:  [Document(id=ea7ea338874232de2d8105a258813f50345db82772e21ad2c4549dbb7adce8a3, content: 'Super appartement. Juste au dessus de plusieurs bars qui ferment très tard. A savoir à l'avance. (Bo...', meta: {'language': 'fr'}), Document(id=6b64c8a60543ee32b81cd39bc8d6e09fae4bff1b22c6ccdcf414db26fa354e7a, content: 'Un peu salé surtout le sol. Manque de service et de souplesse', meta: {'language': 'fr'}), Document(id=b1be23526f19a8af80a190e775bfd05e65878e585529037cb45b47267a4eaa98, content: 'Nous avons passé un séjour formidable. Merci aux personnes , le bonjours à Ricardo notre taxi man, t...', meta: {'language': 'fr'})]\n",
      "Spanish documents:  [Document(id=72b094c163b22a660528bc5adbdf0fecf96b4b4d753c1b117f15dba482d2f948, content: 'El apartamento estaba genial y muy céntrico, todo a mano. Al lado de la librería Lello y De la Torre...', meta: {'language': 'es'}), Document(id=4b37b8bdfffccfb3211ea167b4fdc5121ca51fc5f869b4f834e8da473f0d3353, content: 'Céntrico. Muy cómodo para moverse y ver Oporto. Edificio con terraza propia en la última planta. Tod...', meta: {'language': 'es'})]\n"
     ]
    }
   ],
   "source": [
    "print(\"English documents: \", en_document_store.filter_documents())\n",
    "print(\"French documents: \", fr_document_store.filter_documents())\n",
    "print(\"Spanish documents: \", es_document_store.filter_documents())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "A6J0ac9UWdrT"
   },
   "source": [
    "## (Optional) Create a Multi-Lingual RAG pipeline\n",
    "\n",
    "To build a multi-lingual RAG pipeline, you can use the[`TextLanguageRouter`](https://docs.haystack.deepset.ai/docs/textlanguagerouter) to detect the language of the query. Then, fetch documents in that same language from the correct `DocumentStore`.\n",
    "\n",
    "In order to do this you'll need an [OpenAI access token](https://help.openai.com/en/articles/4936850-where-do-i-find-my-api-key), although this approach would also work with any other [generator Haystack supports](https://docs.haystack.deepset.ai/docs/generators)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "hVJaARodWezy",
    "outputId": "d9bdcb42-bd50-4fd9-f4d8-a69e8b4b64f8"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "if \"OPENAI_API_KEY\" not in os.environ:\n",
    "    os.environ[\"OPENAI_API_KEY\"] = getpass(\"Enter OpenAI API key:\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Ei8up-k3qOC4"
   },
   "source": [
    "Let's assume that all these reviews we put in our document stores earlier are for the same accommodation. A RAG pipeline will let you query for information about that apartment, in the language you choose.\n",
    "\n",
    "Import the components you'll need for a RAG pipeline. Write a prompt that will be passed to our LLM, along with the relevant documents."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "CN1N2sn1yUVx"
   },
   "outputs": [],
   "source": [
    "from haystack.components.retrievers.in_memory import InMemoryBM25Retriever\n",
    "from haystack.components.joiners import DocumentJoiner\n",
    "from haystack.components.builders import ChatPromptBuilder\n",
    "from haystack.components.generators.chat import OpenAIChatGenerator\n",
    "from haystack.dataclasses import ChatMessage\n",
    "from haystack.components.routers import TextLanguageRouter\n",
    "\n",
    "prompt_template = [\n",
    "    ChatMessage.from_user(\n",
    "        \"\"\"\n",
    "You will be provided with reviews for an accommodation.\n",
    "Answer the question concisely based solely on the given reviews.\n",
    "Reviews:\n",
    "  {% for doc in documents %}\n",
    "    {{ doc.content }}\n",
    "  {% endfor %}\n",
    "Question: {{ query}}\n",
    "Answer:\n",
    "\"\"\"\n",
    "    )\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "WTCT6u4cz_z6"
   },
   "source": [
    "### Build the Pipeline\n",
    "\n",
    "Create a new `Pipeline`. Add the following components:\n",
    "- `TextLanguageRouter`\n",
    "- `InMemoryBM25Retriever`. You'll need a retriever per language, since each language has its own `DocumentStore`.\n",
    "- `DocumentJoiner`\n",
    "- `ChatPromptBuilder`\n",
    "- `OpenAIChatGenerator`\n",
    "\n",
    "> Note: The `BM25Retriever` essentially does keyword matching, which isn't as accurate as other search methods. In order to make the LLM responses more precise, you could refacctor your piplines to use an [`EmbeddingRetriever`](https://docs.haystack.deepset.ai/docs/inmemoryembeddingretriever) which performs vector search over the documents."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "BN1Hr_BjWKcl"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<haystack.core.pipeline.pipeline.Pipeline object at 0x315f89ee0>\n",
       "🚅 Components\n",
       "  - router: TextLanguageRouter\n",
       "  - en_retriever: InMemoryBM25Retriever\n",
       "  - fr_retriever: InMemoryBM25Retriever\n",
       "  - es_retriever: InMemoryBM25Retriever\n",
       "  - joiner: DocumentJoiner\n",
       "  - prompt_builder: ChatPromptBuilder\n",
       "  - llm: OpenAIChatGenerator\n",
       "🛤️ Connections\n",
       "  - router.en -> en_retriever.query (str)\n",
       "  - router.fr -> fr_retriever.query (str)\n",
       "  - router.es -> es_retriever.query (str)\n",
       "  - en_retriever.documents -> joiner.documents (List[Document])\n",
       "  - fr_retriever.documents -> joiner.documents (List[Document])\n",
       "  - es_retriever.documents -> joiner.documents (List[Document])\n",
       "  - joiner.documents -> prompt_builder.documents (List[Document])\n",
       "  - prompt_builder.prompt -> llm.messages (List[ChatMessage])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rag_pipeline = Pipeline()\n",
    "rag_pipeline.add_component(instance=TextLanguageRouter([\"en\", \"fr\", \"es\"]), name=\"router\")\n",
    "rag_pipeline.add_component(instance=InMemoryBM25Retriever(document_store=en_document_store), name=\"en_retriever\")\n",
    "rag_pipeline.add_component(instance=InMemoryBM25Retriever(document_store=fr_document_store), name=\"fr_retriever\")\n",
    "rag_pipeline.add_component(instance=InMemoryBM25Retriever(document_store=es_document_store), name=\"es_retriever\")\n",
    "rag_pipeline.add_component(instance=DocumentJoiner(), name=\"joiner\")\n",
    "rag_pipeline.add_component(instance=ChatPromptBuilder(template=prompt_template), name=\"prompt_builder\")\n",
    "rag_pipeline.add_component(instance=OpenAIChatGenerator(), name=\"llm\")\n",
    "\n",
    "\n",
    "rag_pipeline.connect(\"router.en\", \"en_retriever.query\")\n",
    "rag_pipeline.connect(\"router.fr\", \"fr_retriever.query\")\n",
    "rag_pipeline.connect(\"router.es\", \"es_retriever.query\")\n",
    "rag_pipeline.connect(\"en_retriever\", \"joiner\")\n",
    "rag_pipeline.connect(\"fr_retriever\", \"joiner\")\n",
    "rag_pipeline.connect(\"es_retriever\", \"joiner\")\n",
    "rag_pipeline.connect(\"joiner.documents\", \"prompt_builder.documents\")\n",
    "rag_pipeline.connect(\"prompt_builder.prompt\", \"llm.messages\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "q1C5GHK_1Kkk"
   },
   "source": [
    "You can draw this pipeline and compare the architecture to the `indexing_pipeline` diagram we created earlier."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000
    },
    "id": "HAFTD5nt1L9a",
    "outputId": "90cbf82b-8fe5-439d-b099-08510e1c1098"
   },
   "outputs": [],
   "source": [
    "# rag_pipeline.draw(\"rag_pipeline.png\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "-Vr8MbGrEHZV"
   },
   "source": [
    "Try it out by asking a question."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 49,
     "referenced_widgets": [
      "8a6b993b2fbd4537a1f130adc08f2eb0",
      "cbe44862bf474ff692a359314a7c21f1",
      "04daef6e8b9e4779bbe41dc32f4e9083",
      "e5d659cdfd64477bbb9ce80aed7924f8",
      "d8777b76fb5341869afcb084e91231ee",
      "00a38829bf664b0084b5ec704047f00d",
      "f32af41f2b9543e497989b2c44e9d62d",
      "4ffb8a24b1a74cb8be55af79261e65ab",
      "28e5a76ec5b448c7b2d339913fb721c6",
      "d5d73be36bdb4ddb8fcd92f1ae7a2856",
      "f403167cb47840a3b0c796ae4c304401"
     ]
    },
    "id": "wj24fjXN0l6v",
    "outputId": "3c1eed33-c31c-4b72-bcda-fdd64744560b"
   },
   "outputs": [],
   "source": [
    "en_question = \"Is this apartment conveniently located?\"\n",
    "\n",
    "result = rag_pipeline.run({\"router\": {\"text\": en_question}, \"prompt_builder\": {\"query\": en_question}})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "i-2P5oqMeUmC",
    "outputId": "8151923f-bbb1-4e6a-fe4e-08c0d7cfcd49"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Yes, the apartment is conveniently located.\n"
     ]
    }
   ],
   "source": [
    "print(result[\"llm\"][\"replies\"][0].text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "U4ChKAl1EKni"
   },
   "source": [
    "How does the pipeline perform en español?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 49,
     "referenced_widgets": [
      "cb611c28471e487a8c53a7af8d0f7ae7",
      "c3876ec6082f466c89d14ea2dccd8207",
      "f4f835630d074a618f4389c69d1a75d2",
      "713bf7f3026f4a1daa52df12016caf82",
      "ae4725f43a3846acbdcbbf79f51166d0",
      "f0ff1b09bbc34065961a09ee894207bd",
      "d58eb54b8b04455b9e506598491b5b2b",
      "3115ad83af834fe4b4fa12362205d98c",
      "34c2218b0a4d4ba486530aeac007b00a",
      "dbdbd1d389d74c06acd9a1d3066c82dc",
      "7b62bd3498bb49ec9e1db68ca088e7ae"
     ]
    },
    "id": "B4_Be1bs1jxJ",
    "outputId": "0b96cf29-d633-4c9b-f54c-a785e1c2cbe4"
   },
   "outputs": [],
   "source": [
    "es_question = \"¿El desayuno es genial?\"\n",
    "\n",
    "result = rag_pipeline.run({\"router\": {\"text\": es_question}, \"prompt_builder\": {\"query\": es_question}})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "w_1wibY61sjk",
    "outputId": "54f7506e-9af1-42b8-c0c9-cd13fb4cd9eb"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sí, el desayuno es considerado estupendo.\n"
     ]
    }
   ],
   "source": [
    "print(result[\"llm\"][\"replies\"][0].text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "IhHIJYjbTpAw"
   },
   "source": [
    "## What's next\n",
    "\n",
    "If you've been following along, now you know how to incorporate language detection into query and indexing Haystack piplines. Go forth and build the international application of your dreams. 🗺️\n",
    "\n",
    "\n",
    "If you liked this tutorial, there's more to learn about Haystack:\n",
    "- [Serializing Haystack Pipelines](https://haystack.deepset.ai/tutorials/29_serializing_pipelines)\n",
    "-  [Generating Structured Output with Loop-Based Auto-Correction](https://haystack.deepset.ai/tutorials/28_structured_output_with_loop)\n",
    "- [Preprocessing Different File Types](https://haystack.deepset.ai/tutorials/30_file_type_preprocessing_index_pipeline)\n",
    "\n",
    "To stay up to date on the latest Haystack developments, you can [sign up for our newsletter](https://landing.deepset.ai/haystack-community-updates)."
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "gpuType": "T4",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
