문서

투기적 팬아웃

추측 질문을 포함해 많은 질문을 한 번의 호출로 보내고, 무엇이 관련 있는지 코드가 결정하게 합니다.

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단계: 투기적 팬아웃

questions
{
  "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)

전체 결정 트리에 필요한 모든 것이 한 번의 호출에서 나옵니다. 추측 질문은 무관할 때 무시되고, 무관하지 않을 때는 왕복 한 번을 절약해 줍니다.