Skip to content

arjunhq/redquill

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Redquill

A .NET SDK and CLI that brings structure-aware RAG to legal contracts — because splitting PDFs at 500 tokens is the wrong approach.

Status .NET License Build PRs Welcome


Overview

Redquill is an experimental .NET SDK and CLI tool for querying legal contracts with natural language. It builds a full Retrieval-Augmented Generation (RAG) pipeline on top of PDF contracts — parsing, chunking, embedding, and storing them — then answers questions with grounded, section-cited responses.

The central idea is simple but consequential: most RAG implementations chunk documents blindly. Redquill chunks contracts structurally, splitting at clause and section boundaries rather than fixed token windows. That distinction matters a lot when the document is a legal agreement full of cross-references and defined terms.


Demo

Querying an ingested NDA from the command line — the answer cites specific contract sections.

dotnet run --project Redquill.Cli -- ask --query "What are the termination conditions?" --db ../redquill.db

Redquill ask command demo

Why This Project Exists

This project started as an experiment to explore whether structure-aware chunking could meaningfully improve RAG quality on legal documents.

A Stanford/Yale study found that LLMs hallucinate on legal citation tasks 69–88% of the time. The CUAD benchmark shows how poorly general models perform on contract understanding without structured retrieval. I wanted to understand why — and whether a retrieval pipeline that respects document structure could close that gap.

The deeper question I wanted to explore: if you treat a contract as a graph of interconnected clauses rather than a stream of tokens, does the LLM answer more accurately? This project is an attempt to find out.


Key Ideas

  • Clause-aware chunking — split at section headings, numbered provisions, and definition blocks rather than token counts; each chunk maps to a complete legal idea
  • Layout-driven structural detection — use PdfPig's formatting analysis (font size, position, weight) to identify headings, definitions, and body clauses before chunking
  • Grounded answers with mandatory citations — the LLM is constrained to answer only from retrieved excerpts and must cite specific section references; if the contract doesn't say it, the answer says so
  • Pluggable pipeline design — every stage (parser, chunker, embedder, vector store, chat service) is an interface; swap any provider with a single DI registration change
  • Persistent vector storage — ingest once into SQLite, query many times without re-parsing or re-embedding

Features

  • 📄 Parse PDF contracts into structured, clause-aligned chunks
  • 🔍 Semantic search via cosine similarity over persistent embeddings
  • 💬 Natural language Q&A with section-level citations in every answer
  • 🗄️ SQLite-backed vector store — fast, local, zero infrastructure
  • 🔌 Swap OpenAI for Azure, or SQLite for Qdrant, with one line of code
  • 🖥️ Both a CLI for interactive exploration and an SDK for integration
  • ✅ Tested against real contracts from the CUAD dataset

Architecture

graph TD
    subgraph Input
        PDF["📄 PDF Contract"]
    end

    subgraph Ingestion["Ingestion Pipeline — redquill ingest"]
        PARSE["Parse\nPdfPig layout analysis"]
        DETECT["Structural Detection\nHeadings · Definitions · Body"]
        CHUNK["Clause-Aware Chunking\nSplit at legal boundaries"]
        EMBED["Embed\ntext-embedding-3-small"]
        STORE["Store\nSQLite vector store"]
    end

    subgraph Query["Query Pipeline — redquill ask"]
        Q["❓ Natural Language Question"]
        EMBED_Q["Embed Question"]
        SEARCH["Semantic Search\nCosine Similarity"]
        GROUND["Build Grounded Prompt\nInject contract excerpts + citations"]
        LLM["LLM\ngpt-4o-mini"]
        ANSWER["✅ Cited Answer\nSection references included"]
    end

    DB[("🗄️ redquill.db\nSQLite")]

    PDF --> PARSE --> DETECT --> CHUNK --> EMBED --> STORE --> DB
    Q --> EMBED_Q --> SEARCH
    DB --> SEARCH --> GROUND --> LLM --> ANSWER
Loading

The SDK is the productRedquill.Core contains all pipeline logic and is consumable as a library via AddRedquill(). The CLI (Redquill.Cli) is a thin demo shell with no business logic of its own. Every pipeline component is behind an interface, making the whole stack straightforward to extend or replace.


