Generic conversational LLMs are dangerous in a courtroom or financial audit room. If an advocate asks an ungrounded AI assistant to summarize a 60-page Petition or Commercial Plaint and the model invents a case citation, swaps the Petitioner and Respondent, or fabricates a prayer that does not exist on the record, relying on that output in court is catastrophic. In high-stakes legal and financial workflows, every single factual proposition must be anchored to a verifiable page and line coordinate that the practitioner can hover over to read verbatim and click to jump directly to the underlying document canvas.
When building KortiAI — the legal research and interactive workspace assistant inside KortiBundle (kortibundle.com) — we designed a hybrid Deterministic Structural Parser + Coordinate-Grounded RAG Pipeline that guarantees zero hallucinated parties or prayers, attaches clickable [Pg X · LY] badges to every finding, previews verbatim line quotes on hover, and scrolls the document canvas to the exact vertical baseline of the cited line when clicked.
1. Why Naive Chunk-Based RAG Fails on Legal Pleadings
Standard RAG tutorials split PDF text into arbitrary 500-token sliding windows and embed them into a vector database. On structured legal pleadings, court proceedings, and financial agreements, naive chunking fails in four predictable ways:
- Caption & Party Fragmentation: A Kenyan High Court or Magistrates' Court caption spans lines 1 to 16 of Page 1, with dot leaders (
....................), multi-line party descriptions, andVERSUSseparators. Naive chunking loses which party is above vs. belowVERSUS, or confuses front-matter cover columns with the actual pleading caption. - Loss of Line-Coordinate Provenance: Once paragraphs are concatenated into a 500-token string without per-line coordinate tags, the LLM can only cite "Page 2" instead of "Page 2, Line 15".
- Page Index vs. Effective Page Number Drift: In a compiled court bundle, Sheet #1 is the Cover Page, Sheet #2 is the Statutory Index, and Sheet #3 is Page 1 of the Petition. If the RAG pipeline confuses 0-based PDF sheet index with
effective_page_number, hovering over[Pg 2 · L15]pulls Line 1 of the wrong sheet (often the generic header "REPUBLIC OF KENYA"). - Slow Tool-Call Routing on CPU Servers: Passing 2,000+ tokens of nested OpenAI JSON Schema definitions to a local CPU model causes 15-second prefill stalls.
2. Coordinate-Grounded Extraction & Hover Quote Verification
Instead of feeding raw unindexed text to the model, our pipeline indexes every horizontal text line on every non-front-matter pleading page with its exact effective_page_number, 1-based line_index, and vertical baseline_y coordinate in PDF points:
# Coordinate-Grounded Line Indexing & Multi-Line Prayer Extraction
from typing import List, Dict, Any
def build_coordinate_grounded_passages(page: Dict[str, Any]) -> List[Dict[str, Any]]:
eff_pg = page.get("effective_page_number")
sheet_idx = page.get("page_index", 0)
pg_label = f"Page {eff_pg}" if eff_pg is not None else f"Sheet {sheet_idx + 1}"
grounded_hits = []
for dl in page.get("detected_lines", []):
snippet = (dl.get("text_snippet") or "").strip()
if not snippet:
continue
line_no = dl.get("line_index", 1)
grounded_hits.append({
"sheet_index": sheet_idx,
"effective_page": eff_pg,
"page_label": pg_label,
"line_index": line_no,
"baseline_y": dl.get("baseline_y", 0.0),
"cite_tag": f"[{pg_label}, Line {line_no}]",
"snippet": snippet,
})
return grounded_hits
When the backend streams a response to the frontend chat drawer, it also emits a verified sources array containing the exact verbatim text of every cited (effective_page, line_index) pair. When an advocate hovers over [Pg 2 · L15] in KortiBundle, the UI immediately renders a floating quote card showing the exact text of Page 2, Line 15—and when clicked, calculates yRatio = baseline_y / page.height to scroll the viewport directly to that line and illuminate it with a golden highlight bar.
3. Fast JSON Intent Routing Without Brittle Regex Gates
When a user types an ambiguous workspace command like "toggle view into edit mode", "move page 2 one step up", or "get rid of page 4", relying on rigid regular expressions breaks whenever the user adds a natural phrase like "one step" or uses a synonym like "toggle". Conversely, passing a 2,100-token OpenAI tool schema to a local CPU model causes unacceptable latency. By using a compact 280-token format: "json" system prompt kept permanently warm in the LLM's KV prefix cache, intent classification completes in 1.2 to 2.0 seconds on CPU with near-zero classification errors.
| RAG & Agentic Capability | Naive Chunk-Based LLM Wrapper | KortiAI Coordinate-Grounded Pipeline |
|---|---|---|
| Citation Precision | Page-level only (or hallucinated page numbers) | Exact [Page X, Line Y] linked to physical baseline_y |
| Hover Verification | None (user must manually search the PDF) | Instant verbatim line quote preview card on hover |
| Click-to-View Navigation | Scrolls to top of page (bottom lines stay hidden) | Centers exact cited line in viewport + golden spotlight band |
| Workspace Tool Routing | Brittle regex or 15s full-schema prefill timeout | 1.5s KV-cached JSON intent router across 16 live tools |
Explore related production architectures, live Kenyan legal tools, and enterprise guides:
- KortiBundle & KortiAI — Kenyan Legal Bundle & Record of Appeal Studio — Experience coordinate-grounded legal AI with clickable [Page X, Line Y] citations.
- Production RAG Chunking Strategies: Semantic, Recursive & Parent-Document — Comparing retrieval architectures for enterprise knowledge bases.
- Deterministic Structured Outputs from LLMs with Grammar-Constrained Decoding — Enforcing strict JSON schemas on local and cloud language models.