JJev Cookbook
课程首页 中文文档 拓展阅读 英文原文 ↗

推测性扇出

在单次调用中发送多个问题,包括推测性的问题,并让你的代码决定哪些是相关的。

由于 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
{
  "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"
      ]
    }
  }
}
📝注意

推测性问题:bug_severity 和 has_reproducible_steps 只在工单是缺陷报告时才有意义。refund_requested 只对账务类工单有意义。我们之所以把所有问题都提前放入,是因为增加的问题通常对响应时间几乎没有影响。如果工单最终是功能请求,缺陷严重程度的结果将不相关,此时你的代码路径直接忽略它即可。

第 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)

完整决策树所需的一切都来自一次调用。推测性问题在不相关时被忽略,在相关时则省去了一个来回。

🔬 交互实验室
改一改 state 或问题再运行,观察概率与置信度如何变化。默认运行本地演示(离线可用、 非真实模型输出,仅演示答案形状);填入 API Key 可尝试直连真实 API(官方暂未开放跨域时会给出一键复制的本地调用代码);也可一键到官方 Playground 在线试跑。 配套讲解见本页上方内容与「深入学习」素材。
Key 仅保存在本浏览器(localStorage),不会上传到本站。留空 = 本地演示。
📓 内嵌教程 · 第 3 章 · 架构模式实验笔记本(四种模式全套可运行实验)
像运行 notebook 一样逐步学习:点「下一步」逐格展开——代码格会先出现再"运行"出结果。内容来自教程仓库配套笔记本。
0 / 73
配套中文参考文档:docs.typesafe.ai 的社区翻译,以英文原文为准;内容版权归原作者所有。