Agent Wranglers

Structured output and tools Required

Retry a bad answer and then fall back

When an answer fails validation, retry at most twice with the validation error added, then use a fallback. Never pass an invalid answer on.

How to do it

Catch the validation error in the gateway. Send the same request again with a short note naming the failed field. After the last retry, return a fallback the feature can handle, such as "unknown", a fixed message or a hand-off to a person. Count failures per prompt version and alert when more than 2 in 100 calls fail, because that points to a prompt or model problem.

Example

const MAX_ATTEMPTS = 3;

export async function generateValid<T>(call: (hint?: string) => Promise<string>, schema: ZodType<T>, fallback: T): Promise<T> {
  let hint: string | undefined;
  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
    const parsed = schema.safeParse(parseJsonOrUndefined(await call(hint)));
    if (parsed.success) return parsed.data;
    hint = `Your last answer was invalid: ${parsed.error.issues.map(i => `${i.path.join('.')} ${i.message}`).join(', ')}`;
  }
  metrics.increment('ai.invalid_output');
  return fallback;
}
MAX_ATTEMPTS = 3

def generate_valid(call: Callable[[str | None], str], schema: type[T], fallback: T) -> T:
    hint = None
    for _ in range(MAX_ATTEMPTS):
        try:
            return schema.model_validate_json(call(hint))
        except ValidationError as error:
            hint = f"Your last answer was invalid: {error.errors(include_input=False)}"
    metrics.increment("ai.invalid_output")
    return fallback

How to check

A unit test with a fake provider returns invalid JSON three times. The gateway makes exactly three calls and returns the fallback. The failure counter shows one failed request.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers ai features playbook: https://agentwranglers.se/playbook/ai-features/structured-output-and-tools/retry-invalid-output.