A pharmaceutical medical-information team answers clinicians’ unsolicited questions using approved literature and internal evidence. Design a full-stack system that finds evidence, drafts a response with sentence-level citations, supports a six-stage human workflow, and produces an audit-ready final document. Quality matters more than raw latency.
The Citation Is the Product
Design an evidence-grounded medical response authoring system whose drafts, human edits, citations, evaluations, and release decisions survive regulatory scrutiny.
The answer map
Do not memorize every box. Remember this path and rebuild the answer from it.
Understand the problem
Restate the goal in plain English. Name the one thing the system must never get wrong.
The biggest risk is an unsupported medical claim. Every factual sentence must link to the exact page and highlighted area it came from. That link must not change when a source file is updated later.
I will keep the AI’s first draft and every human edit as separate saved versions. This lets us measure the AI honestly. A human makes the final decision. If the system cannot find enough evidence, it stops and asks for help. It never invents a source or silently changes an approved answer.
Step 1 · Set the scope
Name the users, must-have features, speed and safety goals, and what is out of scope.
State your assumptions, users, required capabilities, speed, uptime, recovery, and security goals, and what is out of scope.
The main users are medical writers, evidence-search specialists, reviewers, final approvers, administrators, and auditors. The basic flow is simple: receive a question, search only approved PDFs, draft an answer, check each factual sentence, collect human approvals, export the final document, and keep the full history.
For this mock, edits should feel fast: 95 out of 100 edits finish within 300 milliseconds. Evidence search should finish within 3 seconds. A first draft may take up to 10 minutes because quality matters more than instant output. We keep records for seven years and never mix one customer’s data with another’s. We are not diagnosing patients, selecting treatment, replacing the customer’s document system, or training a new foundation model.
Writers, search specialists, medical/legal/regulatory reviewers, approvers, approved source library curators, auditors, and customer admins.
Question intake, versioned approved source library, evidence retrieval, atomic-claim drafting, citations, six human stages, export, impact analysis.
No unsupported approved claim. Visible source provenance. Write-once pre-edit draft. Explicit final human authority.
99.9% authoring plane, p95 edits <300 ms, draft <10 min, RPO <5 min, RTO <2 h, seven-year audit.
PHI/PII minimization, therapeutic-area access policy, regional storage, customer keys, approved model endpoints, break-glass audit.
Diagnosis, treatment selection, foundation-model training, source DMS replacement, automatic regulatory approval.
Step 2 · Do the useful math
Estimate only what changes the design. After each number, say why it matters.
Use these mock constraints: 2,000 response requests/day, 20 source PDFs/request, 15 pages/PDF, 100 KB/page, 50 factual sentences/response, two citations/sentence, and a 12× ingestion burst. Do the math.
That is 600,000 pages a day, 6.94 pages a second on average, and about 83 pages a second at peak. OCR means optical character recognition: turning scanned page images into searchable text. At two CPU-seconds per page, peak OCR and layout work needs about 167 processor cores. I add 30% spare capacity, bringing the target to about 217 cores. This tells me document processing belongs on a background queue that can add workers during imports.
Raw sources are about 60 GB a day or 153 TB over seven years before backup copies. If a saved decision package averages 3 MB per response, that adds 6 GB a day or 15.3 TB. Search vectors can be rebuilt. Original files, page locations, draft versions, and approvals cannot. Storage retention and page processing shape this design more than ordinary API traffic.
approved source library, citations, and OCR capacity
Steps 4–5 · APIs and data
Start with the few records the system cannot work without. Then add simple endpoints around them.
Give me concrete records, keys, and APIs. How do you prevent a mutable citation from pointing somewhere else later?
I need four main records. First, a source file version identified by its fingerprint. Second, an evidence span that points to a page and highlighted area. Third, a response version. Fourth, an approval decision. A sentence links to an evidence-span ID, never to “the latest PDF.”
We create a new response version for the AI draft, every important human edit, and the approved answer. We never overwrite the old one. An update includes the version the editor saw. If someone else changed it first, we return a conflict instead of losing work. A retry key makes repeated requests safe.
Records and how we find them
| Record | Main key / retry key | Fields we never overwrite | How we find it |
|---|---|---|---|
SourceVersion | (tenant_id, source_digest) | bytes hash, publication metadata, authorization, retraction/effective time | digest lookup; corpus membership |
EvidenceSpan | (tenant_id, span_id) | source digest, page, polygon, crop hash, channel, parser version | by source/page; lexical/vector retrieval |
CorpusRelease | (tenant_id, corpus_release_id) | ordered source digests, policy digest, signature, published_at | active release per therapeutic area |
ResponseVersion | (tenant_id, response_id, version_no) | parent, kind, content hash, corpus/model/prompt manifest | version DAG; current materialized head |
ClaimCitation | (sentence_version_id, claim_no, span_id) | entailment state, verifier/calibrator versions, rationale | reverse impact by source; coverage by response |
StageDecision | (response_version_id, stage, decision_id) | actor, role, expected version, reason, timestamp | stage history; audit export |
JudgeEvaluation | (candidate_digest, rubric_version, evaluator_id) | score vector, calibration set, drift cohort | release comparison by slice |
Simple API
POST /v1/tenants/{t}/requests Idempotency-Key: external_request_id
POST /v1/corpora/{id}/sources returns source_digest + processing job
POST /v1/corpora/{id}/releases If-Match: corpus_version
POST /v1/responses/{id}/drafts corpus_release_id, model_route_id
PATCH /v1/responses/{id}/versions/{n} If-Match: content_digest
POST /v1/responses/{id}/stage-decisions Idempotency-Key: decision_id
GET /v1/evidence/{span_id}/crop short-lived authorized image
GET /v1/responses/{id}/audit-bundle original bytes + manifests + approvals
POST /v1/sources/{digest}/retractions effective_at, severity, reasonSteps 3 and 6 · Draw, then follow one request
Explain the system in a few parts. Then follow one real request from the user to the final result.
Walk me through the architecture and one request end to end.
I would draw four big parts. One, a web app for writers and reviewers. Two, a database for requests, versions, permissions, and approvals. Three, encrypted file storage for PDFs and saved drafts. Four, background workers for PDF reading, search, drafting, and sentence checks.
Here is one request. A writer submits a question. The system locks it to one approved source-library version. Search finds useful page sections. The drafting worker sees only those sections. The checker tests every factual sentence against an exact highlighted area. Unsupported text goes back to the writer. Humans edit and approve the answer. Finally, export sends the approved version to the customer’s document system and saves the receipt.
Break the answer into small, checkable claims
A citation must point to the exact visible evidence for one claim—not decorate the end of a paragraph.
Deep dive on grounding. A paragraph mixes three claims, one citation is only partially supportive, and the PDF has an OCR layer different from the visible scan.
I split a sentence into small claims that can each be checked. For example, “Drug A lowered blood pressure by 20% in adults over 65” contains the treatment, the amount, and the age group. Each part must point to exact highlighted lines. If the source supports the 20% result but not the age group, the full sentence cannot pass.
The visible page image is the final reference. Text already stored inside a PDF can help us search, but it may be hidden or disagree with the scan, so we compare it with OCR text and page position. The checker labels each claim SUPPORTED, PARTIAL, CONFLICTED, or UNSUPPORTED and saves the reason. Only fully supported claims move to human approval.
A draft says, “Drug A lowered blood pressure by 20% in adults over 65.” We split that into the treatment, the 20% result, and the age group. Each part must point to exact highlighted lines in the exact PDF version. If the age group is missing, the sentence cannot be approved as written.
| State | Meaning | Permitted action |
|---|---|---|
SUPPORTED | All material qualifiers entailed by visible authorized evidence. | May advance to human approval. |
PARTIAL | Core idea supported; qualifier, population, or magnitude is not. | Edit/split/qualify; cannot approve as-is. |
CONFLICTED | Authorized sources materially disagree. | Show conflict and escalate to expert. |
UNSUPPORTED | No admissible source span entails the claim. | Delete, retrieve more evidence, or abstain. |
Measure the machine before the human fixes it
Write-once snapshots, F2, blinded expert review to settle disagreements, slice gates, and judge calibration prevent flattering but meaningless scores.
How do you evaluate drafts? Explain F2, golden sets, write-once pre/post snapshots, and an LLM judge without fooling yourself.
We save the untouched AI draft before a person edits it. Otherwise we might give the model credit for a human correction. We measure how many required facts it found, how many claims lacked support, whether citations were correct, and how serious any omissions were. The F2 score gives recall four times the weight of precision because missing a safety fact may be worse than adding a little extra supported detail.
Our trusted test set covers different medical areas, question types, difficult documents, and known failures. Two experts review it, and a third settles disagreements. A large language model (LLM) may help grade more drafts only after we compare it with those experts and keep checking where it disagrees. Human edits are useful clues, not automatic truth; some edits reflect style rather than correctness.
The AI includes 90 of 100 required facts. A writer adds the missing 10. We score the untouched AI draft as 90 out of 100, not the polished final answer as 100. That tells us what the model really did.
| Gate | Why aggregate is insufficient |
|---|---|
| Zero catastrophic unsupported safety claims | A mean can hide rare, severe harm. |
| Minimum F2 per therapeutic/question slice | Easy common questions dominate a global score. |
| Judge/human disagreement control chart | The scalable evaluator itself drifts. |
| Pre→post edit distance + reasons | Separates factual correction from style preference. |
What if it breaks?
Protect the correct data first. Then contain the problem, recover, and explain what users see.
A source paper is retracted after 4,000 approved responses cited it. Search has already indexed the replacement approved source library. What changes?
I do not delete or mutate history. Approved source-library version R17 marks the source retracted with effective time and reason. New authoring excludes it. A reverse citation index finds every claim and approved response locked to the old source file fingerprint. The impact job is retry-safe on (retraction_id,response_version_id) and opens risk-ranked remediation cases.
The original response remains reproducible and visibly “superseded/source retracted.” High-severity cases pause distribution and notify owners. Lower severity enters review. Corrected responses create new versions and preserve who approved the change. If the index is stale, the main citation table drives a slower complete scan. Retraction propagation has its own service target and completeness cross-checking.
What if timing gets messy?
Retries, delayed messages, and two updates at once are normal. State the rule that keeps one clear result.
The new model improves aggregate F2 from .88 to .91, but oncology safety omissions double. At the same time the LLM judge score rises. Ship it?
No. A better overall score cannot hide a safety regression. Oncology stays on the old model. I freeze the wider rollout, send the disputed examples to clinicians who do not know which model produced them, and separately test whether search missed evidence or the writer model omitted it. I also check whether the automated grader shares the same blind spot.
I test the new model only on a small, validated, low-risk group and run it invisibly elsewhere for comparison. Recovery is a one-step switch back to the old model. Existing responses stay tied to the exact model and grader that produced them.
Keep it safe and running
Cover overload, security, monitoring, and disaster recovery in that order.
Cover consistency, duplicate jobs, overload control, security, customer isolation, monitoring, and disaster recovery.
Always reading the newest confirmed value applies to approved source library publication, workflow transitions, approvals, authorization, and export intent. Search/index freshness is allowed to be briefly stale and always displays the indexed approved source library digest. Workers consume at least once. Stage keys combine customer, write-once input digest, stage version, and parameters, so retries reuse an output or create one result. A database-backed event queue prevents state/event gaps. External export resolves timeouts with receiver lookup rather than blind retry.
Admission control and fair queues for each customer separate live authoring from backfill/evaluation. Broken or malicious PDFs have bounded resource sandboxes and failed-job queue. Access policy checks customer, therapeutic area, purpose, stage, and break-glass. Per-tenant separate encryption keys and region-pinned storage isolate data. Model calls use approved model endpoints that do not store prompts or in-VPC models. Observe queue age, stage latency/error, unsupported claims, citation coverage, reviewer override, F2 by slice, judge drift, export cross-checking, audit completeness, and access anomalies. Multi-region metadata uses warm standby. Write-once objects are cross-region replicated and restore is rehearsed.
Request/error/latency/saturation for authoring, queues, OCR, retrieval, model, verifier, export.
Unsupported-claim rate, evidence recall, F2, citation correctness, omissions, reviewer override, judge drift by slice.
Per-stage queues, customer fairness, live/replay isolation, bounded retries, poison-source failed-job queue, optional enrichment shedding.
Compare-and-set safety check stage transitions. Approved source library publication transaction. At-least-once retry-safe stages. Database-backed event queue and export cross-checking.
Customer/area access policy, separate encryption keys, region pins, filtered indexes, no raw content in metrics, approved model routes.
Cross-region write-once objects, warm metadata standby, version list restore, periodic audit-bundle and export cross-checking drills.
Rollout and trade-offs
A credible production answer defines how it earns trust and how it retreats safely.
How do you roll this out, and what trade-off would you call out to an executive?
First shadow retrieval against historical requests. Then give writers evidence search only. Then draft in reviewer-only mode. Then canary a narrow therapeutic area with dual human scoring. Then permit assisted authoring while final approval remains human. Every phase has rollback, frozen baselines, and predefined quality/latency/cost gates. We validate the actual signed release package in a clean environment, not a developer checkout.
The central trade-off is throughput versus defensible completeness. Small claims that can each be checked, page crops, write-once snapshots, and staged approval cost storage and reviewer time, but enable safe iteration and honest evaluation. I would not promise “fully autonomous authoring”. I would promise measured assistance with explicit stopping when unsure and traceable human authority.
- Freeze historical benchmark and harmful-error taxonomy.
- Shadow retrieval and verify source recall without showing drafts.
- Release evidence-search assistant to writers. Measure search misses.
- Reviewer-only drafts with blinded AI/non-AI quality comparison.
- Canary one low-risk therapeutic/question slice behind a route version list.
- Expand only after human, citation, F2, latency, cost, and audit gates pass.
- Keep instant route rollback and retraction-impact replay.
- Validate the signed clean deployment saved item end to end.
One-minute spoken recap
Practice this synthesis until it sounds conversational rather than memorized.
Give me the one-minute summary.
I’ll summarize the source of truth, safety boundary, scale path, and rollout.
Reference shelf
Definitions, traps, and the final checklist stay outside the timed mock.
- Atomic claim
- The smallest proposition that can be independently supported or contradicted.
- Bounding box / polygon
- Coordinates identifying the visible region of a rendered source page.
- Corpus release
- An immutable, signed set of authorized source versions for a scope and effective time.
- F2 score
- An F-score that weights recall four times as strongly as precision.
- Golden set
- A frozen, adjudicated sample used to evaluate systems and calibrate scalable evaluators.
- Judge drift
- Change in an automated evaluator’s relationship to human judgment over time or slices.
- Pre-edit snapshot
- The immutable AI output captured before human correction; essential for honest measurement.
- Retraction impact
- Reverse lineage from a withdrawn source to every claim and response that used it.
- RAG
- Retrieval-augmented generation: generation conditioned on retrieved source material.
- Weak label
- A signal such as an edit that may not equal ground truth without adjudication.
- WORM
- Write-once, read-many retention that resists silent mutation.
- Outbox
- A transactionally written event record relayed asynchronously to avoid state/event gaps.
- Keeping only the human-polished draft and then claiming it as model quality.
- Citing a whole paper when only a sentence or qualifier needs support.
- Trusting hidden PDF text over the visible page.
- Using one aggregate F2 while a safety-critical slice regresses.
- Treating an LLM judge as ground truth because it is cheap.
- Training on reviewer edits without separating truth corrections from style.
- Mutating old responses after a source retraction.
- Pointing citations to mutable “latest” documents.
- Allowing the model to approve or export its own answer.
- Mixing customer corpora in meaning-based search indexes or evaluation sets.
- Blindly retrying an external export after a timeout.
- Testing prompts and model separately from the signed release package.
- Clarified actors, authority, business harm, and out-of-scope.
- Did correct BOTEC and named the variable that changes the architecture.
- Defined stable IDs, versions, access paths, and retry keys.
- Separated source of truth state from derived indexes and model output.
- Explained consistency, retries, overload control, and unknown outcomes.
- Revised the design after both failure injections.
- Covered customer isolation, secrets, least privilege, deletion, and audit.
- Named golden signals, domain quality metrics, rollout gates, and rollback.