Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ClinicalIQ

AI-Driven Multi-Role Clinical Intelligence System powered by LangGraph agents, ChromaDB, and Claude/OpenAI models.

Overview

ClinicalIQ adapts clinical responses based on the user's role — Patient, Clinician, Radiologist, or Care Coordinator. It uses a multi-agent LangGraph orchestrator that routes queries to specialized agents (lab interpreter, radiology analyzer, allergy safety checker) and retrieves context from a ChromaDB vector store.

Tech Stack

Layer Technology
Frontend React 18, Vite, Redux Toolkit, TailwindCSS
Backend FastAPI, LangGraph, LangChain, Python 3.12
AI Providers Anthropic Claude / OpenAI GPT (switchable)
Vector Store ChromaDB Cloud
Observability Langfuse
AWS Infra Lambda (container), ECR, S3, CloudFront, Terraform

Local Development

Prerequisites

  • Python 3.12+
  • Node.js 20+
  • Docker & Docker Compose (optional, for container-based setup)
  • Anthropic API key (or OpenAI API key)
  • ChromaDB Cloud account
  • Langfuse account (optional — app runs without it)

1. Clone and configure environment

git clone <repo-url>
cd clinicaliq
cp .env.example .env

Edit .env and fill in your credentials:

# Required: choose one provider
AI_PROVIDER=anthropic          # or openai
AI_MODEL=claude-haiku-4-5-20251001

ANTHROPIC_API_KEY=sk-ant-...   # if using Anthropic
OPENAI_API_KEY=sk-...          # if using OpenAI

# ChromaDB Cloud (required)
CHROMA_API_KEY=ck-...
CHROMA_TENANT=<your-tenant-id>
CHROMA_DATABASE=health-care-clinical-data
CHROMA_COLLECTION_NAME=clinical_documents

# Langfuse (optional)
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_BASE_URL=https://us.cloud.langfuse.com

Option A: Docker Compose (recommended)

Starts both backend and frontend with hot reload.

docker compose up --build
Service URL
Frontend http://localhost:6153
Backend API http://localhost:12000
API Docs (Swagger) http://localhost:12000/docs
Health check http://localhost:12000/health

To stop:

docker compose down

Option B: Manual Setup

Backend

cd backend
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -r requirements.txt

# Run from project root so .env is found automatically
cd ..
uvicorn backend.app.main:app --host 0.0.0.0 --port 12000 --reload

Frontend (in a separate terminal)

cd frontend
npm install
npm run dev

Open http://localhost:6153 in your browser.


Seed / Ingest Sample Data

The backend auto-ingests documents on startup. To manually trigger ingestion:

cd backend
python scripts/generate_data.py

This generates synthetic clinical documents into data/synthetic/clinical_documents.json and upserts them into ChromaDB.


API Reference

Method Endpoint Description
GET /health Health check
POST /api/v1/clinical/query Submit a clinical query

Example query:

curl -X POST http://localhost:12000/api/v1/clinical/query \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What do elevated troponin levels indicate?",
    "role": "clinician",
    "patient_id": "P001"
  }'

Supported roles: patient, clinician, radiologist, coordinator


AWS Deployment

