Skip to content

Repository files navigation

Litigation Precedent Research Assistant

Python FastAPI License Code style: black

Overview

This project is an end-to-end agentic NLP system for legal precedent research. Given a case fact pattern or query, the system retrieves relevant US Supreme Court precedents, ranks them by similarity, and explains why each case is relevant using paragraph-level citations.

The system focuses on retrieval, explainability, and verification—not legal advice or outcome prediction. It demonstrates modern approaches to building production-grade AI systems with safety mechanisms against hallucinations.

🎯 Built as a portfolio project showcasing agentic workflows, hybrid retrieval, LLM orchestration, and full-stack development.


Problem Statement

Legal professionals spend significant time searching for relevant precedents:

  • Keyword-based search often misses cases with similar fact patterns but different wording
  • LLM-only approaches are unreliable due to hallucinations and missing citations
  • No explainability in why certain cases are relevant

This project explores how LLMs, semantic retrieval, and agentic workflows can be combined safely for professional legal research.


Key Features

Semantic Vector Search

  • Domain-specific embeddings via self-hosted Inception microservice (freelawproject/modernbert-embed-base_finetune_512, 768-dim, fine-tuned on legal text)
  • HNSW approximate nearest-neighbor index (pgvector) for sub-10ms ANN queries
  • Two retrieval modes: raw paragraph similarity or distinct-case results

RRF Case Aggregation

  • Reciprocal Rank Fusion scores cases by their aggregate paragraph relevance
  • Cases with many relevant paragraphs outrank cases with one coincidentally similar paragraph
  • Solves the core problem of paragraph-level search for case-level queries

🔜 Hybrid BM25 + Vector Search (planned — see Roadmap)

  • Combines exact legal term matching (BM25 via PostgreSQL tsvector) with semantic search
  • Merged via RRF: 1/(60+bm25_rank) + 1/(60+vector_rank)
  • Critical for statute citations, doctrine names, and case name lookups

FastAPI Backend with Full CRUD

  • Async psycopg3 connection pool; complete CRUD for cases, opinions, paragraphs
  • POST /api/v1/search — semantic search with configurable top_k, distinct_cases, scan_multiplier

5-Agent Workflow (architecture designed, implementation planned)

  • Ingestion Agent: Fetches and stores court opinions
  • Retriever Agent: Hybrid search across 5,000 SCOTUS cases
  • Reranker Agent: LLM-powered relevance scoring
  • Explanation Agent: Generates detailed relevance explanations
  • Verifier Agent: Validates all citations to prevent hallucinations

Paragraph-Level Citations

  • Every claim is backed by specific paragraph references with text_with_citations markers
  • Verification status displayed for transparency

System Architecture

┌─────────────────────────────────────────────────────────────┐
│                      React/Next.js UI                  (TBD) │
└────────────────────────┬────────────────────────────────────┘
                         │ HTTP/REST
┌────────────────────────▼────────────────────────────────────┐
│               FastAPI Backend  :8000                  (done) │
│  POST /api/v1/search   GET|POST|PUT|DELETE /api/v1/cases    │
│                        GET|POST|PUT|DELETE /api/v1/opinions  │
│                        GET|POST|PUT|DELETE /api/v1/paragraphs│
│  ┌──────────────────────────────────────────────────────┐   │
│  │           Agent Orchestrator                   (TBD) │   │
│  └─────┬───────┬───────┬───────┬────────┬─────────────┘    │
│  Ingest│ Retrie│ Rerank│ Explai│ Verify │  (all TBD)        │
└────────┼───────┼───────┼───────┼────────┼───────────────────┘
         │       │       │       │        │
    ┌────▼───────▼──┐  ┌─▼──────▼──┐  ┌──▼────────────────┐
    │  PostgreSQL   │  │ pgvector  │  │  Inception :8005  │
    │  pg16-trixie  │  │ HNSW ANN  │  │  modernbert-embed │
    │  5,000 cases  │  │  768-dim  │  │  768-dim, legal   │
    │  5,043 opinions│  │  cosine   │  │  GPU-capable      │
    └───────────────┘  └───────────┘  └───────────────────┘
                                LLM APIs (planned)
                           OpenAI GPT-4o-mini (reranker)
                           Anthropic Claude (explanation)

