🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.🚧 Designers never finish their own portfolio. This one ships rough on purpose and gets better in public. If something looks half-done, it probably is, and I'm on it.
Open menu
Switch to Darkhello@product.inc

Constrain the call, don't filter the output

Tags: prompting, guardrails, cost

When the same kind of bad output keeps coming back, the usual response is a check afterwards: detect it, throw it away, try again. That treats a known, recurring failure as though it were a surprise β€” and pays full price for every instance of it.

A filter is a toll on failures you already know about

Follow one bad output through a filter-and-retry design. It is generated, which costs money and time. It is inspected, which costs more. It is discarded. The call is made again, at full cost, with the same inputs β€” which means there is a good chance it fails the same way.

For a genuinely novel failure, that is a reasonable price. You could not have predicted it, so catching it downstream is the only option.

For a failure you have seen a hundred times, it is a strange arrangement. You know what goes wrong, you know how often, and you are choosing to generate it and then pay to notice.

Filters leak, and the leak is confident

There is a second cost, and it is worse than the first.

No filter catches everything. The bad output that slips through is not marked as having slipped through β€” it arrives in the interface looking exactly like every output that passed. The filter's existence makes this worse rather than better, because everyone downstream assumes checked output is good output.

Constraining the call does not eliminate that risk either. But it lowers the rate at which bad outputs are produced, which lowers the rate at which they leak β€” and it does it without a per-failure cost.

Put known failures upstream

Rendering diagram…

The mechanisms depend on the kind of generation:

Keep a check downstream as well β€” for the failures you did not predict. The distinction that matters is not filter or no filter; it is whether each failure you handle is known and recurring, which belongs upstream, or novel, which is what a downstream check is genuinely for.

Grounded in

Pathfinder is a character builder whose portraits restyle every time you change equipment, and image models fail at portraits in a small number of very predictable ways.

So the generation carried targeted negative prompts aimed at exactly those: no extra fingers, no melted weapons, no armour when a slot is unequipped. None of those is a surprise worth detecting after rendering. They are the known, recurring failures of the medium β€” so they were excluded in the request rather than generated, caught, and re-rolled at full cost each time.

Anti-patterns

The smallest version worth building

Pull the last hundred outputs your filter rejected. Group them by reason. Every group that accounts for more than a few percent is a known failure β€” move each of those into the request as a constraint, and leave the filter for the long tail.

The retry rate usually falls sharply, and the cost falls with it.