Legal RAG, cited claim by claim.
A RAG system I built for a law firm. It reads contracts, court records, emails and audio, then drafts structured legal briefs in which each section retrieves its own evidence and cites it. The document base is parsed, transcribed and indexed on the lawyer's machine; only the excerpts a section needs go to the model that drafts it.
Three stages
The pipeline runs as three separate stages, each in isolation. I kept that separation strict because the person using it is a lawyer with no technical background.
Questions with an exact answer, like a case number or a contract field, never touch the vector store. They go to a relational layer and get a deterministic result.
Ingestion
Extracts and normalizes PDF, DOCX, Excel, HTML, email, JSON and compressed archives. Audio and video are transcribed locally with speech-to-text. Source files are never modified.
Indexing and entity extraction
Chunks are embedded with metadata: document type, section and a probative relevance score. Contract boilerplate is filtered out before embedding. In parallel, case numbers, parties and key financial terms are extracted into the relational layer.
Retrieval and generation
Hybrid retrieval with a reranker. For a brief, each section runs its own retrieval and cites its sources. Drafting runs through an LLM API, section by section, and receives only the retrieved excerpts. Output is
.docxand HTML with inline citations.
Hybrid retrieval
Six stages in sequence. Dense and sparse search run in parallel, and their rankings are fused before a cross-encoder reranks the candidates.
Query embedding
Multilingual dense embedding that handles legal terminology.
Dense search
Approximate nearest neighbor search, filtered by document type and case.
Sparse search
Exact keyword matching. Legal identifiers, clause references and proper names depend on it.
Rank fusion
Merges the dense and sparse rankings without normalizing scores.
Cross-encoder rerank
A second pass that scores query and chunk together before anything goes into the context.
Context reorder
The most relevant chunks go at the start and the end of the context window, because models lose track of content buried in the middle of a long context.
Section filtering
Contracts are full of boilerplate that adds noise to retrieval and carries no legal weight. A section classifier runs before indexing. It discards low-signal clauses and gives every remaining chunk a probative relevance score, based on a legal evidence taxonomy.
Very high
Financial obligations, fee structures, disclosure requirements, IP transfer. Embedded at top priority.
High
Rescission, non-compete, territorial exclusivity, termination triggers. Embedded at normal priority.
Medium
Franchisee obligations, support commitments, supply requirements. Embedded at lower priority.
Low and very low
Jurisdiction, confidentiality boilerplate, severability, waiver. Left out of the index.
Document outputs
Briefs come from templates for the document types the firm uses in litigation support. Each one is assembled section by section, with its own retrieval and an inline citation for each claim.
Viability study
Financial modeling, DCF valuation, performance indicators and the indemnification framework.
Jurimetry report
Statistical analysis of the opposing party's judicial history across courts and case types.
Financial audit
Rebuilds the financial statements, balance sheet and performance indicators, then compares them with the disclosed projections.
Technical deficiency report
Documented evidence of operational support failures and contractual non-conformance.
Marketing analysis
Fund spending against contractual commitments, campaign performance and a compliance audit.
Geomarketing report
Territory definition, market saturation and proximity analysis.