Search & Retrieval Workflow (implemented)

  1. User QueryPOST /api/v1/search with optional distinct_cases, top_k
  2. Embed query → Inception /api/v1/embed/text; mean-pool if query > 512 tokens
  3. ANN scan → pgvector HNSW cosine search, top top_k × scan_multiplier candidates
  4. RRF aggregation (distinct_cases mode) → Score each case by SUM(1/(60+rank)) across all its matching paragraphs; return top-k distinct cases
  5. Results → Paragraph text + case/opinion metadata + similarity scores

Full Agentic Workflow (planned)

  1. User Query → System receives query + optional fact pattern
  2. Retriever Agent → Hybrid search (BM25 + Vector + RRF) retrieves top cases
  3. Reranker Agent → GPT-4o-mini scores and selects top 10 cases
  4. Explanation Agent → Claude generates detailed explanations with paragraph citations (parallel)
  5. Verifier Agent → Validates all quoted text against source paragraphs
  6. Results → Verified precedents with confidence scores returned to user

Technology Stack

Backend

  • Python 3.12 with uv for fast dependency management
  • FastAPI — high-performance async REST API (CRUD + semantic search)
  • PostgreSQL 16 with pgvector extension — vector storage, HNSW ANN index
  • psycopg3 (psycopg[binary,pool]) — async connection pool, direct SQL (no ORM)
  • Pydantic v2 — request/response schema validation
  • structlog — JSON structured logging (planned)

Embeddings

  • Inception microservice (self-hosted, port 8005) — wraps freelawproject/modernbert-embed-base_finetune_512
    • 768-dimensional embeddings fine-tuned on legal text from the Free Law Project
    • GPU-capable via NVIDIA CUDA; CPU fallback for development
    • Mean-pools multi-chunk responses for queries > 512 tokens
  • pgvector HNSW index — approximate nearest-neighbor search (cosine, m=16, ef_construction=64)
  • Reciprocal Rank Fusion — case-level score aggregation over paragraph rankings

NLP / LLM (planned)

  • OpenAI GPT-4o-mini — fast reranking agent
  • Anthropic Claude 3.5 Sonnet — high-quality explanations and verification
  • PostgreSQL tsvector + GIN index — BM25 full-text search for hybrid retrieval (next milestone)

Frontend (planned)

  • Next.js 14 — React framework with App Router
  • TypeScript — type-safe frontend code
  • Tailwind CSS — utility-first styling

Infrastructure

  • Docker + Docker Compose — containerized deployment
  • PostgreSQL container with pgvector extension
  • Inception embedding container — separate compose, CUDA-capable
  • host.docker.internal bridges backend → Inception across separate Docker composes

Data Sources

  • US Supreme Court opinions via CourtListener API (Free Law Project)
  • Public case text and metadata only
  • No private or proprietary data
  • Current scope: 5,000 SCOTUS cases (v1); expanding to full corpus

Setup

Prerequisites

  • Docker & Docker Compose
  • OpenAI API key
  • Anthropic API key (optional, for explanations)
  • CourtListener API key (for data ingestion)

Quick Start

  1. Clone the repository
git clone https://github.com/your-username/litigation-precedent-assistant.git
cd litigation-precedent-assistant
  1. Set up environment variables
cp .env.example .env
# Edit .env with your API keys
  1. Start the services
docker-compose up --build
  1. Access the application

Manual Setup (Development)

  1. Install dependencies
# Install uv (fast Python package installer)
pip install uv

# Install project dependencies
uv pip install -e .
  1. Set up PostgreSQL with pgvector
# Using Docker
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=precedent_finder \
  -p 5432:5432 \
  pgvector/pgvector:pg16

# Initialize schema
psql -h localhost -U postgres -d precedent_finder -f scripts/db/init_schema.sql
  1. Ingest data
# Fetch Supreme Court cases
python scripts/ingest/fetch_scotus_cases.py

