## Vectara

> [Vectara](https://vectara.com/) is the trusted GenAI platform that provides an easy-to-use API for document indexing and querying.
> 
> `Vectara` provides an end-to-end managed service for `Retrieval Augmented Generation` or [RAG](https://vectara.com/grounded-generation/), which includes: 1. A way to `extract text` from document files and `chunk` them into sentences. 2. The state-of-the-art [Boomerang](https://vectara.com/how-boomerang-takes-retrieval-augmented-generation-to-the-next-level-via-grounded-generation/) embeddings model. Each text chunk is encoded into a vector embedding using `Boomerang`, and stored in the Vectara internal knowledge (vector+text) store 3. A query service that automatically encodes the query into embedding, and retrieves the most relevant text segments (including support for [Hybrid Search](https://docs.vectara.com/docs/api-reference/search-apis/lexical-matching) and [MMR](https://vectara.com/get-diverse-results-and-comprehensive-summaries-with-vectaras-mmr-reranker/)) 4. An option to create [generative summary](https://docs.vectara.com/docs/learn/grounded-generation/grounded-generation-overview), based on the retrieved documents, including citations.

See the [Vectara API documentation](https://docs.vectara.com/docs/) for more information on how to use the API.

This notebook shows how to use `SelfQueryRetriever` with Vectara.

## Setup

You will need a `Vectara` account to use `Vectara` with `LangChain`. To get started, use the following steps (see our [quickstart](https://docs.vectara.com/docs/quickstart) guide): 1. [Sign up](https://console.vectara.com/signup) for a `Vectara` account if you don’t already have one. Once you have completed your sign up you will have a Vectara customer ID. You can find your customer ID by clicking on your name, on the top-right of the Vectara console window. 2. Within your account you can create one or more corpora. Each corpus represents an area that stores text data upon ingesting from input documents. To create a corpus, use the **“Create Corpus”** button. You then provide a name to your corpus as well as a description. Optionally you can define filtering attributes and apply some advanced options. If you click on your created corpus, you can see its name and corpus ID right on the top. 3. Next you’ll need to create API keys to access the corpus. Click on the **“Authorization”** tab in the corpus view and then the **“Create API Key”** button. Give your key a name, and choose whether you want query only or query+index for your key. Click “Create” and you now have an active API key. Keep this key confidential.

To use LangChain with Vectara, you need three values: customer ID, corpus ID and api\_key. You can provide those to LangChain in two ways:

1.  Include in your environment these three variables: `VECTARA_CUSTOMER_ID`, `VECTARA_CORPUS_ID` and `VECTARA_API_KEY`.

> For example, you can set these variables using `os.environ` and `getpass` as follows:

```
import osimport getpassos.environ["VECTARA_CUSTOMER_ID"] = getpass.getpass("Vectara Customer ID:")os.environ["VECTARA_CORPUS_ID"] = getpass.getpass("Vectara Corpus ID:")os.environ["VECTARA_API_KEY"] = getpass.getpass("Vectara API Key:")
```

1.  Provide them as arguments when creating the `Vectara` vectorstore object:

```
vectorstore = Vectara(                vectara_customer_id=vectara_customer_id,                vectara_corpus_id=vectara_corpus_id,                vectara_api_key=vectara_api_key            )
```

**Note:** The self-query retriever requires you to have `lark` installed (`pip install lark`).

## Connecting to Vectara from LangChain[​](#connecting-to-vectara-from-langchain "Direct link to Connecting to Vectara from LangChain")

In this example, we assume that you’ve created an account and a corpus, and added your VECTARA\_CUSTOMER\_ID, VECTARA\_CORPUS\_ID and VECTARA\_API\_KEY (created with permissions for both indexing and query) as environment variables.

The corpus has 4 fields defined as metadata for filtering: year, director, rating, and genre

```
from langchain.chains import ConversationalRetrievalChainfrom langchain.chains.query_constructor.base import AttributeInfofrom langchain.retrievers.self_query.base import SelfQueryRetrieverfrom langchain_community.document_loaders import TextLoaderfrom langchain_community.embeddings import FakeEmbeddingsfrom langchain_community.vectorstores import Vectarafrom langchain_core.documents import Documentfrom langchain_openai import OpenAIfrom langchain_text_splitters import CharacterTextSplitter
```

```
docs = [    Document(        page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",        metadata={"year": 1993, "rating": 7.7, "genre": "science fiction"},    ),    Document(        page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",        metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2},    ),    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, "director": "Satoshi Kon", "rating": 8.6},    ),    Document(        page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",        metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3},    ),    Document(        page_content="Toys come alive and have a blast doing so",        metadata={"year": 1995, "genre": "animated"},    ),    Document(        page_content="Three men walk into the Zone, three men walk out of the Zone",        metadata={            "year": 1979,            "rating": 9.9,            "director": "Andrei Tarkovsky",            "genre": "science fiction",        },    ),]vectara = Vectara()for doc in docs:    vectara.add_texts(        [doc.page_content],        embedding=FakeEmbeddings(size=768),        doc_metadata=doc.metadata,    )
```

## Creating our self-querying retriever[​](#creating-our-self-querying-retriever "Direct link to Creating our self-querying retriever")

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.

```
from langchain.chains.query_constructor.base import AttributeInfofrom langchain.retrievers.self_query.base import SelfQueryRetrieverfrom langchain_openai import OpenAImetadata_field_info = [    AttributeInfo(        name="genre",        description="The genre of the movie",        type="string or list[string]",    ),    AttributeInfo(        name="year",        description="The year the movie was released",        type="integer",    ),    AttributeInfo(        name="director",        description="The name of the movie director",        type="string",    ),    AttributeInfo(        name="rating", description="A 1-10 rating for the movie", type="float"    ),]document_content_description = "Brief summary of a movie"llm = OpenAI(temperature=0)retriever = SelfQueryRetriever.from_llm(    llm, vectara, document_content_description, metadata_field_info, verbose=True)
```

## Testing it out[​](#testing-it-out "Direct link to Testing it out")

And now we can try actually using our retriever!

```
# This example only specifies a relevant queryretriever.get_relevant_documents("What are some movies about dinosaurs")
```

```
[Document(page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose', metadata={'lang': 'eng', 'offset': '0', 'len': '66', 'year': '1993', 'rating': '7.7', 'genre': 'science fiction', 'source': 'langchain'}), Document(page_content='Toys come alive and have a blast doing so', metadata={'lang': 'eng', 'offset': '0', 'len': '41', 'year': '1995', 'genre': 'animated', 'source': 'langchain'}), Document(page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea', metadata={'lang': 'eng', 'offset': '0', 'len': '116', 'year': '2006', 'director': 'Satoshi Kon', 'rating': '8.6', 'source': 'langchain'}), Document(page_content='Leo DiCaprio gets lost in a dream within a dream within a dream within a ...', metadata={'lang': 'eng', 'offset': '0', 'len': '76', 'year': '2010', 'director': 'Christopher Nolan', 'rating': '8.2', 'source': 'langchain'}), Document(page_content='A bunch of normal-sized women are supremely wholesome and some men pine after them', metadata={'lang': 'eng', 'offset': '0', 'len': '82', 'year': '2019', 'director': 'Greta Gerwig', 'rating': '8.3', 'source': 'langchain'}), Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'lang': 'eng', 'offset': '0', 'len': '60', 'year': '1979', 'rating': '9.9', 'director': 'Andrei Tarkovsky', 'genre': 'science fiction', 'source': 'langchain'})]
```

```
# This example only specifies a filterretriever.get_relevant_documents("I want to watch a movie rated higher than 8.5")
```

```
[Document(page_content='A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea', metadata={'lang': 'eng', 'offset': '0', 'len': '116', 'year': '2006', 'director': 'Satoshi Kon', 'rating': '8.6', 'source': 'langchain'}), Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'lang': 'eng', 'offset': '0', 'len': '60', 'year': '1979', 'rating': '9.9', 'director': 'Andrei Tarkovsky', 'genre': 'science fiction', 'source': 'langchain'})]
```

```
# This example specifies a query and a filterretriever.get_relevant_documents("Has Greta Gerwig directed any movies about women")
```

```
[Document(page_content='A bunch of normal-sized women are supremely wholesome and some men pine after them', metadata={'lang': 'eng', 'offset': '0', 'len': '82', 'year': '2019', 'director': 'Greta Gerwig', 'rating': '8.3', 'source': 'langchain'})]
```

```
# This example specifies a composite filterretriever.get_relevant_documents(    "What's a highly rated (above 8.5) science fiction film?")
```

```
[Document(page_content='Three men walk into the Zone, three men walk out of the Zone', metadata={'lang': 'eng', 'offset': '0', 'len': '60', 'year': '1979', 'rating': '9.9', 'director': 'Andrei Tarkovsky', 'genre': 'science fiction', 'source': 'langchain'})]
```

```
# This example specifies a query and composite filterretriever.get_relevant_documents(    "What's a movie after 1990 but before 2005 that's all about toys, and preferably is animated")
```

```
[Document(page_content='Toys come alive and have a blast doing so', metadata={'lang': 'eng', 'offset': '0', 'len': '41', 'year': '1995', 'genre': 'animated', 'source': 'langchain'})]
```

## Filter k[​](#filter-k "Direct link to Filter k")

We can also use the self query retriever to specify `k`: the number of documents to fetch.

We can do this by passing `enable_limit=True` to the constructor.

```
retriever = SelfQueryRetriever.from_llm(    llm,    vectara,    document_content_description,    metadata_field_info,    enable_limit=True,    verbose=True,)
```

```
# This example only specifies a relevant queryretriever.get_relevant_documents("what are two movies about dinosaurs")
```

```
[Document(page_content='A bunch of scientists bring back dinosaurs and mayhem breaks loose', metadata={'lang': 'eng', 'offset': '0', 'len': '66', 'year': '1993', 'rating': '7.7', 'genre': 'science fiction', 'source': 'langchain'}), Document(page_content='Toys come alive and have a blast doing so', metadata={'lang': 'eng', 'offset': '0', 'len': '41', 'year': '1995', 'genre': 'animated', 'source': 'langchain'})]
```