0Pricing
Claude Architect · Lección

CI/CD y extracción estructurada

Modo headless, salida JSON, esquemas y bucles de validación.

CI/CD y extracción estructurada es una lección gratuita de Claude Architect en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Claude Architect, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Claude Architect incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

Two Scenarios, One Theme

This lesson fuses two exam scenarios that share a single backbone: determinism under automation. Scenario 5 (Claude Code for CI/CD) and Scenario 6 (Structured Data Extraction) both ask the same question — how do you get machine-parseable, trustworthy output with no human in the loop?

The answer is the same in both worlds:

  • Headless / non-interactive execution so a pipeline can drive Claude.
  • JSON output with a schema so downstream code can parse results.
  • Validation loops that catch and repair structural errors before they propagate.

Master this and you cover a meaningful slice of D3 (Config & Workflows) and D4 (Structured Output) — together 40% of the exam.

Headless Mode in CI/CD

A pipeline has no TTY and no human to answer prompts. Claude Code must run non-interactively. The flag for this is -p (also written --print): it runs a single prompt, prints the result, and exits.

Pair it with --output-format json so the pipeline gets a structured envelope instead of free prose. Without these two flags, the command hangs waiting for interactive input and the build stalls.

  • -p / --print = non-interactive, required in pipelines.
  • --output-format json = parseable result (optionally with a schema).
# Headless review step in a CI job
claude -p "Review the staged diff for correctness bugs only. \
  Flag a comment ONLY when it contradicts the code." \
  --output-format json \
  > review.json

# Pipeline now parses review.json deterministically
jq '.result' review.json

The Isolated Review Session

A subtle but heavily-tested rule: in CI, review code in an ISOLATED session, separate from the session that generated it.

Why? The generating session retains its own reasoning and is biased toward defending its work — same-session self-review is a top anti-pattern. A fresh, independent instance has no attachment to the output and challenges it honestly.

This mirrors the extraction-world rule that independent/fresh-instance review beats same-session self-review. The author won't fight its own conclusions; a clean reviewer will.

Minimizing False Positives

A CI reviewer that cries wolf gets ignored. The goal in Scenario 5 is to minimize false positives so developers trust the gate.

The lever is explicit criteria, not vague pleas. "Be more precise" changes nothing. "Flag a comment ONLY when it contradicts the code" gives the model a sharp, testable boundary.

On re-runs, don't re-litigate everything: include the prior results and report only new or still-unfixed issues. This keeps the signal clean across iterations.

claude -p "You are reviewing a re-run. Here are the prior findings:
$(cat prev_findings.json)

Report ONLY issues that are new or remain unfixed.
Flag a defect ONLY when the code's behavior contradicts its stated intent.
Ignore style and subjective preferences." \
  --output-format json > findings.json

Blocking Checks vs the Batch API

A classic distractor: "use the Batch API to cut CI costs by 50%". Wrong for a pre-merge gate.

Message Batches are 50% cheaper with up to a 24h window, but they have NO latency SLA and do NOT support multi-turn tool calling. A blocking, time-sensitive check (like a PR gate) cannot wait an unbounded amount of time.

  • Use Batch for non-blocking work: overnight reports, large audits, nightly extraction runs.
  • Do NOT use Batch for pre-merge / blocking / interactive checks.

For batch jobs, custom_id correlates each request to its result, and you re-submit only the failures.

Structured Output: Tool Use + JSON Schema

Now Scenario 6. To extract data reliably, do not ask for JSON in prose and hope. Use tool_use with a JSON Schema: this eliminates syntax errors and enforces required fields.

Set tool_choice to "any" to guarantee the model calls a tool (i.e. produces structured output) rather than free text. Use {"type":"tool","name":"X"} to force one specific extraction tool.

extract_tool = {
    "name": "extract_invoice",
    "description": "Extract structured fields from an invoice document.",
    "input_schema": {
        "type": "object",
        "properties": {
            "invoice_number": {"type": "string"},
            "line_items": {"type": "array", "items": {"type": "object"}},
            "stated_total": {"type": "number"},
        },
        "required": ["invoice_number"],
    },
}

resp = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=[extract_tool],
    tool_choice={"type": "any"},  # MUST call a tool -> structured output
    messages=[{"role": "user", "content": document_text}],
)

Required Fields: The Fabrication Trap

The single most-tested schema rule: mark a field required ONLY if it is always present in the source.

If you require a field that may be absent, the model has no legal way to satisfy the schema except to fabricate a value. You traded a missing field for a hallucinated one — far worse for a data pipeline.

For optional or open-ended values, prefer an enum with an "other" value plus a free-text detail field. This keeps the output structured while staying extensible for cases you didn't enumerate.

"document_type": {
    "type": "string",
    "enum": ["invoice", "receipt", "purchase_order", "other"]
},
"document_type_detail": {
    "type": "string",
    "description": "Free text. Required only when document_type is 'other'."
}
# 'required' lists ONLY fields guaranteed to appear -> no fabrication pressure