# Generate embeddings
python scripts/embeddings/generate_embeddings.py

# Load to database
python scripts/embeddings/load_to_db.py
  1. Run the backend
uvicorn src.backend.api.main:app --reload --port 8000
  1. Run the frontend
cd src/frontend
npm install
npm run dev

Usage

Web Interface

  1. Navigate to http://localhost:3000
  2. Enter your legal query in the search box
  3. Optionally add context (your fact pattern)
  4. Click "Search" to retrieve relevant precedents
  5. View detailed explanations with paragraph-level citations
  6. Check verification badges (✓ = verified, ⚠ = unverified)

API

Search for precedents:

curl -X POST http://localhost:8000/api/v1/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": "What are the precedents for right to privacy in medical decisions?",
    "context": "Plaintiff is a patient seeking abortion access in Texas.",
    "top_k": 5
  }'

Get case details:

curl http://localhost:8000/api/v1/cases/123

API Documentation:


Evaluation

The system is evaluated as a retrieval and explanation tool, not a legal decision system.

Retrieval Quality Metrics

Metric Target Description
Recall@10 >75% Fraction of relevant cases in top 10
Precision@10 >80% Fraction of top 10 that are relevant
nDCG@10 >0.85 Normalized discounted cumulative gain
MRR >0.80 Mean reciprocal rank of first relevant result

System Performance

Metric Target Measured
p50 latency <3s TBD
p95 latency <5s TBD
Verification accuracy >90% TBD
Throughput 10 RPS TBD

Quality Assurance

  • Golden dataset: 50 test queries with human relevance judgments
  • Verifier pass rate: Citation correctness > 95%
  • Human evaluation: 20 sample explanations reviewed for relevance and completeness
  • Weak supervision: Citation graph validation

Project Structure

end-to-end/
├── docker/                    # Docker configurations
├── scripts/                   # Data ingestion and utilities
│   ├── ingest/               # Data fetching and parsing
│   ├── embeddings/           # Embedding generation
│   └── db/                   # Database setup
├── src/
│   ├── backend/              # Python backend
│   │   ├── agents/          # 5 specialized agents
│   │   ├── api/             # FastAPI routes
│   │   ├── core/            # Config, logging, orchestrator
│   │   ├── db/              # Database models and repositories
│   │   ├── services/        # LLM, embeddings, search services
│   │   └── utils/           # Text processing, citations
│   └── frontend/             # Next.js frontend
│       ├── app/             # Pages and layouts
│       ├── components/      # React components
│       └── lib/             # API client
├── tests/                    # Unit, integration, E2E tests
├── .env.example              # Environment variables template
├── pyproject.toml            # Python dependencies
└── README.md                 # This file

Limitations

Scope Limitations

  • US Supreme Court only (v1 scope)
  • 500 landmark cases in initial release (expanding to full corpus)
  • Limited domain coverage (employment and contract disputes prioritized)

Technical Limitations

  • No legal advice - Tool is for research purposes only
  • No outcome prediction - Does not predict case outcomes
  • OCR not implemented - Scanned documents flagged but not processed
  • English language only - No multilingual support

Performance Limitations

  • Rate limiting: 10 requests per minute per IP
  • Concurrent users: Optimized for 10 concurrent users
  • Context length: Limited by LLM context windows

Development

Running Tests

# Unit tests
pytest tests/unit/

# Integration tests
pytest tests/integration/

# All tests with coverage
pytest --cov=src --cov-report=html

Code Quality

# Format code
black src/ tests/

# Lint
ruff check src/ tests/

# Type checking
mypy src/

Database Migrations

# Create migration
alembic revision --autogenerate -m "Description"

# Apply migrations
alembic upgrade head

Deployment

Using Docker Compose (Recommended)

docker-compose -f docker/docker-compose.prod.yml up -d

Cloud Deployment

The application can be deployed to:

  • AWS: ECS + RDS + CloudFront
  • Google Cloud: Cloud Run + Cloud SQL
  • Render: Web Services + PostgreSQL
  • Railway: All-in-one deployment

