Documentación

Avanzado: estructura

Las instrucciones, las opciones de Choice, los niveles de Score y los criteria de Noul aceptan todos estructura JSON.

Los modelos System One están entrenados para entender la estructura.

Dónde se permite la estructura

Todos estos campos son un EntryType.

Campo Se aplica a Forma aceptada
instructions Choice, Score, Noul string, object, array o null
valores de criteria (descripciones de opciones) Choice string, object, array o null
entradas de criteria (descripciones de niveles) Score string, object, array o null
criteria.true y criteria.false Noul string, object, array o null

Cuándo estructurar una pregunta

  • Cuando ayuda a la claridad. Cuando una pregunta tiene varias partes, ponerlas en forma de JSON ayuda a la claridad porque las claves están etiquetadas.
  • Cuando la pregunta necesita datos de apoyo. Un esquema, una taxonomía o una fila de base de datos ya son JSON. Usa el JSON entero o pasa los subcampos relevantes en lugar de serializarlos en una plantilla de cadena.

Instrucciones estructuradas

Un objeto field describe el campo que se comprueba, y cada pregunta se refiere a él por su clave. La misma forma impulsa un Noul que verifica un valor, un Choice que elige uno entre candidatos y dos Scores que sitúan un valor en una escala.

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"
      ]
    }
  }
}

En el código, podrías recorrer con un bucle los registros potenciales y construir una de estas preguntas por campo, todas enviadas en una sola llamada. El cookbook de cascada SDE hace algo parecido a esto.

Los arrays también funcionan. Usa uno cuando la instrucción sea una lista de cosas que comprobar o comparar:

"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."
}

Opciones de Choice estructuradas

La descripción de una opción de Choice también puede ser un objeto estructurado.

Rúbrica JSON para aclarar límites

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"
          ]
        }
      }
    }
  }
}

El ejemplo le dice al modelo qué cubre cada opción y qué no cubre. Afina el límite entre las opciones.

Recorrer una taxonomía

Para clasificar en una taxonomía profunda, haz un Choice por nivel y recorre el árbol en el código. En cada paso, las opciones son los hijos del nodo actual, y el valor de cada opción es el árbol del hijo. Hacerlo así permite que el modelo vea lo que hay bajo una rama antes de comprometerse con ella, lo cual importa cuando el elemento pertenece a una hoja cuyo nombre no es obvio a partir del nombre de la rama.

Aquí el estado es un anuncio de producto y la primera pregunta elige un departamento de nivel superior.

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"
        ]
      }
    }
  }
}

La botella encaja de forma plausible en dos departamentos. Mostrar los subárboles permite que el modelo vea que existen tanto Sporting Goods > Cycling > Bike Bottles & Cages como Home & Kitchen > Drinkware > Water Bottles, y sopesar el énfasis del anuncio en las jaulas para bicicleta frente a la vajilla de uso diario. Las probabilities de esta respuesta te dicen si el reparto está lo bastante igualado como para explorar ambas ramas.

Una vez elegido un departamento, haz el siguiente Choice con los hijos de ese departamento como opciones y sus subárboles como valores, y repite hasta llegar a una hoja. En el código, esto podría ser un bucle sobre un dict anidado, donde los criteria de cada pregunta son simplemente el nodo actual. El cookbook de clasificación jerárquica muestra un ejemplo de un recorrido similar del árbol, incluida una búsqueda por haces que mantiene vivas varias rutas candidatas cuando las probabilidades están igualadas.

Niveles de Score estructurados

Cada entrada de un array criteria de Score puede ser un objeto.

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"
          ]
        }
      ]
    }
  }
}

Criteria de Noul estructurados

Los criteria de Noul son opcionales, y cuando el límite sí/no es sutil, las descripciones estructuradas true y false te permiten precisarlo con una definición y ejemplos en cada lado.

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"
          ]
        }
      }
    }
  }
}