优化客服智能体的成本与质量(中)
说明提示缓存如何复用稳定前缀,以及如何把质量保证和打标移出同步路径,并按场景选择架构。

目录
优化第 3 轮:提示缓存
每个支持请求都包含相同的核心指令、政策规则、工具定义和回复模式。提示缓存(prompt caching)让 API 在工单之间复用这份共享上下文,减少重复处理并降低输入 Token 成本。客户特有细节,例如订单号、账户信息和检索到的记录,应当出现在共享前缀之后。
提示缓存在模型代际之间有变化。使用 gpt-5.4-mini 时,API 会自动识别重复前缀,即使客户特有细节改变,也可以复用共享的支持上下文。写入新前缀不会另收缓存写入费。保持工具定义一致,并用 tool_choice.allowed_tools 控制哪些工具可用,同时不改变共享工具列表。
GPT-5.6 引入两项变化:缓存写入会计费,开发者可以明确选择提示中哪一部分应当被缓存。使用 gpt-5.6-luna、gpt-5.6-terra 或 gpt-5.6-sol 时,默认缓存断点放在最新消息之后。如果这条消息在工单之间变化,最长的缓存前缀可能对不上。隐式模式仍然可以复用更早的合格消息结尾,包括最初的开发者消息块。因为把内容写入缓存的价格是正常输入 Token 价格的 1.25 倍,反复缓存这些独特消息可能增加成本,却产生不了有用的复用。
例如,两张订单状态工单可以共享相同的支持指令、政策规则和工具,尽管一张询问订单 O-1001,另一张询问订单 O-2002。对 GPT-5.6,把共享操作手册放在开发者消息的 input_text 块中,并在订单特有细节之前用 prompt_cache_breakpoint={"mode": "explicit"} 标记其结尾。顶层 instructions 不能包含断点。把 prompt_cache_options 设为显式模式并使用 ttl="30m",两次请求使用同一个 prompt_cache_key,例如 support_order_status_v1。当前缀合格且匹配时,第一张工单写入操作手册,后续工单可以按缓存输入费率复用它,同时正常处理各自的订单细节。
把 cached_tokens 和 cache_write_tokens 与延迟、每张已解决工单的成本放在一起比较。更多实现细节见提示缓存指南。
cache_friendly_request = {
"model": "gpt-5.4-mini",
"instructions": CACHE_FRIENDLY_PROMPT,
"tools": SLIM_TOOLS,
"tool_choice": allowed_tool_choice(["lookup_order"], mode="auto"),
"prompt_cache_key": "support_order_status_v1",
"reasoning": {"effort": "low"},
"text": {"verbosity": "low"},
"max_output_tokens": 300,
"input": [
{
"role": "user",
"content": json.dumps(
{
"ticket_id": "T-001",
"customer_id": "C-100",
"message": "Where is order O-1001?",
"order_id": "O-1001",
}
),
}
],
}
print(json.dumps(cache_friendly_request, indent=2)[:2400] + "\n...")
{
"model": "gpt-5.4-mini",
"instructions": "Role: E-commerce support assistant.\nConstraints: Be concise, policy-compliant, and explicit about next steps. Do not disclose internal data.\nEscalate: duplicate charges, account access without verification, high-value disputes, and refunds outside the window.\nOutput shape: customer_message, resolution_type, escalate, internal_tags.\nTool contract: tool definitions are stable across requests; restrict callable tools with tool_choice.allowed_tools.\nVersion: support-agent-optimization-v1.\n\nStable support playbook digest:\n- Shipping delays: provide status, ETA, and tracking next steps; do not refund solely for short carrier delays.\n- Delivered-not-received: verify delivery details, ask the customer to check common locations, and start carrier trace steps when appropriate.\n- Damaged delivery: request photo evidence before offering replacement or refund; high-value damaged items require human review.\n- Refunds: standard returnable items are eligible within 30 days; outside-window or high-value disputes require human review.\n- Billing: duplicate-charge reports require billing review; acknowledge and escalate, but do not promise a completed refund.\n- Account access: when identity is not verified, escalate to account security; do not change credentials or contact information in chat.\n- Customer messages must be concise, policy-compliant, and explicit about next steps.\n- Internal notes, raw carrier payloads, CRM audit logs, and policy appendices must never be exposed to the customer.\nStable support playbook digest:\n- Shipping delays: provide status, ETA, and tracking next steps; do not refund solely for short carrier delays.\n- Delivered-not-received: verify delivery details, ask the customer to check common locations, and start carrier trace steps when appropriate.\n- Damaged delivery: request photo evidence before offering replacement or refund; high-value damaged items require human review.\n- Refunds: standard returnable items are eligible within 30 days; outside-window or high-value disputes require human review.\n- Billing: duplicate-charge reports require billing review; acknowledge and escalate, but do not promise a completed refund.\n- Account access: when identity is not verified, escalate to account security; do not change credentials or contact information in chat.\n- Customer messages must be
...
previous_response_id_example = '''
from support import STABLE_SUPPORT_PREFIX
first = client.responses.create(
model="gpt-5.4-mini",
instructions=STABLE_SUPPORT_PREFIX,
tools=SLIM_TOOLS,
input="Customer asks: Where is order O-1001?",
prompt_cache_key="support_order_status_v1",
)
follow_up = client.responses.create(
model="gpt-5.4-mini",
previous_response_id=first.id,
instructions=STABLE_SUPPORT_PREFIX,
input="Customer follow-up: the carrier link is stale. What should I do?",
prompt_cache_key="support_order_status_v1",
)
'''
print(previous_response_id_example)
from support import STABLE_SUPPORT_PREFIX
first = client.responses.create(
model="gpt-5.4-mini",
instructions=STABLE_SUPPORT_PREFIX,
tools=SLIM_TOOLS,
input="Customer asks: Where is order O-1001?",
prompt_cache_key="support_order_status_v1",
)
follow_up = client.responses.create(
model="gpt-5.4-mini",
previous_response_id=first.id,
instructions=STABLE_SUPPORT_PREFIX,
input="Customer follow-up: the carrier link is stale. What should I do?",
prompt_cache_key="support_order_status_v1",
)
caching_view = traces[traces["variant"].isin(["02_model_routing", "03_prompt_caching"])]
display(
caching_view[
[
"variant_label",
"ticket_id",
"model",
"input_tokens",
"cacheable_prefix_tokens",
"cached_tokens",
"latency_input_tokens",
"output_tokens",
"cost_usd",
"latency_s",
"quality_score",
]
].style.format({"cost_usd": "${:.5f}", "quality_score": "{:.2f}", "latency_s": "{:.2f}"})
)
| variant\_label | ticket\_id | model | input\_tokens | cacheable\_prefix\_tokens | cached\_tokens | latency\_input\_tokens | output\_tokens | cost\_usd | latency\_s | quality\_score | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 20 | Round 2: routing | T-001 | gpt-5.4-mini | 1068 | 0 | 0 | 1068 | 77 | $0.00123 | 1.56 | 0.98 |
| 21 | Round 2: routing | T-002 | gpt-5.4-mini | 1139 | 0 | 0 | 1139 | 104 | $0.00141 | 1.72 | 0.98 |
| 22 | Round 2: routing | T-003 | gpt-5.4-mini | 1162 | 0 | 0 | 1162 | 118 | $0.00149 | 1.87 | 0.98 |
| 23 | Round 2: routing | T-004 | gpt-5.4-mini | 1150 | 0 | 0 | 1150 | 117 | $0.00147 | 1.87 | 0.98 |
| 24 | Round 2: routing | T-005 | gpt-5.4 | 1119 | 0 | 0 | 1119 | 165 | $0.00536 | 2.48 | 0.99 |
| 25 | Round 2: routing | T-006 | gpt-5.4 | 1166 | 0 | 0 | 1166 | 158 | $0.00537 | 2.49 | 0.99 |
| 26 | Round 2: routing | T-007 | gpt-5.4-mini | 1179 | 0 | 0 | 1179 | 100 | $0.00142 | 1.73 | 0.98 |
| 27 | Round 2: routing | T-008 | gpt-5.4 | 1180 | 0 | 0 | 1180 | 172 | $0.00562 | 2.49 | 0.99 |
| 28 | Round 2: routing | T-009 | gpt-5.4-mini | 1166 | 0 | 0 | 1166 | 118 | $0.00149 | 1.87 | 0.98 |
| 29 | Round 2: routing | T-010 | gpt-5.4 | 1123 | 0 | 0 | 1123 | 165 | $0.00537 | 2.48 | 0.99 |
| 30 | Round 3: caching | T-001 | gpt-5.4-mini | 2267 | 1779 | 1779 | 933 | 77 | $0.00093 | 1.54 | 0.98 |
| 31 | Round 3: caching | T-002 | gpt-5.4-mini | 2338 | 1779 | 1779 | 1004 | 104 | $0.00111 | 1.70 | 0.98 |
| 32 | Round 3: caching | T-003 | gpt-5.4-mini | 2361 | 1779 | 1779 | 1027 | 118 | $0.00119 | 1.85 | 0.98 |
| 33 | Round 3: caching | T-004 | gpt-5.4-mini | 2349 | 1779 | 1779 | 1015 | 117 | $0.00117 | 1.84 | 0.98 |
| 34 | Round 3: caching | T-005 | gpt-5.4 | 2318 | 1779 | 1779 | 984 | 165 | $0.00435 | 2.45 | 0.99 |
| 35 | Round 3: caching | T-006 | gpt-5.4 | 2365 | 1779 | 1779 | 1031 | 158 | $0.00437 | 2.46 | 0.99 |
| 36 | Round 3: caching | T-007 | gpt-5.4-mini | 2378 | 1779 | 1779 | 1044 | 100 | $0.00112 | 1.70 | 0.98 |
| 37 | Round 3: caching | T-008 | gpt-5.4 | 2379 | 1779 | 1779 | 1045 | 172 | $0.00461 | 2.47 | 0.99 |
| 38 | Round 3: caching | T-009 | gpt-5.4-mini | 2365 | 1779 | 1779 | 1031 | 118 | $0.00119 | 1.85 | 0.98 |
| 39 | Round 3: caching | T-010 | gpt-5.4 | 2322 | 1779 | 1779 | 988 | 165 | $0.00436 | 2.46 | 0.99 |
优化第 4 轮:拆分工作流
把分类、必要查询、解决或升级决策,以及客户回复留在同步路径上。当质量保证、标签、内部摘要、审计和报告不改变即时结果时,把它们移到后续工作。
默认或优先处理可以服务对延迟敏感的请求。Flex 用更低成本换更慢的响应和偶尔的资源不可用;确认模型支持,并处理超时或容量不可用。Batch 适合完成窗口为 24h 的离线作业。后台模式使请求异步,但本身不提供价格折扣。
sync_request = {
"model": "gpt-5.4-mini",
"instructions": CACHE_FRIENDLY_PROMPT,
"tools": SLIM_TOOLS,
"tool_choice": allowed_tool_choice(["lookup_order", "lookup_policy"], mode="auto"),
"input": "Customer says order O-1002 arrived cracked. Resolve or escalate.",
"reasoning": {"effort": "low"},
"text": {"verbosity": "low"},
"max_output_tokens": 260,
"service_tier": "default",
"prompt_cache_key": "support_damaged_delivery_v1",
}
background_flex_request = background_followup_request(EVAL_SET[1])
print("Synchronous customer-facing request:")
print(json.dumps(sync_request, indent=2)[:1800] + "\n...")
print("\nFollow-up flex request:")
print(json.dumps(background_flex_request, indent=2)[:1600] + "\n...")
Synchronous customer-facing request:
{
"model": "gpt-5.4-mini",
"instructions": "Role: E-commerce support assistant.\nConstraints: Be concise, policy-compliant, and explicit about next steps. Do not disclose internal data.\nEscalate: duplicate charges, account access without verification, high-value disputes, and refunds outside the window.\nOutput shape: customer_message, resolution_type, escalate, internal_tags.\nTool contract: tool definitions are stable across requests; restrict callable tools with tool_choice.allowed_tools.\nVersion: support-agent-optimization-v1.\n\nStable support playbook digest:\n- Shipping delays: provide status, ETA, and tracking next steps; do not refund solely for short carrier delays.\n- Delivered-not-received: verify delivery details, ask the customer to check common locations, and start carrier trace steps when appropriate.\n- Damaged delivery: request photo evidence before offering replacement or refund; high-value damaged items require human review.\n- Refunds: standard returnable items are eligible within 30 days; outside-window or high-value disputes require human review.\n- Billing: duplicate-charge reports require billing review; acknowledge and escalate, but do not promise a completed refund.\n- Account access: when identity is not verified, escalate to account security; do not change credentials or contact information in chat.\n- Customer messages must be concise, policy-compliant, and explicit about next steps.\n- Internal notes, raw carrier payloads, CRM audit logs, and policy appendices must never be exposed to the customer.\nStable support playbook digest:\n- Shipping delays: provide status, ETA, and tracking next steps; do not refund solely for short carrier delays.\n- Delivered-not-received: verify delivery details, ask the customer to check common location
...
Follow-up flex request:
{
"model": "gpt-5.4-nano",
"input": "{\"ticket\": {\"ticket_id\": \"T-002\", \"customer_id\": \"C-200\", \"message\": \"My blender arrived cracked. Order O-1002. Can you replace it?\", \"intent\": \"damaged_delivery\", \"order_id\": \"O-1002\", \"risk\": \"medium\", \"difficulty\": \"routine_policy\", \"must_escalate\": false, \"expected_policy\": \"damaged_delivery\", \"expected_tools\": [\"lookup_order\", \"lookup_policy\"], \"expected_action\": \"request_photo_then_offer_replacement\", \"expected_resolution_type\": \"resolved_next_step\", \"expected_customer_response_contains\": [\"photo\", \"replacement\"], \"forbidden_response_claims\": [\"refund completed\", \"no photo needed\"]}, \"policy\": \"If damage is reported within 7 days of delivery, ask for a photo and offer replacement or refund after evidence is collected. High-value damaged items over $1,000 require human review before promising a refund or replacement.\"}",
"reasoning": {
"effort": "low"
},
"text": {
"verbosity": "low"
},
"max_output_tokens": 160,
"service_tier": "flex"
}
...
batch_requests = []
for ticket in EVAL_SET:
batch_requests.append(
{
"custom_id": f"qa-{ticket['ticket_id']}",
"method": "POST",
"url": "/v1/responses",
"body": {
"model": "gpt-5.4-nano",
"instructions": "Return concise internal support QA tags and a one-sentence summary.",
"input": json.dumps(ticket),
"reasoning": {"effort": "low"},
"text": {"verbosity": "low"},
"max_output_tokens": 160,
},
}
)
from pathlib import Path
Path("outputs").mkdir(exist_ok=True)
batch_file_path = "outputs/nightly_support_qa_batch.jsonl"
with open(batch_file_path, "w") as f:
f.writelines(json.dumps(row) + "\n" for row in batch_requests)
print(f"Wrote {len(batch_requests)} example batch rows to {batch_file_path}")
print(json.dumps(batch_requests[0], indent=2))
Wrote 10 example batch rows to outputs/nightly_support_qa_batch.jsonl
{
"custom_id": "qa-T-001",
"method": "POST",
"url": "/v1/responses",
"body": {
"model": "gpt-5.4-nano",
"instructions": "Return concise internal support QA tags and a one-sentence summary.",
"input": "{\"ticket_id\": \"T-001\", \"customer_id\": \"C-100\", \"message\": \"Where is order O-1001? It was supposed to arrive yesterday.\", \"intent\": \"order_status\", \"order_id\": \"O-1001\", \"risk\": \"low\", \"difficulty\": \"simple_lookup\", \"must_escalate\": false, \"expected_policy\": \"shipping\", \"expected_tools\": [\"lookup_order\"], \"expected_action\": \"provide_status_eta\", \"expected_resolution_type\": \"resolved\", \"expected_customer_response_contains\": [\"in transit\", \"tomorrow\"], \"forbidden_response_claims\": [\"refund completed\", \"replacement opened\"]}",
"reasoning": {
"effort": "low"
},
"text": {
"verbosity": "low"
},
"max_output_tokens": 160
}
}
batch_submission_example = '''
batch_input_file = client.files.create(
file=open(batch_file_path, "rb"),
purpose="batch",
)
batch = client.batches.create(
input_file_id=batch_input_file.id,
endpoint="/v1/responses",
completion_window="24h",
metadata={"description": "nightly support QA tags"},
)
'''
print(batch_submission_example)
batch_input_file = client.files.create(
file=open(batch_file_path, "rb"),
purpose="batch",
)
batch = client.batches.create(
input_file_id=batch_input_file.id,
endpoint="/v1/responses",
completion_window="24h",
metadata={"description": "nightly support QA tags"},
)
split_view = traces[traces["variant"].isin(["03_prompt_caching", "04_split_workflow"])]
display(
split_view[
[
"variant_label",
"ticket_id",
"model",
"tool_calls",
"sync_tokens",
"total_tokens",
"background_tokens",
"latency_s",
"sync_cost_usd",
"background_cost_usd",
"cost_usd",
"quality_score",
]
].style.format(
{
"sync_cost_usd": "${:.5f}",
"background_cost_usd": "${:.5f}",
"cost_usd": "${:.5f}",
"quality_score": "{:.2f}",
"latency_s": "{:.2f}",
}
)
)
| variant\_label | ticket\_id | model | tool\_calls | sync\_tokens | total\_tokens | background\_tokens | latency\_s | sync\_cost\_usd | background\_cost\_usd | cost\_usd | quality\_score | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 30 | Round 3: caching | T-001 | gpt-5.4-mini | 1 | 2552 | 2552 | 0 | 1.54 | $0.00093 | $0.00000 | $0.00093 | 0.98 |
| 31 | Round 3: caching | T-002 | gpt-5.4-mini | 2 | 2650 | 2650 | 0 | 1.70 | $0.00111 | $0.00000 | $0.00111 | 0.98 |
| 32 | Round 3: caching | T-003 | gpt-5.4-mini | 3 | 2689 | 2689 | 0 | 1.85 | $0.00119 | $0.00000 | $0.00119 | 0.98 |
| 33 | Round 3: caching | T-004 | gpt-5.4-mini | 3 | 2673 | 2673 | 0 | 1.84 | $0.00117 | $0.00000 | $0.00117 | 0.98 |
| 34 | Round 3: caching | T-005 | gpt-5.4 | 3 | 2689 | 2689 | 0 | 2.45 | $0.00435 | $0.00000 | $0.00435 | 0.99 |
| 35 | Round 3: caching | T-006 | gpt-5.4 | 3 | 2735 | 2735 | 0 | 2.46 | $0.00437 | $0.00000 | $0.00437 | 0.99 |
| 36 | Round 3: caching | T-007 | gpt-5.4-mini | 2 | 2691 | 2691 | 0 | 1.70 | $0.00112 | $0.00000 | $0.00112 | 0.98 |
| 37 | Round 3: caching | T-008 | gpt-5.4 | 3 | 2769 | 2769 | 0 | 2.47 | $0.00461 | $0.00000 | $0.00461 | 0.99 |
| 38 | Round 3: caching | T-009 | gpt-5.4-mini | 3 | 2697 | 2697 | 0 | 1.85 | $0.00119 | $0.00000 | $0.00119 | 0.98 |
| 39 | Round 3: caching | T-010 | gpt-5.4 | 3 | 2696 | 2696 | 0 | 2.46 | $0.00436 | $0.00000 | $0.00436 | 0.99 |
| 40 | Round 4: split workflow | T-001 | gpt-5.4-mini | 1 | 2287 | 2867 | 580 | 1.10 | $0.00071 | $0.00011 | $0.00082 | 0.98 |
| 41 | Round 4: split workflow | T-002 | gpt-5.4-mini | 2 | 2381 | 2940 | 559 | 1.26 | $0.00087 | $0.00010 | $0.00097 | 0.98 |
| 42 | Round 4: split workflow | T-003 | gpt-5.4-mini | 3 | 2418 | 2978 | 560 | 1.41 | $0.00094 | $0.00010 | $0.00105 | 0.98 |
| 43 | Round 4: split workflow | T-004 | gpt-5.4-mini | 3 | 2401 | 2942 | 541 | 1.41 | $0.00092 | $0.00010 | $0.00103 | 0.98 |
| 44 | Round 4: split workflow | T-005 | gpt-5.4 | 3 | 2413 | 2956 | 543 | 2.02 | $0.00346 | $0.00010 | $0.00356 | 0.99 |
| 45 | Round 4: split workflow | T-006 | gpt-5.4 | 3 | 2459 | 3019 | 560 | 2.03 | $0.00348 | $0.00010 | $0.00358 | 0.99 |
| 46 | Round 4: split workflow | T-007 | gpt-5.4-mini | 2 | 2422 | 3023 | 601 | 1.27 | $0.00088 | $0.00011 | $0.00099 | 0.98 |
| 47 | Round 4: split workflow | T-008 | gpt-5.4 | 3 | 2492 | 3063 | 571 | 2.03 | $0.00371 | $0.00010 | $0.00381 | 0.99 |
| 48 | Round 4: split workflow | T-009 | gpt-5.4-mini | 3 | 2426 | 2988 | 562 | 1.41 | $0.00095 | $0.00010 | $0.00105 | 0.98 |
| 49 | Round 4: split workflow | T-010 | gpt-5.4 | 3 | 2420 | 2962 | 542 | 2.02 | $0.00347 | $0.00010 | $0.00357 | 0.99 |
权衡与场景映射
没有普遍最佳的配置。最优点取决于流量形态、对客户的承诺、政策风险、缓存命中率、工具延迟、可观测性成熟度,以及有多少工作可以移出同步路径。
支持智能体的重要权衡是:
| 约束 | 把你推向 | 需要留意 |
|---|---|---|
| 高政策或账户安全风险 | 高风险路径用更大的模型、更严格的升级、评判器评测 | 过度升级会损害客户体验和支持产能 |
| 高工单量且工作流重复 | 稳定前缀、提示缓存、更小的模型、后续工作用 Batch | 大前缀上的缓存未命中会增加延迟 |
| 低延迟的客户承诺 | 短提示、精简工具载荷、路由、异步后续工作 | 如果任务本来就简单,过多路由会增加开销 |
| 严格的成本目标 | 分诊和常规路径用 nano/mini、输出上限、离线工作用 flex 或 Batch | 如果质量门很弱,只按成本调优会去掉防护 |
| 工具混乱或数据不可靠 | 更少的工具调用、经过校验的载荷、回退、工具失败时升级 | 盲目缩小上下文会去掉政策决策所需的证据 |
| 高端或受监管的支持 | 更高的质量下限、更低的升级阈值、更多离线审计元数据 | 更多同步复核会增加延迟和成本 |
| 季节性突发 | 对缓存友好的请求、感知队列的服务层级、异步分析 | 如果路由键过于碎片化,高峰流量会降低缓存效果 |
下表把常见运行场景映射到候选配置。把它当作设计辅助:选择能通过该场景质量、延迟和运行约束的最便宜配置。
候选架构组合
这张表比较同一客户支持用例的候选智能体架构。它使用笔记本的模拟评测集和确定性空跑模拟指标,而不是实时 API 轨迹。用相对差异理解权衡;做部署决策之前,用生产轨迹数据替换这些指标。
from scenarios import (
ARCHITECTURE_OPTIONS,
OPERATING_SCENARIOS,
architecture_metrics,
scenario_fit_score,
)
architecture_rows = [
{"architecture": key, **option, **architecture_metrics(key, summary)}
for key, option in ARCHITECTURE_OPTIONS.items()
]
architecture_df = pd.DataFrame(architecture_rows)
print("Table: Candidate architecture combinations (mock eval set + deterministic dry-run metrics)")
display(
architecture_df[
[
"label",
"models",
"tools",
"cache",
"workflow",
"quality",
"policy_compliance",
"p50_latency_s",
"monthly_cost_at_100k_tickets",
"best_for",
]
].style.format(
{
"quality": "{:.2f}",
"policy_compliance": "{:.0%}",
"p50_latency_s": "{:.2f}",
"monthly_cost_at_100k_tickets": "${:,.0f}",
}
)
)
Table: Candidate architecture combinations (mock eval set + deterministic dry-run metrics)
| label | models | tools | cache | workflow | quality | policy\_compliance | p50\_latency\_s | monthly\_cost\_at\_100k\_tickets | best\_for | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | One broad agent | gpt-5.4 for every step | all tools exposed | none | all work synchronous | 0.51 | 10% | 4.88 | $3,813 | prototype smell test only |
| 1 | Controlled full model | gpt-5.4 for resolution | allowed tools by routed path | none | some follow-up still synchronous | 0.98 | 100% | 2.32 | $512 | high-risk launch or low confidence in routing/model mix |
| 2 | Routed, no cache | nano triage, mini routine, gpt-5.4 high risk | allowed tools by routed path | none | some follow-up still synchronous | 0.98 | 100% | 1.87 | $302 | mixed ticket queues with moderate repeat traffic |
| 3 | Routed split, no cache | nano triage/tags, mini routine, gpt-5.4 high risk | allowed tools by routed path | none | customer path sync, QA/tags/reporting async | 0.98 | 100% | 1.57 | $285 | low-repeat queues that still need async follow-up work |
| 4 | Routed + cache | nano triage, mini routine, gpt-5.4 high risk | stable full tool list plus allowed\_tools | stable playbook prefix | some follow-up still synchronous | 0.98 | 100% | 1.85 | $244 | high-volume repeated workflows with good cache locality |
| 5 | Balanced split workflow | nano triage/tags, mini routine, gpt-5.4 high risk | stable full tool list plus allowed\_tools | stable playbook prefix | customer path sync, QA/tags/reporting async | 0.98 | 100% | 1.41 | $204 | most mature repeated-workflow support deployments |
场景最优点
这张表把常见的真实运行场景映射到得分最高的架构组合。场景约束是为演示而模拟的,架构指标来自上面的空跑模拟。在生产环境中,用你的支持服务级别协议(SLA)、预算、政策风险阈值和观察到的缓存命中率替换这些约束。
fit_rows = [
scenario_fit_score(scenario, option_key, summary)
for scenario in OPERATING_SCENARIOS
for option_key in ARCHITECTURE_OPTIONS
]
fit_df = pd.DataFrame(fit_rows)
best_fit = (
fit_df.sort_values(["scenario", "score", "monthly_cost_at_100k_tickets"], ascending=[True, False, True])
.groupby("scenario", sort=False)
.head(1)
.reset_index(drop=True)
)
scenario_context = pd.DataFrame(OPERATING_SCENARIOS)[
[
"scenario",
"description",
"quality_floor",
"policy_floor",
"p50_latency_target_s",
"monthly_budget_100k_usd",
"needs_async",
"cache_locality",
]
]
best_fit_view = best_fit.merge(scenario_context, on="scenario")
print("Table: Recommended sweet spot by scenario (mock constraints + dry-run architecture metrics)")
display(
best_fit_view[
[
"scenario",
"description",
"label",
"score",
"quality",
"quality_floor",
"policy_compliance",
"policy_floor",
"p50_latency_s",
"p50_latency_target_s",
"monthly_cost_at_100k_tickets",
"monthly_budget_100k_usd",
"cache_locality",
"failed_constraints",
]
].style.format(
{
"quality": "{:.2f}",
"quality_floor": "{:.2f}",
"policy_compliance": "{:.0%}",
"policy_floor": "{:.0%}",
"p50_latency_s": "{:.2f}",
"p50_latency_target_s": "{:.2f}",
"monthly_cost_at_100k_tickets": "${:,.0f}",
"monthly_budget_100k_usd": "${:,.0f}",
}
)
)
Table: Recommended sweet spot by scenario (mock constraints + dry-run architecture metrics)
| scenario | description | label | score | quality | quality\_floor | policy\_compliance | policy\_floor | p50\_latency\_s | p50\_latency\_target\_s | monthly\_cost\_at\_100k\_tickets | monthly\_budget\_100k\_usd | cache\_locality | failed\_constraints | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Account and billing sensitive queue | Risky account recovery and duplicate-charge workflows dominate. | Routed split, no cache | 13 | 0.98 | 0.98 | 100% | 100% | 1.57 | 2.80 | $285 | $750 | medium | none |
| 1 | Early pilot | Low volume, quality learning matters more than unit cost. | Routed, no cache | 13 | 0.98 | 0.94 | 100% | 98% | 1.87 | 3.00 | $302 | $800 | low | none |
| 2 | High-volume routine ecommerce | Many repeated order, return, and damage workflows. | Balanced split workflow | 13 | 0.98 | 0.96 | 100% | 99% | 1.41 | 2.00 | $204 | $300 | high | none |
| 3 | Low-repeat long tail | Many rare ticket types; cache hit rate is uncertain. | Routed split, no cache | 13 | 0.98 | 0.96 | 100% | 99% | 1.57 | 2.50 | $285 | $450 | low | none |
| 4 | Peak sale burst | Latency and cost matter during temporary traffic spikes. | Balanced split workflow | 13 | 0.98 | 0.95 | 100% | 99% | 1.41 | 1.80 | $204 | $250 | high | none |
| 5 | Premium support | Higher customer value, lower tolerance for wrong actions. | Routed split, no cache | 13 | 0.98 | 0.98 | 100% | 100% | 1.57 | 2.50 | $285 | $650 | medium | none |
一个场景的完整组合图
这张表展示一个模拟场景 Low-repeat long tail 的全部架构选项。放在这里是为了让权衡可见,而不是把一切藏在单一最佳选择后面。数字仍然是模拟的;重点是说明当缓存局部性低时,重度依赖缓存的设计为什么没那么有吸引力。
# Show the full combination map for one scenario so tradeoffs are visible, not hidden behind the best pick.
scenario_to_inspect = "Low-repeat long tail"
combo_map = fit_df[fit_df["scenario"] == scenario_to_inspect].sort_values("score", ascending=False)
print(f"Table: Full architecture ranking for {scenario_to_inspect} (mock scenario + dry-run metrics)")
display(
combo_map[
[
"label",
"score",
"quality",
"policy_compliance",
"p50_latency_s",
"monthly_cost_at_100k_tickets",
"failed_constraints",
]
].style.format(
{
"quality": "{:.2f}",
"policy_compliance": "{:.0%}",
"p50_latency_s": "{:.2f}",
"monthly_cost_at_100k_tickets": "${:,.0f}",
}
)
)
Table: Full architecture ranking for Low-repeat long tail (mock scenario + dry-run metrics)
| label | score | quality | policy\_compliance | p50\_latency\_s | monthly\_cost\_at\_100k\_tickets | failed\_constraints | |
|---|---|---|---|---|---|---|---|
| 27 | Routed split, no cache | 13 | 0.98 | 100% | 1.57 | $285 | none |
| 26 | Routed, no cache | 10 | 0.98 | 100% | 1.87 | $302 | async split |
| 29 | Balanced split workflow | 9 | 0.98 | 100% | 1.41 | $204 | cache locality |
| 28 | Routed + cache | 6 | 0.98 | 100% | 1.85 | $244 | async split, cache locality |
| 25 | Controlled full model | 5 | 0.98 | 100% | 2.32 | $512 | budget, async split |
| 24 | One broad agent | -14 | 0.51 | 10% | 4.88 | $3,813 | quality, policy, latency, budget, async split |
在这些模拟场景中,重复工作流偏向共享缓存前缀和异步后续处理。低重复队列可能偏向不使用缓存的路由拆分,而早期试点在路由可靠之前,可能有理由使用完整模型。
把这些排名当作一次设计练习。它们包含手工设定的约束和评分加成,因此高分并不能证明某个架构满足每一项要求。选择生产配置之前,检查 failed_constraints,并强制执行质量和政策门。
PRIMARY_SOURCE: https://developers.openai.com/cookbook/examples/agent_optimization/optimizing_agents_for_cost_and_quality
- #提示缓存
- #工作流拆分
- #客服智能体
- #成本优化
- #架构选型