See DEPLOYMENT.md for detailed instructions.


Roadmap

Phase 1 — Retrieval Foundation (current)

  • 5,000 SCOTUS cases ingested and normalized
  • Chunking v2: tokenizer-based boundaries, [[CIT:id|display]] inline citation markers
  • Inception embedding microservice (768-dim, legal domain fine-tuned)
  • pgvector HNSW index for approximate nearest-neighbor search
  • FastAPI backend — full CRUD + semantic search
  • RRF case aggregation — cases scored by aggregate paragraph relevance
  • Embeddings backfill (generate + load pipeline ready, awaiting Inception validation)
  • Hybrid BM25 + Vector Search (next milestone — see below)

Hybrid BM25 + Vector Search — Planned Implementation

BM25 (Best Match 25) ranks documents by exact term frequency weighted by how rare the term is across the corpus. It excels at what vector search misses: statute citations ("42 U.S.C. § 1983"), doctrine names ("res judicata"), and case names ("Miranda v. Arizona").

Implementation plan:

  1. Add PostgreSQL full-text index (migration 005_bm25_index.sql):
ALTER TABLE paragraphs
    ADD COLUMN text_tsv tsvector
        GENERATED ALWAYS AS (to_tsvector('english', text)) STORED;
CREATE INDEX idx_paragraphs_text_tsv ON paragraphs USING gin(text_tsv);
  1. Run parallel scans — BM25 via tsvector @@ websearch_to_tsquery and vector via HNSW, each returning top-N candidates

  2. Merge via RRF — assign ranks to each result list, combine:

score = 1/(60 + bm25_rank) + 1/(60 + vector_rank)

Documents appearing in both lists (exact match AND semantically similar) rise to the top.

  1. Apply existing RRF case aggregation on top of the hybrid paragraph scores.

When it helps most: queries with specific legal terminology, statute numbers, and case names where vector search may over-generalize to conceptually similar but doctrinally distinct results.

Phase 2 — Agent System

  • Retriever Agent wrapper around hybrid search
  • LLM integration (OpenAI GPT-4o-mini + Anthropic Claude)
  • Reranker Agent — LLM-based final relevance scoring
  • Explanation Agent — paragraph-level citation generation
  • Verifier Agent — citation hallucination detection
  • Agent Orchestrator — parallel workflow coordination

Phase 3 — Frontend & Coverage

  • Next.js 14 web interface with search UI and verification badges
  • Full SCOTUS corpus (10,000+ cases)
  • Circuit Court opinions

Phase 4 — Advanced Features

  • Citation graph visualization
  • Shepardizing (track overturned cases)
  • Document upload (analyze user's brief)
  • ColBERT late-interaction retrieval
  • Active learning from user feedback

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines.

Development Workflow

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run tests and linting
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.


Disclaimer

⚠️ IMPORTANT: This tool is for informational and research purposes only.

  • It does NOT provide legal advice
  • It should NOT be used as a substitute for professional legal judgment
  • Users should independently verify all citations and precedents
  • No warranty is provided for accuracy or completeness
  • Consult qualified legal professionals for legal matters

Project Status

🚧 Under Active Development - Portfolio & Learning Project

This is a learning project focused on:

  • Agentic workflow design and implementation
  • Hybrid retrieval system architecture
  • LLM safety and verification mechanisms
  • Production-grade NLP system design

Not intended for production legal use without significant additional development and validation.


Acknowledgments

  • Free Law Project for CourtListener API
  • OpenAI for GPT and embedding models
  • Anthropic for Claude models
  • pgvector team for PostgreSQL vector extension
  • Legal professionals who provided feedback on requirements

Contact & Support


Citations

If you use this project in your research or reference it in your work, please cite:

@software{litigation_precedent_assistant,
  title = {Litigation Precedent Research Assistant},
  author = {Your Name},
  year = {2026},
  url = {https://github.com/your-username/litigation-precedent-assistant}
}

Built with ❤️ for the legal tech community

Demonstrating the intersection of AI, NLP, and legal research

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages