At Qoves the model output isn't the product. The product is the report a customer reads once and decides whether to believe. That gap between what the model produces and what the customer actually reads is where most of the engineering lives.
Chain stages, not notebooks#
A report pipeline is a sequence of bounded stages: ingest, detect, measure, analyze, compose, render. Each stage takes a typed input and returns a typed output, fails on its own terms, and can be retried without repeating the work before it.
ingest -> detect -> measure -> analyze -> compose -> render
| | | | | |
bytes regions metrics findings sections PDF/HTMLStages that write their outputs make the pipeline resumable. A failure in compose doesn't cost another round of paid model runs.
LLMs belong where language is#
We use OpenAI, Anthropic and Gemini through LangChain for the parts that are genuinely language problems: turning structured findings into readable prose, choosing an explanation for a measured value, answering follow-up questions grounded in retrieval. The measurements themselves stay in deterministic code. You cannot debug a landmark detector that lives inside a prompt.
Deterministic where it must be#
Two runs of the same customer image should produce the same measurements. Pin model versions, seed anything stochastic, and store the pipeline version with the report. When a customer asks why a number changed, you need an answer better than "the model is like that".
Evaluation before release#
Every report change runs against an evaluation set of images with known outcomes. Reports that fall outside tolerance don't ship. This is unglamorous work, and it's the reason customers can trust a document generated by machines.