My Pricing Machine Could Not Answer Questions, So I Built It a Brain
- Habib Abdurrasyid
- 23 Sep, 2026
- · 3 min read
On this page
A while ago I taught a machine to price documents the way I used to in college, by sorting pages into buckets (the full story is here). It worked. Then someone asked it about spiral binding, and it had nothing to say. A pricing machine is not a shop assistant. Shops answer questions.
That gap bothered me for months. So I built the Dokuprint agent: a chat that prices your PDF and answers questions about the shop’s services. Laminating prices, binding options, whether your file is ready to print. If you are new to AI agents, this is a friendly place to meet one, because the whole project rests on a single rule you can hold in your head.
The one rule
Every price in an answer must come from a tool, in that same conversation. Not from the model’s memory. Not from a guess. From a tool.
Why so strict? Because language models are confident liars about numbers. Ask one for a laminating price and it will give you a figure with a straight face, sourced from nowhere. The catalog in my project says one thing on Monday and the model remembers another. So the architecture removes the temptation entirely. The model writes sentences around numbers that Python already computed. It is not allowed to compute.
There are two tools and two kinds of prices. One runs the pricing engine over your uploaded PDF and returns the firm quote. The other searches the shop catalog and returns market ranges, always labeled as estimates. When the answer says Rp 4,500 for laminating, that number traveled from a catalog row, through code, into the sentence. You can trace it.
The guard dog
Between the model and you sits the part I trust most, and it is gloriously dumb. It scans the draft answer for anything shaped like a price and checks each one against the list the tools produced. Anything else gets exactly one rewrite. Fail twice and a fixed template answers instead, built from tool output only.
No intelligence involved. A regex and a set lookup. The fanciest model in the pipeline writes the prose, and the cheapest script in the pipeline decides what ships. I like that arrangement. It means the safety of the system never depends on the mood of the model.
What the shop knows
The assistant also needs knowledge: binding types, paper weights, package deals, the boring facts a real shopkeeper carries in her head. Mine lives in a small catalog, 145 chunks, searched two ways at once. One search understands meaning, the other matches exact words. Exact names kept drowning under related-but-useless results, so I fused both rankings. When nothing in the catalog matches well enough, the assistant says it does not know. That sentence took real work. Models would rather invent than admit ignorance, so the admission is enforced from outside.
The honest footnote
The catalog is made up. I wrote it as stand-in data, every row marked low confidence, and the assistant labels its answers as estimates. The plumbing is proven: 362 automated tests, retrieval that finds the right row 94.7% of the time, zero invented prices across the whole eval set. But plumbing is not a shop. Until a real price list replaces my fictional rows, this is a demonstration of how to keep an AI honest, not a shop assistant.
That is also why I like this project. Most AI demos show you the answers. This one shows you the leash.