I build AI systems that verify before they generate.
Applied AI engineer working on LLM systems for healthcare β verification, regulatory review, patient communication. Particularly interested in constraining model behaviour to reduce harm in high-stakes domains (the subject of my recent publication, below). Founder of PharmaTools.AI, a suite of production AI tools used by clinicians, medical writers, and patients.
- Retrieve evidence rather than invent it
- Expose uncertainty rather than conceal it
- Constrain capability where consequences are high
- Help humans audit reasoning, not replace judgement
LLM systems: Claude API Β· MCP Β· RAG (Pinecone Β· FAISS) Β· multimodal Β· structured outputs Β· evals
Application: Node.js Β· Python Β· Swift / SwiftUI Β· Firebase Β· Postgres
Lamb NJ. Translation, not Interpretation: Rethinking Language Model Design for Healthcare. SN Comprehensive Clinical Medicine. 2026;8:71.
Argues that LLMs in healthcare should be constrained to translational tasks β restructuring information across clinical, scientific, regulatory and patient-facing domains β rather than performing open-ended interpretation. A scoping argument aligned with capability-control approaches to AI safety: narrower model surface, clearer accountability, lower harm ceiling.
Lamb NJ. Validation of an AI-powered mobile application for personalizing medical note explanations. medRxiv, 2025.
A three-phase validation of Patiently AI β computational readability metrics across 210 outputs, expert review by 15 clinicians, and a 54-patient survey β finding 87.3% of outputs rated clinically safe, 70% patient preference over standard notes, and FleschβKincaid grade level reduced by ~3. Empirical evidence for the "translation, not interpretation" thesis above, applied in a shipped product.
Patiently AI β Patient Communication
Transforms complex medical notes into clear, patient-friendly language. Approach: constrained simplification to a target audience and reading level, gated so the model stays in translation β restating what the note already says, never crossing into diagnosis or new clinical interpretation.
flowchart TD
A["Medical note<br/>(typed, uploaded, scanned or dictated)"] --> T
U["User preferences<br/>Audience + reading level + language + tone"] --> T
T["AI transformation<br/>Simplifies and explains medical language<br/>while preserving clinical meaning"] --> S
S{"Safety guardrails<br/>No diagnosis, no new clinical facts,<br/>no medical interpretation added"}
S --> O["Clear, audience-appropriate explanation<br/>Same clinical information, easier to understand"]
5Γ Award Winner β PMEA 2025 (Innovation & Patient Education), CommuniquΓ© 2025 Progress Award, HTN AI & Data 2025 (Highly Commended), Best Mobile App Awards.
RefCheckr β Medical Writing
Verifies clinical claims against supporting references for medical writers and MLR reviewers. Approach: the user's draft claim is judged against each reference by an LLM that must cite verbatim passages; a post-hoc integrity check rejects any citation that can't be located in the source PDF (hallucinated quotes get the verdict downgraded). References can be uploaded PDFs (with OCR fallback) or fetched live from PubMed / ClinicalTrials.gov / DailyMed. Output is an annotated PDF with colour-coded highlights.
flowchart TD
A[Draft claim] --> V
B["References β uploads, library,<br/>or live search via PubCrawl MCP"] --> X[PDF text extraction<br/>OCR fallback for scans]
X --> V[Per-reference LLM verification<br/>judges claim against full source text]
V --> O[Verdict + confidence +<br/>quoted passages with PDF locations]
O --> G{Can each quote be matched<br/>in the source PDF?}
G -- no --> D[Downgrade verdict<br/>hallucinated quotes rejected]
G -- yes --> P[Annotated PDF<br/>colour-coded highlights]
D --> P
MedCheckr β Regulatory Compliance
AI-powered regulatory review tool that checks promotional claims against the ABPI Code of Practice with clause-level transparency. Code Clarity Awards Winner, 2024. Approach: RAG over the ABPI Code corpus with Pinecone vector embeddings; every finding cites the specific clause(s) it relies on, so reviewers can audit each decision.
PosterLens β Research
Captures scientific posters and generates instant AI summaries. Presented at ESMO AI & Digital Oncology Congress 2025. Approach: mobile vision capture β multimodal LLM extraction into a structured schema (study design, endpoints, results, limitations).
BiomarkerFinder β Drug Discovery
AI-powered insights into complex biomarker data, explained in plain language. Winner at Open Targets Hackathon. Approach: pulls structured biomarker associations from Open Targets and translates them into plain-language explanations with provenance back to the underlying datasets.
HushMap β Wellbeing
Helps neurodivergent individuals locate sensory-friendly places nearby. Community contributions and Apple Watch support.
The consumer products above are underpinned by an open-source spine: OpenGATE, a deterministic grounding-verification standard I built, and the tools it gates. One evaluation standard, four published systems β together several thousand downloads a month, each release checked against a fidelity baseline before it ships.
| Tool | What it does | Adoption |
|---|---|---|
| OpenGATE | Deterministic grounding verification β no LLM judge | |
| PubCrawl | MCP server for biomedical literature (14 tools) | |
| Redacta | De-identify clinical text before it reaches an AI | |
| StudyDiff | Explains why two studies disagree, grounded in source |
OpenGATE β the verification spine
Deterministic, gold-anchored verification for evidence-grounded AI β no LLM judge. OpenGATE answers one question: can a system prove its answer from the evidence it was given? Required facts must be present, every number must trace back to source, and when the context can't answer, the system must abstain rather than fabricate. Because the check is pure logic β not a grader model β it's reproducible, free, and fast enough to run on every answer or gate on every commit. It's the pattern behind RefCheckr and Patiently AI, published as a standalone standard and wired in as a CI release gate on the tools below.
It catches real regressions. Wired into PubCrawl's release pipeline, OpenGATE flagged a records-shape inconsistency (an author list serialised as a string instead of an array) before it shipped β the kind of silent parser regression that would quietly poison every downstream grounding claim. Fixed, gated, and now green at 100% retrieval fidelity across PubMed and Europe PMC on every release.
flowchart LR
S["AI system output<br/>(RAG Β· doc-QA Β· MCP server)"] --> G{"OpenGATE<br/>facts present? numbers trace?<br/>abstains when unsupported?"}
G -- "pass" --> R["Ship / merge"]
G -- "regressed vs baseline" --> B["Block release"]
PubCrawl β MCP server for biomedical literature
TypeScript MCP server giving LLM clients direct access to PubMed, Europe PMC, ClinicalTrials.gov, FDA DailyMed (USPI), and the UK eMC (SmPC) β 14 tools in all, including a side-by-side US/UK label comparison. Built so models retrieve and reason over real biomedical literature rather than rely on parametric memory. Powers retrieval in RefCheckr; gated by OpenGATE on every release (100% retrieval fidelity across PubMed and Europe PMC). Published to npm as @pharmatools/pubcrawl and listed in the official MCP registry.
Redacta β de-identify clinical text before it reaches an AI
One detection engine shipped across eight surfaces β an iOS app, an agent skill, an MCP server, TypeScript and Python libraries, a CLI, and two whiteboard plugins. It replaces patient identifiers with labelled tokens ([PATIENT_NAME_1], [NHS_NUMBER_1], β¦) while leaving the clinical meaning intact, and it works in reverse: redact β process elsewhere β re-identify locally, so real identifiers never leave your machine. Deterministic pattern-matching (Modulus-11-validated NHS numbers, NI numbers, dates, postcodes) with an optional reasoning layer for free-text names, plus a HIPAA Safe Harbor mode.
StudyDiff β why two studies reach different conclusions
Give it two papers and it extracts each one's design, surfaces the methodological differences that could explain a disagreement (a cell type, a dose, a follow-up window), and ranks the likely drivers β grounding every statement in the source text, so it never invents a finding. Any field the source doesn't state is shown as not reported, never inferred; grounding runs first, so a fact that can't be verified is downgraded before it's ever used as a reason. Verification is deterministic (OpenGATE) β no second LLM acting as judge. Built for the Built with Claude: Life Sciences hackathon; shipped as an MCP server so any agent can ask why do these papers disagree? as a tool call.
Concept implementations β the verification patterns above, distilled into small, readable reference repos:
RSI Loop β validated self-improving detector
A computer-vision pipeline that detects RSI risk and improves its own detection logic against a benchmark suite β but is gated by a separate regulatory Auditor that rejects mutations producing test-passing but clinically implausible thresholds. A concrete miniature of specification-gaming / reward-hacking mitigation: optimise freely, accept only iterations that are simultaneously accurate and within published clinical norms.
flowchart TD
A["Webcam pose + hand landmarks"] --> D["RSI-risk detector vN"]
D --> E["Score against benchmark suite"]
E --> I["Self-improvement proposes vN+1<br/>new thresholds / logic"]
I --> G{"Auditor: accurate on benchmark<br/>AND within published clinical norms?"}
G -- no --> R["Reject mutation<br/>specification-gaming blocked"]
R --> I
G -- yes --> N["Accept vN+1 as new baseline"]
N --> D
LitRAG β grounded RAG with a built-in citation-faithfulness eval
A small, readable RAG pipeline over PubMed abstracts that doesn't stop at "it retrieved something and answered" β it checks whether each generated claim is actually supported by its cited source, and flags hallucinated or unsupported ones. A deterministic quote-locator catches fabricated citations for free; an LLM-as-judge then grades support level (supports / partial / contradicts / not-found) from the passage alone. Embedding and retrieval run fully local (Hugging Face sentence-transformers + FAISS β no managed vector-DB key); only generation and the judge call an LLM. It's the citation-faithfulness pattern behind RefCheckr, distilled into an open reference implementation, with its corpus pulled via PubCrawl.
flowchart TD
Q[Question] --> R["Local retrieval<br/>sentence-transformers + FAISS"]
R --> G["LangChain RAG chain<br/>answer + verbatim cited quote per claim"]
G --> L{"Quote locatable in source?<br/>(deterministic β no model call)"}
L -- no --> H["Flag: hallucinated quote"]
L -- yes --> J{"LLM judge: does the passage<br/>support the claim?"}
J -- no --> F["Flag: unsupported / contradicted"]
J -- yes --> S["Grounded β"]
- π pharmatools.ai
- π medcopywriter.com
- βοΈ nick@pharmatools.ai
- πΌ LinkedIn


