Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Case Folder AI

An in-house RAG-powered AI tool for attorneys at Edelson PC to query, summarize, and extract facts from case folders.

Features

  • Document Ingestion: Upload multiple files (PDFs, Word docs, text files)
  • Intelligent Q&A: Ask questions and get cited answers from your documents
  • Document Summarization: Generate comprehensive summaries of any document
  • Auto Classification: Documents automatically classified by type (deposition, motion, etc.)
  • Conversation Memory: Multi-turn conversations with context awareness
  • Hybrid Search: Dense + sparse + ColBERT reranking for best retrieval
  • Matter Management: Organize documents by case/matter
  • Citation Tracking: Every answer includes source references with file names and page numbers

Tech Stack

  • Backend: FastAPI + Python
  • Frontend: React + TypeScript + Vite
  • Vector Store: Qdrant
  • Database: PostgreSQL
  • LLM: Anthropic Claude Sonnet 4
  • Embeddings: OpenAI text-embedding-3-small
  • Agent Framework: LangGraph
  • Document Processing: LangChain

Setup Instructions

Prerequisites

  • Python 3.11+
  • Node.js 18+
  • Docker and Docker Compose
  • uv (Python package manager)

1. Clone and Setup Environment

# Clone the repository
cd casedoc-pro

# Copy environment file
cp .env.example .env

# Edit .env and add your API keys
# OPENAI_API_KEY=your_key_here
# ANTHROPIC_API_KEY=your_key_here

2. Start Docker Services

# Start Qdrant and PostgreSQL
docker-compose up -d

# Verify services are running
docker-compose ps

3. Setup Backend

cd backend

# Install dependencies with uv
uv sync

# Run the backend server
uv run python main.py

Backend will be available at http://localhost:8000

4. Setup Frontend

cd frontend

# Install dependencies
npm install

# Run the dev server
npm run dev

Frontend will be available at http://localhost:5173

Usage

Ingesting Documents

  1. Click "Ingest New Folder" in the sidebar
  2. Enter a matter name (e.g., "Smith v. Acme Corp")
  3. Choose files to upload (supports multiple files)
  4. Click "Ingest" and wait for processing

The system will:

  • Parse all PDFs, DOCX, and TXT files
  • Automatically classify document types (deposition, motion, etc.)
  • Extract text and chunk documents
  • Create hybrid embeddings (dense + sparse + ColBERT)
  • Store in Qdrant vector database and PostgreSQL

Asking Questions

  1. Select a matter from the sidebar
  2. Type your question in the chat input
  3. Press Enter or click "Send"

The AI will:

  • Use hybrid search to retrieve relevant chunks
  • Generate an answer using Claude with conversation context
  • Provide citations with file names and page numbers

Example Questions

Regular Q&A:

  • "What did the plaintiff claim in their complaint?"
  • "What are the key dates in this case?"
  • "Who testified about the safety procedures?"
  • "What damages are being sought?"

Follow-up Questions (using conversation history):

  • "What did Smith say about the accident?"
  • "When did that happen?" ← Knows "that" refers to the accident
  • "Were there any witnesses?"

Document Summarization:

  • "Summarize deposition_smith.pdf"
  • "Give me a summary of the contract"
  • "Summarize the motion for summary judgment"

Project Structure

casedoc-pro/
├── backend/
│   ├── main.py              # FastAPI app with endpoints
│   ├── config.py            # Configuration and settings
│   ├── models.py            # Database and API models
│   ├── ingest.py            # Document ingestion pipeline
│   ├── retriever.py         # Vector search and retrieval
│   ├── agent.py             # LangGraph agent (router + RAG)
│   ├── chunker.py           # Text chunking with LangChain
│   └── parsers/             # Document loaders
│       └── document_loader.py
├── frontend/
│   └── src/
│       ├── App.tsx          # Main app with sidebar
│       ├── api/
│       │   └── client.ts    # API client functions
│       └── components/
│           ├── ChatWindow.tsx
│           ├── MessageBubble.tsx
│           └── CitationChip.tsx
├── docker-compose.yml       # Qdrant + PostgreSQL
├── .env.example             # Environment template
└── README.md

