How to Integrate LlamaIndex for healthcare with Supabase for AI agents

By Cyprian AaronsUpdated 2026-04-21
llamaindex-for-healthcaresupabaseai-agents

Why this integration matters

If you’re building AI agents for healthcare, you need two things working together: trusted clinical retrieval and durable application state. LlamaIndex for healthcare gives your agent a structured way to index and query medical knowledge, while Supabase gives you Postgres, auth, and storage for patient context, conversation history, and audit trails.

The practical result is an agent that can answer from clinical sources, persist user sessions, and keep every interaction queryable in a real database.

Prerequisites

  • Python 3.10+
  • A Supabase project with:
    • SUPABASE_URL
    • SUPABASE_SERVICE_ROLE_KEY or anon key for non-sensitive testing
  • A LlamaIndex setup with healthcare-specific packages installed
  • Access to your healthcare documents or datasets
  • Basic familiarity with:
    • llama_index
    • supabase-py
    • PostgreSQL tables and SQL

Install the dependencies:

pip install supabase llama-index llama-index-core llama-index-embeddings-openai llama-index-llms-openai

If you’re using a healthcare-specific LlamaIndex package in your stack, install that too. In production, keep PHI handling behind proper access controls and encryption.

Integration Steps

1) Connect to Supabase

Start by creating a Supabase client. Use the service role key only on the server side.

import os
from supabase import create_client, Client

SUPABASE_URL = os.environ["SUPABASE_URL"]
SUPABASE_SERVICE_ROLE_KEY = os.environ["SUPABASE_SERVICE_ROLE_KEY"]

supabase: Client = create_client(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY)

Create a table for agent memory or retrieval metadata:

create table if not exists agent_messages (
  id bigserial primary key,
  session_id text not null,
  role text not null,
  content text not null,
  created_at timestamptz default now()
);

2) Load healthcare documents into LlamaIndex

Use LlamaIndex to ingest your healthcare documents. The exact loader depends on your source, but the pattern stays the same: load files, chunk them, then build an index.

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("./healthcare_docs").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

If you’re using healthcare-specific connectors or node parsers in your stack, plug them in before indexing. Keep source provenance intact so responses can be traced back to the original document.

3) Store agent conversation state in Supabase

Your agent needs memory outside the process. Persist each turn so you can replay sessions, debug behavior, and support audit requirements.

def save_message(session_id: str, role: str, content: str):
    supabase.table("agent_messages").insert({
        "session_id": session_id,
        "role": role,
        "content": content,
    }).execute()

def get_recent_messages(session_id: str):
    response = (
        supabase.table("agent_messages")
        .select("*")
        .eq("session_id", session_id)
        .order("created_at", desc=False)
        .execute()
    )
    return response.data

This gives you persistent context without stuffing everything into the prompt. That matters when the conversation gets long or regulated.

4) Build the agent loop that queries LlamaIndex and writes to Supabase

Now wire retrieval and persistence together. The agent reads prior messages from Supabase, asks LlamaIndex for a grounded answer, then stores both sides of the exchange.

from llama_index.core import Settings
from llama_index.llms.openai import OpenAI

Settings.llm = OpenAI(model="gpt-4o-mini")

def answer_healthcare_question(session_id: str, question: str):
    history = get_recent_messages(session_id)

    context = "\n".join(
        f"{msg['role']}: {msg['content']}" for msg in history[-10:]
    )

    prompt = f"""
You are a healthcare assistant.
Use only retrieved medical context when possible.
Conversation history:
{context}

User question: {question}
"""

    response = query_engine.query(prompt)
    answer_text = str(response)

    save_message(session_id, "user", question)
    save_message(session_id, "assistant", answer_text)

    return answer_text

If your setup uses LlamaIndex’s chat engines instead of direct query engines, swap in index.as_chat_engine() and keep the same persistence pattern.

5) Add structured logging for traceability

For healthcare workflows, raw text logs are not enough. Store metadata like document source, timestamps, and confidence signals if your pipeline exposes them.

def log_retrieval(session_id: str, query: str, answer: str):
    supabase.table("retrieval_logs").insert({
        "session_id": session_id,
        "query": query,
        "answer": answer,
    }).execute()

A simple schema is enough to start:

create table if not exists retrieval_logs (
  id bigserial primary key,
  session_id text not null,
  query text not null,
  answer text not null,
  created_at timestamptz default now()
);

Testing the Integration

Run a basic end-to-end check: write a message to Supabase, retrieve it back, and ask LlamaIndex a question from your indexed docs.

session_id = "demo-session-001"

save_message(session_id, "user", "What are common symptoms of hypertension?")
answer = answer_healthcare_question(session_id, "What are common symptoms of hypertension?")

print("Answer:", answer)

messages = get_recent_messages(session_id)
print("Stored messages:", len(messages))
print("Last role:", messages[-1]["role"])

Expected output:

Answer: ...grounded response based on indexed healthcare documents...
Stored messages: 2
Last role: assistant

If you see two stored records and a non-empty answer from the index, the integration is working. If retrieval returns empty or generic output only, check your document ingestion path and confirm the index was built from actual healthcare content.

Real-World Use Cases

  • Clinical FAQ agents

    • Answer staff questions from policy docs, treatment guidelines, or internal SOPs while storing every interaction in Supabase.
  • Patient intake assistants

    • Collect symptoms and history through an agent flow, persist structured intake data in Postgres tables, and retrieve relevant medical context with LlamaIndex.
  • Audit-ready support workflows

    • Keep conversation history, retrieval logs, and document references in Supabase so compliance teams can inspect what the agent saw and returned.

Keep learning

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

Related Guides