← Matter Intake

Matter Intake — Pipeline Deep Dive

Two-stage AI pipeline. Router classifies. Evaluator scores across five dimensions. Programmatic scoring never trusts the LLM directly. Every decision auditable.

FastAPI Pydantic Claude / DeepSeek Next.js 16 Vercel + Fly.io
Pipeline — Two Stages, Five Dimensions
Matter Summary
Unstructured text describing a potential new client engagement. Could be an email, intake form, or partner dictation. No required format.
Input
Stage 1 — Router
Classifies practice area, matter type, jurisdiction, and urgency. Extracts key signals and confidence score. Low temperature — focused classification, not creative reasoning.
Classification
Output: practice_area, confidence, matter_type, jurisdiction, urgency_indicators
Stage 2 — Evaluator
Scores across 5 dimensions with detailed reasoning. Enriched prompt includes router classification for context. Higher temperature — this stage needs nuance.
Deep Evaluation
Output: practice_area (refined), urgency_risk, conflict_check, staffing, data_integrity
Programmatic Scoring
Weighted calculation across all 5 dimensions. Applies deterministic weights and rules — never trusts LLM-generated scores directly. Conflict type gates score levels.
Deterministic
overall_score = Σ(dimension.score × dimension.weight)
Structured Response
Risk badge (high / medium / low), 5 dimension score cards with reasoning, conflict flag, staffing recommendation, data integrity issues. Processing time and model info included.
API Response
POST /api/evaluate → EvaluateResponse (Pydantic model)
Evaluation Dimensions
25% — Classification
Practice Area Classification Accuracy
Is the matter correctly classified? Does it span multiple practice areas? Router confidence + evaluator re-confirmation. Cross-practice elements flagged for partner review.
25% — Risk
Urgency & Risk Assessment
Deadlines, regulatory exposure, financial stakes, reputational risk. Scored as inverted risk — lower risk = higher score. Urgency classified: immediate / short-term / routine.
20% — Conflicts
Conflict Check Completeness
Adverse parties identified. Business conflicts flagged. Prior representations checked. Direct adverse = highest score (conflict found). None identified = baseline.
15% — Staffing
Staffing Recommendation Quality
Role recommendation + hour estimate. Partner oversight assessed. Specialty requirements identified. Scored on completeness — has role + hours = higher score.
15% — Integrity
Client/Matter Data Integrity
What's missing from the intake? How clear is the summary? Completeness and clarity scored 0–100. Issues surfaced explicitly so intake can be improved before the engagement letter.
Scoring — Deterministic, Never Trusts the LLM
overall_score = (PA_classification × 0.25) + (urgency_risk × 0.25) + (conflict_check × 0.20) + (staffing × 0.15) + (data_integrity × 0.15)
≥70 = Low Risk 40–69 = Medium Risk <40 = High Risk

The LLM returns dimension scores and reasoning. The programmatic layer re-computes the weighted score and applies threshold rules. If the LLM hallucinates a score, the deterministic layer catches it. Conflict type gates score levels — a direct adverse conflict caps the overall score regardless of other dimensions.

Audit Trail — Every Decision, Attributable

Full Prompt Capture

Every evaluation stores the complete prompt sent to the LLM, including the router classification context, the rubric version, and the model configuration. If the rubric changes, you can trace which evaluations used which version.

Response + Reasoning Chain

The full LLM response is stored — not just the scores, but the reasoning behind each dimension. If a partner questions a conflict flag, the system shows exactly why the evaluator flagged it.

Deterministic Score Replay

The programmatic scoring layer is deterministic. Given the same dimension scores, it produces the same overall score and risk level. The scoring formula is versioned and stored alongside each evaluation.

Structured JSONL Logging

All evaluation events are logged as structured JSONL — machine-readable, queryable, and exportable. No parsing. No black-box "the system said so." Every field is typed and documented.

Technical Architecture
Backend
FastAPI + Pydantic
Single POST /api/evaluate endpoint. Two-stage async pipeline. Provider auto-detection from API key prefix. Structured JSONL logging with configurable log levels.
LLM Provider
Auto-detect: Anthropic or OpenAI-compatible
sk-ant- prefix → Anthropic (Claude). sk- prefix → OpenAI-compatible (DeepSeek by default). Separate model + temperature per stage. Override with LLM_BASE_URL and LLM_MODEL env vars.
Frontend
Next.js 16 — Single Page
State machine: empty → loading → success / error. Textarea input, risk badge, 5 score cards with progress bars, conflict + staffing panels. No auth. No routing. Demo-scoped.
Deploy
Vercel (frontend) + Fly.io (backend)
Single-command deploy for both. Stateless — no database, no auth. Wide-open CORS for demo. Production version would add Supabase for audit trail persistence and RLS for practice group scoping.