API Endpoints

POST /ingest

Ingest a folder of documents into a matter.

Request:

{
  "matter_name": "Smith v. Acme Corp",
  "folder_path": "/path/to/case/folder"
}

Response:

{
  "matter_id": "uuid",
  "files_processed": 24,
  "chunks_created": 312,
  "files_skipped": [],
  "skipped_reason": ""
}

POST /chat

Ask a question about case documents.

Request:

{
  "matter_id": "uuid",
  "message": "What did the plaintiff claim?"
}

Response:

{
  "answer": "According to the complaint...",
  "citations": [
    {
      "file_name": "complaint.pdf",
      "page_number": 3,
      "chunk_id": "uuid"
    }
  ]
}

GET /matters

Get all matters with document counts.

Response:

[
  {
    "matter_id": "uuid",
    "matter_name": "Smith v. Acme Corp",
    "document_count": 24,
    "created_at": "2025-02-25T12:00:00"
  }
]

V1 Feature Set

Completed Features:

  • ✅ Multi-file upload ingestion (PDF, DOCX, TXT)
  • ✅ Fixed chunking (400 tokens, 80 overlap)
  • ✅ Hybrid search (dense + sparse + ColBERT reranking)
  • ✅ LangGraph agent with routing
  • ✅ Document summarization
  • ✅ Automatic doc-type classification (using Claude)
  • ✅ Conversation history and context
  • ✅ Chat interface with citations
  • ✅ Matter management
  • ✅ Production-grade logging
  • ✅ Comprehensive error handling

Not Yet Implemented (V2+):

  • ❌ Doc-type-aware chunking strategies
  • ❌ Neighbor chunk expansion
  • ❌ Multi-agent orchestration with parallel execution
  • ❌ Fact extraction agent
  • ❌ Drafting and critique agents
  • ❌ Authentication
  • ❌ Streaming responses

Troubleshooting

Backend Issues

Import errors:

cd backend
uv sync

Database connection errors:

docker-compose down
docker-compose up -d

Frontend Issues

Type errors:

cd frontend
npm install

CORS errors: Make sure backend is running on port 8000 and frontend on port 5173.

Next Steps (Post-MVP)

  1. Add MMR re-ranking for better retrieval diversity
  2. Implement doc-type-aware chunking
  3. Add neighbor chunk context expansion
  4. Claude-powered metadata extraction
  5. Document drafting capabilities
  6. Streaming responses
  7. Authentication and multi-user support
  8. Advanced reranking (Voyage/Cohere)

License

Internal use only - Edelson PC

⏺ Excellent document! This is a very well-thought-out design. Let me break down my analysis:


🎯 My Assessment: This is brilliant and feasible

What I Love About This Design:

  1. Three-Level Classification is Smart - Level 1 (structural signals) handles 70-80% for free ✅ - Level 2 (targeted AI) handles edge cases cheaply ✅ - Level 3 (paragraph fallback) always works ✅ - This is production-grade thinking - not just "throw it all at Claude"
  2. Doc-Type Aware Chunking Makes Sense - Keeping Q&A exchanges together for depositions is exactly right - Section-based chunking for motions preserves legal arguments - One line per docket entry is perfect - This will dramatically improve retrieval quality
  3. Retrieval Controls UI is Genius - Gives attorneys control without overwhelming them - Auto-suggests smart defaults based on doc type - Search provenance line builds trust - This is what makes the tool attorney-grade vs. toy
  4. Single-Pass Architecture - Classify → Chunk → Embed in one pass - No re-chunking needed later - Efficient and clean

📊 Implementation Complexity Analysis

Easy Wins (1-2 days each):

✅ Retrieval Controls UI (search scope, fetch K, rerank K)

  • Just add 3 dropdowns + state management
  • Modify retriever to accept these parameters
  • Already have hybrid search, just expose the knobs

