Dokumentation

Fortgeschritten: Struktur

Anweisungen, Choice-Optionen, Score-Stufen und Noul-criteria akzeptieren alle JSON-Struktur.

System One-Modelle sind darauf trainiert, Struktur zu verstehen.

Wo Struktur erlaubt ist

Jedes dieser Felder ist ein EntryType.

Feld Gilt für Akzeptierte Form
instructions Choice, Score, Noul string, object, array oder null
criteria-Werte (Optionsbeschreibungen) Choice string, object, array oder null
criteria-Einträge (Stufenbeschreibungen) Score string, object, array oder null
criteria.true und criteria.false Noul string, object, array oder null

Wann du eine Frage strukturierst

  • Wenn es der Klarheit hilft. Wenn eine Frage mehrere Teile hat, hilft es der Klarheit, sie in Form von JSON abzulegen, weil die Schlüssel benannt sind.
  • Wenn die Frage stützende Daten braucht. Ein Schema, eine Taxonomie oder eine Datenbankzeile sind bereits JSON. Verwende das JSON ganz oder übergib die relevanten Teilfelder, statt sie in eine Zeichenkettenvorlage zu serialisieren.

Strukturierte Anweisungen

Ein field-Objekt beschreibt das geprüfte Feld, und jede Frage bezieht sich per Schlüssel darauf. Dieselbe Form steuert einen Noul, der einen Wert verifiziert, einen Choice, der einen aus Kandidaten auswählt, und zwei Score, die einen Wert auf einer Skala einordnen.

request
{
  "state": {
    "source_text": "Invoice #4471 issued March 3, 2026 to Beaver Dam Logistics for $12,840.00, net 30."
  },
  "questions": {
    "invoice_number_is_correct": {
      "type": "noul",
      "instructions": {
        "field": {
          "name": "invoice_number",
          "type": "string",
          "description": "The identifier printed on the invoice."
        },
        "extracted_value": "4471",
        "question": "Does `extracted_value` match the `field` as it appears in `source_text`?"
      }
    },
    "customer_name": {
      "type": "choice",
      "instructions": {
        "field": {
          "name": "customer_name",
          "type": "string",
          "description": "The organization the invoice was issued to."
        },
        "question": "Which option is the value of `field` in `source_text`?"
      },
      "criteria": {
        "Beaver Logistics": null,
        "Dam Logistics": null,
        "Beaver Dam Logistics": null,
        "Beaver": null,
        "Dam": null
      }
    },
    "amount_due": {
      "type": "score",
      "instructions": {
        "field": {
          "name": "amount_due",
          "type": "number",
          "unit": "USD",
          "description": "The total the invoice asks to be paid."
        },
        "question": "How large is the `field` value in `source_text`?"
      },
      "criteria": [
        "Under $1,000",
        "$1,000 to $10,000",
        "$10,000 to $100,000",
        "$100,000 to $1,000,000",
        "Over $1,000,000"
      ]
    },
    "payment_terms": {
      "type": "score",
      "instructions": {
        "field": {
          "name": "payment_terms",
          "type": "integer",
          "unit": "days",
          "description": "Days allowed for payment, from terms such as \"net 30\"."
        },
        "question": "How many days does the `field` in `source_text` allow for payment?"
      },
      "criteria": [
        "Due on receipt",
        "Net 10",
        "Net 30",
        "Net 60",
        "Net 90"
      ]
    }
  }
}

Im Code könntest du über die möglichen Datensätze iterieren und pro Feld eine dieser Fragen bauen, alle in einem einzigen Aufruf gesendet. Das SDE-Cascade-Cookbook macht etwas Ähnliches.

Arrays funktionieren ebenfalls. Verwende eines, wenn die Anweisung eine Liste von Dingen ist, die geprüft oder verglichen werden sollen:

"instructions": {
  "question": "Does the claimed sender identity conflict with the sending domain?",
  "compare": ["ticket.sender.display_name", "ticket.sender.email"],
  "focus": "Compare the named organization with the email domain."
}

Strukturierte Choice-Optionen

Eine Choice-Optionsbeschreibung kann ebenfalls ein strukturiertes Objekt sein.

JSON-Rubrik zur Grenzklärung

request
{
  "state": "I ordered the standing desk two weeks ago and tracking still says label created. Was I even charged?",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": {
        "question": "Which team should handle this message?",
        "focus": "Classify the customer's primary request, not every topic mentioned."
      },
      "criteria": {
        "billing": {
          "what": "Charges, invoices, refunds, or subscriptions",
          "not_for": "Order tracking or account access",
          "examples": [
            "I was charged twice",
            "Where is my refund?"
          ]
        },
        "orders": {
          "what": "Order status, delivery, cancellation, or returns",
          "not_for": "Charges or account access",
          "examples": [
            "Where is my package?",
            "Cancel my order"
          ]
        },
        "account": {
          "what": "Login, password, profile, or security",
          "not_for": "Charges or delivery",
          "examples": [
            "I can't log in",
            "Change my email"
          ]
        }
      }
    }
  }
}

