{
 "cells": [
  {
   "cell_type": "raw",
   "id": "dbb38c29-59a4-43a0-87d1-8a09796f8ed8",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_position: 4\n",
    "title: Retrievers\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1d4b55d-d8ef-4b3c-852f-837b1a217227",
   "metadata": {},
   "source": [
    ":::info\n",
    "\n",
    "Head to [Integrations](/docs/integrations/retrievers/) for documentation on built-in retriever integrations with 3rd-party tools.\n",
    "\n",
    ":::\n",
    "\n",
    "A retriever is an interface that returns documents given an unstructured query. It is more general than a vector store.\n",
    "A retriever does not need to be able to store documents, only to return (or retrieve) them. Vector stores can be used\n",
    "as the backbone of a retriever, but there are other types of retrievers as well.\n",
    "\n",
    "Retrievers implement the [Runnable interface](/docs/expression_language/interface), the basic building block of the [LangChain Expression Language (LCEL)](/docs/expression_language/). This means they support `invoke`, `ainvoke`, `stream`, `astream`, `batch`, `abatch`, `astream_log` calls.\n",
    "\n",
    "Retrievers accept a string query as input and return a list of `Document`'s as output."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9bf5d37b-20ae-4b70-ae9d-4c0a3fcc9f77",
   "metadata": {},
   "source": [
    "## Get started\n",
    "\n",
    "In this example we'll use a `Chroma` vector store-backed retriever. To get setup we'll need to run:\n",
    "\n",
    "```bash\n",
    "pip install chromadb\n",
    "```\n",
    "\n",
    "And download the state_of_the_union.txt file [here](https://github.com/langchain-ai/langchain/blob/master/docs/docs/modules/state_of_the_union.txt)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8cf15d4a-613b-4d2f-b1e6-5e9302bfac66",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.embeddings import OpenAIEmbeddings\n",
    "from langchain.text_splitter import CharacterTextSplitter\n",
    "from langchain.vectorstores import Chroma\n",
    "\n",
    "full_text = open(\"state_of_the_union.txt\", \"r\").read()\n",
    "text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)\n",
    "texts = text_splitter.split_text(full_text)\n",
    "\n",
    "embeddings = OpenAIEmbeddings()\n",
    "db = Chroma.from_texts(texts, embeddings)\n",
    "retriever = db.as_retriever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "3275187b-4a21-45a1-8419-d14c9a54646f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "One of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n",
      "\n",
      "And I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence. \n",
      "\n",
      "A former top litigator in private practice. A former federal public defender. And from a family of public school educators and police officers. A consensus builder. Since she’s been nominated, she’s received a broad range of support—from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \n",
      "\n",
      "And if we are to advance liberty and justice, we need to secure the Border and fix the immigration system. \n",
      "\n",
      "We can do both. At our border, we’ve installed new technology like cutting-edge scanners to better detect drug smuggling.  \n",
      "\n",
      "We’ve set up joint patrols with Mexico and Guatemala to catch more human traffickers.\n"
     ]
    }
   ],
   "source": [
    "retrieved_docs = retriever.invoke(\n",
    "    \"What did the president say about Ketanji Brown Jackson?\"\n",
    ")\n",
    "print(retrieved_docs[0].page_content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cbeeda8b-a828-415e-9de4-0343696e40af",
   "metadata": {},
   "source": [
    "## LCEL\n",
    "\n",
    "Since retrievers are `Runnable`'s, we can easily compose them with other `Runnable` objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "0164dcc1-4734-4a30-ab94-9c035add008d",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.prompts import ChatPromptTemplate\n",
    "from langchain.schema import StrOutputParser\n",
    "from langchain.schema.runnable import RunnablePassthrough\n",
    "\n",
    "template = \"\"\"Answer the question based only on the following context:\n",
    "\n",
    "{context}\n",
    "\n",
    "Question: {question}\n",
    "\"\"\"\n",
    "prompt = ChatPromptTemplate.from_template(template)\n",
    "model = ChatOpenAI()\n",
    "\n",
    "\n",
    "def format_docs(docs):\n",
    "    return \"\\n\\n\".join([d.page_content for d in docs])\n",
    "\n",
    "\n",
    "chain = (\n",
    "    {\"context\": retriever | format_docs, \"question\": RunnablePassthrough()}\n",
    "    | prompt\n",
    "    | model\n",
    "    | StrOutputParser()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "b8ce3176-aadd-4dfe-bfc5-7fe8a1d6d9e2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'The president said that technology plays a crucial role in the future and that passing the Bipartisan Innovation Act will make record investments in emerging technologies and American manufacturing. The president also mentioned Intel\\'s plans to build a semiconductor \"mega site\" and increase their investment from $20 billion to $100 billion, which would be one of the biggest investments in manufacturing in American history.'"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(\"What did the president say about technology?\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
