Rubric
Contents — domains, guide and mocks

Validation and retry loops

CCAR-F 4.411 min read · checked 21 September 2026

Task statementImplement validation, retry, and feedback loops for extraction quality

The validate–retry loop

  1. Extractschema-enforced tool call
  2. Validate in codetypes, cross-field and business rules
  3. Return the errorsexact field, value and rule broken
  4. Retry or escalatelimited attempts, then human review

errors fixable from the document → retry with them · otherwise → review queue

Validation happens in code, not in the model’s head. Each retry carries the specific errors, and the loop has a limit and an exit to human review.

Two kinds of error, two kinds of check

Extraction errors come in two families. Syntax and shape errors — unparseable JSON, a missing key, a string where a number belongs — are what schema enforcement removes (see 4.3). Anthropic’s tool-use docs say that strict tool use guarantees inputs match the schema, eliminating missing parameters and type mismatches. Semantic errors survive that guarantee: a total that does not match its line items, a due date copied into the invoice-date field, a start date after the end date, a currency that contradicts the supplier’s country. Only your own validation catches those.

CheckExampleWhere it lives
Shapetotal is a number; po_number present or nullSchema (strict mode)
Range and formatDate parses; quantity is positiveCode — the grammar does not enforce minimum or pattern-style limits
Cross-fieldLine items sum to the total; start ≤ endCode
Reference dataSupplier ID exists; tax rate valid for the countryCode, against your systems
GroundingEach value appears in the source textCode, using a quoted source_text field

The last row is a design choice worth copying. If the schema asks for a short quote from the document alongside each important value, your validator can check that the quote actually appears in the source and that the value appears in the quote. Anthropic’s hallucination guidance recommends grounding answers in direct quotes and retracting claims without supporting evidence; a source_text field turns that advice into something code can test.

Retry with the errors, not just again

When validation fails, the useful retry sends three things back: the original document, the extraction that failed, and a precise description of what was wrong. With tool-based extraction this fits the tool-use protocol naturally. Append Claude’s turn, then a tool_result with is_error: true whose content lists the failures. The docs describe exactly this behaviour for invalid tool calls: given an error, Claude retries with corrections — and they advise writing instructive errors that say what went wrong and what to try next, rather than a bare “failed”.

Semantic validation fed back as a tool errorpython
def validate(inv: dict) -> list[str]:
    errors = []
    items = sum(line["amount"] for line in inv["line_items"])
    if abs(items - inv["total"]) > 0.01:
        errors.append(f"line_items sum to {items:.2f} but total is "
                      f"{inv['total']:.2f}; check for missed lines or discounts.")
    if date.fromisoformat(inv["invoice_date"]) > date.today():
        errors.append("invoice_date is in the future; you may have used the due date.")
    return errors

def extract(document: str) -> dict:
    messages = [{"role": "user", "content": document}]
    for attempt in range(3):                                  # bounded
        resp = client.messages.create(model=MODEL, max_tokens=2048, messages=messages,
            tools=[record_invoice], tool_choice={"type": "tool", "name": "record_invoice"})
        call = next(b for b in resp.content if b.type == "tool_use")
        errors = validate(call.input)
        if not errors:
            return call.input
        messages += [{"role": "assistant", "content": resp.content},
                     {"role": "user", "content": [{"type": "tool_result",
                         "tool_use_id": call.id, "is_error": True,
                         "content": "\n".join(errors)}]}]
    return send_to_review(document, call.input, errors)       # never loop forever

A retry with error feedback

Your code
Claude API
Review queue
Step 1: Your code to Claude API: Document + forced extraction tool
Step 2: Claude API to Your code: tool_use: total 450.00
Step 3: Your code : Items sum to 412.00 — fail
Step 4: Your code to Claude API: tool_result, is_error: the mismatch
Step 5: Claude API to Your code: tool_use: total 412.00, discount noted
Step 6: Your code : Validation passes
Step 7: Your code to Review queue: Only if attempts run out
The second request carries the failed attempt and the precise error. The model corrects the one thing that was wrong instead of re-extracting blind.

If you build on the Agent SDK, part of this loop comes built in: when you set output_format (Python) or outputFormat (TypeScript), the SDK validates the final output against your schema and re-prompts on a mismatch. If no valid output emerges within its retry limit, the result’s subtype is error_max_structured_output_retries. The docs also note that a result can say success yet carry no structured_output, and that you should treat that as a failure too. Your semantic checks still sit on top.

When retrying cannot help

Retries fix errors of reading: a value put in the wrong field, a line missed, a format slip. They cannot fix errors of absence. If a CV never states a graduation year, or a scanned page is illegible, asking again only invites the model to guess — and a guess that passes validation is worse than a visible gap. Before retrying, ask whether the correct answer is actually in the input.

Validation failed — what now?

Why did it fail?
  • Misread; answer is in the text
    Retry with the errors
  • Value is not in the source
    Accept null, no retry
  • Source is ambiguous or conflicting
    Flag for human review
  • Same failure across many docs
    Fix prompt or schema

Feedback loops beyond a single document

