Case Study · AI Agents / Pharmacovigilance · 2026

PV

Agent

A pharmacovigilance agent that answers drug safety questions
with figures you can trace back to the source.

Scroll
ROR = (a / b) / (c / d) assert figure.source_url is not None SmPC section 4.8: frequency = "uncommon"
01

The Problem.

Drug safety teams answer the same question all day: is this adverse event a known effect, a coincidence, or a signal? The data is public but scattered across EudraVigilance, FAERS and the MHRA Yellow Card scheme, each with its own format, and the reference (section 4.8 of the product label) lives in PDFs. In this field, a chatbot that returns a number nobody can verify is worse than no answer.

02

The Solution.

An agent built at Kirha. It works out what is being asked (drug, effect, population, comparator), collects case counts from the three regulators, reads the label's adverse reaction table with its frequency bands, and matches reported reactions against labelled ones. It computes disproportionality (ROR, PRR) under strict guardrails: a frozen denominator, no mixing across databases, and a plain reminder that disproportionality is not causality. Every figure ships with its inputs and its source link, so a pharmacovigilant can redo the calculation. Case files dropped in by the user are read through openicsr.

From question to sourced report.
01 Understand Drug, effect, population, comparator
02 Collect EMA, FDA and MHRA case counts
03 Read the label SmPC 4.8 reactions and frequency bands
04 Compute Label matching, ROR and PRR with guardrails
05 Report Every figure with inputs and source link
36/36 Intent benchmark Was 4/23 before the redesign
0 False frequency bands Across 17 reports checked against the SmPC
3 Regulators EMA / FDA / MHRA
The Stack.
01 TypeScript Agent runtime
02 MCP Data collection through Kirha search
03 LLM extraction Anchored to the document, checked by geometry
04 openicsr E2B(R3) case files
05 Vitest Benchmarks and regression suite
← Back to works Next: openicsr →