0Pricing
Claude Architect · 课时

必填字段与可选/可为空字段

绝不要要求可能缺失的字段。

必填字段与可选/可为空字段 是 CoddyKit 上的免费 Claude Architect 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Claude Architect 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Claude Architect 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

The Core Rule

Structured output with tool_use and a JSON Schema eliminates syntax errors and lets you enforce required fields. But that power has a sharp edge.

The exam-critical rule for this lesson: mark a field required only if it is always present. Never require a field that may be absent.

Why? When a field is required, the model must emit a value for it. If the source data doesn't actually contain that value, the model has no choice but to fabricate one to satisfy the schema. A required field is a promise the model will keep even when it shouldn't.

Why Required Forces Fabrication

A JSON Schema's required array is a hard constraint, not a hint. The model cannot return a structurally valid object while omitting a required key.

Consider extracting a customer's phone_number from a support email that never mentions a phone number. If phone_number is required, the model must produce something — and a plausible-looking but invented number is worse than no number at all, because nothing downstream can tell it apart from a real one.

The fix is structural: make optional fields optional, so the model can legitimately leave them out when the information is absent.

A Schema That Invites Fabrication

Here is an extraction tool that marks every field as required. The email below has no phone number — yet the schema forces the model to invent one.

This is the anti-pattern. Read required carefully: it lists fields that may genuinely be missing from real inputs.

tool = {
    "name": "extract_contact",
    "description": "Extract contact details from a support email.",
    "input_schema": {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "email": {"type": "string"},
            "phone_number": {"type": "string"},
        },
        # BAD: phone_number is often absent, but it is required here
        "required": ["name", "email", "phone_number"],
    },
}

The Fix: Require Only the Guaranteed

Keep in required only the fields that are always present. Everything that may be absent stays out of required — the model can then omit it honestly.

Notice name and email stay required because every support ticket has them, while phone_number drops out of the list.

tool = {
    "name": "extract_contact",
    "description": "Extract contact details from a support email.",
    "input_schema": {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "email": {"type": "string"},
            "phone_number": {"type": "string"},
        },
        # GOOD: only the always-present fields are required
        "required": ["name", "email"],
    },
}

Optional vs. Nullable: Two Different Tools

There are two ways to let a field be "missing", and they mean different things:

  • Optional — the key is simply omitted from required. The model may leave the key out of the object entirely.
  • Nullable — the key is always present but its type allows null, signalling "this slot was checked and found empty."

Optional answers "did the model report on this field at all?" Nullable answers "the model looked, and the value is explicitly absent." Choose nullable when a downstream consumer needs every key present for a stable shape.

Expressing Nullable in JSON Schema

To make a field nullable, allow null as one of its types. With structured outputs you typically express this with anyOf (a supported keyword) combining the real type and null.

Here phone_number is always emitted as a key, but its value is null when the email contains no number — an honest "empty", not a fabricated digit string.

"phone_number": {
    "anyOf": [
        {"type": "string"},
        {"type": "null"}
    ],
    "description": "Customer phone number, or null if none is stated in the email."
}

Nullable Still Needs an Honest Instruction

A nullable type permits null, but the model still decides when to use it. Make the intent explicit in the field description: tell the model to return null rather than guess.

This pairs the structural guarantee (the type allows null) with a behavioural one (the description says when to use it). The schema defines the shape; the description steers the judgment.

"discount_code": {
    "anyOf": [{"type": "string"}, {"type": "null"}],
    "description": "The promo code the customer mentioned. Return null if no code is present — do not invent or infer one."
}

Enums Plus an 'Other' Escape Hatch

The same fabrication risk appears with enums. If a field must be one of a fixed set of values and the real input doesn't match any of them, a strict enum forces the model to pick the closest wrong answer.

The exam-recommended pattern for extensibility: include an "other" value in the enum plus a free-text detail field. This gives the model an honest place to land when reality exceeds your enum — instead of misclassifying.

"category": {
    "type": "string",
    "enum": ["billing", "technical", "account", "other"]
},
"category_detail": {
    "anyOf": [{"type": "string"}, {"type": "null"}],
    "description": "Free-text description used when category is 'other'; otherwise null."
}

Retry Won't Rescue an Absent Value

When validation fails, retry-with-feedback is powerful — you resend the original document, the model's wrong output, and the exact validation error to fix format, structural, or arithmetic mistakes.

But retry does not help when the information is simply absent from the source. If the phone number isn't in the email, no amount of re-prompting will conjure a correct one. The right design lets the field be absent in the first place — required-and-missing is a schema bug, not a transient error to retry.

Self-Correction Detects, Schema Prevents

For values that should be present and verifiable, a complementary technique is self-correction: extract both a calculated_total and a stated_total so a mismatch surfaces a discrepancy you can catch.

But self-correction detects errors in present data; it cannot validate a field that was never in the source. The first line of defense against fabrication is still the schema itself: don't require what may be absent. Use Pydantic-style validation on the result to enforce these invariants in code.

from pydantic import BaseModel
from typing import Optional

class Invoice(BaseModel):
    invoice_id: str            # always present → required
    po_number: Optional[str]   # may be absent → optional / nullable
    calculated_total: float
    stated_total: float        # compare the two to detect discrepancies

Distinguish Empty From Failure

One more architect-grade distinction: a valid empty result ("the email has no phone number") is not the same as an access failure ("the extraction tool errored").

A nullable field cleanly represents the first case. Don't model a genuine absence as an error to retry, and don't silently suppress a real failure as null. Make the schema say which is which: null for legitimately empty, a separate error path for access failures. Clear, structured signals downstream beat ambiguous ones.

Quick Check: Optional Field Design

Apply the rule to a realistic extraction scenario.

Recap: Never Require the Maybe-Absent

Key takeaways:

  • Require only always-present fields. Requiring a possibly-absent field forces the model to fabricate a value.
  • Optional = key may be omitted; nullable = key always present, value may be null. Pick nullable when consumers need a stable key set.
  • Pair nullable types with a description that says "return null if absent — don't guess."
  • For closed value sets, add an "other" enum value plus a free-text detail field for extensibility.
  • Retry-with-feedback fixes format/structural/arithmetic errors, not absent information. Self-correction detects discrepancies in present data, not missing fields.
  • Keep a valid empty result distinct from an access failure — never silently suppress either.

常见问题解答

「必填字段与可选/可为空字段」课时是免费的吗?

是的 — 「必填字段与可选/可为空字段」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Claude Architect 课程的其余内容,请升级到 CoddyKit PRO。 Claude Architect 课程共包含 4 节课。

「必填字段与可选/可为空字段」这节课中我会学到什么?

绝不要要求可能缺失的字段。 你通过在浏览器中直接运行的动手代码来练习 Claude Architect,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Claude Architect 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Claude Architect 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「必填字段与可选/可为空字段」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Claude Architect 课中编写并运行代码吗?

能。每节 Claude Architect 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用 tool_use 保证结构
  2. 设计 JSON 模式
  3. 必填字段与可选/可为空字段
  4. 使用带有“other”的枚举实现可扩展性
← 返回 Claude Architect