Using LlamaIndex and Nile together
LlamaIndex can be used with Nile to build RAG (Retrieval Augmented Generation) architectures. You’ll use LLamaIndex to simply and orchestrate the different steps in your RAG workflows, and Nile to store and query data and embeddings. In this example, we’ll show how to chat with a sales transcript in just a few lines of code, using LlamaIndex’s high-level interface and its integration with Nile and OpenAI. We’ll walk you through the setup steps and then explain the code line by line. The entire Python script is available here or in iPython/Jupyter Notebook.Setting Up Nile
Start by signing up for Nile. Once you’ve signed up for Nile, you’ll be promoted to create your first database. Go ahead and do so. You’ll be redirected to the “Query Editor” page of your new database. You can see the built-intenants
table on the left-hand side.
From there, click on “Home” (top icon on the left menu), click on “generate credentials” and copy the resulting connection string. You will need it in a sec.
Setting Up LlamaIndex
LlamaIndex is a Python library, so you’ll need to set up a Python environment with the necessary dependencies. We recommend using venv to create a virtual environment. This step is optional, but it will help you manage your dependencies and avoid conflicts.Setting up the data
In this example, we’ll chat with sales transcript of two different companies. Download the transcripts to./data
directory.
Setting up the OpenAI API key
This quickstart uses OpenAI’s API to generate embeddings. So grab your OpenAI API key and set it as an environment variable:Quickstart
Open a file namednile_llamaindex_quickstart.py
and start by importing the necessary dependencies (or follow along with the script mentioned above):
Setting up the NileVectorStore
Next, create a NileVectorStore instance:tenant_aware=True
. This is because we want to isolate the documents for each tenant in our vector store.
🔥 NileVectorStore supports both tenant-aware vector stores, that isolates the documents for each tenant and a regular store which is typically used for shared data that all tenants can access.
Below, we’ll demonstrate the tenant-aware vector store.
Loading and transforming the data
With all this in place, we’ll load the data for the sales transcripts. We’ll use LlamaIndex’sSimpleDirectoryReader
to load the documents. Because we want to update the documents with the tenant
metadata after loading, we’ll use a separate reader for each tenant.
VectorStoreIndex
. Since we created a tenant-aware NileVectorStore
when we set things up,
Nile will correctly use the tenant_id
field in the metadata to isolate them. Loading documents without tenant_id
to a tenant-aware store will throw a ValueException
.
Chatting with the documents
Now that we have our vector embeddings stored in Nile, we can build a query engine for each tenant and chat with the documents:Full application
Ready to build something amazing? Check out our TaskGenius example. The README includes step by step instructions on how to run the application locally. Lets go over a few of the code highlights:Use of LlamaIndex with FastAPI
The example is a full-stack application with a FastAPI back-end and a React front-end. When we initialize FastAPI, we create an instance of ourAIUtils
class, which is responsible for interfacing with the Nile vector store and the OpenAI API.
POST /api/todos
endpoint, we use the AIUtils
instance to generate a time estimate for the todo item, and to store the embedding in the Nile vector store.
Using LlamaIndex with Ollama
If you look at theAIUtils
class, you’ll see that it is very similar to the simple quickstart example earlier. Except we use Ollama instead of OpenAI.
We initialize the vector store and the index in the __init__
method:
Using FastAPI with Nile for tenant isolation
If you look at thePOST /api/todos
handler, you’ll see that we get all the todos for a tenant without needing to do any filtering.
This is because the get_tenant_session
function returns a session for the tenant database:
get_tenant_session
is implemented in db.py
and it is a wrapper around the get_session
function that sets the nile.tenant_id
and nile.use_id
context.
tenant_middleware.py
.