Getting Started

Prerequisites

Redquill is not yet on NuGet — build from source for now. Packaging is next on the roadmap.

Installation

git clone https://github.com/AM10101010/redquill.git
cd redquill
dotnet build

Run the CLI

export OPENAI_API_KEY="sk-..."
dotnet run --project src/Redquill.Cli

Example Usage

CLI

# Ingest a contract — parses, chunks, embeds, and stores locally
redquill ingest ./nda-acme-2025.pdf

# Ask questions in plain English
redquill ask --query "What are the termination conditions?"
redquill ask --query "How is confidential information defined?"
redquill ask --query "Who bears the indemnification obligations?"

# Inspect detected document structure without AI
redquill parse ./nda-acme-2025.pdf --show-blocks

SDK

using Redquill.Core;
using Microsoft.Extensions.DependencyInjection;

// Register the full pipeline with one call
var services = new ServiceCollection();
services.AddRedquill(opts =>
{
    opts.ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY");
    opts.StoragePath = "./data/redquill.db";
});

var provider = services.BuildServiceProvider();

// Ingest — parse, chunk, embed, and persist
var ingestion = provider.GetRequiredService<IIngestionPipeline>();
await ingestion.IngestAsync("./nda-acme-2025.pdf");
// → Ingested 30 chunks from 12 pages in 4.2s

// Query — grounded answer with section citations
var query = provider.GetRequiredService<IQueryPipeline>();
var answer = await query.AskAsync("What are the termination conditions?");

Console.WriteLine(answer.Answer);
// → "Either party may terminate with 30 days written notice (§8.2).
//    Immediate termination is permitted for material breach (§8.4)."

foreach (var source in answer.SourceChunks)
    Console.WriteLine($"  [{source.Score:F2}] {source.Chunk.SectionReference}");
// → [0.91] §8.2 — Termination for Convenience
// → [0.87] §8.4 — Termination for Cause

Swapping Providers

// Use defaults, then override just what you need — no pipeline changes required
services.AddRedquill(opts => { opts.ApiKey = "..."; });
services.AddSingleton<IEmbeddingService, AzureEmbeddingService>();
services.AddSingleton<IVectorStore, QdrantVectorStore>();

Project Status

🚧 Alpha — experimental and actively evolving

This project is primarily an exploration of ideas around document structure and RAG quality. APIs will change, and it is not ready for production use. That said, the core pipeline is functional and has been tested against real contracts.

Sprint Status Focus
1 · Parse & Chunk ✅ Complete PDF parsing, clause-aware chunking, structural detection
2 · Embed & Query ✅ Complete Semantic Kernel integration, RAG pipeline, in-memory search
3 · Persist & Search ✅ Complete SQLite persistence, ingest command, chunker improvements
4 · Package & Ship 🔜 Planned NuGet package, CI/CD pipeline, polished docs

Roadmap

Possible future directions — not a commitment, just what I find interesting:

  • Hybrid search — combine vector similarity with BM25 keyword matching for better recall on exact legal terms
  • Smarter chunking heuristics — current approach handles most contracts well, but edge cases remain; more experimentation needed
  • DOCX support — contracts don't always arrive as PDFs
  • Multi-document querying — ask questions across an entire contract portfolio
  • Web API host — expose the pipeline over HTTP for integration with other tools
  • Domain-specific embeddings — explore whether fine-tuned legal embeddings outperform general-purpose ones on retrieval tasks

Ideas and suggestions for any of these are welcome — open an issue and let's discuss.


Contributing

Ideas, feedback, and contributions are welcome. This is a solo project at an early stage, built in the open specifically to invite that kind of conversation.

If something looks wrong, could be improved, or sparks a question about the design — open an issue. The specs/ directory has detailed feature specs explaining the reasoning behind key decisions, and is worth a read before diving into code.

Pull requests are welcome too. No contribution is too small.


License

Apache 2.0 — see LICENSE for details.

About

RAG pipeline for legal contracts — clause-aware chunking, grounded answers with citations. .NET 9 + Semantic Kernel.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages