Примитивы (вопросы)
Три типа вопросов TypeSafe (Choice, Score, Noul), типизированные ответы, которые они возвращают, как выбирать между ними и как задавать несколько сразу.
Примитивы TypeSafe — это небольшие типизированные строительные блоки, которые вы компонуете в коде. Они образуют пары: вопрос определяет одно суждение, которое модель System One должна вынести о состоянии, а его ответ — это типизированное значение, которое возвращается. Вы компонуете ответы в своём коде, чтобы принимать решения. Есть три типа вопросов, каждый возвращает свою форму ответа.
| Тип | На что отвечает | Возвращает |
|---|---|---|
| Choice | Какой из этих вариантов? | choice, probabilities, confidence |
| Score | Какой уровень? | score, legend, probabilities, confidence |
| Noul | Истинно ли это? | noul (от 0 до 1) |
Вы можете задать один вопрос или отправить несколько вместе. Каждый вопрос в запросе видит одно и то же состояние, оценивается независимо и возвращает типизированный ответ под выбранным вами ID.
Один быстрый вывод на вопрос
Модели System One созданы для быстрых, сфокусированных суждений. Просите о суждении, которое знающий человек выносит за секунду при наличии нужного контекста. «Передаёт ли это сообщение срочность?» — хороший вопрос. «Проанализируйте это сообщение и определите лучший образ действий» — нет. Он требует медленных рассуждений, и это сигнал разбить задачу на маленькие вопросы, а ответы скомпоновать в коде.
Если нужное суждение зависит от нескольких независимых факторов, спросите о каждом факторе отдельно и объедините ответы собственной логикой. Вместо «оцените этот стартап-питч» спросите о размере рынка, технической осуществимости и дифференциации, а затем взвесьте их в коде по относительной важности. Когда приоритеты меняются, измените значения весов, а не переписывайте промпт. О том, как это сделать, см. Несколько вопросов в одном запросе.
Определение вопроса
У каждого вопроса есть ID, type и instructions. Вопросы Choice и Score также принимают criteria, которые определяют варианты для вопроса Choice или уровни для Score. Вопросы Noul принимают criteria как необязательное уточнение того, что означают «да» и «нет».
- ID. Ключ, который вы выбираете, например
refund_requested. По нему опознаётся ответ в ответе сервера. type. Одно изchoice,scoreилиnoul.instructions. Вопрос, который вы задаёте о состоянии. Здесь и находится ваша логика оценки. Напишите его как ясный, конкретный вопрос или как утверждение, которое модель должна оценить. Для большинства вопросов достаточно строки. Он также может быть объектом или массивом, где вопрос помещается в одно поле, а данные, на которые он ссылается, — в другие; см. Использование структуры в вопросах.criteria. Возможные ответы: карта вариантов для вопроса Choice, упорядоченный список уровней для Score и необязательное описание «да» и «нет» для Noul. Форма каждого типа вопроса описана на его странице.
Этот вопрос спрашивает, запросил ли клиент возврат:
from typesafe_sdk import Noul
questions = {
"refund_requested": Noul(
instructions="Does the customer request a refund?",
),
}
Выбор типа вопроса
Выберите тип, соответствующий форме нужного вам ответа.
-
Choice подходит, когда ответ — один из известного набора вариантов без порядка между ними: направление заявки в отдел, классификация типа документа, определение языка программирования. Приведите полный список вариантов и добавьте вариант
otherилиnone of the above, когда список может не покрывать все входные данные. -
Score подходит, когда ответ лежит на спектре и вы можете описать, что означает каждая точка этого спектра: серьёзность бага, недовольство клиента, уровень навыка. Уровни определяете вы, а модель возвращает позицию по ним.
-
Noul подходит для чёткого вопроса «да/нет», где сам сигнал — это вероятность: содержит ли это сообщение персональные данные, запрашивает ли клиент возврат, упоминает ли резюме распределённые системы.
Если подходят оба типа, предпочтите тот, по ответу которого ваш код может действовать напрямую. Choice между refund, rebook и information напрямую отображается на три ветки кода. Score недовольства клиента отображается на порог. Noul отображается на if.
Что возвращается
Ответы — тоже примитивы. Каждый тип вопроса возвращает типизированное значение, которое ваш код может сравнить, порогово обработать, отсортировать, передать в дальнейшую логику или поместить в состояние последующего запроса (см. Когда один вопрос зависит от другого).
| Тип | Поля ответа | Как читать |
|---|---|---|
| Choice | choice, probabilities, confidence |
choice — выбранный вариант. probabilities — распределение по всем вариантам. confidence обобщает, насколько острым является это распределение. |
| Score | score, legend, probabilities, confidence |
score — позиция по вашим уровням, может попасть между двумя из них. legend повторяет уровни по номерам. probabilities — распределение по уровням. |
| Noul | noul |
Вероятность того, что ответ — «да». Близко к 1 — уверенное «да», близко к 0 — уверенное «нет», около 0.5 — неопределённость. У Noul нет отдельной confidence. |
Два свойства этих ответов делают их компонуемыми:
- Каждый ответ ограничен заданными вами вариантами. Модель возвращает распределение вероятностей по вашим вариантам или уровням и никогда не возвращает значение вне их. Вашему коду никогда не приходится извлекать значение из сгенерированного текста.
- Каждый ответ независим. Ответ на один вопрос не является скрытым контекстом для другого. Вы можете добавлять или удалять вопросы, не меняя результаты остальных.
Уверенность объясняет, как confidence выводится из probabilities и как использовать её, чтобы решать, когда действовать автоматически, а когда эскалировать к человеку.
Ссылки на конкретные поля
Оцениваемое содержимое, состояние, часто представляет собой объект JSON из нескольких частей: переписка, запись, правило. Когда вопрос касается одной из этих частей, назовите её в instructions путём с точками и индексами к её ключу, включая обратные кавычки. Тогда модель знает, какую часть состояния оценивать.
Возьмём переписку со службой поддержки со страницы «Состояние»:
{
"ticket": {
"subject": "Duplicate charge",
"messages": [
{"from": "customer", "text": "I was charged twice for order A-104. Please refund the duplicate."},
{"from": "support", "text": "We are checking the charges."}
]
},
"order": {
"id": "A-104",
"charges": [
{"amount_usd": 49, "status": "captured"},
{"amount_usd": 49, "status": "captured"}
]
},
"refund_policy": "Duplicate charges are eligible for a refund."
}
Эти два вопроса указывают на сообщение клиента, правило и списания по пути:
questions = {
"refund_requested": {
"type": "noul",
"instructions": "Does `ticket.messages[0].text` request a refund?",
},
"policy_supports_refund": {
"type": "noul",
"instructions": (
"Does `refund_policy` support the refund requested "
"in `ticket.messages[0].text`, given `order.charges`?"
),
},
}
Явные пути дают понять, какие части структурированного состояния должны влиять на каждое суждение. О том, как структурировать входные данные, см. Состояние.
Несколько вопросов в одном запросе
Отправляйте в одном запросе все вопросы, использующие одно и то же состояние. Типы вопросов можно свободно смешивать. Модели System One оценивают каждый вопрос в запросе параллельно. Добавление вопросов почти не меняет время ответа и стоит лишь токены за дополнительные вопросы, которые дёшевы. Задать вопрос, который может не понадобиться, почти ничего не стоит.
Этот запрос классифицирует сообщение клиента, проверяет срочность и оценивает недовольство сразу:
{
"state": "Our API integration started returning 500 errors on every request about 20 minutes ago, and we can't process any customer orders until this is fixed.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this",
"criteria": {
"billing": "Payment or subscription issues",
"technical": "Bugs or integration problems",
"sales": "Pricing or account questions"
}
},
"is_urgent": {
"type": "noul",
"instructions": "The message conveys urgency or time-sensitivity"
},
"frustration": {
"type": "score",
"instructions": "How frustrated the customer appears",
"criteria": [
"Calm, just stating facts",
"Frustrated but civil",
"Very angry, strong language"
]
}
}
}Наши клиентские SDK предоставляют типизированные вопросы и ответы. В Python передайте словарь questions из объектов Choice, Noul и Score в client.system_one(...). Этот запрос отправляет заявку и правило возврата один раз и получает типизированный ответ на каждый вопрос:
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient
state = {
"ticket_message": "My flight was cancelled. Can I get a refund?",
"refund_policy": "Cancelled flights are eligible for a full refund.",
}
with TypeSafeClient() as client:
response = client.system_one(
state=state,
questions={
"refund_requested": Noul(
instructions="Does `ticket_message` request a refund?",
),
"request_type": Choice(
instructions="What is the main request in `ticket_message`?",
criteria={
"refund": "The customer wants money returned.",
"rebooking": "The customer wants a replacement flight.",
"information": "The customer is asking for information only.",
},
),
"frustration": Score(
instructions="How frustrated does the customer appear in `ticket_message`?",
criteria=[
"Calm and neutral.",
"Concerned but civil.",
"Very angry or using strong language.",
],
),
},
)
print(response.answers["refund_requested"].noul)
print(response.answers["request_type"].choice)
print(response.answers["frustration"].score)
Об установке и использовании на вашем языке см. клиентские SDK.
Спекулятивные вопросы
Задавайте каждый вопрос, который может понадобиться вашему коду, включая те, чей ответ важен лишь для некоторых входных данных, и позвольте коду решить, какие ответы использовать. Если заявка окажется не отчётом об ошибке, проигнорируйте ответ о серьёзности. Мы называем это паттерном Спекулятивный fan-out. Cookbook о параллельных вопросах показывает, что объединение 13 вопросов в один вызов в 11.5 раза дешевле и в 9.6 раза быстрее, чем 13 отдельных вызовов, без изменения ответов.
Разбиение сложного вывода на несколько вопросов
Суждение, зависящее от нескольких вещей, лучше всего разбить на один вопрос на каждую вещь. Объедините ответы в своём коде, придав каждому вес по его относительной важности. Веса — ваши. Когда объединённый результат не совпадает с тем, что решила бы ваша команда, измените их в коде и запустите снова. Добавление вопросов почти не меняет время ответа, потому что они выполняются параллельно внутри одного запроса. Разбиение стоит несколько дополнительных токенов за вопросы.
Например, приоритет заявки может строиться из трёх вопросов Score: насколько серьёзен баг, насколько недоволен клиент и сколько отчёт даёт инженеру для работы. Страница Score разбирает этот запрос и код, который нормализует и взвешивает ответы, в разделе Разбиение сложного вывода на несколько оценок Score. Этот приём называется паттерном Композитное оценивание.
Когда один вопрос зависит от другого
Вопросы в одном запросе независимы: ответ на один не становится контекстом для другого вопроса. Если более позднее суждение зависит от более раннего ответа, сделайте в коде второй запрос. Зависимость реальна только тогда, когда ваш код не может построить второй запрос, пока не получит первый ответ: ответ нужен, чтобы получить больше данных для состояния, решить, из чего состоит состояние, или выбрать варианты для следующего вопроса. В остальных случаях задавайте вопросы вместе и объединяйте их ответы в коде.
Два запроса — это исключение, а не правило. Если вопросы второго запроса можно было задать относительно исходного состояния, задайте их в первом запросе, а коду позвольте игнорировать ненужные. Три cookbook делают второй запрос по реальной причине. Подсказка навыка ранжирует 182 навыка в одном запросе, затем получает полный текст трёх лучших и оценивает их снова по этим более качественным данным. Восстановление структуры спрашивает, разбивал ли каждый перенос строки предложение, объединяет строки в блоки по этим ответам, а затем классифицирует блоки, которых не существовало, пока первый запрос не ответил. Иерархическая классификация использует каждый ответ Choice, чтобы решить, какие варианты предложит следующий запрос.
О том, как разбить рабочий процесс на сфокусированные суждения, см. Как строить с помощью TypeSafe.
Следующие шаги
Choice
Выберите один вариант из фиксированного списка.
Score
Оцените состояние по упорядоченным уровням.
Noul
Получите вероятность того, что утверждение истинно.
Чтобы увидеть, как они складываются в архитектуры систем, перейдите к Паттернам.