Документация

Продвинутое: структура

Инструкции, варианты Choice, уровни Score и критерии Noul — всё это принимает структуру JSON.

Модели System One обучены понимать структуру.

Где допустима структура

Каждое из этих полей — это EntryType.

Поле Применимо к Допустимая форма
instructions Choice, Score, Noul string, object, array или null
значения criteria (описания вариантов) Choice string, object, array или null
записи criteria (описания уровней) Score string, object, array или null
criteria.true и criteria.false Noul string, object, array или null

Когда структурировать вопрос

  • Когда это помогает ясности. Когда у вопроса несколько частей, представление их в виде JSON помогает ясности, потому что ключи помечены.
  • Когда вопросу нужны вспомогательные данные. Схема, таксономия или строка базы данных уже являются JSON. Используйте JSON целиком или передайте нужные подполя, а не сериализуйте их в строковый шаблон.

Структурированные инструкции

Один объект field описывает проверяемое поле, и каждый вопрос ссылается на него по ключу. Одна и та же форма управляет Noul, который проверяет значение, Choice, который выбирает одно из кандидатов, и двумя Score, которые размещают значение на шкале.

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

В коде вы могли бы пройти циклом по потенциальным записям и построить по одному такому вопросу на поле, отправив все в одном вызове. Cookbook по каскаду SDE делает нечто похожее.

Массивы тоже работают. Используйте массив, когда инструкция — список того, что нужно проверить или сравнить:

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

Структурированные варианты Choice

Описание варианта Choice тоже может быть структурированным объектом.

JSON-рубрика для уточнения границы

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

Пример говорит модели, что каждый вариант покрывает, а что не покрывает. Он уточняет границу между вариантами.

Обход таксономии

Чтобы классифицировать по глубокой таксономии, задайте по одному Choice на уровень и обходите дерево в коде. На каждом шаге варианты — это дочерние узлы текущего узла, а значение каждого варианта — поддерево дочернего узла. Так модель видит, что находится под ветвью, прежде чем выбрать её, а это важно, когда элемент относится к листу, имя которого не очевидно из одного имени ветви.

Здесь состояние — описание товара, а первый вопрос выбирает отдел верхнего уровня.

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

Бутылка правдоподобно подходит под два отдела. Показ поддеревьев даёт модели увидеть, что существуют и Sporting Goods > Cycling > Bike Bottles & Cages, и Home & Kitchen > Drinkware > Water Bottles, и взвесить акцент описания на велоклетки против повседневной посуды для напитков. probabilities у этого ответа говорят, достаточно ли близко разделение, чтобы исследовать обе ветви.

Как только отдел выбран, задайте следующий Choice, где варианты — дочерние узлы этого отдела, а значения — их поддеревья, и повторяйте, пока не дойдёте до листа. В коде это может быть цикл по вложенному словарю, где criteria каждого вопроса — просто текущий узел. Cookbook по иерархической классификации показывает пример похожего обхода дерева, включая лучевой поиск, который сохраняет несколько путей-кандидатов, когда вероятности близки.

Структурированные уровни Score

Каждая запись в массиве criteria вопроса Score может быть объектом.

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

Структурированные критерии Noul

criteria у Noul необязателен, и когда граница «да/нет» тонкая, структурированные описания true и false позволяют зафиксировать её определением и примерами с каждой стороны.

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