CI/CD ed estrazione strutturata
Modalità headless, output JSON, schemi e cicli di validazione.
CI/CD ed estrazione strutturata è una lezione Claude Architect gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Claude Architect, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Claude Architect include 4 lezioni in totale.
Parti di questa lezione non sono ancora state tradotte e vengono mostrate in inglese.
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.jsonThe 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.jsonBlocking 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 pressureThe 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 jsonfor 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.
Domande Frequenti
La lezione «CI/CD ed estrazione strutturata» è gratuita?
Sì — il testo completo di «CI/CD ed estrazione strutturata» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Claude Architect, passa a CoddyKit PRO. Il corso Claude Architect include 4 lezioni in totale.
Cosa imparerò in «CI/CD ed estrazione strutturata»?
Modalità headless, output JSON, schemi e cicli di validazione. Eserciti Claude Architect con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Claude Architect?
Non è richiesta alcuna esperienza precedente. Claude Architect su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «CI/CD ed estrazione strutturata»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Claude Architect?
Sì. Ogni lezione Claude Architect include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Agente di supporto e ricerca multi-agente
- Generazione del codice e produttività degli sviluppatori
- CI/CD ed estrazione strutturata
- Pattern conversazionali e strumenti agentici