The Validation / Retry Loop

A schema constrains shape, not correctness. Wrap extraction in a validation loop (Pydantic-style validation is the canonical pattern).

When validation fails, use retry-with-feedback: send the model three things together — the original document, the wrong output it produced, and the exact validation error. This is precise enough to fix format, structural, and arithmetic mistakes.

Critical boundary: retry fixes FORMAT errors. It does NOT help when the information is simply ABSENT from the source — re-asking a document for data it never contained just invites a fabricated answer.

from pydantic import BaseModel, ValidationError

def extract_with_retry(doc, max_attempts=2):
    history = [{"role": "user", "content": doc}]
    for _ in range(max_attempts):  # cap = safety net, not primary stop
        out = call_extractor(history)
        try:
            return InvoiceModel.model_validate(out)
        except ValidationError as e:
            history.append({"role": "assistant", "content": str(out)})
            history.append({"role": "user", "content":
                f"Validation failed: {e}. Re-extract from the SAME document. "
                f"If a field is not present in the source, omit it; do not invent it."})
    raise ExtractionError("unresolved after retries")

Self-Correction: Detecting Discrepancies

How do you catch a wrong arithmetic value the schema happily accepted? Build the check into the extraction itself.

The pattern: extract both the calculated_total (sum the line items) and the stated_total (the figure printed on the document). Then compare them in code.

If they diverge, you've detected a discrepancy deterministically — either a document error or an extraction error — and can flag, retry, or escalate. One number can lie silently; two numbers expose the lie.

# Schema asks for BOTH so code can self-correct
"calculated_total": {"type": "number",
    "description": "Sum of all line_items, computed by you."},
"stated_total": {"type": "number",
    "description": "The total figure printed on the document."}

# Downstream deterministic check
if abs(result.calculated_total - result.stated_total) > 0.01:
    flag_for_review(result, reason="total mismatch")

Provenance: Claim to Source

Extraction without provenance is unauditable. For every extracted claim, keep a claim-to-source mapping: the source document name or URL, the supporting quote, and the publication date.

When two sources give conflicting figures, do not arbitrarily pick one — annotate the conflict. Often the dates resolve the apparent contradiction (one figure is simply newer).

And render by content type: tables for financials, prose for narrative, lists for technical findings. Provenance plus correct rendering is what makes the output trustworthy enough to automate on.

"fields": [{
    "name": "annual_revenue",
    "value": "4.2B USD",
    "source_doc": "FY24-10K.pdf",
    "quote": "Total revenue was $4.2 billion in fiscal 2024.",
    "published": "2024-03-01"
}]
# Conflicting value from an older filing? Annotate, don't overwrite.

Metrics: Aggregate Accuracy Lies

Before you let an extraction pipeline run unattended, validate it honestly. A headline like "97% accurate" can hide poor performance on one specific document type or one field.

The disciplined approach:

  • Stratified random sampling across document types — not a convenience sample.
  • Field-level confidence, calibrated on a labeled validation set, before automating.

Aggregate-only metrics are a known anti-pattern. A 97% average with 40% accuracy on tax forms is a production incident waiting to happen.

Exam Scenario: The Pre-Merge Gate

Apply the full picture to a realistic exam decision.

Recap: Deterministic Output Under Automation

Key takeaways for CI/CD and structured extraction:

  • Headless: -p / --print + --output-format json for non-interactive, parseable pipeline runs.
  • Isolated review beats same-session self-review; explicit criteria minimize false positives; on re-runs report only new/unfixed issues.
  • Batch API = 50% cheaper, no latency SLA, no multi-turn tools — for overnight jobs, NEVER blocking checks.
  • Structured output: tool_use + JSON Schema; tool_choice:"any" guarantees a structured call.
  • Required only if always present — requiring an absent field forces fabrication; use enum + 'other' + detail for extensibility.
  • Retry-with-feedback (original doc + wrong output + exact error) fixes FORMAT errors, not ABSENT data.
  • Self-correct with calculated vs stated totals; keep provenance (source, quote, date) and annotate conflicts.
  • Validate with stratified sampling + field-level confidence — aggregate accuracy hides weak spots.

Preguntas frecuentes

¿La lección «CI/CD y extracción estructurada» es gratis?

Sí — el texto completo de «CI/CD y extracción estructurada» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Claude Architect, actualiza a CoddyKit PRO. El curso de Claude Architect incluye 4 lecciones en total.

¿Qué aprenderé en «CI/CD y extracción estructurada»?

Modo headless, salida JSON, esquemas y bucles de validación. Practicas Claude Architect con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Claude Architect?

No se requiere experiencia previa. Claude Architect en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «CI/CD y extracción estructurada»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Claude Architect?

Sí. Cada lección de Claude Architect incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Agente de soporte e investigación multiagente
  2. Generación de código y productividad del desarrollador
  3. CI/CD y extracción estructurada
  4. Patrones conversacionales y herramientas agentic
← Volver a Claude Architect