Your AI-powered legal document intelligence assistant.
LegalPilot AI is a production-quality, full-stack AI application that helps legal professionals and everyday users understand complex legal documents instantly. Upload a contract, NDA, or employment agreement and get AI-powered answers, summaries, clause extraction, and risk analysis — all backed by citations from the source document.
Built as an AI Engineering portfolio project demonstrating modern RAG (Retrieval-Augmented Generation) architecture, multi-provider LLM support, and clean full-stack design.
| Feature | Description |
|---|---|
| 📄 Document Upload | Upload PDF, DOCX, or TXT legal documents for instant processing |
| 💬 Conversational Q&A | Ask grounded questions with cited, evidence-backed answers |
| 📋 Contract Summarization | Structured summaries covering parties, terms, obligations, and risks |
| 🔍 Clause Extraction | Auto-detect termination, confidentiality, liability, payment, and non-compete clauses |
| Analyze contracts from stakeholder perspectives (Employee, Employer, Tenant, Landlord) | |
| 💾 Chat Persistence | All conversations saved in SQLite — pick up where you left off |
| 🔄 Multi-LLM Support | Switch between Gemini 2.5 Flash and Groq (Llama 3.3) from the UI |
| 📎 ChatGPT-style UI | Upload documents directly in chat, rendered markdown responses, citation cards |
┌──────────────────┐ ┌──────────────────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ Next.js 15 UI │◄────►│ FastAPI Backend │◄────►│ Gemini API │
│ (Tailwind CSS, │ REST │ │ │ Groq API │
│ shadcn/ui) │ │ ┌──────────┐ ┌────────┐ │ │ │
│ │ │ │ SQLite │ │ FAISS │ │ └─────────────┘
└──────────────────┘ │ │ (docs, │ │(vector │ │
│ │ chunks, │ │ search)│ │
│ │ chats) │ │ │ │
│ └──────────┘ └────────┘ │
└──────────────────────────┘
Frontend
- Next.js 15 (App Router) with TypeScript
- Tailwind CSS for utility-first styling
- shadcn/ui for accessible component primitives
- react-markdown for rendering AI responses
Backend
- FastAPI for async API endpoints
- LangChain for LLM orchestration
- FAISS for optional vector similarity search
- SQLite for zero-config persistence (documents, chunks, chat history)
LLM Providers
- Google Gemini 2.5 Flash — latest multimodal model
- Groq Llama 3.3 70B — ultra-fast open-source inference
Document Parsers
- pypdf — PDF text extraction with page tracking
- python-docx — DOCX paragraph extraction
backend/app/
├── api/ # FastAPI route handlers (upload, chat, intelligence)
│ ├── upload.py # Document upload, listing, deletion
│ ├── chat.py # RAG-powered Q&A with chat history
│ └── intelligence.py # Summarization, clause extraction, risk analysis
├── llm/
│ └── provider.py # LLM abstraction (BaseLLMProvider → Gemini, Groq)
├── parsers/
│ └── document_parser.py # PDF/DOCX/TXT parsers with page tracking
├── prompts/
│ ├── qa.py # Question-answering prompt with hallucination safeguards
│ └── intelligence.py # Prompts for summary, clauses, risk analysis
├── rag/
│ ├── chunker.py # Recursive text chunking with configurable overlap
│ └── vector_store.py # FAISS index management
├── schemas/
│ ├── document.py # Pydantic models for documents and chunks
│ ├── chat.py # Request/response models for chat
│ └── intelligence.py # Models for summary, risk, clauses
├── services/
│ ├── rag_service.py # RAG orchestration (retrieve → context → generate)
│ └── intelligence_service.py # Document analysis services
└── utils/
└── database.py # SQLite schema, CRUD operations
- Python 3.10+
- Node.js 18+
- A Gemini API key — Get one here
- A Groq API key — Get one here
cd backend
python3 -m venv --system-site-packages venv
source venv/bin/activate
pip install pypdf python-docx langchain langchain-community \
langchain-google-genai langchain-groq faiss-cpu \
python-multipart pydantic-settingsCreate backend/.env:
GOOGLE_API_KEY="your_gemini_key"
GEMINI_API_KEY="your_gemini_key"
GROQ_API_KEY="your_groq_key"Start the server:
python -m uvicorn app.main:app --reload --port 8000The API docs are available at http://localhost:8000/docs (Swagger UI).
cd frontend
npm install
npm run devOpen http://localhost:3000 in your browser.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/upload |
Upload and process a document (PDF/DOCX/TXT) |
GET |
/api/documents |
List all uploaded documents |
DELETE |
/api/documents/{id} |
Delete a document and all related data |
POST |
/api/chat |
Ask a question about a document |
GET |
/api/chat/history/{id} |
Retrieve chat history for a document |
POST |
/api/summarize |
Generate a structured contract summary |
POST |
/api/extract-clauses |
Extract legal clauses as structured JSON |
POST |
/api/risk-analysis |
Stakeholder-specific risk analysis |
GET |
/health |
Health check |
POST /api/chat
{
"question": "What are the termination conditions?",
"document_ids": ["uuid-of-uploaded-doc"],
"provider": "groq"
}{
"answer": "Either party may terminate with 30 days written notice...",
"citations": [
{
"document_id": "uuid",
"filename": "contract.pdf",
"page_number": 3,
"text_excerpt": "..."
}
],
"provider_used": "groq",
"retrieval_latency": 0.001,
"generation_latency": 0.65
}- Upload — Documents are parsed page-by-page (preserving page numbers for citations), then split into overlapping 1000-character chunks with 200-character overlap.
- Store — Chunks are saved to SQLite for reliable retrieval. If a Gemini API key is available, chunks are also embedded and indexed in FAISS for semantic vector search.
- Query — When you ask a question, the system retrieves relevant chunks (via FAISS vector search or SQLite fallback), constructs a context-aware prompt, and sends it to the selected LLM provider.
- Cite — Every response includes citations linking back to the exact page of the source document.
- Safeguard — The system prompt explicitly prevents hallucination. If evidence is insufficient, the AI says so instead of fabricating information.
Legal clauses often span paragraph boundaries. A 200-character overlap ensures that if a termination clause starts at the end of one chunk, the next chunk also contains its beginning — preventing the retrieval system from missing critical context.
Not everyone has a Gemini API key for embeddings. The SQLite fallback loads all document chunks directly and passes them as context to the LLM. This works well for small-to-medium documents and ensures the app is functional out of the box with just a Groq key.
- FAISS is optional: Without a Gemini API key for embeddings, all chunks are sent to the LLM. This works for documents under ~50 pages but may hit token limits on larger ones.
- SQLite is single-server: For horizontal scaling, migrate to PostgreSQL.
- No streaming: Responses are returned in full (not streamed token-by-token).
- No OCR: Scanned PDFs without embedded text are not supported yet.
- Hybrid Search (FAISS dense vectors + BM25 keyword search)
- Cross-encoder re-ranking for better retrieval precision
- Map-Reduce summarization for 500+ page documents
- PostgreSQL for production deployments
- Streaming responses via Server-Sent Events
- OCR support for scanned PDF documents
- Multi-agent legal reasoning system
- User authentication and document sharing
This project is for educational and portfolio purposes.
