# How to load JSON

[JSON (JavaScript Object Notation)](https://en.wikipedia.org/wiki/JSON) is an open standard file format and data interchange format that uses human-readable text to store and transmit data objects consisting of attribute–value pairs and arrays (or other serializable values).

[JSON Lines](https://jsonlines.org/) is a file format where each line is a valid JSON value.

LangChain implements a [JSONLoader](https://python.langchain.com/api_reference/community/document_loaders/langchain_community.document_loaders.json_loader.JSONLoader.html)
to convert JSON and JSONL data into LangChain [Document](https://python.langchain.com/api_reference/core/documents/langchain_core.documents.base.Document.html#langchain_core.documents.base.Document)
objects. It uses a specified [jq schema](https://en.wikipedia.org/wiki/Jq_(programming_language)) to parse the JSON files, allowing for the extraction of specific fields into the content
and metadata of the LangChain Document.

It uses the `jq` python package. Check out this [manual](https://stedolan.github.io/jq/manual/#Basicfilters) for a detailed documentation of the `jq` syntax.

Here we will demonstrate:

- How to load JSON and JSONL data into the content of a LangChain `Document`;
- How to load JSON and JSONL data into metadata associated with a `Document`.

```python
#!pip install jq
```

```python
from langchain_community.document_loaders import JSONLoader
```

```python
import json
from pathlib import Path
from pprint import pprint

file_path='./example_data/facebook_chat.json'
data = json.loads(Path(file_path).read_text())
```

```python
pprint(data)
```
```output
    {'image': {'creation_timestamp': 1675549016, 'uri': 'image_of_the_chat.jpg'},
     'is_still_participant': True,
     'joinable_mode': {'link': '', 'mode': 1},
     'magic_words': [],
     'messages': [{'content': 'Bye!',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675597571851},
                  {'content': 'Oh no worries! Bye',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675597435669},
                  {'content': 'No Im sorry it was my mistake, the blue one is not '
                              'for sale',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675596277579},
                  {'content': 'I thought you were selling the blue one!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675595140251},
                  {'content': 'Im not interested in this bag. Im interested in the '
                              'blue one!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675595109305},
                  {'content': 'Here is $129',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595068468},
                  {'photos': [{'creation_timestamp': 1675595059,
                               'uri': 'url_of_some_picture.jpg'}],
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595060730},
                  {'content': 'Online is at least $100',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675595045152},
                  {'content': 'How much do you want?',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675594799696},
                  {'content': 'Goodmorning! $50 is too low.',
                   'sender_name': 'User 2',
                   'timestamp_ms': 1675577876645},
                  {'content': 'Hi! Im interested in your bag. Im offering $50. Let '
                              'me know if you are interested. Thanks!',
                   'sender_name': 'User 1',
                   'timestamp_ms': 1675549022673}],
     'participants': [{'name': 'User 1'}, {'name': 'User 2'}],
     'thread_path': 'inbox/User 1 and User 2 chat',
     'title': 'User 1 and User 2 chat'}
```

## Using `JSONLoader`

Suppose we are interested in extracting the values under the `content` field within the `messages` key of the JSON data. This can easily be done through the `JSONLoader` as shown below.

### JSON file

```python
loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[].content',
    text_content=False)

data = loader.load()
```

```python
pprint(data)
```

```output
    [Document(page_content='Bye!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1}),
     Document(page_content='Oh no worries! Bye', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2}),
     Document(page_content='No Im sorry it was my mistake, the blue one is not for sale', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3}),
     Document(page_content='I thought you were selling the blue one!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4}),
     Document(page_content='Im not interested in this bag. Im interested in the blue one!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5}),
     Document(page_content='Here is $129', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6}),
     Document(page_content='', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7}),
     Document(page_content='Online is at least $100', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8}),
     Document(page_content='How much do you want?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9}),
     Document(page_content='Goodmorning! $50 is too low.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10}),
     Document(page_content='Hi! Im interested in your bag. Im offering $50. Let me know if you are interested. Thanks!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11})]
```

### JSON Lines file

If you want to load documents from a JSON Lines file, you pass `json_lines=True`
and specify `jq_schema` to extract `page_content` from a single JSON object.

```python
file_path = './example_data/facebook_chat_messages.jsonl'
pprint(Path(file_path).read_text())
```

```output
    ('{"sender_name": "User 2", "timestamp_ms": 1675597571851, "content": "Bye!"}\n'
     '{"sender_name": "User 1", "timestamp_ms": 1675597435669, "content": "Oh no '
     'worries! Bye"}\n'
     '{"sender_name": "User 2", "timestamp_ms": 1675596277579, "content": "No Im '
     'sorry it was my mistake, the blue one is not for sale"}\n')
```

```python
loader = JSONLoader(
    file_path='./example_data/facebook_chat_messages.jsonl',
    jq_schema='.content',
    text_content=False,
    json_lines=True)

data = loader.load()
```

```python
pprint(data)
```

```output
    [Document(page_content='Bye!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 1}),
     Document(page_content='Oh no worries! Bye', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 2}),
     Document(page_content='No Im sorry it was my mistake, the blue one is not for sale', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat_messages.jsonl', 'seq_num': 3})]
```


```python
loader = JSONLoader(
    file_path=file_path,
    jq_schema=".data[]",
    content_key=".attributes.message",
    is_content_key_jq_parsable=True,
)

data = loader.load()
```

```python
pprint(data)
```

```output
    [Document(page_content='message1', metadata={'source': '/path/to/sample.json', 'seq_num': 1}),
     Document(page_content='message2', metadata={'source': '/path/to/sample.json', 'seq_num': 2})]
```

## Extracting metadata

Generally, we want to include metadata available in the JSON file into the documents that we create from the content.

The following demonstrates how metadata can be extracted using the `JSONLoader`.

There are some key changes to be noted. In the previous example where we didn't collect the metadata, we managed to directly specify in the schema where the value for the `page_content` can be extracted from.

```
.messages[].content
```

In the current example, we have to tell the loader to iterate over the records in the `messages` field. The jq_schema then has to be:

```
.messages[]
```

This allows us to pass the records (dict) into the `metadata_func` that has to be implemented. The `metadata_func` is responsible for identifying which pieces of information in the record should be included in the metadata stored in the final `Document` object.

Additionally, we now have to explicitly specify in the loader, via the `content_key` argument, the key from the record where the value for the `page_content` needs to be extracted from.

```python
# Define the metadata extraction function.
def metadata_func(record: dict, metadata: dict) -> dict:

    metadata["sender_name"] = record.get("sender_name")
    metadata["timestamp_ms"] = record.get("timestamp_ms")

    return metadata

loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)

data = loader.load()
```

```python
pprint(data)
```

```output
    [Document(page_content='Bye!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'User 2', 'timestamp_ms': 1675597571851}),
     Document(page_content='Oh no worries! Bye', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669}),
     Document(page_content='No Im sorry it was my mistake, the blue one is not for sale', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'User 2', 'timestamp_ms': 1675596277579}),
     Document(page_content='I thought you were selling the blue one!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'User 1', 'timestamp_ms': 1675595140251}),
     Document(page_content='Im not interested in this bag. Im interested in the blue one!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'User 1', 'timestamp_ms': 1675595109305}),
     Document(page_content='Here is $129', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'User 2', 'timestamp_ms': 1675595068468}),
     Document(page_content='', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'sender_name': 'User 2', 'timestamp_ms': 1675595060730}),
     Document(page_content='Online is at least $100', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'User 2', 'timestamp_ms': 1675595045152}),
     Document(page_content='How much do you want?', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'User 1', 'timestamp_ms': 1675594799696}),
     Document(page_content='Goodmorning! $50 is too low.', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'User 2', 'timestamp_ms': 1675577876645}),
     Document(page_content='Hi! Im interested in your bag. Im offering $50. Let me know if you are interested. Thanks!', metadata={'source': '/Users/avsolatorio/WBG/langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'User 1', 'timestamp_ms': 1675549022673})]
```

Now, you will see that the documents contain the metadata associated with the content we extracted.

## The `metadata_func`

As shown above, the `metadata_func` accepts the default metadata generated by the `JSONLoader`. This allows full control to the user with respect to how the metadata is formatted.

For example, the default metadata contains the `source` and the `seq_num` keys. However, it is possible that the JSON data contain these keys as well. The user can then exploit the `metadata_func` to rename the default keys and use the ones from the JSON data.

The example below shows how we can modify the `source` to only contain information of the file source relative to the `langchain` directory.

```python
# Define the metadata extraction function.
def metadata_func(record: dict, metadata: dict) -> dict:

    metadata["sender_name"] = record.get("sender_name")
    metadata["timestamp_ms"] = record.get("timestamp_ms")

    if "source" in metadata:
        source = metadata["source"].split("/")
        source = source[source.index("langchain"):]
        metadata["source"] = "/".join(source)

    return metadata

loader = JSONLoader(
    file_path='./example_data/facebook_chat.json',
    jq_schema='.messages[]',
    content_key="content",
    metadata_func=metadata_func
)

data = loader.load()
```


```python
pprint(data)
```

```output
    [Document(page_content='Bye!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 1, 'sender_name': 'User 2', 'timestamp_ms': 1675597571851}),
     Document(page_content='Oh no worries! Bye', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 2, 'sender_name': 'User 1', 'timestamp_ms': 1675597435669}),
     Document(page_content='No Im sorry it was my mistake, the blue one is not for sale', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 3, 'sender_name': 'User 2', 'timestamp_ms': 1675596277579}),
     Document(page_content='I thought you were selling the blue one!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 4, 'sender_name': 'User 1', 'timestamp_ms': 1675595140251}),
     Document(page_content='Im not interested in this bag. Im interested in the blue one!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 5, 'sender_name': 'User 1', 'timestamp_ms': 1675595109305}),
     Document(page_content='Here is $129', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 6, 'sender_name': 'User 2', 'timestamp_ms': 1675595068468}),
     Document(page_content='', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 7, 'sender_name': 'User 2', 'timestamp_ms': 1675595060730}),
     Document(page_content='Online is at least $100', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 8, 'sender_name': 'User 2', 'timestamp_ms': 1675595045152}),
     Document(page_content='How much do you want?', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 9, 'sender_name': 'User 1', 'timestamp_ms': 1675594799696}),
     Document(page_content='Goodmorning! $50 is too low.', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 10, 'sender_name': 'User 2', 'timestamp_ms': 1675577876645}),
     Document(page_content='Hi! Im interested in your bag. Im offering $50. Let me know if you are interested. Thanks!', metadata={'source': 'langchain/docs/modules/indexes/document_loaders/examples/example_data/facebook_chat.json', 'seq_num': 11, 'sender_name': 'User 1', 'timestamp_ms': 1675549022673})]
```

## Common JSON structures with jq schema

The list below provides a reference to the possible `jq_schema` the user can use to extract content from the JSON data depending on the structure.

```
JSON        -> [{"text": ...}, {"text": ...}, {"text": ...}]
jq_schema   -> ".[].text"

JSON        -> {"key": [{"text": ...}, {"text": ...}, {"text": ...}]}
jq_schema   -> ".key[].text"

JSON        -> ["...", "...", "..."]
jq_schema   -> ".[]"
```


Let's load the Hugging Face Embedding class.

%pip install --upgrade --quiet  langchain sentence_transformers

from langchain_huggingface.embeddings import HuggingFaceEmbeddings

We can also access embedding models via the Hugging Face Inference API, which does not require us to install ``sentence_transformers`` and download models locally.

stdout

Enter your HF Inference API Key:
········

inference_api_key = getpass.getpass("Enter your HF Inference API Key:\n\n")

from langchain_community.embeddings import HuggingFaceInferenceAPIEmbeddings

We can also generate embeddings locally via the Hugging Face Hub package, which requires us to install ``huggingface_hub ``

from langchain_huggingface.embeddings import HuggingFaceEndpointEmbeddings


Let's load the LocalAI Embedding class. In order to use the LocalAI Embedding class, you need to have the LocalAI service hosted somewhere and configure the embedding models. See the documentation at https://localai.io/basics/getting_started/index.html and https://localai.io/features/embeddings/index.html.

from langchain_community.embeddings import LocalAIEmbeddings

Let's load the LocalAI Embedding class with first generation models (e.g. text-search-ada-doc-001/text-search-ada-query-001). Note: These are not recommended models - see [here](https://platform.openai.com/docs/guides/embeddings/what-are-embeddings)

# if you are behind an explicit proxy, you can use the OPENAI_PROXY environment variable to pass through


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "afaf8039",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_label: AzureOpenAI\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a3d6f34",
   "metadata": {},
   "source": [
    "# AzureOpenAIEmbeddings\n",
    "\n",
    "This will help you get started with AzureOpenAI embedding models using LangChain. For detailed documentation on `AzureOpenAIEmbeddings` features and configuration options, please refer to the [API reference](https://python.langchain.com/api_reference/openai/embeddings/langchain_openai.embeddings.azure.AzureOpenAIEmbeddings.html).\n",
    "\n",
    "## Overview\n",
    "### Integration details\n",
    "\n",
    "import { ItemTable } from \"@theme/FeatureTables\";\n",
    "\n",
    "<ItemTable category=\"text_embedding\" item=\"AzureOpenAI\" />\n",
    "\n",
    "## Setup\n",
    "\n",
    "To access AzureOpenAI embedding models you'll need to create an Azure account, get an API key, and install the `langchain-openai` integration package.\n",
    "\n",
    "### Credentials\n",
    "\n",
    "You’ll need to have an Azure OpenAI instance deployed. You can deploy a version on Azure Portal following this [guide](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal).\n",
    "\n",
    "Once you have your instance running, make sure you have the name of your instance and key. You can find the key in the Azure Portal, under the “Keys and Endpoint” section of your instance.\n",
    "\n",
    "```bash\n",
    "AZURE_OPENAI_ENDPOINT=<YOUR API ENDPOINT>\n",
    "AZURE_OPENAI_API_KEY=<YOUR_KEY>\n",
    "AZURE_OPENAI_API_VERSION=\"2024-02-01\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "36521c2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "if not os.getenv(\"OPENAI_API_KEY\"):\n",
    "    os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your AzureOpenAI API key: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c84fb993",
   "metadata": {},
   "source": [
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "39a4953b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"Enter your LangSmith API key: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9664366",
   "metadata": {},
   "source": [
    "### Installation\n",
    "\n",
    "The LangChain AzureOpenAI integration lives in the `langchain-openai` package:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64853226",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install -qU langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45dd1724",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "Now we can instantiate our model object and generate chat completions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9ea7a09b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import AzureOpenAIEmbeddings\n",
    "\n",
    "embeddings = AzureOpenAIEmbeddings(\n",
    "    model=\"text-embedding-3-large\",\n",
    "    # dimensions: Optional[int] = None, # Can specify dimensions with new text-embedding-3 models\n",
    "    # azure_endpoint=\"https://<your-endpoint>.openai.azure.com/\", If not provided, will read env variable AZURE_OPENAI_ENDPOINT\n",
    "    # api_key=... # Can provide an API key directly. If missing read env variable AZURE_OPENAI_API_KEY\n",
    "    # openai_api_version=..., # If not provided, will read env variable AZURE_OPENAI_API_VERSION\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77d271b6",
   "metadata": {},
   "source": [
    "## Indexing and Retrieval\n",
    "\n",
    "Embedding models are often used in retrieval-augmented generation (RAG) flows, both as part of indexing data as well as later retrieving it. For more detailed instructions, please see our RAG tutorials under the [working with external knowledge tutorials](/docs/tutorials/#working-with-external-knowledge).\n",
    "\n",
    "Below, see how to index and retrieve data using the `embeddings` object we initialized above. In this example, we will index and retrieve a sample document in the `InMemoryVectorStore`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d817716b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain is the framework for building context-aware reasoning applications'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create a vector store with a sample text\n",
    "from langchain_core.vectorstores import InMemoryVectorStore\n",
    "\n",
    "text = \"LangChain is the framework for building context-aware reasoning applications\"\n",
    "\n",
    "vectorstore = InMemoryVectorStore.from_texts(\n",
    "    [text],\n",
    "    embedding=embeddings,\n",
    ")\n",
    "\n",
    "# Use the vectorstore as a retriever\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "# Retrieve the most similar text\n",
    "retrieved_documents = retriever.invoke(\"What is LangChain?\")\n",
    "\n",
    "# show the retrieved document's content\n",
    "retrieved_documents[0].page_content"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e02b9855",
   "metadata": {},
   "source": [
    "## Direct Usage\n",
    "\n",
    "Under the hood, the vectorstore and retriever implementations are calling `embeddings.embed_documents(...)` and `embeddings.embed_query(...)` to create embeddings for the text(s) used in `from_texts` and retrieval `invoke` operations, respectively.\n",
    "\n",
    "You can directly call these methods to get embeddings for your own use cases.\n",
    "\n",
    "### Embed single texts\n",
    "\n",
    "You can embed single texts or documents with `embed_query`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0d2befcd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.0011676070280373096, 0.007125577889382839, -0.014674457721412182, -0.034061674028635025, 0.01128\n"
     ]
    }
   ],
   "source": [
    "single_vector = embeddings.embed_query(text)\n",
    "print(str(single_vector)[:100])  # Show the first 100 characters of the vector"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b5a7d03",
   "metadata": {},
   "source": [
    "### Embed multiple texts\n",
    "\n",
    "You can embed multiple texts with `embed_documents`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2f4d6e97",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [


"cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "zn_zeRGP64DJ"
   },
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet  langchain faiss-cpu tiktoken langchain_community\n",
    "\n",
    "from operator import itemgetter\n",
    "\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from langchain_core.runnables import RunnablePassthrough\n",
    "from langchain_nvidia_ai_endpoints import ChatNVIDIA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 36
    },
    "id": "zIXyr9Vd7CED",
    "outputId": "a8d36812-c3e0-4fd4-804a-4b5ba43948e5"
   },
   "outputs": [],
   "source": [
    "vectorstore = FAISS.from_texts(\n",
    "    [\"harrison worked at kensho\"],\n",
    "    embedding=NVIDIAEmbeddings(model=\"NV-Embed-QA\"),\n",
    ")\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\n",
    "            \"system\",\n",
    "            \"Answer solely based on the following context:\\n<Documents>\\n{context}\\n</Documents>\",\n",
    "        ),\n",
    "        (\"user\", \"{question}\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "model = ChatNVIDIA(model=\"ai-mixtral-8x7b-instruct\")\n",
    "\n",
    "chain = (\n",
    "    {\"context\": retriever, \"question\": RunnablePassthrough()}\n",
    "    | prompt\n",
    "    | model\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "chain.invoke(\"where did harrison work?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 36
    },
    "id": "OuY62kJ28oNK",
    "outputId": "672ff6df-64d8-442b-9143-f69dbc09f763"
   },
   "outputs": [],
   "source": [
    "prompt = ChatPromptTemplate.from_messages(\n",
    "    [\n",
    "        (\n",
    "            \"system\",\n",
    "            \"Answer using information solely based on the following context:\\n<Documents>\\n{context}\\n</Documents>\"\n",
    "            \"\\nSpeak only in the following language: {language}\",\n",
    "        ),\n",
    "        (\"user\", \"{question}\"),\n",
    "    ]\n",
    ")\n",
    "\n",
    "chain = (\n",
    "    {\n",
    "        \"context\": itemgetter(\"question\") | retriever,\n",
    "        \"question\": itemgetter(\"question\"),\n",
    "        \"language\": itemgetter(\"language\"),\n",
    "    }\n",
    "    | prompt\n",
    "    | model\n",
    "    | StrOutputParser()\n",
    ")\n",
    "\n",
    "chain.invoke({\"question\": \"where did harrison work\", \"language\": \"italian\"})"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "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.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}


Let's load the `SageMaker Endpoints Embeddings` class. The class can be used if you host, e.g. your own Hugging Face model on SageMaker.

For instructions on how to do this, please see [here](https://www.philschmid.de/custom-inference-huggingface-sagemaker).

**Note**: In order to handle batched requests, you will need to adjust the return line in the `predict_fn()` function within the custom `inference.py` script:

from langchain_community.embeddings import SagemakerEndpointEmbeddings

from langchain_community.embeddings.sagemaker_endpoint import EmbeddingsContentHandler

def transform_input(self, inputs: list[str], model_kwargs: Dict) -> bytes:

Transforms the input into bytes that can be consumed by SageMaker endpoint.

model_kwargs: Additional keyword arguments to be passed to the endpoint.

# Example: inference.py expects a JSON string with a "inputs" key:

input_str = json.dumps({"inputs": inputs, **model_kwargs})

def transform_output(self, output: bytes) -> List[List[float]]:

Transforms the bytes output from the endpoint into a list of embeddings.

output: The bytes output from SageMaker endpoint.

The transformed output - list of embeddings

The length of the outer list is the number of input strings.

The length of the inner lists is the embedding dimension.

# Example: inference.py returns a JSON string with the list of

# embeddings = SagemakerEndpointEmbeddings(

#     endpoint_name="huggingface-pytorch-inference-2023-03-21-16-14-03-834",


{
 "cells": [
  {
   "cell_type": "raw",
   "id": "afaf8039",
   "metadata": {},
   "source": [
    "---\n",
    "sidebar_label: OpenAI\n",
    "keywords: [openaiembeddings]\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a3d6f34",
   "metadata": {},
   "source": [
    "# OpenAIEmbeddings\n",
    "\n",
    "This will help you get started with OpenAI embedding models using LangChain. For detailed documentation on `OpenAIEmbeddings` features and configuration options, please refer to the [API reference](https://python.langchain.com/api_reference/openai/embeddings/langchain_openai.embeddings.base.OpenAIEmbeddings.html).\n",
    "\n",
    "\n",
    "## Overview\n",
    "### Integration details\n",
    "\n",
    "import { ItemTable } from \"@theme/FeatureTables\";\n",
    "\n",
    "<ItemTable category=\"text_embedding\" item=\"OpenAI\" />\n",
    "\n",
    "## Setup\n",
    "\n",
    "To access OpenAI embedding models you'll need to create a/an OpenAI account, get an API key, and install the `langchain-openai` integration package.\n",
    "\n",
    "### Credentials\n",
    "\n",
    "Head to [platform.openai.com](https://platform.openai.com) to sign up to OpenAI and generate an API key. Once you’ve done this set the OPENAI_API_KEY environment variable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "36521c2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "if not os.getenv(\"OPENAI_API_KEY\"):\n",
    "    os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"Enter your OpenAI API key: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c84fb993",
   "metadata": {},
   "source": [
    "If you want to get automated tracing of your model calls you can also set your [LangSmith](https://docs.smith.langchain.com/) API key by uncommenting below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "39a4953b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass(\"Enter your LangSmith API key: \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d9664366",
   "metadata": {},
   "source": [
    "### Installation\n",
    "\n",
    "The LangChain OpenAI integration lives in the `langchain-openai` package:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64853226",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install -qU langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45dd1724",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "Now we can instantiate our model object and generate chat completions:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9ea7a09b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_openai import OpenAIEmbeddings\n",
    "\n",
    "embeddings = OpenAIEmbeddings(\n",
    "    model=\"text-embedding-3-large\",\n",
    "    # With the `text-embedding-3` class\n",
    "    # of models, you can specify the size\n",
    "    # of the embeddings you want returned.\n",
    "    # dimensions=1024\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77d271b6",
   "metadata": {},
   "source": [
    "## Indexing and Retrieval\n",
    "\n",
    "Embedding models are often used in retrieval-augmented generation (RAG) flows, both as part of indexing data as well as later retrieving it. For more detailed instructions, please see our RAG tutorials under the [working with external knowledge tutorials](/docs/tutorials/#working-with-external-knowledge).\n",
    "\n",
    "Below, see how to index and retrieve data using the `embeddings` object we initialized above. In this example, we will index and retrieve a sample document in the `InMemoryVectorStore`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d817716b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LangChain is the framework for building context-aware reasoning applications'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Create a vector store with a sample text\n",
    "from langchain_core.vectorstores import InMemoryVectorStore\n",
    "\n",
    "text = \"LangChain is the framework for building context-aware reasoning applications\"\n",
    "\n",
    "vectorstore = InMemoryVectorStore.from_texts(\n",
    "    [text],\n",
    "    embedding=embeddings,\n",
    ")\n",
    "\n",
    "# Use the vectorstore as a retriever\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "# Retrieve the most similar text\n",
    "retrieved_documents = retriever.invoke(\"What is LangChain?\")\n",
    "\n",
    "# show the retrieved document's content\n",
    "retrieved_documents[0].page_content"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e02b9855",
   "metadata": {},
   "source": [
    "## Direct Usage\n",
    "\n",
    "Under the hood, the vectorstore and retriever implementations are calling `embeddings.embed_documents(...)` and `embeddings.embed_query(...)` to create embeddings for the text(s) used in `from_texts` and retrieval `invoke` operations, respectively.\n",
    "\n",
    "You can directly call these methods to get embeddings for your own use cases.\n",
    "\n",
    "### Embed single texts\n",
    "\n",
    "You can embed single texts or documents with `embed_query`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0d2befcd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.019276829436421394, 0.0037708976306021214, -0.03294256329536438, 0.0037671267054975033, 0.008175\n"
     ]
    }
   ],
   "source": [
    "single_vector = embeddings.embed_query(text)\n",
    "print(str(single_vector)[:100])  # Show the first 100 characters of the vector"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1b5a7d03",
   "metadata": {},
   "source": [
    "### Embed multiple texts\n",
    "\n",
    "You can embed multiple texts with `embed_documents`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2f4d6e97",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.019260549917817116, 0.0037612367887049913, -0.03291035071015358, 0.003757466096431017, 0.0082049\n",
      "[-0.010181212797760963, 0.023419594392180443, -0.04215526953339577, -0.001532090245746076, -0.023573\n"
     ]
    }
   ],
   "source": [
    "text2 = (\n",
    "    \"LangGraph is a library for building stateful, multi-actor applications with LLMs\"\n",
    ")\n",
    "two_vectors = embeddings.embed_documents([text, text2])\n",
    "for vector in two_vectors:\n",


{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Outline\n",
    "\n",
    ">[Outline](https://www.getoutline.com/) is an open-source collaborative knowledge base platform designed for team information sharing.\n",
    "\n",
    "This notebook shows how to retrieve documents from your Outline instance into the Document format that is used downstream."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet langchain langchain-openai"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You first need to [create an api key](https://www.getoutline.com/developers#section/Authentication) for your Outline instance. Then you need to set the following environment variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ[\"OUTLINE_API_KEY\"] = \"xxx\"\n",
    "os.environ[\"OUTLINE_INSTANCE_URL\"] = \"https://app.getoutline.com\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`OutlineRetriever` has these arguments:\n",
    "- optional `top_k_results`: default=3. Use it to limit number of documents retrieved.\n",
    "- optional `load_all_available_meta`: default=False. By default only the most important fields retrieved: `title`, `source` (the url of the document). If True, other fields also retrieved.\n",
    "- optional `doc_content_chars_max` default=4000. Use it to limit the number of characters for each document retrieved.\n",
    "\n",
    "`get_relevant_documents()` has one argument, `query`: free text which used to find documents in your Outline instance."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Running retriever"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.retrievers import OutlineRetriever"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "retriever = OutlineRetriever()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Document(page_content='This walkthrough demonstrates how to use an agent optimized for conversation. Other agents are often optimized for using tools to figure out the best response, which is not ideal in a conversational setting where you may want the agent to be able to chat with the user as well.\\n\\nIf we compare it to the standard ReAct agent, the main difference is the prompt. We want it to be much more conversational.\\n\\nfrom langchain.agents import AgentType, Tool, initialize_agent\\n\\nfrom langchain_openai import OpenAI\\n\\nfrom langchain.memory import ConversationBufferMemory\\n\\nfrom langchain_community.utilities import SerpAPIWrapper\\n\\nsearch = SerpAPIWrapper() tools = \\\\[ Tool( name=\"Current Search\", func=search.run, description=\"useful for when you need to answer questions about current events or the current state of the world\", ), \\\\]\\n\\n\\\\\\nllm = OpenAI(temperature=0)\\n\\nUsing LCEL\\n\\nWe will first show how to create this agent using LCEL\\n\\nfrom langchain import hub\\n\\nfrom langchain.agents.format_scratchpad import format_log_to_str\\n\\nfrom langchain.agents.output_parsers import ReActSingleInputOutputParser\\n\\nfrom langchain.tools.render import render_text_description\\n\\nprompt = hub.pull(\"hwchase17/react-chat\")\\n\\nprompt = prompt.partial( tools=render_text_description(tools), tool_names=\", \".join(\\\\[[t.name](http://t.name) for t in tools\\\\]), )\\n\\nllm_with_stop = llm.bind(stop=\\\\[\"\\\\nObservation\"\\\\])\\n\\nagent = ( { \"input\": lambda x: x\\\\[\"input\"\\\\], \"agent_scratchpad\": lambda x: format_log_to_str(x\\\\[\"intermediate_steps\"\\\\]), \"chat_history\": lambda x: x\\\\[\"chat_history\"\\\\], } | prompt | llm_with_stop | ReActSingleInputOutputParser() )\\n\\nfrom langchain.agents import AgentExecutor\\n\\nmemory = ConversationBufferMemory(memory_key=\"chat_history\") agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=memory)\\n\\nagent_executor.invoke({\"input\": \"hi, i am bob\"})\\\\[\"output\"\\\\]\\n\\n```\\n> Entering new AgentExecutor chain...\\n\\nThought: Do I need to use a tool? No\\nFinal Answer: Hi Bob, nice to meet you! How can I help you today?\\n\\n> Finished chain.\\n```\\n\\n\\\\\\n\\'Hi Bob, nice to meet you! How can I help you today?\\'\\n\\nagent_executor.invoke({\"input\": \"whats my name?\"})\\\\[\"output\"\\\\]\\n\\n```\\n> Entering new AgentExecutor chain...\\n\\nThought: Do I need to use a tool? No\\nFinal Answer: Your name is Bob.\\n\\n> Finished chain.\\n```\\n\\n\\\\\\n\\'Your name is Bob.\\'\\n\\nagent_executor.invoke({\"input\": \"what are some movies showing 9/21/2023?\"})\\\\[\"output\"\\\\]\\n\\n```\\n> Entering new AgentExecutor chain...\\n\\nThought: Do I need to use a tool? Yes\\nAction: Current Search\\nAction Input: Movies showing 9/21/2023[\\'September 2023 Movies: The Creator • Dumb Money • Expend4bles • The Kill Room • The Inventor • The Equalizer 3 • PAW Patrol: The Mighty Movie, ...\\'] Do I need to use a tool? No\\nFinal Answer: According to current search, some movies showing on 9/21/2023 are The Creator, Dumb Money, Expend4bles, The Kill Room, The Inventor, The Equalizer 3, and PAW Patrol: The Mighty Movie.\\n\\n> Finished chain.\\n```\\n\\n\\\\\\n\\'According to current search, some movies showing on 9/21/2023 are The Creator, Dumb Money, Expend4bles, The Kill Room, The Inventor, The Equalizer 3, and PAW Patrol: The Mighty Movie.\\'\\n\\n\\\\\\nUse the off-the-shelf agent\\n\\nWe can also create this agent using the off-the-shelf agent class\\n\\nagent_executor = initialize_agent( tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION, verbose=True, memory=memory, )\\n\\nUse a chat model\\n\\nWe can also use a chat model here. The main difference here is in the prompts used.\\n\\nfrom langchain import hub\\n\\nfrom langchain_openai import ChatOpenAI\\n\\nprompt = hub.pull(\"hwchase17/react-chat-json\") chat_model = ChatOpenAI(temperature=0, model=\"gpt-4\")\\n\\nprompt = prompt.partial( tools=render_text_description(tools), tool_names=\", \".join(\\\\[[t.name](http://t.name) for t in tools\\\\]), )\\n\\nchat_model_with_stop = chat_model.bind(stop=\\\\[\"\\\\nObservation\"\\\\])\\n\\nfrom langchain.agents.format_scratchpad import format_log_to_messages\\n\\nfrom langchain.agents.output_parsers import JSONAgentOutputParser\\n\\n# We need some extra steering, or the c', metadata={'title': 'Conversational', 'source': 'https://d01.getoutline.com/doc/conversational-B5dBkUgQ4b'}),\n",


" Document(page_content='Quickstart\\n\\nIn this quickstart we\\'ll show you how to:\\n\\nGet setup with LangChain, LangSmith and LangServe\\n\\nUse the most basic and common components of LangChain: prompt templates, models, and output parsers\\n\\nUse LangChain Expression Language, the protocol that LangChain is built on and which facilitates component chaining\\n\\nBuild a simple application with LangChain\\n\\nTrace your application with LangSmith\\n\\nServe your application with LangServe\\n\\nThat\\'s a fair amount to cover! Let\\'s dive in.\\n\\nSetup\\n\\nInstallation\\n\\nTo install LangChain run:\\n\\nPip\\n\\nConda\\n\\npip install langchain\\n\\nFor more details, see our Installation guide.\\n\\nEnvironment\\n\\nUsing LangChain will usually require integrations with one or more model providers, data stores, APIs, etc. For this example, we\\'ll use OpenAI\\'s model APIs.\\n\\nFirst we\\'ll need to install their Python package:\\n\\npip install openai\\n\\nAccessing the API requires an API key, which you can get by creating an account and heading here. Once we have a key we\\'ll want to set it as an environment variable by running:\\n\\nexport OPENAI_API_KEY=\"...\"\\n\\nIf you\\'d prefer not to set an environment variable you can pass the key in directly via the openai_api_key named parameter when initiating the OpenAI LLM class:\\n\\nfrom langchain_openai import ChatOpenAI\\n\\nllm = ChatOpenAI(openai_api_key=\"...\")\\n\\nLangSmith\\n\\nMany of the applications you build with LangChain will contain multiple steps with multiple invocations of LLM calls. As these applications get more and more complex, it becomes crucial to be able to inspect what exactly is going on inside your chain or agent. The best way to do this is with LangSmith.\\n\\nNote that LangSmith is not needed, but it is helpful. If you do want to use LangSmith, after you sign up at the link above, make sure to set your environment variables to start logging traces:\\n\\nexport LANGCHAIN_TRACING_V2=\"true\" export LANGCHAIN_API_KEY=...\\n\\nLangServe\\n\\nLangServe helps developers deploy LangChain chains as a REST API. You do not need to use LangServe to use LangChain, but in this guide we\\'ll show how you can deploy your app with LangServe.\\n\\nInstall with:\\n\\npip install \"langserve\\\\[all\\\\]\"\\n\\nBuilding with LangChain\\n\\nLangChain provides many modules that can be used to build language model applications. Modules can be used as standalones in simple applications and they can be composed for more complex use cases. Composition is powered by LangChain Expression Language (LCEL), which defines a unified Runnable interface that many modules implement, making it possible to seamlessly chain components.\\n\\nThe simplest and most common chain contains three things:\\n\\nLLM/Chat Model: The language model is the core reasoning engine here. In order to work with LangChain, you need to understand the different types of language models and how to work with them. Prompt Template: This provides instructions to the language model. This controls what the language model outputs, so understanding how to construct prompts and different prompting strategies is crucial. Output Parser: These translate the raw response from the language model to a more workable format, making it easy to use the output downstream. In this guide we\\'ll cover those three components individually, and then go over how to combine them. Understanding these concepts will set you up well for being able to use and customize LangChain applications. Most LangChain applications allow you to configure the model and/or the prompt, so knowing how to take advantage of this will be a big enabler.\\n\\nLLM / Chat Model\\n\\nThere are two types of language models:\\n\\nLLM: underlying model takes a string as input and returns a string\\n\\nChatModel: underlying model takes a list of messages as input and returns a message\\n\\nStrings are simple, but what exactly are messages? The base message interface is defined by BaseMessage, which has two required attributes:\\n\\ncontent: The content of the message. Usually a string. role: The entity from which the BaseMessage is coming. LangChain provides several ob', metadata={'title': 'Quick Start', 'source': 'https://d01.getoutline.com/doc/quick-start-jGuGGGOTuL'}),\n",


" Document(page_content='This walkthrough showcases using an agent to implement the [ReAct](https://react-lm.github.io/) logic.\\n\\n```javascript\\nfrom langchain.agents import AgentType, initialize_agent, load_tools\\nfrom langchain_openai import OpenAI\\n```\\n\\nFirst, let\\'s load the language model we\\'re going to use to control the agent.\\n\\n```javascript\\nllm = OpenAI(temperature=0)\\n```\\n\\nNext, let\\'s load some tools to use. Note that the llm-math tool uses an LLM, so we need to pass that in.\\n\\n```javascript\\ntools = load_tools([\"serpapi\", \"llm-math\"], llm=llm)\\n```\\n\\n## Using LCEL[\\u200b](/docs/modules/agents/agent_types/react#using-lcel \"Direct link to Using LCEL\")\\n\\nWe will first show how to create the agent using LCEL\\n\\n```javascript\\nfrom langchain import hub\\nfrom langchain.agents.format_scratchpad import format_log_to_str\\nfrom langchain.agents.output_parsers import ReActSingleInputOutputParser\\nfrom langchain.tools.render import render_text_description\\n```\\n\\n```javascript\\nprompt = hub.pull(\"hwchase17/react\")\\nprompt = prompt.partial(\\n    tools=render_text_description(tools),\\n    tool_names=\", \".join([t.name for t in tools]),\\n)\\n```\\n\\n```javascript\\nllm_with_stop = llm.bind(stop=[\"\\\\nObservation\"])\\n```\\n\\n```javascript\\nagent = (\\n    {\\n        \"input\": lambda x: x[\"input\"],\\n        \"agent_scratchpad\": lambda x: format_log_to_str(x[\"intermediate_steps\"]),\\n    }\\n    | prompt\\n    | llm_with_stop\\n    | ReActSingleInputOutputParser()\\n)\\n```\\n\\n```javascript\\nfrom langchain.agents import AgentExecutor\\n```\\n\\n```javascript\\nagent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)\\n```\\n\\n```javascript\\nagent_executor.invoke(\\n    {\\n        \"input\": \"Who is Leo DiCaprio\\'s girlfriend? What is her current age raised to the 0.43 power?\"\\n    }\\n)\\n```\\n\\n```javascript\\n    \\n    \\n    > Entering new AgentExecutor chain...\\n     I need to find out who Leo DiCaprio\\'s girlfriend is and then calculate her age raised to the 0.43 power.\\n    Action: Search\\n    Action Input: \"Leo DiCaprio girlfriend\"model Vittoria Ceretti I need to find out Vittoria Ceretti\\'s age\\n    Action: Search\\n    Action Input: \"Vittoria Ceretti age\"25 years I need to calculate 25 raised to the 0.43 power\\n    Action: Calculator\\n    Action Input: 25^0.43Answer: 3.991298452658078 I now know the final answer\\n    Final Answer: Leo DiCaprio\\'s girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\\n    \\n    > Finished chain.\\n\\n\\n\\n\\n\\n    {\\'input\\': \"Who is Leo DiCaprio\\'s girlfriend? What is her current age raised to the 0.43 power?\",\\n     \\'output\\': \"Leo DiCaprio\\'s girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\"}\\n```\\n\\n## Using ZeroShotReactAgent[\\u200b](/docs/modules/agents/agent_types/react#using-zeroshotreactagent \"Direct link to Using ZeroShotReactAgent\")\\n\\nWe will now show how to use the agent with an off-the-shelf agent implementation\\n\\n```javascript\\nagent_executor = initialize_agent(\\n    tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True\\n)\\n```\\n\\n```javascript\\nagent_executor.invoke(\\n    {\\n        \"input\": \"Who is Leo DiCaprio\\'s girlfriend? What is her current age raised to the 0.43 power?\"\\n    }\\n)\\n```\\n\\n```javascript\\n    \\n    \\n    > Entering new AgentExecutor chain...\\n     I need to find out who Leo DiCaprio\\'s girlfriend is and then calculate her age raised to the 0.43 power.\\n    Action: Search\\n    Action Input: \"Leo DiCaprio girlfriend\"\\n    Observation: model Vittoria Ceretti\\n    Thought: I need to find out Vittoria Ceretti\\'s age\\n    Action: Search\\n    Action Input: \"Vittoria Ceretti age\"\\n    Observation: 25 years\\n    Thought: I need to calculate 25 raised to the 0.43 power\\n    Action: Calculator\\n    Action Input: 25^0.43\\n    Observation: Answer: 3.991298452658078\\n    Thought: I now know the final answer\\n    Final Answer: Leo DiCaprio\\'s girlfriend is Vittoria Ceretti and her current age raised to the 0.43 power is 3.991298452658078.\\n    \\n    > Finished chain.\\n\\n\\n\\n\\n\\n    {\\'input\\': \"Who is L', metadata={'title': 'ReAct', 'source': 'https://d01.getoutline.com/doc/react-d6rxRS1MHk'})]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "retriever.invoke(\"LangChain\", doc_content_chars_max=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Answering Questions on Outline Documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "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(\"OpenAI API Key:\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import ConversationalRetrievalChain\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "model = ChatOpenAI(model=\"gpt-3.5-turbo\")\n",
    "qa = ConversationalRetrievalChain.from_llm(model, retriever=retriever)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'question': 'what is langchain?',\n",
       " 'chat_history': {},\n",
       " 'answer': \"LangChain is a framework for developing applications powered by language models. It provides a set of libraries and tools that enable developers to build context-aware and reasoning-based applications. LangChain allows you to connect language models to various sources of context, such as prompt instructions, few-shot examples, and content, to enhance the model's responses. It also supports the composition of multiple language model components using LangChain Expression Language (LCEL). Additionally, LangChain offers off-the-shelf chains, templates, and integrations for easy application development. LangChain can be used in conjunction with LangSmith for debugging and monitoring chains, and with LangServe for deploying applications as a REST API.\"}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "qa({\"question\": \"what is langchain?\", \"chat_history\": {}})"
   ]
  }
 ],
 "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",


{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a0eb506a-f52e-4a92-9204-63233c3eb5bd",
   "metadata": {},
   "source": [
    "# DocArray\n",
    "\n",
    ">[DocArray](https://github.com/docarray/docarray) is a versatile, open-source tool for managing your multi-modal data. It lets you shape your data however you want, and offers the flexibility to store and search it using various document index backends. Plus, it gets even better - you can utilize your `DocArray` document index to create a `DocArrayRetriever`, and build awesome Langchain apps!\n",
    "\n",
    "This notebook is split into two sections. The [first section](#document-index-backends) offers an introduction to all five supported document index backends. It provides guidance on setting up and indexing each backend and also instructs you on how to build a `DocArrayRetriever` for finding relevant documents. \n",
    "In the [second section](#movie-retrieval-using-hnswdocumentindex), we'll select one of these backends and illustrate how to use it through a basic example.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51db6285-58db-481d-8d24-b13d1888056b",
   "metadata": {},
   "source": [
    "## Document Index Backends"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b72a4512-6318-4572-adf2-12b06b2d2e72",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-03-06T23:32:57.103738Z",
     "iopub.status.busy": "2024-03-06T23:32:57.103379Z",
     "iopub.status.idle": "2024-03-06T23:32:57.106662Z",
     "shell.execute_reply": "2024-03-06T23:32:57.106261Z",
     "shell.execute_reply.started": "2024-03-06T23:32:57.103723Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "from docarray import BaseDoc\n",
    "from docarray.typing import NdArray\n",
    "from langchain_community.embeddings import FakeEmbeddings\n",
    "from langchain_community.retrievers import DocArrayRetriever\n",
    "\n",
    "embeddings = FakeEmbeddings(size=32)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdac41b4-67a1-483f-b3d6-fe662b7bdacd",
   "metadata": {},
   "source": [
    "Before you start building the index, it's important to define your document schema. This determines what fields your documents will have and what type of data each field will hold.\n",
    "\n",
    "For this demonstration, we'll create a somewhat random schema containing 'title' (str), 'title_embedding' (numpy array), 'year' (int), and 'color' (str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8a97c56a-63a0-405c-929f-35e1ded79489",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "class MyDoc(BaseDoc):\n",
    "    title: str\n",
    "    title_embedding: NdArray[32]\n",
    "    year: int\n",
    "    color: str"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "297bfdb5-6bfe-47ce-90e7-feefc4c160b7",
   "metadata": {
    "tags": []
   },
   "source": [
    "### InMemoryExactNNIndex\n",
    "\n",
    "`InMemoryExactNNIndex` stores all Documents in memory. It is a great starting point for small datasets, where you may not want to launch a database server.\n",
    "\n",
    "Learn more here: https://docs.docarray.org/user_guide/storing/index_in_memory/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8b6e6343-88c2-4206-92fd-5a634d39da09",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from docarray.index import InMemoryExactNNIndex\n",
    "\n",
    "# initialize the index\n",
    "db = InMemoryExactNNIndex[MyDoc]()\n",
    "# index data\n",
    "db.index(\n",
    "    [\n",
    "        MyDoc(\n",
    "            title=f\"My document {i}\",\n",
    "            title_embedding=embeddings.embed_query(f\"query {i}\"),\n",
    "            year=i,\n",
    "            color=random.choice([\"red\", \"green\", \"blue\"]),\n",
    "        )\n",
    "        for i in range(100)\n",
    "    ]\n",
    ")\n",
    "# optionally, you can create a filter query\n",
    "filter_query = {\"year\": {\"$lte\": 90}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "142060e5-3e0c-4fa2-9f69-8c91f53617f4",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Document(page_content='My document 56', metadata={'id': '1f33e58b6468ab722f3786b96b20afe6', 'year': 56, 'color': 'red'})]\n"
     ]
    }
   ],
   "source": [
    "# create a retriever\n",
    "retriever = DocArrayRetriever(\n",
    "    index=db,\n",
    "    embeddings=embeddings,\n",
    "    search_field=\"title_embedding\",\n",
    "    content_field=\"title\",\n",
    "    filters=filter_query,\n",
    ")\n",
    "\n",
    "# find the relevant document\n",
    "doc = retriever.invoke(\"some query\")\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9daf2c4-6568-4a49-ba6e-21687962d2c1",
   "metadata": {},
   "source": [
    "### HnswDocumentIndex\n",
    "\n",
    "`HnswDocumentIndex` is a lightweight Document Index implementation that runs fully locally and is best suited for small- to medium-sized datasets. It stores vectors on disk in [hnswlib](https://github.com/nmslib/hnswlib), and stores all other data in [SQLite](https://www.sqlite.org/index.html).\n",
    "\n",
    "Learn more here: https://docs.docarray.org/user_guide/storing/index_hnswlib/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e0be3c00-470f-4448-92cc-3985f5b05809",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from docarray.index import HnswDocumentIndex\n",
    "\n",
    "# initialize the index\n",
    "db = HnswDocumentIndex[MyDoc](work_dir=\"hnsw_index\")\n",
    "\n",
    "# index data\n",
    "db.index(\n",
    "    [\n",
    "        MyDoc(\n",
    "            title=f\"My document {i}\",\n",
    "            title_embedding=embeddings.embed_query(f\"query {i}\"),\n",
    "            year=i,\n",
    "            color=random.choice([\"red\", \"green\", \"blue\"]),\n",
    "        )\n",
    "        for i in range(100)\n",
    "    ]\n",
    ")\n",
    "# optionally, you can create a filter query\n",
    "filter_query = {\"year\": {\"$lte\": 90}}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ea9eb5a0-a8f2-465b-81e2-52fb773466cf",


"question = \"Show me all the items purchased from AstroTech Solutions\"\n",
    "\n",
    "prompt = ChatPromptTemplate.from_template(\n",
    "    \"\"\"Answer the question based only on the context provided.\n",
    "\n",
    "    Context: {context}\n",
    "\n",
    "    Question: {question}\"\"\"\n",
    ")\n",
    "\n",
    "\n",
    "def format_docs(docs):\n",
    "    return \"\\n\\n\".join(doc.page_content for doc in docs)\n",
    "\n",
    "\n",
    "chain = (\n",
    "    {\"context\": retriever | format_docs, \"question\": RunnablePassthrough()}\n",
    "    | prompt\n",
    "    | llm\n",
    "    | StrOutputParser()\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "d47c37dd-5c11-416c-a3b6-bec413cd70e8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'- Gravitational Wave Detector Kit: $800\\n- Exoplanet Terrarium: $120'"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke(question)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04813f37-ac97-48f3-8001-98c6c0d50c15",
   "metadata": {},
   "source": [
    "## Use as an agent tool\n",
    "\n",
    "Like other retrievers, BoxRetriever can be also be added to a LangGraph agent as a tool."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "24e617ff-2285-4056-9421-9f9bfd3044b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "pip install -U langsmith"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "52a56c14-228e-4b11-a6bd-5b75c0f403fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain import hub\n",
    "from langchain.agents import AgentExecutor, create_openai_tools_agent\n",
    "from langchain.tools.retriever import create_retriever_tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "b2e7b413-f49a-4bfe-b1e1-d0643704686e",
   "metadata": {},
   "outputs": [],
   "source": [
    "box_search_options = BoxSearchOptions(\n",
    "    ancestor_folder_ids=[box_folder_id],\n",
    "    search_type_filter=[SearchTypeFilter.FILE_CONTENT],\n",
    "    created_date_range=[\"2023-01-01T00:00:00-07:00\", \"2024-08-01T00:00:00-07:00,\"],\n",
    "    k=200,\n",
    "    size_range=[1, 1000000],\n",
    "    updated_data_range=None,\n",
    ")\n",
    "\n",
    "retriever = BoxRetriever(\n",
    "    box_developer_token=box_developer_token, box_search_options=box_search_options\n",
    ")\n",
    "\n",
    "box_search_tool = create_retriever_tool(\n",
    "    retriever,\n",
    "    \"box_search_tool\",\n",
    "    \"This tool is used to search Box and retrieve documents that match the search criteria\",\n",
    ")\n",
    "tools = [box_search_tool]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "0cfdb1bf-d328-4d56-aad7-7c71064c091f",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/shurrey/local/langchain/.venv/lib/python3.11/site-packages/langsmith/client.py:312: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "prompt = hub.pull(\"hwchase17/openai-tools-agent\")\n",
    "prompt.messages\n",
    "\n",
    "llm = ChatOpenAI(temperature=0, openai_api_key=openai_key)\n",
    "\n",
    "agent = create_openai_tools_agent(llm, tools, prompt)\n",
    "agent_executor = AgentExecutor(agent=agent, tools=tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "3b928f20-a28b-4954-bc71-ad35eba27253",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "result = agent_executor.invoke(\n",
    "    {\n",
    "        \"input\": \"list the items I purchased from AstroTech Solutions from most expensive to least expensive\"\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "1ae20ded-69ae-4b4e-b7c1-07aa2d50db31",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "result The items you purchased from AstroTech Solutions from most expensive to least expensive are:\n",
      "\n",
      "1. Gravitational Wave Detector Kit: $800\n",
      "2. Exoplanet Terrarium: $120\n",
      "\n",
      "Total: $920\n"
     ]
    }
   ],
   "source": [
    "print(f\"result {result['output']}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3a5bb5ca-c3ae-4a58-be67-2cd18574b9a3",
   "metadata": {},
   "source": [
    "## API reference\n",
    "\n",
    "For detailed documentation of all BoxRetriever features and configurations head to the [API reference](https://python.langchain.com/api_reference/box/retrievers/langchain_box.retrievers.box.BoxRetriever.html).\n",
    "\n",
    "\n",
    "## Help\n",
    "\n",
    "If you have questions, you can check out our [developer documentation](https://developer.box.com) or reach out to use in our [developer community](https://community.box.com)."
   ]
  }
 ],
 "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.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}


>`Lord of the Retrievers (LOTR)`, also known as `MergerRetriever`, takes a list of retrievers as input and merges the results of their get_relevant_documents() methods into a single list. The merged results will be a list of documents that are relevant to the query and that have been ranked by the different retrievers.

The `MergerRetriever` class can be used to improve the accuracy of document retrieval in a number of ways. First, it can combine the results of multiple retrievers, which can help to reduce the risk of bias in the results. Second, it can rank the results of the different retrievers, which can help to ensure that the most relevant documents are returned first.

from langchain_community.document_transformers import (

from langchain_huggingface import HuggingFaceEmbeddings

from langchain_openai import OpenAIEmbeddings

# Instantiate 2 diff chromadb indexes, each one with a diff embedding.

# Define 2 diff retrievers with 2 diff embeddings and diff search type.

search_type="similarity", search_kwargs={"k": 5, "include_metadata": True}

search_type="mmr", search_kwargs={"k": 5, "include_metadata": True}

# The Lord of the Retrievers will hold the output of both retrievers and can be used as any other

# retriever on different types of chains.

lotr = MergerRetriever(retrievers=[retriever_all, retriever_multi_qa])

## Remove redundant results from the merged retrievers.

# We can remove redundant results from both retrievers using yet another embedding.

# Using multiples embeddings in diff steps could help reduce biases.

## Pick a representative sample of documents from the merged retrievers.

# This filter will divide the documents vectors into clusters or "centers" of meaning.

# Then it will pick the closest document to that center for the final results.

# By default the result document will be ordered/grouped by clusters.

# If you want the final document to be ordered by the original retriever scores

# you need to add the "sorted" parameter.

## Re-order results to avoid performance degradation.

No matter the architecture of your model, there is a substantial performance degradation when you include 10+ retrieved documents.

In brief: When models must access relevant information  in the middle of long contexts, then tend to ignore the provided documents.

# You can use an additional document transformer to reorder documents after removing redundancy.

from langchain_community.document_transformers import LongContextReorder

pipeline = DocumentCompressorPipeline(transformers=[filter, reordering])


---
sidebar_position: 0
sidebar_class_name: hidden
---

import {CategoryTable, IndexTable} from '@theme/FeatureTables'

# Retrievers

A [retriever](/docs/concepts/#retrievers) is an interface that returns documents given an unstructured query.
It is more general than a vector store.
A retriever does not need to be able to store documents, only to return (or retrieve) them.
Retrievers can be created from vector stores, but are also broad enough to include [Wikipedia search](/docs/integrations/retrievers/wikipedia/) and [Amazon Kendra](/docs/integrations/retrievers/amazon_kendra_retriever/).

Retrievers accept a string query as input and return a list of [Documents](https://python.langchain.com/api_reference/core/documents/langchain_core.documents.base.Document.html) as output.

For specifics on how to use retrievers, see the [relevant how-to guides here](/docs/how_to/#retrievers).

Note that all [vector stores](/docs/concepts/#vector-stores) can be [cast to retrievers](/docs/how_to/vectorstore_retriever/).
Refer to the vector store [integration docs](/docs/integrations/vectorstores/) for available vector stores.
This page lists custom retrievers, implemented via subclassing [BaseRetriever](/docs/how_to/custom_retriever/).

## Bring-your-own documents

The below retrievers allow you to index and search a custom corpus of documents.

<CategoryTable category="document_retrievers" />

## External index

The below retrievers will search over an external index (e.g., constructed from Internet data or similar).

<CategoryTable category="external_retrievers" />

## All retrievers

<IndexTable />


"Document 3:\n",
      "\n",
      "<ref#> let� Or between equal Let’ to protect, restore law accountable  why the Justice Department cameras bannedhold and restricted its officers. <\n",
      "----------------------------------------------------------------------------------------------------\n",
      "Document 4:\n",
      "\n",
      "<# The Sergeant Class Combat froms widow us toBut burn pits ravaged Heath’s lungs and body. \n",
      "Danielle says Heath was a fighter to the very end.\n"
     ]
    }
   ],
   "source": [
    "from langchain.retrievers import ContextualCompressionRetriever\n",
    "from langchain_community.document_compressors import LLMLinguaCompressor\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "llm = ChatOpenAI(temperature=0)\n",
    "\n",
    "compressor = LLMLinguaCompressor(model_name=\"openai-community/gpt2\", device_map=\"cpu\")\n",
    "compression_retriever = ContextualCompressionRetriever(\n",
    "    base_compressor=compressor, base_retriever=retriever\n",
    ")\n",
    "\n",
    "compressed_docs = compression_retriever.invoke(\n",
    "    \"What did the president say about Ketanji Jackson Brown\"\n",
    ")\n",
    "pretty_print_docs(compressed_docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "529f72d3",
   "metadata": {},
   "source": [
    "## QA generation with LLMLingua\n",
    "\n",
    "We can see what it looks like to use this in the generation step now"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "367dafe0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import RetrievalQA\n",
    "\n",
    "chain = RetrievalQA.from_chain_type(llm=llm, retriever=compression_retriever)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "46ee62fc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'query': 'What did the president say about Ketanji Brown Jackson',\n",
       " 'result': \"The President mentioned that Ketanji Brown Jackson is one of the nation's top legal minds and will continue Justice Breyer's legacy of excellence.\"}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.invoke({\"query\": query})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7bf3985",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}


"output_type": "execute_result"
    }
   ],
   "source": [
    "dense_embedding_func = OpenAIEmbeddings()\n",
    "dense_dim = len(dense_embedding_func.embed_query(texts[1]))\n",
    "dense_dim"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Initialize sparse embedding function.\n",
    "\n",
    "Note that the output of sparse embedding is a set of sparse vectors, which represents the index and weight of the keywords of the input text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{0: 0.4270424944042204,\n",
       " 21: 1.845826690498331,\n",
       " 22: 1.845826690498331,\n",
       " 23: 1.845826690498331,\n",
       " 24: 1.845826690498331,\n",
       " 25: 1.845826690498331,\n",
       " 26: 1.845826690498331,\n",
       " 27: 1.2237754316221157,\n",
       " 28: 1.845826690498331,\n",
       " 29: 1.845826690498331,\n",
       " 30: 1.845826690498331,\n",
       " 31: 1.845826690498331,\n",
       " 32: 1.845826690498331,\n",
       " 33: 1.845826690498331,\n",
       " 34: 1.845826690498331,\n",
       " 35: 1.845826690498331,\n",
       " 36: 1.845826690498331,\n",
       " 37: 1.845826690498331,\n",
       " 38: 1.845826690498331,\n",
       " 39: 1.845826690498331}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sparse_embedding_func = BM25SparseEmbedding(corpus=texts)\n",
    "sparse_embedding_func.embed_query(texts[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create Milvus Collection and load data\n",
    "\n",
    "Initialize connection URI and establish connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "connections.connect(uri=CONNECTION_URI)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define field names and their data types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "pk_field = \"doc_id\"\n",
    "dense_field = \"dense_vector\"\n",
    "sparse_field = \"sparse_vector\"\n",
    "text_field = \"text\"\n",
    "fields = [\n",
    "    FieldSchema(\n",
    "        name=pk_field,\n",
    "        dtype=DataType.VARCHAR,\n",
    "        is_primary=True,\n",
    "        auto_id=True,\n",
    "        max_length=100,\n",
    "    ),\n",
    "    FieldSchema(name=dense_field, dtype=DataType.FLOAT_VECTOR, dim=dense_dim),\n",
    "    FieldSchema(name=sparse_field, dtype=DataType.SPARSE_FLOAT_VECTOR),\n",
    "    FieldSchema(name=text_field, dtype=DataType.VARCHAR, max_length=65_535),\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a collection with the defined schema"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "schema = CollectionSchema(fields=fields, enable_dynamic_field=False)\n",
    "collection = Collection(\n",
    "    name=\"IntroductionToTheNovels\", schema=schema, consistency_level=\"Strong\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define index for dense and sparse vectors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "dense_index = {\"index_type\": \"FLAT\", \"metric_type\": \"IP\"}\n",
    "collection.create_index(\"dense_vector\", dense_index)\n",
    "sparse_index = {\"index_type\": \"SPARSE_INVERTED_INDEX\", \"metric_type\": \"IP\"}\n",
    "collection.create_index(\"sparse_vector\", sparse_index)\n",
    "collection.flush()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Insert entities into the collection and load the collection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "entities = []\n",
    "for text in texts:\n",
    "    entity = {\n",
    "        dense_field: dense_embedding_func.embed_documents([text])[0],\n",
    "        sparse_field: sparse_embedding_func.embed_documents([text])[0],\n",
    "        text_field: text,\n",
    "    }\n",
    "    entities.append(entity)\n",
    "collection.insert(entities)\n",
    "collection.load()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instantiation\n",
    "\n",
    "Now we can instantiate our retriever, defining search parameters for sparse and dense fields:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sparse_search_params = {\"metric_type\": \"IP\"}\n",
    "dense_search_params = {\"metric_type\": \"IP\", \"params\": {}}\n",
    "retriever = MilvusCollectionHybridSearchRetriever(\n",
    "    collection=collection,\n",
    "    rerank=WeightedRanker(0.5, 0.5),\n",
    "    anns_fields=[dense_field, sparse_field],\n",
    "    field_embeddings=[dense_embedding_func, sparse_embedding_func],\n",
    "    field_search_params=[dense_search_params, sparse_search_params],\n",
    "    top_k=3,\n",
    "    text_field=text_field,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "source": [
    "In the input parameters of this Retriever, we use a dense embedding and a sparse embedding to perform hybrid search on the two fields of this Collection, and use WeightedRanker for reranking. Finally, 3 top-K Documents will be returned."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Usage"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Document(page_content=\"In 'The Lost Expedition' by Caspian Grey, a team of explorers ventures into the heart of the Amazon rainforest in search of a lost city, but soon finds themselves hunted by a ruthless treasure hunter and the treacherous jungle itself.\", metadata={'doc_id': '449281835035545843'}),\n",
       " Document(page_content=\"In 'The Phantom Pilgrim' by Rowan Welles, a charismatic smuggler is hired by a mysterious organization to transport a valuable artifact across a war-torn continent, but soon finds themselves pursued by deadly assassins and rival factions.\", metadata={'doc_id': '449281835035545845'}),\n",
       " Document(page_content=\"In 'The Dreamwalker's Journey' by Lyra Snow, a young dreamwalker discovers she has the ability to enter people's dreams, but soon finds herself trapped in a surreal world of nightmares and illusions, where the boundaries between reality and fantasy blur.\", metadata={'doc_id': '449281835035545846'})]"
      ]
     },
     "execution_count": 14,
     "metadata": {},


"llm = Cohere(temperature=0)\n",
    "compressor = CohereRerank(model=\"rerank-english-v3.0\")\n",
    "compression_retriever = ContextualCompressionRetriever(\n",
    "    base_compressor=compressor, base_retriever=retriever\n",
    ")\n",
    "\n",
    "compressed_docs = compression_retriever.invoke(\n",
    "    \"What did the president say about Ketanji Jackson Brown\"\n",
    ")\n",
    "pretty_print_docs(compressed_docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70727c2f",
   "metadata": {},
   "source": [
    "You can of course use this retriever within a QA pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "367dafe0",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import RetrievalQA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ae697ca4",
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = RetrievalQA.from_chain_type(\n",
    "    llm=Cohere(temperature=0), retriever=compression_retriever\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "46ee62fc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'query': 'What did the president say about Ketanji Brown Jackson',\n",
       " 'result': \" The president speaks highly of Ketanji Brown Jackson, stating that she is one of the nation's top legal minds, and will continue the legacy of excellence of Justice Breyer. The president also mentions that he worked with her family and that she comes from a family of public school educators and police officers. Since her nomination, she has received support from various groups, including the Fraternal Order of Police and judges from both major political parties. \\n\\nWould you like me to extract another sentence from the provided text? \"}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain({\"query\": query})"
   ]
  }
 ],
 "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}


{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Milvus\n",
    "\n",
    ">[Milvus](https://milvus.io/docs/overview.md) is a database that stores, indexes, and manages massive embedding vectors generated by deep neural networks and other machine learning (ML) models.\n",
    "\n",
    "In the walkthrough, we'll demo the `SelfQueryRetriever` with a `Milvus` vector store."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating a Milvus vectorstore\n",
    "First we'll want to create a Milvus VectorStore and seed it with some data. We've created a small demo set of documents that contain summaries of movies.\n",
    "\n",
    "I have used the cloud version of Milvus, thus I need `uri` and `token` as well.\n",
    "\n",
    "NOTE: The self-query retriever requires you to have `lark` installed (`pip install lark`). We also need the `langchain_milvus` package."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install --upgrade --quiet lark langchain_milvus"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We want to use `OpenAIEmbeddings` so we have to get the OpenAI API Key."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "OPENAI_API_KEY = \"Use your OpenAI key:)\"\n",
    "\n",
    "os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.documents import Document\n",
    "from langchain_milvus.vectorstores import Milvus\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "\n",
    "embeddings = OpenAIEmbeddings()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = [\n",
    "    Document(\n",
    "        page_content=\"A bunch of scientists bring back dinosaurs and mayhem breaks loose\",\n",
    "        metadata={\"year\": 1993, \"rating\": 7.7, \"genre\": \"action\"},\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"Leo DiCaprio gets lost in a dream within a dream within a dream within a ...\",\n",
    "        metadata={\"year\": 2010, \"genre\": \"thriller\", \"rating\": 8.2},\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"A bunch of normal-sized women are supremely wholesome and some men pine after them\",\n",
    "        metadata={\"year\": 2019, \"rating\": 8.3, \"genre\": \"drama\"},\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"Three men walk into the Zone, three men walk out of the Zone\",\n",
    "        metadata={\"year\": 1979, \"rating\": 9.9, \"genre\": \"science fiction\"},\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea\",\n",
    "        metadata={\"year\": 2006, \"genre\": \"thriller\", \"rating\": 9.0},\n",
    "    ),\n",
    "    Document(\n",
    "        page_content=\"Toys come alive and have a blast doing so\",\n",
    "        metadata={\"year\": 1995, \"genre\": \"animated\", \"rating\": 9.3},\n",
    "    ),\n",
    "]\n",
    "\n",
    "vector_store = Milvus.from_documents(\n",
    "    docs,\n",
    "    embedding=embeddings,\n",
    "    connection_args={\"uri\": \"Use your uri:)\", \"token\": \"Use your token:)\"},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating our self-querying retriever\n",
    "Now we can instantiate our retriever. To do this we'll need to provide some information upfront about the metadata fields that our documents support and a short description of the document contents."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.query_constructor.base import AttributeInfo\n",
    "from langchain.retrievers.self_query.base import SelfQueryRetriever\n",
    "from langchain_openai import OpenAI\n",
    "\n",
    "metadata_field_info = [\n",
    "    AttributeInfo(\n",
    "        name=\"genre\",\n",
    "        description=\"The genre of the movie\",\n",
    "        type=\"string\",\n",
    "    ),\n",
    "    AttributeInfo(\n",
    "        name=\"year\",\n",
    "        description=\"The year the movie was released\",\n",
    "        type=\"integer\",\n",
    "    ),\n",
    "    AttributeInfo(\n",
    "        name=\"rating\", description=\"A 1-10 rating for the movie\", type=\"float\"\n",
    "    ),\n",
    "]\n",
    "document_content_description = \"Brief summary of a movie\"\n",
    "llm = OpenAI(temperature=0)\n",
    "retriever = SelfQueryRetriever.from_llm(\n",
    "    llm, vector_store, document_content_description, metadata_field_info, verbose=True\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Testing it out\n",
    "And now we can try actually using our retriever!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "query='dinosaur' filter=None limit=None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose', metadata={'year': 1993, 'rating': 7.7, 'genre': 'action'}),\n",
       " Document(page_content='Toys come alive and have a blast doing so', metadata={'year': 1995, 'rating': 9.3, 'genre': 'animated'}),\n",
       " Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'year': 1979, 'rating': 9.9, 'genre': 'science fiction'}),\n",
       " Document(page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea', metadata={'year': 2006, 'rating': 9.0, 'genre': 'thriller'})]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# This example only specifies a relevant query\n",
    "retriever.invoke(\"What are some movies about dinosaurs\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "query=' ' filter=Comparison(comparator=<Comparator.GT: 'gt'>, attribute='rating', value=9) limit=None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='Toys come alive and have a blast doing so', metadata={'year': 1995, 'rating': 9.3, 'genre': 'animated'}),\n",
       " Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'year': 1979, 'rating': 9.9, 'genre': 'science fiction'})]"
      ]
     },
     "execution_count": 8,


"query='women' filter=Comparison(comparator=<Comparator.EQ: 'eq'>, attribute='director', value='Greta Gerwig') limit=None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='A bunch of normal-sized women are supremely wholesome and some men pine after them', metadata={'year': 2019, 'rating': 8.3, 'director': 'Greta Gerwig'})]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# This example specifies a query and a filter\n",
    "retriever.invoke(\"Has Greta Gerwig directed any movies about women?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f900e40e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "query=' ' filter=Operation(operator=<Operator.AND: 'and'>, arguments=[Comparison(comparator=<Comparator.GTE: 'gte'>, attribute='rating', value=8.5), Comparison(comparator=<Comparator.EQ: 'eq'>, attribute='genre', value='science fiction')]) limit=None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'year': 1979, 'genre': 'science fiction', 'rating': 9.9, 'director': 'Andrei Tarkovsky'})]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# This example specifies a composite filter\n",
    "retriever.invoke(\"What's a highly rated (above 8.5) science fiction film?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "12a51522",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "query='toys' filter=Operation(operator=<Operator.AND: 'and'>, arguments=[Comparison(comparator=<Comparator.GT: 'gt'>, attribute='year', value=1990), Comparison(comparator=<Comparator.LTE: 'lte'>, attribute='year', value=2005), Comparison(comparator=<Comparator.LIKE: 'like'>, attribute='genre', value='animated')]) limit=None\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='Toys come alive and have a blast doing so', metadata={'year': 1995, 'genre': 'animated'})]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# This example specifies a query and composite filter\n",
    "retriever.invoke(\n",
    "    \"What's a movie after 1990 but before (or on) 2005 that's all about toys, and preferably is animated\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39bd1de1-b9fe-4a98-89da-58d8a7a6ae51",
   "metadata": {},
   "source": [
    "## Filter k\n",
    "\n",
    "We can also use the self query retriever to specify `k`: the number of documents to fetch.\n",
    "\n",
    "We can do this by passing `enable_limit=True` to the constructor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "bff36b88-b506-4877-9c63-e5a1a8d78e64",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "retriever = SelfQueryRetriever.from_llm(\n",
    "    llm,\n",
    "    vectorstore,\n",
    "    document_content_description,\n",
    "    metadata_field_info,\n",
    "    enable_limit=True,\n",
    "    verbose=True,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "2758d229-4f97-499c-819f-888acaf8ee10",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "query='dinosaur' filter=None limit=2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[Document(page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose', metadata={'year': 1993, 'genre': 'science fiction', 'rating': 7.7}),\n",
       " Document(page_content='Toys come alive and have a blast doing so', metadata={'year': 1995, 'genre': 'animated'})]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# This example only specifies a relevant query\n",
    "retriever.invoke(\"what are two movies about dinosaurs\")"
   ]
  }
 ],
 "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.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}