Ulysse
Case example

From 320 consultation notes to a trial-ready cohort

This is the output, not a mock-up. A pool of 320 consultation notes was taken from four different practice management systems, in English and French, and run through the engine end to end. What comes out is the answer a sponsor asks for at protocol design: how many animals like this exist, and where are they?

320 consultation notes 4 practice systems 2 languages 9 standardised conditions No template per format Accuracy graded against ground truth

Open the console full screen for more room on a small display.

Reading the output

What the console is showing you

Pick a protocol, then change the criteria. Patient counts, site density and the eligible, near-miss and excluded splits recompute against the structured records. Every number traces back to a consultation note that arrived as an unstructured document.

The hard part is the input

The 320 consultation notes behind this console are PDFs from four different practice management systems, in English and French, with different layouts, different field labels and free-text clinical prose. There is no template per format. The documents are read, structured and coded automatically.

Free text becomes a searchable field

A vet writes "renal mass, likely carcinoma" or "insuffisance rénale chronique". Both become one standardised condition that a sponsor can filter on. Nine conditions are standardised from the diagnoses as written, which is what turns unsearchable notes into a cohort query.

Accuracy is measured, not claimed

Every extracted field is graded against ground truth recorded when the documents were created. The accuracy panel at the bottom right of the console is that measurement. A pipeline that cannot be graded cannot be trusted with a protocol.

The data is entirely synthetic. Every animal, owner, practice, sponsor and trial shown here was generated for demonstration. No real clinical record, practice or pharmaceutical company appears anywhere in this dataset. Sponsor and practice-group names are invented.
Try the switch at the top right of the console. Sponsor view is what a paying customer sees: de-identified patient references, corporate group and city instead of a named practice, and no access to the consultation note. Practice view is what the treating vet sees: named patients and the source note, which is what lets them approach the owner. In the underlying deployment that separation is enforced by row access and masking policies, so a sponsor account cannot read the hidden columns even by querying directly. On this page the switch demonstrates the behaviour.

A note on what is live. The console above is a fixed snapshot of the underlying warehouse: all filtering, recounting and site density is computed in your browser, so it responds exactly as the real thing does, but the numbers are frozen at the point the snapshot was taken. The eligibility decisions, match scores and failed-criteria lists were computed in the warehouse against machine-evaluable protocol criteria, not in this page. Publishing a live database connection behind an anonymous public URL would be the wrong trade for a demonstration.

Under the hood

What runs behind the console

Documents in, structured records out

Consultation PDFs land in cloud object storage. Each is read and laid out, then the clinical fields are extracted: signalment, weight, diagnosis as written, medications, comorbidities. The free-text diagnosis is then classified into a standardised condition. Every step is a query in the warehouse, so there is no separate service to run, monitor or scale, and the extracted data never leaves the platform.

Criteria evaluated as data, not code

Protocol criteria are stored as machine-evaluable rows: an attribute, an operator, a value, and whether the criterion is hard or soft. Adding a trial means adding rows, not writing a query. That is what makes the difference between eligible and near miss meaningful: a near miss failed exactly one soft criterion, so it is worth a phone call, and the console can say which criterion failed.

Isolation is enforced, not promised

Each sponsor sees only their own trials. Each corporate group sees only its own practices and only its own owners unmasked. A French practice sees only French patients. This is enforced at the row and column level in the warehouse, which matters because the commercial model asks competing sponsors and competing practice groups to put data in the same place.

Built on Snowflake

The document reading, extraction, classification, standardisation, criteria engine and access control all run inside one platform. For a company of one, that removes most of the infrastructure work that would otherwise sit between a concept and a demonstration a sponsor can be shown.

Architecture

Five stages from PDF to cohort

Every stage below runs inside Snowflake as a query. There is no separate application server, no document-processing service to operate, and the clinical data is never copied out to a third party to be read.

1

Land the documents

320 consultation PDFs arrive in cloud storage from four different practice management systems, in English and French, with no shared template.

internal stage
2

Read the page

Each PDF is converted to structured text with its layout preserved, so tables and field labels survive. One call handles every format.

AI_PARSE_DOCUMENT
3

Extract and code

Signalment, weight, diagnosis as written, medications and comorbidities are pulled out as fields. The free-text diagnosis is then mapped to one of nine standardised conditions.

AI_EXTRACT · AI_CLASSIFY
4

Model and score

Records are cleaned and joined in layers, then every patient is scored against protocol criteria stored as data. Output is eligible, near miss or excluded, with the failing criterion named.

dbt · criteria engine
5

Serve the answer

A semantic layer, a search index over the notes and an agent sit on top. The console reads that layer, in sponsor view or practice view.

semantic view · search · agent
Across all stages

Access control is applied in the warehouse, not in the application. Row access policies restrict each sponsor to their own trials and each practice group to its own patients. Masking policies hide owner identity outside the treating group. A sponsor account querying the tables directly gets the same restricted result the console shows.

Measured, not assumed

Every extracted field is graded against ground truth captured when the document was created. That produces a field-level accuracy figure per condition, which is what a sponsor needs before a feasibility count can be used to size a study.

What this proves

The riskiest assumption, tested first

Messy records can be standardised

Four incompatible formats and two languages resolve into one data model without a human writing a parser per practice system. That is the technical claim the whole business rests on, and it is now demonstrable rather than asserted.

Feasibility can be answered in seconds

The question that currently takes weeks of phone calls and chart review is answered against structured data while the sponsor is still designing the protocol.

Sponsor and practice can share one system

The same records serve a sponsor who must not see owner identity and a vet who must, with the boundary enforced in the data layer rather than promised in a contract.

What comes next. The pilot replaces synthetic documents with a live integration to one practice management system and one practice group, on a real sponsor protocol, measured against a manual recruitment baseline. See the eighteen-month plan.