← All work

Auction intake agent

Turns a receiving clerk's data entry into a written, priced, and bundled auction lot.

Role
ML engineer, two on the project
Year
2025
Status
archived
Built with
Python, FastAPI, OpenAI GPT, LangChain
Context
GoPrime Systems, production auction platform

Built for an employer and since retired, so there is nothing to open. This is written from memory rather than from source, and it is deliberately thinner on implementation detail than the rest of these.

An auction house receiving a pallet of items has a bottleneck that is entirely human. Someone has to look at each item, work out what it is, write a title and a description that will make someone bid on it, decide what it is worth, and decide which other items it should be sold alongside.

That is slow, and most of it is the same judgement made repeatedly. So the pipeline started where the physical work ended: a clerk recorded what had arrived, and everything downstream was automated.

The chain

A language model wrote the title and description from the recorded attributes, and produced a first-pass price. That item then went to the trained pricing model for the actual valuation, and finally into a bundling step that grouped it with similar items into a lot worth putting in front of bidders. LangChain held the sequence together over a tool server exposing each capability as something callable.

The lot bundling is the part that made the rest worth doing. Individually low-value items are not worth the handling cost of a separate listing, so the economics depend on grouping them well, and grouping them well depends on having a reliable value for each one first.

Two kinds of pricing, and only one of them survived

Both the language model and the trained model could produce a price, and they are not the same object.

The language model produces a plausible number. It has read a great deal about what things cost, it will give you a figure for anything, and it has no way of telling you when it is guessing. The trained model produces a calibrated number, fitted to what this auction house’s own items actually sold for, and it knows the difference between a familiar category and one it has barely seen.

For copy, plausible is exactly what you want. For money, it is not. So the generated price was only ever a first pass and the trained model was the answer.

That model is still running in production today. The agent around it is not.

Why it was dropped

Not because it broke. The client stopped using it, temporarily at first and then permanently, because the team preferred having full manual control of intake.

I have thought about that more than about anything I built here. The pipeline took a set of decisions that belonged to experienced people and moved them somewhere those people could not see into or easily override. Each individual output was defensible. The arrangement was not, because it asked them to accept an outcome rather than to make a judgement faster.

There is a version of the technical argument where they were wrong and it would have paid for itself. That version does not matter. Automation that its users switch off has failed, and the reason it failed is a design fact about the system rather than a preference on their side.

What I would build instead

The same components, with the authority the other way round.

Every piece of that pipeline is genuinely useful as a draft. A receiving screen that opens pre-filled with a generated title, a generated description, a suggested price with the model’s confidence attached, and a proposed lot to add it to, where every field is editable and nothing is committed until a person commits it, does almost all of the same work. It removes the typing and the recall, which is where the time actually goes, and it leaves the judgement with the people whose judgement it was.

It would also have produced the thing the fully automated version never did: a record of every correction a human made, which is training data for the next version and an honest measure of how good the outputs really were.

I would take the same view now on anything that replaces expert judgement rather than accelerating it. The pricing model survived precisely because it never tried to be the decision. It hands over a number and a confidence, and somebody else decides.