Self-hosted
Contract review and clause extraction
Docling converts the contract to structured text with layout preserved; a 32B open-weight model on vLLM fills a JSON schema of clause fields under constrained decoding; results land in PostgreSQL with pgvector for search and precedent lookup; a reviewer approves in the UI.
- Source
- Editorial recipe, 4 of 8 references fetched and hashed
- Verified
- 20 Aug 2026
- Confidence
- High
01Objective
Extract the clauses that matter from incoming contracts into a reviewable table, with a link back to the page each answer came from, without the contracts leaving the firm.
- use caseContract reviewReading an agreement against a checklist: which clauses are present, how they deviate from the standard position, what the renewal and liability terms say. Output is a marked-up list of issues for a lawyer, not an opinion on whether to sign.
- use caseData extractionPulling defined fields out of unstructured text into a schema — from forms, reports, emails, filings or web pages. The general case of invoice extraction, and the step that turns documents into something a database can hold.
- use caseDocument Q&AAsk questions of a specific document or a small set of them and get an answer with the passage it came from. Narrower than company-wide search: the user already knows which file matters and wants it read carefully.
- use caseLegal researchFinding the statute, case or precedent that answers a question, and showing the passage. Distinct from contract review: the corpus is law and commentary, the standard for citation accuracy is absolute, and a fabricated citation is a professional risk.
Field notes about this recipe
02Recommended stack
| Role | Component |
|---|---|
| Inference | Qwen2.5-32B-Instruct (or Qwen3-32B) |
| Inference | vLLM with structured outputs |
| Ingestion | Docling |
| Uioptional | Open WebUI (or a small internal review app) |
| Vector store | PostgreSQL with pgvector |
Architecture and data flow
Components
- Lawyers and contract managers — people
- Docling conversion (PDF → structured text) — storage
- Review interface — application
- Identity provider (OIDC), scoped by matter — identity
- Clause extraction service (JSON schema) — retrieval
- PostgreSQL + pgvector (clause embeddings) — vector store
- PostgreSQL (extractions, reviews, versions) — database
- Contract file store — storage
- vLLM (structured outputs) — inference server
- Qwen2.5-32B-Instruct — model
- Company GPU server (48 GB) — hardware
Connections
- Lawyers and contract managers to Review interface — HTTPS (confidential data)
- Review interface to Identity provider (OIDC), scoped by matter — OIDC sign-in (personal data)
- Docling conversion (PDF → structured text) to Clause extraction service (JSON schema) — documents to index (confidential data)
- Review interface to Clause extraction service (JSON schema) — question + user groups (confidential data)
- Clause extraction service (JSON schema) to PostgreSQL + pgvector (clause embeddings) — embedding search (confidential data)
- Clause extraction service (JSON schema) to PostgreSQL (extractions, reviews, versions) — documents + permissions (confidential data)
- Review interface to PostgreSQL (extractions, reviews, versions) — chats, users, settings (personal data)
- Clause extraction service (JSON schema) to Contract file store — original files (confidential data)
- Clause extraction service (JSON schema) to vLLM (structured outputs) — prompt + retrieved passages (confidential data)
- vLLM (structured outputs) to Qwen2.5-32B-Instruct — loaded weights
- Qwen2.5-32B-Instruct to Company GPU server (48 GB) — GPU memory
- vLLM (structured outputs) to Company GPU server (48 GB) — GPU memory
External data transfer · NONE
- No edge in this design crosses out of the company network.
- Contracts never leave the network: conversion, extraction and search all run on the same machines.
- Model weights are downloaded once at setup.
03Suitable for
- Organisation size
- 10–500 employees
- Data classes
- confidential, privileged, personal
- Constraints
- contracts are privileged or commercially sensitive and must stay in-house; a defined clause set worth extracting — not "review everything"; a lawyer who will check the output and own the clause definitions; a 48 GB GPU for a 32B model; 24 GB works for a narrower clause set at lower accuracy
- Industries
- Legal, Professional services, Financial services, Real estate
- Jurisdictions
- any
04Hardware
On-premise single 24 GB GPU server
- GPU
- NVIDIA RTX 4090 24 GB (or NVIDIA L4 24 GB for a rack-mounted, 72 W alternative)
- VRAM
- 24 GB
- System RAM
- 64 GB
- Storage
- 2000 GB
- CPU
- 16-core x86 server CPU (AMD EPYC 7003/9004 or Intel Xeon Scalable)
- Form factor
- Tower server
Indicative costUS$4,000 – US$9,000
indicative build cost for the complete machine, USD, Aug 2026 — verify with a local supplier
The default box for a 20–60 person firm. Fits a 14B model at 4-bit with roughly 8 GB of KV cache left for concurrent chat, or an 8B model at fp16. NVMe storage sized for the model cache plus a document corpus and its embeddings. Add a UPS and an offsite backup target — this machine holds the whole knowledge base.
On-premise single 48 GB GPU server
- GPU
- NVIDIA L40S 48 GB (rack) or NVIDIA RTX 6000 Ada 48 GB (office workstation)
- VRAM
- 48 GB
- System RAM
- 128 GB
- Storage
- 4000 GB
- CPU
- 24–32-core x86 server CPU (AMD EPYC or Intel Xeon Scalable)
- Form factor
- Rack server
Indicative costUS$12,000 – US$22,000
indicative build cost for the complete machine, USD, Aug 2026 — verify with a local supplier
The step up when answer quality matters more than price: a 32B model at 4-bit with generous KV cache, or a 14B model at fp16 with a long context. ECC memory and a standard 2U chassis mean it belongs in a rack or comms room rather than under a desk.
Indicative costUSD · one-off plus monthly
- Software licences
- All components are open source and self-installed. Check each licence for use limits.
- US$0
- Model usage
- Open weights served locally: no per-token charge. The GPU cost sits under infrastructure.
- US$0
- GPU server (48 GB class), purchased
- Hardware profile onprem-medium-48gb — indicative build cost, Aug 2026, verify locally.
- US$12,000 – US$22,000
- Implementation (10–25 FDE-days)
- 10–25 FDE-days at US$760–1940 per day, converted from the HK$6,000–15,000 band at the HKMA Linked Exchange Rate band of HK$7.75–7.85 to one US dollar. One-off; excludes internal staff time.
- US$7,600 – US$48,500
- One clause set of roughly 10–20 fields, one contract type family, one reviewing team.
- The implementation band assumes the clause definitions come from the firm; writing them from scratch adds several days of lawyer time that is not counted here.
- Excludes the ongoing review time, which is the real running cost of this pipeline.
- Every figure is an assessment from the inputs listed, not a quotation.
05Difficulty
4 / 5
Multiple weeks and a team that has shipped infrastructure
06Skills
- Dockerdocker
- infrastructure
- Linuxlinux
- operations
- LLM evaluationllm-evaluation
- ml
- LLM inferencellm-inference
- ml
- OCR and document parsingocr
- ml
- PostgreSQLpostgresql
- data
- Prompt engineeringprompt-engineering
- ml
- Pythonpython
- development
- Retrieval-augmented generationrag
- ml
- Security hardeningsecurity-hardening
- security
07Deployment steps
Commands are copied from each project’s own documentation, and the page they came from is linked under the step. 5 of 7 steps currently open an evidence record. The rest are linked to their source; §10 says which of those documents were fetched and which were fetched without their anchor being found — two different states, named differently there.
- 01
Define the clause set with a lawyer, on paper, first
AssessmentList the fields: parties, term, termination, liability cap, indemnities, governing law, assignment, confidentiality, data protection. For each, write what a correct extraction looks like and what an ambiguous one looks like. This document is the specification, the prompt and the test set — no code should be written before it exists.
- 02
Convert contracts with Doclingversion-sensitive
AssessmentInstall Docling and convert a sample of real contracts, including the scanned ones. Inspect the markdown output: if the tables and clause numbering survive, extraction will work; if they do not, fix conversion before touching the model.
pip install doclingdocling https://arxiv.org/pdf/2206.01062from the Docling README
- 03
Serve the model with vLLMversion-sensitive
AssessmentStart the official image with the GPU attached, sized for a 32B model at 4-bit on a 48 GB card. Set an API key. Keep the context length high enough for the longest contract section you will pass, not the longest contract — chunk by clause, not by document.
docker run --runtime nvidia --gpus all \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=$HF_TOKEN" \ -p 8000:8000 \ --ipc=host \ vllm/vllm-openai:latest \ --model Qwen/Qwen3-0.6Bfrom the vLLM docs — substitute the model you sized for
- 04
Extract against a JSON schema, not into proseversion-sensitive
AssessmentvLLM "supports the generation of structured outputs using xgrammar or guidance as backends". Send each clause section with the schema for that clause and require a source quote plus page number in the schema — a field the model cannot fill without pointing at the text is a field a reviewer can check in seconds.
- 05
Store extractions and embeddings in PostgreSQL
AssessmentOne row per clause with the contract id, the field, the value, the quote, the page and the model version. Embed the clause text so "have we agreed this liability cap before?" becomes a query rather than a memory test.
CREATE EXTENSION vector; - 06
Put a human in the loop, visibly
AssessmentEvery extraction starts as a draft with a reviewer, a decision and a timestamp. Show the source quote beside the field. Record corrections: the corrected set is both your accuracy measure and the evidence for whether the tool is earning its keep. A purpose-built review screen beats a chat box for this; Open WebUI, cited below, is the fast way to have something in front of a lawyer this week, and it is optional in the sense that a small internal app replaces it — not in the sense that the review step is.
- 07
Measure per field, not per document
AssessmentTake 50 contracts a lawyer has already marked up. Report precision and recall for each field separately. A pipeline that finds governing law perfectly and misses indemnities is not "85% accurate" — it is ready for one field and not the other, and only a per-field table shows that.
08Compliance considerations
Structured issue-spotting to support your own review — not legal advice. Verify against the cited primary sources and your counsel.
Applies everywhere
Professional secrecy · Confidentialityhigh
Contracts under review are usually privileged or confidential. Keeping the pipeline in-house removes the disclosure question; matter-level access control inside the tool is what stops it reappearing internally.
Human oversight · Automated decision-makinghigh
Extraction supports review; it does not perform it. Record the reviewer and the decision for every clause, and never let an unreviewed extraction flow into a downstream system.
Personal data · Retentionmedium
Contracts contain personal data about signatories and staff. Extracted clause tables are a second copy with its own retention period; set it deliberately.
Logging · Auditabilitymedium
Keep the model version and prompt version against every extraction. When a mistake is found later, the first question is which version produced it.
Open-source licensinglow
Docling, vLLM and pgvector are permissively licensed, but verify each against the fetched licence text, and check the model card for the model you deploy.
09Alternatives
A specialist legal AI vendor
Vendors in this space ship the clause library, the review UI and the evaluation work you would otherwise build. The trade is that privileged documents go to a processor.
- — Far less to build; domain-tuned out of the box
- — Privileged material leaves the firm — DPA, residency and client consent questions follow
- — Per-seat or per-document pricing rather than a one-off build
Start with retrieval only
If the real need is "find the contract with this clause", a knowledge base answers it in a fortnight without any extraction schema at all.
- — Much simpler and quicker to value
- — No structured clause table, so no comparison or reporting across contracts
10Evidence
- 01Tier 2official vendor legal documentationVendor legal and technical documentation
https://docs.vllm.ai/en/latest/deployment/docker/
FreshRetrieved 25 Aug 2026sha256:67e8574916141 record
- 02Tier 2official vendor legal documentationVendor legal and technical documentation
https://docs.vllm.ai/en/latest/features/structured_outputs/
FreshRetrieved 25 Aug 2026sha256:1d9d9841283c1 record
- 03Tier 2official vendor legal documentationVendor legal and technical documentation
https://docling-project.github.io/docling/usage/
FreshRetrieved 25 Aug 2026sha256:b695cbd955091 record
- 04Tier 2official vendor legal documentationVendor legal and technical documentation
GitHub - docling-project/docling: Get your documents ready for gen AI
https://github.com/docling-project/docling
FreshRetrieved 25 Aug 2026sha256:7f9d5e4fa3031 record
Not yet in the ledger
not yet fetched
not yet fetched
not yet fetched
not yet fetched
11Community
Deployed this stack, or hit something this page does not cover? Corrections, sources and implementation reports are what keep a recipe worth reading.
Improve this page
Sign in to contribute
From the field
0 deployments · 0 questions
Nobody has reported deploying this here yet, and no question has been opened against this page. Both appear once a reviewer accepts them.
12Hire an FDE
If you would rather not build it, we can introduce a forward-deployed engineer who has deployed this stack before. The enquiry form starts from this recipe.