Das Beispiel sagt dem Modell, was jede Option abdeckt und was nicht. Es schärft die Grenze zwischen den Optionen.

Eine Taxonomie durchlaufen

Um in eine tiefe Taxonomie zu klassifizieren, stelle einen Choice pro Ebene und durchlaufe den Baum im Code. Bei jedem Schritt sind die Optionen die Kinder des aktuellen Knotens, und der Wert jeder Option ist der Baum des Kindes. So sieht das Modell, was unter einem Zweig liegt, bevor es sich darauf festlegt — das ist wichtig, wenn das Element zu einem Blatt gehört, dessen Name sich nicht schon aus dem Zweignamen erschließt.

Hier ist der Zustand ein Produktangebot und die erste Frage wählt eine Abteilung auf oberster Ebene.

request
{
  "state": "32oz plastic bottle with a flip straw lid. Fits most bike cages.",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which top-level department does this product belong to?",
      "criteria": {
        "Sporting Goods": {
          "Cycling": [
            "Bike Bottles & Cages",
            "Bike Lights",
            "Helmets"
          ],
          "Fitness": [
            "Yoga Mats",
            "Resistance Bands"
          ],
          "Outdoor": [
            "Tents",
            "Sleeping Bags",
            "Hydration Packs"
          ]
        },
        "Home & Kitchen": {
          "Drinkware": [
            "Water Bottles",
            "Travel Mugs",
            "Tumblers"
          ],
          "Cookware": [
            "Pots & Pans",
            "Bakeware"
          ]
        },
        "Baby & Toddler": [
          "Sippy Cups",
          "Bottle Warmers",
          "Bibs"
        ]
      }
    }
  }
}

Die Flasche passt plausibel unter zwei Abteilungen. Die Unterbäume zu zeigen, lässt das Modell sehen, dass sowohl Sporting Goods > Cycling > Bike Bottles & Cages als auch Home & Kitchen > Drinkware > Water Bottles existieren, und die Betonung des Angebots auf Fahrradhalterungen gegen den alltäglichen Trinkbedarf abzuwägen. Die probabilities dieser Antwort sagen dir, ob die Aufteilung nah genug ist, um beide Zweige zu erkunden.

Sobald eine Abteilung gewählt ist, stelle den nächsten Choice mit den Kindern dieser Abteilung als Optionen und ihren Unterbäumen als Werten und wiederhole das, bis du ein Blatt erreichst. Im Code könnte das eine Schleife über ein verschachteltes dict sein, wobei die criteria jeder Frage einfach der aktuelle Knoten sind. Das Cookbook zur hierarchischen Klassifikation zeigt ein Beispiel für einen ähnlichen Durchlauf des Baums, einschließlich einer Beam-Suche, die mehrere Kandidatenpfade am Leben hält, wenn die Wahrscheinlichkeiten nah beieinanderliegen.

Strukturierte Score-Stufen

Jeder Eintrag in einem Score-criteria-Array kann ein Objekt sein.

request
{
  "state": "Fixed the null check in the payment handler. Also refactored the retry loop while I was in there, and bumped the SDK version since the old one had that timeout bug.",
  "questions": {
    "pr_scope": {
      "type": "score",
      "instructions": {
        "question": "How focused is this pull request description on a single change?",
        "note": "Judge the number of independent changes, not the size of any one change."
      },
      "criteria": [
        {
          "summary": "One change, clearly stated",
          "signals": [
            "A single fix or feature",
            "Nothing described as \"also\" or \"while I was in there\""
          ]
        },
        {
          "summary": "One main change plus a small related tweak",
          "signals": [
            "A primary change and one minor adjacent edit",
            "The tweak supports the main change"
          ]
        },
        {
          "summary": "Several independent changes bundled together",
          "signals": [
            "Two or more unrelated fixes or features",
            "Changes that could each be their own PR"
          ]
        }
      ]
    }
  }
}

Strukturierte Noul-criteria

Noul-criteria ist optional, und wenn die Ja/Nein-Grenze subtil ist, lassen sich mit strukturierten true- und false-Beschreibungen eine Definition und Beispiele auf jeder Seite festlegen.

request
{
  "state": {
    "sender": {
      "display_name": "Beaver Dam Builders Ltd.",
      "email": "donotreply@payroll.example"
    },
    "message": "Your Q3 bonus is ready. Reply with your login password so we can verify your identity and release the funds."
  },
  "questions": {
    "requests_credentials": {
      "type": "noul",
      "instructions": {
        "question": "Does the `message` ask the recipient to disclose a sensitive credential?",
        "inspect": "message",
        "focus": "Look for a request to send the credential itself, not a request to change or reset it."
      },
      "criteria": {
        "true": {
          "what": "Asks the recipient to reply with, type, or send a password, PIN, one-time code, or other security sensitive answer",
          "examples": [
            "Reply with your password",
            "Send us the 6-digit code you just received"
          ]
        },
        "false": {
          "what": "No sensitive credential is requested",
          "examples": [
            "Reset your password from the settings page",
            "Your statement is ready"
          ]
        }
      }
    }
  }
}