How to Integrate LlamaIndex for investment banking with Supabase for RAG
Combining LlamaIndex for investment banking with Supabase gives you a practical RAG stack for deal rooms, research assistants, and internal knowledge search. LlamaIndex handles ingestion, chunking, indexing, and retrieval orchestration, while Supabase gives you Postgres-backed persistence, auth-friendly storage, and a clean place to keep embeddings and metadata.
For investment banking teams, this is useful when you need to answer questions over CIMs, pitch books, earnings transcripts, credit memos, and internal notes without wiring together a separate vector database from scratch.
Prerequisites
- •Python 3.10+
- •A Supabase project with:
- •
SUPABASE_URL - •
SUPABASE_SERVICE_ROLE_KEY
- •
- •A Postgres table for documents and embeddings
- •OpenAI API key or another embedding/LLM provider supported by LlamaIndex
- •Installed packages:
- •
llama-index - •
llama-index-vector-stores-supabase - •
supabase - •
python-dotenv
- •
- •A folder of source files for your banking corpus:
- •PDFs
- •DOCX
- •TXT
- •HTML
Install the dependencies:
pip install llama-index llama-index-vector-stores-supabase supabase python-dotenv
Integration Steps
1) Configure environment variables
Keep secrets out of code. For banking workflows, use service-role access only on the backend.
from dotenv import load_dotenv
import os
load_dotenv()
SUPABASE_URL = os.environ["SUPABASE_URL"]
SUPABASE_SERVICE_ROLE_KEY = os.environ["SUPABASE_SERVICE_ROLE_KEY"]
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
Set your LlamaIndex settings so embeddings and chat completions are available across the pipeline.
from llama_index.core import Settings
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.llm = OpenAI(model="gpt-4o-mini")
2) Create the Supabase vector store
LlamaIndex can write embeddings into Supabase Postgres using the vector store integration. This is the cleanest path if you want one system for storage and retrieval state.
from supabase import create_client
from llama_index.vector_stores.supabase import SupabaseVectorStore
supabase_client = create_client(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY)
vector_store = SupabaseVectorStore(
postgres_connection_string=f"postgresql://postgres:{os.environ['SUPABASE_DB_PASSWORD']}@{os.environ['SUPABASE_DB_HOST']}:{os.environ.get('SUPABASE_DB_PORT', '5432')}/postgres",
collection_name="investment_banking_rag",
embed_dim=1536,
)
If you prefer a direct Postgres connection string from Supabase dashboard settings, use that instead of building it manually. The important part is that the vector store points at a table-backed pgvector index.
3) Ingest banking documents into LlamaIndex
Use LlamaIndex readers to load your deal materials. For production systems, separate ingestion from query-time retrieval so you can reindex on schedule.
from llama_index.core import VectorStoreIndex, StorageContext, SimpleDirectoryReader
documents = SimpleDirectoryReader(
input_dir="./banking_docs",
recursive=True,
).load_data()
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
show_progress=True,
)
This writes chunks plus embeddings into Supabase through the vector store adapter. If your corpus includes OCR-heavy PDFs or scanned filings, preprocess them before indexing to avoid garbage retrieval.
4) Build a query engine for RAG responses
Once indexed, query through LlamaIndex’s standard retrieval APIs. This is where your agent starts answering questions grounded in deal documents instead of model memory.
query_engine = index.as_query_engine(
similarity_top_k=5,
response_mode="compact",
)
response = query_engine.query(
"What are the main risks highlighted in the latest acquisition memo?"
)
print(response)
For investment banking use cases, add metadata filters on deal name, issuer, sector, or date. That keeps answers scoped to the right transaction instead of mixing unrelated files.
5) Add metadata-aware document loading
Banking teams need traceability. Store document metadata during ingestion so you can filter by client name, asset class, or workstream later.
from llama_index.core.schema import Document
docs = [
Document(
text="Revenue grew 18% year-over-year with margin expansion in Q3.",
metadata={
"client": "Northwind Capital",
"deal_type": "sell-side",
"source": "earnings_note_2024_q3.txt",
"sector": "software",
},
)
]
index = VectorStoreIndex.from_documents(
docs,
storage_context=storage_context,
)
Then query with filters when needed:
from llama_index.core.vector_stores.types import MetadataFilters, ExactMatchFilter
filters = MetadataFilters(filters=[
ExactMatchFilter(key="client", value="Northwind Capital"),
])
query_engine = index.as_query_engine(filters=filters)
print(query_engine.query("Summarize performance trends."))
Testing the Integration
Run a simple end-to-end check: ingest one document, retrieve it back through RAG, and confirm the answer references the source content.
from llama_index.core.schema import Document
from llama_index.core import VectorStoreIndex, StorageContext
test_doc = Document(
text="The company expects EBITDA margins to expand by 200 basis points next year.",
metadata={"client": "Test Deal", "source": "memo.txt"},
)
test_index = VectorStoreIndex.from_documents(
[test_doc],
storage_context=StorageContext.from_defaults(vector_store=vector_store),
)
qe = test_index.as_query_engine(similarity_top_k=1)
result = qe.query("What margin improvement is expected?")
print(result)
Expected output:
The company expects EBITDA margins to expand by 200 basis points next year.
If you get an unrelated answer or no hit at all:
- •Check that embeddings were written into Supabase
- •Confirm
embed_dimmatches your embedding model - •Verify your document text is clean and not empty after parsing
Real-World Use Cases
- •Deal team assistant
- •Search CIMs, management presentation decks, diligence notes, and QA logs with grounded answers.
- •Research copilot
- •Query earnings transcripts and broker notes by issuer or sector before drafting an investment thesis.
- •Credit memo retrieval
- •Pull relevant clauses, risks, covenants, and historical commentary from prior lending packages during underwriting.
This stack works well because each tool stays in its lane. LlamaIndex manages retrieval logic and response generation; Supabase gives you durable storage and operational control for production RAG systems in banking.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit