Voice intake for pre-op questionnaires — one prompt, one Questionnaire, and a live production timeline — Aug 13, 2026
Voice intake for pre-op questionnaires — the demo
Vitaly Banchenko, tech lead on the Formbox team at Health Samurai, showed a prototype that replaces the pre-visit form with an AI phone call. The demo screen listed upcoming appointments — a knee replacement, a hip replacement — and Vitaly triggered a "bot-to-bot" call so an agent could interview a simulated patient in front of the group. The system walked through five validated instruments (KOOS JR, SANE, Pain Score, PHQ-2, GAD-2) and produced a call summary, a patient story, a list of priorities and concerns with supporting quotes from the transcript, and a score profile plotted across the five domains over time.
Nikolai framed why they're chasing this in the opening:
Just a year ago I talked to my friend who is a physician in Tartu University, and they all hate EHRs. I promise that in a couple of years they will talk to the system so they don't have to open any screens, learn how to navigate.
Vitaly's own framing was more pragmatic. Patients have weeks to fill a pre-op form and consistently wait until the waiting room, often quitting partway through. His wager is that a minute of talking feels normal, while tapping through 16 scored items across four scales does not.
Architecture — one prompt, Questionnaire as the guardrail
The first version of the system was a state machine built from the Questionnaire's nodes, each with its own prompt. It broke whenever a patient went off-script, and it couldn't accommodate the two clinicians consulting on the project — one who wanted the questions read verbatim, and another who wanted an open story-first conversation from which answers were extracted afterwards. That mismatch forced a rewrite.
The replacement is a single loop: one LLM prompt handles the whole conversation, and the FHIR Questionnaire defines what answers are valid. The model routes itself within those bounds. The prompt itself has two layers — a static system section describing how to read questionnaires and extract answers into the correct shapes, and a tunable section that carries tone, pacing, and how to handle refusals or reschedules. Every prompt version is stored with a URL, the same way canonical Questionnaires are, so historical calls can always be traced back to the exact prompt that produced them.
We stopped programming the dialogue and we started to constrain it.
John Moehrke asked whether the SDC IG already covered the shape they'd landed on. Nikolai and Vitaly confirmed the Questionnaire is still the source of constraints and the output is a QuestionnaireResponse — the change is that the state-machine layer around it was deleted in favor of letting the model handle routing:
I was not expecting it was going to do everything. I was just kind of expecting it could be the structure that the AI builds on top of, so it doesn't go down dead ends and those kinds of things.
Prompt tuning is currently done by trial and error: run the demo bot-to-bot, feed the transcript and QuestionnaireResponse into a Claude Code skill, ask it what went wrong, and iterate. There's no automated benchmark suite yet — Vitaly noted that once the prompt grows past a certain size it becomes too hard to reason about by hand and the model becomes a better editor than the human.
Provenance, confidence, and the transparency IG
Every mapped answer in the QuestionnaireResponse carries a receipt: the source phrase from the transcript, whether it was a direct answer or an inference, two separate confidence scores (one for the LLM mapping, one for the STT transcription), and the exact prompt version and utterance index. Right now all of that lives in a nested tree of custom extensions on the QuestionnaireResponse. Call metrics — end-to-end latency broken down by STT, LLM, and TTS — are stored separately for later comparison across models and configurations.
Michael Campbell flagged that this is exactly the shape the AI Transparency on FHIR IG (walked through by John the previous week) is designed for — model cards, provenance, and confidence intervals as first-class fields:
I would also suggest — is it something you're interested in as a test case for the AI transparency on FHIR? It seems like a perfect fit, because you're capturing some of the discussion we mentioned before, including the confidence interval, and that was an open ticket — where if we capture it, where do we capture it and how do we standardize it.
Vitaly confirmed the team looked at the IG last week and plans to migrate toward it. After the QuestionnaireResponse is built, standard FHIR SDC extract operations pull observations, provenance, and other resources out — the agent's job stops at gathering answers.
Model choice: latency vs smartness
The stack is STT → LLM → TTS over raw WebSockets. WebRTC was considered — it would bring built-in noise cancellation and echo suppression — but dropped for now because it requires TURN and STUN servers on the infrastructure side. Production will run over phone, not browser, so browser audio quirks are lower priority. End-to-end voice-to-voice models were considered too but discarded: they extract structured data less reliably and are harder to tune than a pipeline where each stage is swappable.
Gemini 2.5 Flash was chosen for latency after benchmarking. It's fast enough that a five-minute call costs roughly fifty cents end to end — but it's visibly less capable on longer Questionnaire lists, which showed during the live demo when the agent failed to compress the interview after being told "I only have two minutes." Nikolai pushed on whether the OpenAI models — including the reportedly 15x-faster GPT-5 API tier — were worth trying. Vitaly's counter was production economics:
Five minutes of conversation currently costs about fifty cents. If we just switch to a GPT-5-class model, it goes up roughly 10x. No one wants to make those calls.
The bet is that the price curve keeps moving and the tradeoff softens over the next few months. The feature is targeted for Formbox production in roughly one to two months.
Side thread — meeting bots and group-therapy diarization
The conversation drifted into a related unsolved problem. Jayte Boehler, product officer at BestNotes (an addiction-treatment EHR), asked how anyone is handling diarization for group therapy — individual session scribing is solved, group sessions are not:
A lot of our providers do group therapy, and this is the one thing they're asking for — I want to have an AI scribe a group session. That diarization is something that I'm a little bit at a loss on how we're going to approach.
Gino Canessa has been chasing the same problem from the meeting-bot angle. He's been using CRISP ASR as a normalization layer to compare STT backends on word-error rate, language support, and diarization-embedding extraction — nothing production-ready yet, weeks to months away from something usable. Gino and Joshua Bagley have been building meeting bots in parallel — Josh's uses Mistral streaming to produce live minutes during the call; Gino's is focused on post-meeting review with local models, integrated with Jira, Zulip, and Confluence. Nikolai pointed out that being inside the platform (via the Zoom API, for instance) makes diarization trivial because speaker identity is already known, but Gino noted he dropped the Zoom route after hitting per-minute access costs and transcription restrictions. Brian Beatty mentioned Granola for AI meeting summaries; Gino noted Open Whisper covers similar ground for local recording. Nikolai closed the call with a nod to a Google Health release: a physician-avatar product for virtual visits that even attempts a rough physical examination from video — very early stage.