How to Integrate LlamaIndex for healthcare with Supabase for production AI
Combining LlamaIndex for healthcare with Supabase gives you a clean production pattern for clinical AI systems: structured patient data in Postgres, vector retrieval for unstructured notes, and an agent layer that can answer questions with traceable context. This is the setup you want when building things like chart summarization, care-gap assistants, or policy-aware clinical search.
Prerequisites
- •Python 3.10+
- •A Supabase project with:
- •PostgreSQL enabled
- •a table for patient documents or clinical notes
- •pgvector enabled if you want embeddings in Postgres
- •Access to your LlamaIndex healthcare package and an embedding/LLM provider
- •Environment variables set:
- •
SUPABASE_URL - •
SUPABASE_SERVICE_ROLE_KEY - •
OPENAI_API_KEYor your preferred model key
- •
- •A healthcare dataset ready for indexing:
- •discharge summaries
- •encounter notes
- •ICD/CPT metadata
- •care plan documents
Integration Steps
- •Install the Python packages.
pip install llama-index supabase python-dotenv sqlalchemy psycopg2-binary
pip install llama-index-vector-stores-supabase llama-index-embeddings-openai llama-index-llms-openai
If you are using a healthcare-specific extension or package in your stack, keep it in the same environment as your core LlamaIndex dependencies. The integration pattern stays the same: ingest clinical content, embed it, store it in Supabase, then query it through LlamaIndex.
- •Connect to Supabase and create a storage table.
import os
from supabase import create_client, Client
from dotenv import load_dotenv
load_dotenv()
supabase_url = os.environ["SUPABASE_URL"]
supabase_key = os.environ["SUPABASE_SERVICE_ROLE_KEY"]
supabase: Client = create_client(supabase_url, supabase_key)
# Example: insert a clinical note record
record = {
"patient_id": "pat_001",
"document_type": "discharge_summary",
"content": "Patient discharged after CHF exacerbation. Continue furosemide 40mg daily.",
}
response = supabase.table("clinical_documents").insert(record).execute()
print(response.data)
Use a real table schema like this:
create table clinical_documents (
id bigserial primary key,
patient_id text not null,
document_type text not null,
content text not null,
created_at timestamptz default now()
);
For production AI, keep PHI access behind service-role credentials on the backend only. Do not expose the key in browser code.
- •Build a LlamaIndex index over healthcare content and push vectors into Supabase.
import os
from llama_index.core import VectorStoreIndex, StorageContext, Document
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.vector_stores.supabase import SupabaseVectorStore
embed_model = OpenAIEmbedding(model="text-embedding-3-small")
vector_store = SupabaseVectorStore(
postgres_connection_string=os.environ["SUPABASE_POSTGRES_CONNECTION_STRING"],
collection_name="clinical_vectors",
dimension=1536,
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
documents = [
Document(
text="Patient has type 2 diabetes and was started on metformin 500mg BID.",
metadata={"patient_id": "pat_001", "source": "endocrinology_note"},
),
Document(
text="History of CHF with recent weight gain and lower extremity edema.",
metadata={"patient_id": "pat_002", "source": "cardiology_note"},
),
]
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
embed_model=embed_model,
)
This is the core pattern: LlamaIndex handles chunking and retrieval logic; Supabase stores vectors close to your application data. In production, I prefer this over keeping embeddings in a separate managed vector service unless you have a hard requirement for one.
- •Query the indexed healthcare data through a retriever-backed agent.
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.llms.openai import OpenAI
llm = OpenAI(model="gpt-4o-mini")
retriever = VectorIndexRetriever(
index=index,
similarity_top_k=3,
)
query_engine = RetrieverQueryEngine.from_args(
retriever=retriever,
llm=llm,
)
response = query_engine.query("What medication was started for the patient with diabetes?")
print(str(response))
In a real agent system, you would wrap this query engine with tool calling and add policy filters around patient access. For example:
- •restrict retrieval by
patient_id - •log every query to an audit table in Supabase
- •redact sensitive fields before sending context to the model
- •Persist audit logs and retrieval traces back into Supabase.
from datetime import datetime
audit_row = {
"user_id": "clinician_17",
"query_text": "What medication was started for the patient with diabetes?",
"retrieved_at": datetime.utcnow().isoformat(),
"top_k": 3,
}
audit_response = supabase.table("retrieval_audit").insert(audit_row).execute()
print(audit_response.data)
A production deployment should always record:
- •who queried the system
- •what patient scope was used
- •which chunks were retrieved
- •what answer was returned
That gives you traceability for compliance reviews and debugging when retrieval quality drops.
Testing the Integration
Run one end-to-end query against the index and confirm both retrieval and persistence work.
test_query = "Summarize the cardiac history."
result = query_engine.query(test_query)
supabase.table("retrieval_audit").insert({
"user_id": "test_user",
"query_text": test_query,
}).execute()
print("ANSWER:", result)
Expected output:
ANSWER: History of CHF with recent weight gain and lower extremity edema.
If that returns relevant clinical context and your audit row lands in Supabase, the integration is working.
Real-World Use Cases
- •
Clinical chart assistant
- •Retrieve patient-specific notes from Supabase and summarize them into concise chart briefs for clinicians.
- •
Care-gap detection
- •Combine structured claims/encounter data with unstructured notes to flag missing follow-ups, overdue labs, or medication mismatches.
- •
Policy-aware medical search
- •Let staff ask natural-language questions over internal guidelines while enforcing tenant-level access control through Supabase policies.
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