---
title: 成本、性能与可靠性
url: https://doc.liz6.com/ai/03-applications-and-production/03-cost-performance-and-reliability
locale: zh
area: ai
tags:
- ai
- 应用与生产
date: 2026-06-30
modified: 2026-07-16
description: 把 LLM 接进生产,绕不开三件事:账单(token 怎么省)、延迟(怎么不卡)、稳定(限流和错误怎么扛)。它们散落在前几篇里,这篇收口成一张工程清单。
---

# 成本、性能与可靠性

> 把 LLM 接进生产,绕不开三件事:账单(token 怎么省)、延迟(怎么不卡)、稳定(限流和错误怎么扛)。它们散落在前几篇里,这篇收口成一张工程清单。

## 概述

原型跑通到上线,中间隔着工程化。Demo 里一次 `messages.create` 拿到结果就行;生产里要回答:这一万次调用要花多少钱?用户等几秒?撞了 429 怎么办?重试会不会把一封邮件发两遍?

这些问题的答案散在前几篇——[prompt caching](/ai/01-models-and-context/01-context-engineering.md)、[流式与 thinking](/ai/01-models-and-context/04-reasoning-and-thinking.md)、[usage 字段](/ai/02-Agent/05-evaluation-and-observability.md)、[按能力选模型](/ai/01-models-and-context/03-model-architecture-dense-vs-moe.md)。这一篇把它们按**成本 / 性能 / 可靠性**三条线收口,作为上线前的核对清单。

## 成本:token 是唯一计费单位

账单 = input token × 单价 + output token × 单价(output 通常贵 5×)。省钱的杠杆按收益排序:

### 1. prompt caching —— 最大的杠杆

多轮和 agent 循环里前缀高度重复。命中缓存的部分按 **~0.1x** 计费(见 [上下文工程](/ai/01-models-and-context/01-context-engineering.md))。算笔账(写入 5 分钟 TTL 是 1.25x):

- 不缓存:每次 1.0x。
- 缓存:首次写 1.25x,之后每次读 0.1x。**两次就回本**(1.25 + 0.1 = 1.35 < 2.0)。1 小时 TTL 写入 2x,需三次回本。

前提是前缀**逐字节稳定**——别在 system 插 `now()`/UUID、别中途改工具集或换模型,否则缓存静默失效。验证看 `usage.cache_read_input_tokens`,长期为 0 就是有"静默失效器"。

### 2. 选对模型

不是所有任务都要顶配。用 [Models API](/ai/01-models-and-context/03-model-architecture-dense-vs-moe.md) 查能力、按成本分层:简单分类/抽取走便宜模型,复杂推理/agent 走 Opus。多 agent 场景把子任务派给便宜模型(但**别在同一循环里换模型**毁缓存,另起 subagent,见 [多 Agent 编排](/ai/02-Agent/04-multi-agent-orchestration.md))。

### 3. 控输出与思考

output 比 input 贵。`max_tokens` 给足以防截断,但别无脑拉满;用 **effort** 调思考深度(见 [推理与 thinking](/ai/01-models-and-context/04-reasoning-and-thinking.md)),`effort` 越低 token 越省——简单任务别反射式拉 `xhigh`。

### 4. 批处理 —— 非实时任务半价

不要求即时返回的活(离线分析、批量分类、建索引)走 **Batches API**,所有 token **5 折**:

```python
batch = client.messages.batches.create(requests=[
    Request(custom_id="job-1", params=MessageCreateParamsNonStreaming(
        model="claude-opus-4-8", max_tokens=1024,
        messages=[{"role": "user", "content": "..."}])),
    # ... 最多 10 万条 / 256MB
])
# 轮询 batches.retrieve(id).processing_status 直到 "ended"(多在 1h 内, 上限 24h)
```

**结果乱序返回——必须按 `custom_id` 对号,绝不能靠顺序。** 这与下文"绝不靠顺序归因"是同一条铁律。

### 估算先行

发请求前能用 `count_tokens`(无状态,见 [Token 与采样](/ai/01-models-and-context/02-tokens-and-sampling.md))估 input 量、乘单价预判成本;**别用 `tiktoken` 估 Claude**,少算 15–20%。

## 性能:延迟从哪来,怎么压

延迟主要是 output 长度的函数(每个 token 逐个解码)+ 思考开销 + 网络。

- **流式(streaming)是默认。** 长输入/长输出/大 `max_tokens` 一律流式:首 token 就开始返回,既改善体感(TTFT),又**避开非流式请求的 HTTP 超时**(SDK 对大 `max_tokens` 的非流式请求会直接拒绝,因为可能超 10 分钟把连接拖断)。要完整结果用 `.get_final_message()` / `.finalMessage()`。
- **effort 与回合数非线性。** agentic 任务上高 effort 常**减少**回合、反而更快更省;别假设"低 effort 一定快"。在自己的 eval 集上扫档(见 [评估与可观测](/ai/02-Agent/05-evaluation-and-observability.md))。
- **缓存也是延迟杠杆。** 命中缓存的前缀跳过重算,首请求慢可用 **预热**(启动时发一个 `max_tokens: 0` 请求把前缀写进缓存)消掉。
- **并行有缓存时序坑。** N 个相同前缀的请求**同时**发,谁也读不到别人还在写的缓存,全付全价;先发 1 个、等它开始流式、再发其余 N−1,后面的就能命中。

