Спекулятивный fan-out
Отправляйте много вопросов одним вызовом, включая спекулятивные, и пусть ваш код решает, что релевантно.
Поскольку TypeSafe поддерживает отправку множества вопросов одним вызовом API, мы рекомендуем поместить все вопросы, нужные вашей системе, в один запрос, а затем с помощью кода решить, что релевантно, уже по факту. Все вопросы оцениваются параллельно, поэтому добавление новых вопросов обычно мало влияет на время ответа.
Пример: сортировка заявок в поддержку
Представьте, что вы создаёте систему поддержки, которой нужно сортировать заявки. Вам нужно классифицировать заявку по категории. Если это отчёт об ошибке, нужно также определить серьёзность ошибки.
Вместо того чтобы сначала спрашивать категорию, а затем серьёзность отдельным вызовом, вы можете спросить и то и другое сразу. Если заявка не является отчётом об ошибке, вы просто игнорируете результаты вопроса о серьёзности.
%%{init: {"fontFamily": "Inter, sans-serif", "flowchart": {"rankSpacing": 35, "wrappingWidth": 300, "subGraphTitleMargin": {"top": 8, "bottom": 60}}}}%%
flowchart LR
t["support ticket"]
subgraph req["TypeSafe AI model<br/>evaluates each question<br/>against the ticket in parallel"]
direction TB
c["<b>Choice:</b> category"]
b["<b>Score:</b> bug severity"]
r["<b>Noul:</b> reproducible steps?"]
f["<b>Noul:</b> refund requested?"]
s["<b>Score:</b> frustration"]
%% invisible links: without an edge these share a rank and sit side by side
c ~~~ b ~~~ r ~~~ f ~~~ s
end
t -- "one request<br/>ticket + 5 questions" --> req
req -- "one response: 5 answers<br/>decisions + probabilities" --> route{"<b>filter, combine, and route</b><br/>in your code"}
route -- "bug_report" --> eng["read severity + repro steps<br/>escalate or backlog"]
route -- "billing" --> bill["refund requested<br/>send to billing"]
route -- "feature_request" --> feat["log it<br/>sent to devs"]
Шаг 1: спекулятивный fan-out
{
"category": {
"type": "choice",
"instructions": "Determine the broad category of this support ticket",
"criteria": {
"bug_report": "The user is reporting something that is broken or producing errors",
"billing": "Charges, invoices, refunds, subscriptions",
"feature_request": "The user is requesting new functionality",
"account": "Login, permissions, profile, security"
}
},
"bug_severity": {
"type": "score",
"instructions": "How severe is the reported issue",
"criteria": [
"Cosmetic; no impact to functionality",
"Broken or degraded feature; workaround exists",
"Blocking issue; no workaround exists"
]
},
"has_reproducible_steps": {
"type": "noul",
"instructions": "The user describes specific steps to reproduce the issue"
},
"refund_requested": {
"type": "noul",
"instructions": "The user is explicitly asking for a refund or credit"
},
"frustration": {
"type": "score",
"instructions": "How frustrated the user appears",
"criteria": [
"Calm, matter-of-fact",
"Frustrated but civil",
"Very angry"
]
}
}Шаг 2: маршрутизируйте с помощью кода
Ваш код решает, что релевантно, по результату классификации:
triage.py
category = response.answers["category"]
bug_severity = response.answers["bug_severity"]
bug_repro = response.answers["has_reproducible_steps"]
refund = response.answers["refund_requested"]
frustration = response.answers["frustration"]
if category.choice == "bug_report":
if bug_severity.score > 1.5 and bug_repro.noul > 0.6:
escalate_to_engineering(ticket_id, severity="high")
else:
add_to_bug_backlog(ticket_id)
elif category.choice == "billing":
if refund.noul > 0.7:
route_to_billing_with_flag(ticket_id, refund_likely=True)
else:
route_to_billing(ticket_id)
elif category.choice == "feature_request":
log_feature_request(ticket_id)
# Frustration is useful regardless of category
if frustration.score > 1.5:
flag_for_priority_response(ticket_id)
Всё необходимое для полного дерева решений приходит из одного вызова. Спекулятивные вопросы игнорируются, когда нерелевантны, и экономят одно обращение, когда релевантны.