✅ Dynamic Doc Type Dropdown

  • New endpoint: GET /matters/{matter_id}/doc_types
  • Query: SELECT doc_type, COUNT(*) FROM documents GROUP BY doc_type
  • Already storing doc_type, just expose it

✅ Search Provenance Line

  • Return metadata from retrieval agent
  • Display under each response

Medium Effort (3-5 days):

🟡 Level 1: Structural Signal Detection

  • Write signal detectors for each doc type
  • This is just pattern matching, no AI needed
  • Test with your existing RFA files

🟡 Level 2: Targeted AI Classification

  • Already have Claude integration
  • Just need the JSON prompt + fallback logic
  • 500 tokens = very cheap

🟡 Schema Additions

  • Add classification_confidence, boundary_type, avg_chunk_tokens
  • These are simple column adds

Big Lift (1-2 weeks):

🔴 Doc-Type Aware Chunking

  • Need custom chunkers for each doc type:
    • chunk_deposition() - Q&A exchange detection
    • chunk_motion() - Section heading detection
    • chunk_docket() - Line-by-line split
    • chunk_medical() - Encounter boundary detection
    • chunk_fallback() - Paragraph-aware sliding window

This is the heavyweight refactor - but it's isolated to the chunking module.

🔴 Retrieval Config Per Doc Type

  • Modify retriever to adjust fetch_k/rerank_k based on doc_type
  • Not hard, but needs testing across doc types

🚧 Refactoring Impact Assessment

What Breaks:

❌ Nothing breaks! This is additive.

What Changes:

  1. chunker.py - biggest change - Currently: One chunk_documents() function - New: Router function + 5 specialized chunkers - Old function stays as fallback
  2. ingest_files_hybrid.py - Add Level 1 structural detection - Call Level 2 if confidence low - Route to appropriate chunker based on doc_type
  3. retriever_hybrid.py - Accept doc_type_filter, fetch_k, rerank_k parameters - Apply doc_type filter to Qdrant query - Use custom K values instead of hardcoded 50/15
  4. models.py - Add 3 columns to documents table - Add new Pydantic models for retrieval controls
  5. Frontend - Add 3 dropdowns above chat - Update ChatRequest to include new params - Display provenance line

🎯 Recommended Implementation Order

I suggest phased rollout so you can test each piece:

Phase 1: Retrieval Controls (Quick Win - 1-2 days)

Enable attorneys to control what they're searching without waiting for smart chunking.

  1. Add retrieval controls UI (3 dropdowns)
  2. Add GET /matters/{matter_id}/doc_types endpoint
  3. Modify retriever to accept filters
  4. Add provenance line

Value: Immediate control over search scope. Works with existing chunks.


Phase 2: Better Classification (Medium - 3-4 days)

Get accurate doc types for better filtering.

  1. Implement Level 1 structural detectors
  2. Implement Level 2 Claude-based fallback
  3. Add confidence scoring
  4. Re-classify existing documents (migration script)

Value: Doc type filter actually works reliably.


Phase 3: Smart Chunking (Big - 1-2 weeks)

The real quality improvement.

  1. Build specialized chunkers (one at a time)
  2. Test each chunker independently
  3. Add router logic in ingestion
  4. Add avg_chunk_tokens tracking
  5. Implement retrieval config lookup

Value: Dramatically better retrieval quality. This is the differentiator.


💡 My Recommendation

Start with Phase 1 immediately. It's high-value, low-risk, and gives you:

  • Working doc type filter (with current "unknown" → "all")
  • Exposed fetch_k/rerank_k knobs
  • Search provenance

Then we can tackle classification and smart chunking when you're ready.


🤔 Questions for You:

  1. Do you want to start with Phase 1 (retrieval controls)? This is the quickest win and works with what you have now.
  2. Do you have sample documents of each type (deposition, motion, docket, medical) so we can test the chunkers properly?
  3. Should we reclassify your existing RFA documents first, or test on fresh uploads?

What do you think? Want to start with Phase 1?

About

legal AI

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages