You have an operational worklist and a structured filter UI in front of it — dozens of fields, a stack of dropdowns, and a combination rule that only two people in the building actually understand. The people who need the data most urgently are the domain experts, and they do not think in filter combinations. They think in domain language: unconfirmed AI findings from last week, abnormal impressions for Site 12, everything a particular reviewer has not signed off yet.
Every one of those questions is answerable by the data you already have. The gap is not the records and it is not the model — it is the distance between how an expert thinks and how the system insists on being asked. That distance is a tax, and it gets charged to your most expensive people, on the days they are busiest.
ML LABS built the natural language search layer on the cloud ECG backend behind HeartSciences' MyoVista Insights platform — the multi-tenant AI platform whose backend ML LABS engineered, running in clinical production in the US and the UK. Clinical experts needed to search a worklist of records annotated with AI-generated outputs, and the phone was a first-class surface in the requirement rather than an afterthought in the backlog. What follows is what that took: a parser that refuses to guess, an index layer that decides the latency, and a mobile budget that set the bar for everyone.
What The Parser Actually Recognizes
The core is a constrained intent parser that maps a natural language query onto a known set of domain entities and structured filters. This is not general-purpose text-to-SQL, and the difference is the whole design. The parser recognizes the entities that exist in this operational domain — a classification status, a site identifier, a confirmation state, a date range — and translates them into an executable query against the fields that actually exist. Type "abnormal AI impressions for Site 12 this month" and it resolves three entities and one range, then runs the query those four things define.
graph TD
A1["Natural Language<br/>Query"] --> B1["Domain Entity<br/>Recognition"]
B1 --> C1{"Query Targets"}
C1 -->|"Record Fields"| D1["Primary Record<br/>Search"]
C1 -->|"AI Outputs"| D2["AI-Generated<br/>Content Search"]
C1 -->|"Both"| D3["Unified<br/>Intersection"]
D1 --> E1["Sub-Second<br/>Results"]
D2 --> E1
D3 --> E1
style A1 fill:#1a1a2e,stroke:#0f3460,color:#fff
style B1 fill:#1a1a2e,stroke:#ffd700,color:#fff
style C1 fill:#1a1a2e,stroke:#ffd700,color:#fff
style D1 fill:#1a1a2e,stroke:#0f3460,color:#fff
style D2 fill:#1a1a2e,stroke:#0f3460,color:#fff
style D3 fill:#1a1a2e,stroke:#0f3460,color:#fff
style E1 fill:#1a1a2e,stroke:#16c79a,color:#fffThe parser's reliability comes from constraint, not sophistication. It recognizes every entity that maps to a filterable field — and nothing else. Bounded vocabulary means predictable results.
Why Constraint Beats LLM Parsing
A general LLM-driven parser demos better and operates worse, and the reason is the shape of its failure rather than the size of its vocabulary. A free-form parser fails silently: it returns a plausible result set that quietly misses what the user asked for, and nothing in the interface distinguishes that from a correct answer. In a worklist where clinicians act on the records they pull up, a silent miss is not a usability complaint. A constrained parser fails loudly instead — when a phrase does not map to a known entity, the system says so, shows the phrase it could not resolve, and offers to refine. Users learn the bounded vocabulary quickly, because the system is willing to tell them what it knows. Health informatics has known this for two decades: the interoperability that actually works in the field runs on deliberately constrained profiles of a general standard (Journal of the American Medical Informatics Association, 2009), not on the general standard itself.
Take the query "borderline impressions Site 12 not yet confirmed last week." A free-form parser might read "borderline" as a fuzzy confidence modifier, a generated severity class, or a free-text fragment to match anywhere — three interpretations, three different result sets, and no way for the user to see which path was taken. The constrained parser resolves "borderline" against an explicit lookup: if it is a registered classification value, the filter pins and the query runs; if it is not, the parser refuses to guess and asks whether the user meant the equivocal-finding class or something else. The disagreement surfaces at parse time instead of hiding inside the result set.
That property is worth more than it looks, because trust in these systems is asymmetric and unforgiving. People abandon an algorithm faster after seeing it err than they adopt one after seeing it succeed (Journal of Experimental Psychology: General, 2015) — and a search tool that silently drops the one record an expert was looking for has spent its credibility permanently. Constraint is what buys the system the right to be believed. It is also why the general-purpose chatbot pattern is the wrong tool here, as the comparison between a knowledge search build and an off-the-shelf assistant works through in more detail: an assistant that is confidently approximate is worse than a filter UI that is honestly rigid.
Two Indexes, One Query Plan
The worklist holds two layers of searchable data: the raw operational records, and the AI-generated outputs the inference pipeline attaches to them — classifications, interpretive analyses, and impressions produced by multiple AI model providers. Search runs across both as one surface. "Abnormal AI impression" searches the outputs. "Site 12 records from last week" searches the primary records. A query that mentions both returns the intersection, and the user never learns which layer answered them. When a provider produces a new output type, the search layer expands to include it as a configuration change rather than a code change — the same design property that runs through the whole platform, from onboarding a new organization to the billing engine's per-site pricing rules.
Hitting the latency budget is an indexing problem, not a query-engine problem, and that is the part teams get backwards. Each layer needs its own index shape. Primary records are indexed on the high-cardinality fields that appear in nearly every query — site, date, assignment status. AI outputs are indexed on classification value and confirmation state, with the impression text held in a secondary inverted index. Because the parser already knows which index each recognized entity belongs to, a query naming a site and a classification touches two narrow indexes and intersects the resulting keysets, instead of scanning the worklist and filtering afterward. That is the difference between a search that returns while the expert is still looking at the screen and one they learn to stop using.
The engine delivers sub-second results at production data volumes, and it serves desktop and mobile without modification — because mobile set the bar. The latency budget on a phone is harsher, not looser: a query that takes 800ms on a wired desktop reads as acceptable, and the same 800ms on a phone over cellular reads as broken. Tuning for the harsher surface meant the desktop got its performance for free. Treating that budget as an explicit service level objective rather than a hope (Google, 2016) is what keeps it from eroding release by release.
Where Natural Language Breaks Down
The approach has a working envelope, and it is worth naming the two conditions that put a system outside it. Poor upstream data quality is the first: inconsistent naming, missing fields, and duplicate records produce unreliable results no parser can rescue, and the first investment in that environment is cleanup rather than search. Genuinely unstructured content is the second: searching freeform narrative notes is a full-text ranking problem, not a structured filtering one, and a constrained intent parser has no schema to map against. That is the territory where retrieval-augmented generation over an indexed corpus (Microsoft Learn, 2026) is the right architecture rather than the wrong one — a different problem with a different answer. The evidence from enterprise retrieval systems (Packowski et al., 2024) points the same way: retrieval quality in production tracks the structure and curation of the content far more than the cleverness of the retrieval layer.
Inside the envelope, parser quality still drifts as the vocabulary grows, and three signals are worth instrumenting from the first release. The share of submitted queries where the parser surfaces an unmapped phrase measures coverage gaps. The share of queries a user re-runs through the structured UI within a minute of the natural language version measures trust gaps. And the share of result clicks landing on records produced by the most recently added entity measures whether new entities are carrying any weight at all. When one of those moves the wrong way across a release, the fix is to add an entity or split an existing one — not to relax the constraint and let the parser start guessing.
First Steps
- Collect real queries before writing any parser. The distribution of what people actually ask determines the entity set and the index shapes. Guessing at it produces a parser tuned for questions nobody has.
- Ship the structured filter API first, then the language layer on top. The API is the stable foundation and the thing you can test; the parser is a translation into it, and translations are easier to fix than foundations.
- Set the latency budget on the worst surface you support. Measure at the 95th percentile, on mobile, against production data volumes. The queries that time out are the ones your experts remember.
Constrain Parser To Domain Entities
The pattern that holds up is a constrained intent parser over a known entity set, unified search across primary records and AI-generated outputs, an index shape per layer, and a latency budget set by the harshest client rather than the friendliest. It avoids the two failure modes that kill operational search projects: over-engineering the language layer to handle questions users never ask, and under-engineering the data layer so that correctly parsed queries still time out. Both failures look like a search problem and neither of them is one.
Search that reaches into a live operational platform is not a widget you drop on top — it touches the record store, the AI output pipeline, the tenancy model, the auth boundary, and the mobile client, and the hard part is that it has to be correct in all of them at once. That is the shape of an AI system integration, which includes its first 60 days of Operate, run by the person who built it — because the queries that expose a missing entity are the ones real experts type once the thing is live, and someone has to be there to add it. If your experts are already describing what they want in plain language and then translating it into dropdowns by hand, they have specified the parser for you. The build is the easy part after that.
References
- Dietvorst, B. J., Simmons, J. P., and Massey, C. Algorithm Aversion: People Erroneously Avoid Algorithms After Seeing Them Err. Journal of Experimental Psychology: General, 2015.
- Packowski, S., Halilovic, I., Schlotfeldt, J., and Smith, T. Optimizing and Evaluating Enterprise Retrieval-Augmented Generation (RAG): A Content Design Perspective. Proceedings of the 8th International Conference on Advances in Artificial Intelligence (ICAAI), 2024.
- Google. Service Level Objectives. Site Reliability Engineering, 2016.
- Microsoft. Retrieval-Augmented Generation in Azure AI Search. Microsoft Learn, 2026.
- Sujansky WV, Overhage JM, Chang S, Frohlich J, Faus SA. The Development of a Highly Constrained Health Level 7 Implementation Guide to Facilitate Electronic Laboratory Reporting to Ambulatory Electronic Health Record Systems. Journal of the American Medical Informatics Association, 2009.