## 可靠性:限流、重试、幂等

### 错误码与该不该重试

| 码 | 含义 | 可重试 |
|---|---|:--:|
| 400 | 请求非法(参数/格式) | ❌ 改请求 |
| 401 / 403 | 认证/权限 | ❌ |
| 404 | 模型 ID 错或端点错 | ❌ |
| 429 | 限流(RPM/TPM/TPD 超额) | ✅ 退避后重试 |
| 500 / 529 | 服务端错/过载 | ✅ 退避后重试 |

铁律:**4xx(除 429)不要重试**——同样的请求重发还是错。**429/5xx 才退避重试。**

### 退避与 SDK 自带重试

429 响应带 `retry-after` 头(等多少秒)。**SDK 默认已对 408/409/429/5xx 做指数退避重试(`max_retries=2`)**——多数情况无需自己写。只有要更激进/更克制时才自定义:指数退避 + 抖动(jitter),设上限。

> 超时也会被重试,所以最坏墙钟时间可达 `timeout × (max_retries+1)`,设 `timeout` 时把这点算进去。

### 幂等:重试不能把副作用做两遍

退避重试遇上**有副作用的工具**(发邮件、扣款、`git push`)是隐患:第一次其实成功了只是响应超时,重试就发了两封。对策落在宿主侧,不在模型侧:

- 危险/不可逆动作走 **human-in-the-loop** 确认(见 [Agent 循环](/ai/02-Agent/01-the-agent-loop-and-tool-use.md))。
- 副作用操作带**幂等键**:同一逻辑动作用同一 key,服务端去重。
- 把"决定做"和"真去做"分开:模型产出意图,宿主校验+幂等执行。

### 归因:并发/批量结果绝不靠顺序

并发请求、Batches 结果都可能**乱序**返回。用 `custom_id` / trace id 把结果对回请求(见 [评估与可观测](/ai/02-Agent/05-evaluation-and-observability.md)),**绝不靠到达顺序**——这是批量场景最常见的串号 bug。

## 最佳实践

- **prompt caching 先上,前缀焊死。** 稳定前缀放前、动态后置,两次调用即回本;盯 `cache_read_input_tokens` 验证命中。
- **按成本分层选模型。** 简单任务便宜模型、复杂走 Opus;Models API 查能力,别猜。
- **非实时任务走 Batches,半价。** 结果按 `custom_id` 对号,绝不靠顺序。
- **长输入/输出一律流式。** 改善 TTFT + 避开非流式 HTTP 超时;完整结果用 `get_final_message`。
- **重试只给 429/5xx,4xx 不重试。** 优先用 SDK 自带退避,别重造轮子。
- **有副作用的动作要幂等 + 人工确认。** 退避重试 × 副作用 = 重复执行,用幂等键 + human-in-the-loop 兜。
- **成本/延迟进监控。** `usage` 三字段、`stop_reason` 分布、缓存命中率上仪表盘(见 [评估与可观测](/ai/02-Agent/05-evaluation-and-observability.md))。

## 权衡与失败模式

- **缓存静默失效**:system 插时间戳/中途换模型,`cache_read` 长期 0、成本翻几倍 → 焊死前缀,逐字节 diff 排查。
- **无脑顶配模型**:简单任务也用 Opus + `max`,贵且慢 → 按任务分层,扫 effort。
- **大 `max_tokens` 非流式**:HTTP 超时、连接被拖断 → 流式 + `get_final_message`。
- **4xx 也重试**:同样请求重发还是错,白烧配额 → 只重试 429/5xx。
- **重试踩副作用**:超时重发把邮件发两遍 → 幂等键 + 人工确认危险动作。
- **靠顺序归因**:Batches/并发乱序导致串号 → 一律 `custom_id`/trace id 对号。
- **用 `tiktoken` 估 Claude 成本**:低估 15–20% → `count_tokens`。

## 参考

- **Anthropic 官方文档**: Prompt Caching、Batch Processing、Rate Limits、Errors、Streaming、Models API、Token Counting(platform.claude.com,实现前以官方为准)
- **关联**: [上下文工程](/ai/01-models-and-context/01-context-engineering.md)、[评估与可观测](/ai/02-Agent/05-evaluation-and-observability.md)、[Agent 循环与工具](/ai/02-Agent/01-the-agent-loop-and-tool-use.md)、[多 Agent 编排](/ai/02-Agent/04-multi-agent-orchestration.md)

*Keywords: cost optimization, token 计费, prompt caching 经济学, cache_read_input_tokens, Batches API, custom_id, 乱序归因, 50% 折扣, count_tokens, 选模型, Models API, effort, streaming, TTFT, HTTP timeout, 缓存预热, max_tokens 0, rate limit, 429, retry-after, 指数退避, exponential backoff, jitter, max_retries, 幂等, idempotency, human-in-the-loop, 错误码, 4xx 不重试*