The infrastructure is fully managed by Terraform. The architecture is:

  • Backend: Docker container image → ECR → Lambda (Function URL)
  • Frontend: Vite build → S3 → CloudFront
  • CloudFront: routes /api/* to Lambda, everything else to S3

Prerequisites

  • AWS CLI configured (aws configure)
  • Terraform >= 1.6 installed
  • Docker installed (for building the Lambda image)

Step 1: Deploy Infrastructure with Terraform

cd terraform
terraform init

Create a terraform.tfvars file (do not commit this file):

anthropic_api_key      = "sk-ant-..."
openai_api_key         = ""                          # leave empty if unused
chroma_api_key         = "ck-..."
chroma_tenant          = "<your-tenant-id>"
langfuse_secret_key    = "sk-lf-..."
langfuse_public_key    = "pk-lf-..."
aws_region             = "us-east-1"

Apply the infrastructure:

terraform apply -var-file="terraform.tfvars"

Note the outputs — you will need them in the next steps:

cloudfront_url      = "https://xxxx.cloudfront.net"
ecr_repository_url  = "123456789.dkr.ecr.us-east-1.amazonaws.com/clinicaliq-prod-backend"
s3_bucket_name      = "clinicaliq-prod-frontend-123456789"
lambda_function_url = "https://xxxx.lambda-url.us-east-1.on.aws/"

Step 2: Build and Push the Backend Docker Image

export AWS_REGION=us-east-1
export ECR_URL=<ecr_repository_url from terraform output>

# Authenticate Docker with ECR
aws ecr get-login-password --region $AWS_REGION | \
  docker login --username AWS --password-stdin $ECR_URL

# Build for Lambda (AMD64)
docker build --platform linux/amd64 -t clinicaliq-backend ./backend

# Tag and push
docker tag clinicaliq-backend:latest $ECR_URL:latest
docker push $ECR_URL:latest

After pushing, update the Lambda to use the new image:

aws lambda update-function-code \
  --function-name clinicaliq-prod-backend \
  --image-uri $ECR_URL:latest \
  --region $AWS_REGION

Step 3: Build and Deploy the Frontend

export CLOUDFRONT_URL=<cloudfront_url from terraform output>
export S3_BUCKET=<s3_bucket_name from terraform output>

# Build with the production API base URL
cd frontend
VITE_API_BASE_URL=$CLOUDFRONT_URL npm run build

# Upload to S3
aws s3 sync dist/ s3://$S3_BUCKET --delete

# Invalidate CloudFront cache
aws cloudfront create-invalidation \
  --distribution-id <your-cloudfront-distribution-id> \
  --paths "/*"

The CloudFront distribution ID can be retrieved with:

cd ../terraform
terraform output cloudfront_url
# Then find the distribution ID:
aws cloudfront list-distributions --query \
  "DistributionList.Items[?DomainName=='<domain-from-output>'].Id" \
  --output text

Step 4: Verify Deployment

# Health check
curl https://<cloudfront_url>/health

# Test a query
curl -X POST https://<cloudfront_url>/api/v1/clinical/query \
  -H "Content-Type: application/json" \
  -d '{"query": "Explain CBC results", "role": "patient", "patient_id": "P001"}'

Open https://<cloudfront_url> in your browser to use the full application.


Tear Down

To remove all AWS resources:

cd terraform
terraform destroy -var-file="terraform.tfvars"

Note: This deletes the S3 bucket and all its contents (force_destroy = true), the ECR repository and all images, and the Lambda function.


Project Structure

clinicaliq/
├── backend/
│   ├── app/
│   │   ├── agents/          # LangGraph agents (orchestrator, lab, radiology, allergy)
│   │   ├── api/routes/      # FastAPI route handlers
│   │   ├── data/            # Document ingestion pipeline
│   │   ├── knowledge_graph/ # Medical ontology graph
│   │   ├── models/          # Pydantic schemas
│   │   ├── observability/   # Langfuse client
│   │   ├── vectorstore/     # ChromaDB client
│   │   ├── config.py
│   │   └── main.py
│   ├── scripts/
│   │   └── generate_data.py
│   ├── Dockerfile           # Production Lambda image
│   ├── Dockerfile.dev       # Local dev image
│   ├── lambda_handler.py    # Mangum ASGI adapter for Lambda
│   └── requirements.txt
├── frontend/
│   └── src/
│       ├── components/      # React UI components
│       ├── store/slices/    # Redux state (role, clinical)
│       └── services/api.js  # Axios API client
├── terraform/               # AWS infrastructure (Lambda, ECR, S3, CloudFront)
├── data/synthetic/          # Sample clinical documents
├── docker-compose.yml
├── .env.example
└── README.md

Environment Variables Reference

Variable Required Description
AI_PROVIDER Yes anthropic or openai
AI_MODEL Yes Model ID (e.g. claude-haiku-4-5-20251001)
ANTHROPIC_API_KEY If using Anthropic API key
OPENAI_API_KEY If using OpenAI API key
CHROMA_API_KEY Yes ChromaDB Cloud API key
CHROMA_TENANT Yes ChromaDB tenant UUID
CHROMA_DATABASE Yes Database name
CHROMA_COLLECTION_NAME Yes Collection name
LANGFUSE_SECRET_KEY Optional Langfuse tracing
LANGFUSE_PUBLIC_KEY Optional Langfuse tracing
LANGFUSE_BASE_URL Optional Langfuse endpoint
ALLOWED_ORIGINS Yes Comma-separated CORS origins
APP_ENV No development or production
APP_PORT No Backend port (default: 12000)

About

ClinicalIQ

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors