Bangladesh Post Office · Foreign Remittance

Form M.O. 7(a) · AI bench · series 2026

Amount in Words. (must match figures)

Stop typing tokens, start typing schemas.

Instructions to Clerk

Most agentic codebases treat the model's output as a string to parse. The clerk at counter no. 3 of Gulshan post office knows better. Schemas are the form, and tokens that don't match the form go nowhere.

SenderS. Eshpel
From P.O.Gulshan, Dhaka 1212
Amount (figures)৳ 24,800.00
CurrencyBDT
BeneficiaryThe Reader

Postmaster's Stamp

(pending)

Sender's Signature

S. Eshpel

counter no. 3 · clerk on duty
gulshan p.o. · 11 may 2026
fill in the form

I work counter no. 3 at the Gulshan post office, on the foreign remittance side, where the queue starts at half past nine. My name is M. Hossain, and I have been validating money order forms since 1998. Some customers put the postal code in the amount line, others write the recipient's name where the currency code belongs, and one customer last March misspelled BDT three different ways on the same sheet before he gave up and asked me to write it for him. My job, before any cash leaves the drawer or the wire goes out to a counter in Sydney or Sharjah, is to look at the money order form and read each field against the rules printed on the back. Then I either stamp APPROVED, or I hand the form back with a green tick mark next to the line that needs fixing.

Lately a young man from an AI startup in Banani DOHS comes in on Thursdays to send a small amount to his sister in Toronto. While I check his form, he has taken to telling me that the system he is building at work has the same problem I do, which is his phrase and not mine. His model writes something, his code reads the string, and half the time the string is shaped almost like what he asked for, except the postal code is in the amount line and the currency is missing entirely. He calls it parsing, and I call it counter no. 3 on a Tuesday morning when the new customer at the front cannot read English.

The fix in his world has a name, and it has been sitting in the Zod documentation for about five years. Stop trying to parse the model's output as a string. Define the form first, then hand it to the model and demand it back, and only then validate every field against its rule before any downstream code is allowed to touch a single value. The discipline is the same one I bring to the queue at Gulshan. The form is the schema, and cash that does not match the form goes nowhere.

Most teams I hear about, through the young man and the others who wait with him on Thursdays, write code that looks roughly the same shape before they discover Zod. The model returns a blob of text, the code calls JSON.parse on it, and the code hopes. If the model has hallucinated a comma where there should have been a colon, the code crashes three files away. The bug report comes back two days later from a regulated insurance customer staring at a stack trace where his quote should have been. The whole thing reads, to me, like sending a money order out because the envelope feels heavy enough in the hand. The validation was always meant to be the form inside, with its fields stamped and signatures legible to a clerk at counter no. 3.

Field 7. The clause

A schema is the gatekeeper that decides whether the model's output is allowed to count as output at all, which makes it more useful than the kind of documentation that sits in a sibling file and quietly drifts out of date over the course of a quarter.

The library most people reach for in TypeScript is Zod, whose release notes have had the quiet reliability of a Pran bottle rolling off the shelf for years, and it is now the default schema layer in almost every agent codebase the young man brings up. You define a z.object with the fields you expect, each with a type and sometimes a regex or an enum of allowed values. Then schema.parse(raw) either returns a typed object or throws a structured error pointing at exactly which field failed and why. The TypeScript compiler infers the output type from the schema itself, which means downstream code knows parsed.amount is a number without anyone having to write a single as cast. The autocomplete works on the model's brain.

What changed in 2024 and 2025 is that the model providers caught up. OpenAI shipped Structured Outputs for the chat completions endpoint, which lets you pass a JSON schema along with the request, and the model is guaranteed at the decoding step to produce output that satisfies the schema. The guarantee is mechanical. The tokens that would violate the schema are masked out before sampling, and there is no probability left over for the model to fill the form in wrong. Anthropic shipped the equivalent shape through tool use, where each tool definition carries a JSON schema for its input, and the model is constrained to produce an object for the tool call that matches. The same idea, two API surfaces, both shipped in the same year. The clerk now has a stamp that physically cannot print the wrong thing.

The way I think about the difference is the queue at counter no. 3 on a Tuesday morning. Before structured outputs, the young man would send a request, get a string back, and try to parse it. If parsing failed, he would send the same request again with a more emphatic prompt asking the model please to return valid JSON and to put the postal code in the right field this time. Three tries on a calm morning, five on a bad one. Each try cost money and a second of the customer's morning. The retry was the cost of not having validated the form before the model started writing. With a typed schema as the contract, the form is filled in correctly on the first attempt, or the model returns a refusal you can route to a human. There is no third option where the form looks right and is silently wrong.

There is an effect one step removed that the documentation tends not to spell out. Schemas become a shared vocabulary across the codebase. When the Zod schema for a money order says currency: z.enum(["BDT", "USD", "GBP", "AED"]), the four allowed currencies are now a fact the rest of the system can rely on. The UI dropdown, the database migration, and the Slack notification that pings the compliance team all read from that same enum. Add a fifth currency next quarter, and the type errors cascade through the codebase telling you exactly which files need to be touched. The young man's engineering lead, who is older than me and grumpier, calls this "the file is the only person in the room who remembers," which is roughly the rule I would write on the back of the form if there were room.

Where this all breaks down is when the team treats the schema as decoration rather than as the contract. The schema sits next to the prompt in a file called types.ts and nobody actually wires it into the request. The validation runs after the response comes back, which catches the worst failures but does nothing about the silent ones. The cure is to insist that the schema is passed to the provider in the structured output mode, so the constraint is enforced at decode time and not after. The cure, in queue terms, is to look at the form before the customer hands it across the counter, not after he has walked away with the carbon copy in his pocket.

The young man came in last Thursday with a clean form for the first time in months. Every field was where it should be. The currency was BDT in three clean capital letters, and the purpose box was ticked as "family." He had finally rewritten his pipeline around a Zod schema he hands to both Claude and to his Postgres migration, with the structured output flag set on the API call. I stamped APPROVED with the green pad and slid the carbon copy across, the way I have done about forty thousand times since 1998. He took it and walked out without saying anything, which is the highest compliment a customer at counter no. 3 ever pays.