The per-document retry is the inner loop. The outer loop is what you learn across thousands of documents. Log every validation failure with its rule, field and document type. When one rule fails far more than the others — say, dates on invoices from one country — that is not a retry problem; it is a prompt, example or schema problem. Fix it at the source with a clearer criterion (4.1), a targeted example (4.2) or a schema change (4.3), then re-run your test set.

The same logs tell you where to point human review. Anthropic’s prompting guide describes the common self-correction chain — draft, review against criteria, refine — as separate calls so each step can be logged and evaluated. Whether a reviewer is a person or a second model instance, it should see the validator’s findings, not start from scratch. How to calibrate confidence and sample outputs for human review is covered in 5.5; multi-pass review architectures are covered in 4.6.

Traps the wrong answers are built from

Tempting but wrongDo this instead
Retrying with the identical request after a failureSend back the failed output and the specific validation errors.
Unbounded retry loopsCap attempts, then route to human review with the errors attached.
Retrying because a field is empty when the source lacks itAccept null for absent data; retry only fixable misreads.
Trusting schema-valid output without semantic checksValidate cross-field and business rules in code.
Fixing the same failure document by documentAggregate failures by rule and fix the prompt, examples or schema.

You should now be able to

  • Separate schema-level errors from semantic errors and put each check in the right layer.
  • Implement a bounded retry that returns specific validation errors via tool_result with is_error.
  • Decide between retrying, accepting null and escalating for a given validation failure.
  • Add self-checking fields such as stated versus calculated totals, conflict flags and source quotes.
  • Use aggregated validation failures to improve the prompt, examples or schema.

Practice questions

Original questions written for this lesson, in the exam’s style. Answer first, then open the reasoning — every option is explained, including why the wrong ones are tempting.

  1. Question 1

    A shipping company’s extraction pipeline validates each bill of lading. When the container count does not match the listed containers, it resends the same request, up to three times. Most failing documents fail all three attempts.

    What change will most improve the retry success rate?

    1. ARaise the retry limit from three attempts to ten.
    2. BSend the failed output and the exact mismatch with the retry.
    3. CSwitch the retry to a different, larger model.
    4. DRemove the container-count check to stop the failures.
    Show answer and reasoning
    1. AIncorrect. An identical request tends to produce the same reading; more attempts mostly add cost.
    2. BCorrect. Specific error feedback tells the model what to re-examine, so it corrects the misread instead of repeating it.
    3. CIncorrect. It might help occasionally, but it still gives no information about what went wrong.
    4. DIncorrect. That hides real extraction errors from downstream systems.
  2. Question 2

    An HR system extracts employee start dates from signed offer letters. Some older letters were signed without a stated start date. The validator rejects records without a date and triggers a retry.

    How should the pipeline treat these letters?

    1. AKeep retrying until a date is produced, up to a limit.
    2. BFill in the signature date as a default start date.
    3. CTell the model to infer the most likely start date.
    4. DAllow null for a missing start date and route it to HR to confirm.
    Show answer and reasoning
    1. AIncorrect. The date is not in the document, so retries pressure the model to invent one.
    2. BIncorrect. That writes a guess into the record as if it were fact.
    3. CIncorrect. Inference presented as extraction is fabrication by another name.
    4. DCorrect. Absent information cannot be retried into existence; a visible null plus a human follow-up is honest and actionable.
  3. Question 3

    A bank extracts loan applications with a strict extraction tool, so every response matches the schema. Auditors find cases where monthly income exceeds annual income, and where the applicant’s name was taken from the referee section.

    Which two measures address these errors? (Select 2.)

    1. AAdd code checks for cross-field rules such as annual ≥ 12 × monthly income.
    2. BAdd a source_text field per key value and verify it appears in the relevant section.
    3. CTurn strict mode off so the model has more freedom.
    4. DAsk the model to confirm that it is confident in each value.
    5. ERetry every application twice and keep the most common answer.
    Show answer and reasoning
    1. ACorrect. These are semantic errors that a schema cannot express; code can check them on every record.
    2. BCorrect. Grounding each value in a quoted passage lets code catch values taken from the wrong part of the document.
    3. CIncorrect. Strict mode is not causing these errors, and removing it reintroduces shape errors.
    4. DIncorrect. Self-reported confidence is not a check; the model can be confidently wrong.
    5. EIncorrect. Repetition without feedback tends to reproduce the same misreading and multiplies cost.
  4. Question 4

    An Agent SDK run with output_format set ends with subtype error_max_structured_output_retries. What does this mean?

    1. AThe agent used up its turn limit while calling tools.
    2. BNo schema-valid output was produced within the retry limit.
    3. CThe schema itself was invalid, so it was ignored.
    4. DThe output is valid but exceeded max_tokens.
    Show answer and reasoning
    1. AIncorrect. Turn exhaustion is a different subtype; this one is about the structured output.
    2. BCorrect. The SDK validates against the schema and re-prompts on mismatch; this subtype means it never got a valid result.
    3. CIncorrect. Current docs say an invalid schema fails the run at startup with an error naming the problem.
    4. DIncorrect. Truncation is reported through the stop reason, not this result subtype.

Sources

Drafted with AI assistance and checked against the sources above; expert review is in progress. Spotted an error? Tell us and it gets fixed, dated and listed on how this is written.