DeepSeek 模型选型:Flash 与 Pro 怎么选,怎么算账
这篇不谈跑分,谈工程上能落地的三件事:两个模型在接口层面到底差在哪里、思考模式怎么开关又有哪些坑、成本怎么估。所有价格和参数来自官方文档,查询日期 2026-11-10;价格会调整,下单前请以官方页面为准。
1. 当前的两个模型
官方“Models & Pricing”页目前列出两个 API 模型名:
| API 名称 | 背后的模型版本 | 定位 |
|---|---|---|
deepseek-flash | DeepSeek-V4.1-Flash-1017 | 便宜、快、并发高、支持图像输入 |
deepseek-v4-pro | DeepSeek-V4-Pro-0813 | 更大的模型,价格约为 Flash 的 3.3 到 4.4 倍(输出 3.3 倍,未命中输入 4.4 倍) |
两点命名上的提醒:
deepseek-flash是现在的推荐写法。旧名deepseek-v4-flash等仍可使用,但对应的旧模型已经下线,请求会被转到当前的 Flash 版本,并按 Flash 价格计费。- “模型名”是别名,“模型版本”会变。像
-1017这样的后缀是版本标记。如果你的程序对输出格式很敏感,要意识到别名背后的模型可能更新,建议在日志里记录每次调用返回的模型信息,行为变化时才查得到原因。
2. 接口层面的差异
下面这些是官方页面上明确写出的,不是我的推测:
| 项目 | deepseek-flash | deepseek-v4-pro |
|---|---|---|
| 上下文长度 | 1M(两者相同) | |
| 最大输出 | 384K(两者相同) | |
| 思考 / 非思考模式 | 都支持,默认思考 | |
| JSON 输出、工具调用 | 支持 | 支持 |
| 图像输入(Vision) | 支持 | 不支持 |
| FIM 补全(Beta) | 仅非思考模式 | |
| 并发上限 | 2500 | 500 |
| OpenAI / Anthropic 格式 | 都兼容(基础地址分别为 api.deepseek.com 与 api.deepseek.com/anthropic) | |
从这张表能直接推出几条选型结论,不需要任何评测:
- 要处理图片,只能用 Flash。
- 要大批量并发(比如一次性并行处理几千个小任务),Flash 的并发上限是 Pro 的 5 倍。
- 上下文窗口和输出长度没有差别,不要因为“长文档”而默认选 Pro。
3. 思考模式:开关、强度与一个必踩的坑
开关与强度
思考模式默认开启,默认强度是 high。用 OpenAI SDK 调用时,开关要放在 extra_body 里,强度用 reasoning_effort:
from openai import OpenAI
client = OpenAI(api_key=KEY, base_url="https://api.deepseek.com")
# 简单分类、抽取、改写:关掉思考,更快更省
resp = client.chat.completions.create(
model="deepseek-flash",
messages=[{"role": "user", "content": "把这段话改成一句话摘要:..."}],
extra_body={"thinking": {"type": "disabled"}},
)
# 复杂推理:开启思考并拉高强度
resp = client.chat.completions.create(
model="deepseek-flash",
messages=[{"role": "user", "content": "..."}],
reasoning_effort="max", # low / high / max
extra_body={"thinking": {"type": "enabled"}},
)
强度的取值是 low / high / max,其他常见写法会被映射:minimal 与 low 归为 low,medium 与 xhigh 归为 high,ultra 归为 max。
思考模式下,采样参数基本无效
temperature、presence_penalty、frequency_penalty 在思考模式下不报错但也不起作用。如果你的程序靠调 temperature 来控制输出的随机性,切到思考模式后这个手段就失效了。
必踩的坑:工具调用时要回传 reasoning_content
模型返回的内容里,除了 content,还有和它平级的 reasoning_content(思考过程)。官方的规则是:
- 请求里没有
tools:不用回传,传了也会被忽略。 - 请求里带了
tools:后续每一轮请求都必须把之前所有轮次的reasoning_content完整带回去,即使某一轮模型没有发起工具调用也要带。否则接口返回 400 错误。
4. 计费:峰谷、缓存、输出
价格单位是美元 / 百万 token。下表为官方页面的数字(查询日期 2026-11-10):
| Flash 谷时 | Flash 峰时 | Pro 谷时 | Pro 峰时 | |
|---|---|---|---|---|
| 输入(缓存命中) | $0.003 | $0.006 | $0.022 | $0.044 |
| 输入(缓存未命中) | $0.15 | $0.30 | $0.66 | $1.32 |
| 输出 | $0.60 | $1.20 | $1.98 | $3.96 |
从这张表里能读出三件事:
① 峰谷价差是 2 倍
官方说明:谷时价是峰时价的一半。峰时为每周一到周五的 UTC 01:00–04:00 与 06:00–10:00(中国法定节假日除外),其余时间,包括周末和中国法定节假日全天,都是谷时。换算成北京时间(UTC+8),峰时就是工作日的 09:00–12:00 和 14:00–18:00。
结论很直接:不着急的批处理任务,排到晚上或周末跑,价格直接减半。定时任务的触发时间,值得专门核对一下有没有落进这两个时间段。
② 缓存命中便宜得多
Flash 的缓存命中输入价只有未命中的 1/50,Pro 约为 1/30。含义是:把固定不变的内容(系统提示词、规则说明、few-shot 示例)放在提示词的最前面,把每次变化的内容放在最后,才有机会命中缓存。如果每次都把日期、随机 ID 之类的变量塞在开头,缓存就全废了。
③ 输出比输入贵 3 到 4 倍
Flash 的输出价是未命中输入价的 4 倍,Pro 约 3 倍。限制输出长度(比如要求“只输出 JSON,不要解释”)往往比压缩输入更能省钱。思考模式会产生额外的思考内容,实际消耗以返回结果里的 usage 字段为准,不要凭感觉估。
5. 一个具体的成本估算
假设有一个每天跑一次的摘要任务:每次输入约 20 万 token(其中固定的提示词与规则占 4 万,缓存可命中;其余 16 万是当天的新内容,不命中),输出约 2 万 token,全部在谷时运行。
| 项目 | Flash | Pro |
|---|---|---|
| 缓存命中输入 0.04M | 0.04×0.003 = $0.00012 | 0.04×0.022 = $0.00088 |
| 未命中输入 0.16M | 0.16×0.15 = $0.024 | 0.16×0.66 = $0.1056 |
| 输出 0.02M | 0.02×0.60 = $0.012 | 0.02×1.98 = $0.0396 |
| 单次合计 | 约 $0.036 | 约 $0.146 |
| 30 天合计 | 约 $1.1 | 约 $4.4 |
同一个任务如果落在峰时,价格翻倍。这个量级说明:对个人和小规模应用,模型的单价通常不是瓶颈,调用方式(是否命中缓存、是否错峰、是否无谓地开思考)才决定账单是 1 美元还是 10 美元。大规模调用时,Flash 与 Pro 的差距才会变成实质性的预算问题。
6. 怎么选:一张决策表
| 场景 | 建议 | 理由 |
|---|---|---|
| 输入里有图片 | Flash | Pro 不支持图像 |
| 大批量并发的小任务(分类、抽取、改写) | Flash,关思考 | 并发上限 2500,便宜,这类任务通常不需要深度推理 |
| 定时批处理、不赶时间 | Flash,排在谷时 | 价格减半,延迟不重要 |
| 结构化输出(JSON) | 先用 Flash + JSON 输出 + 校验重试 | 失败率可以用工程手段压低,见第 8 节 |
| 复杂代码生成、多步推理、长链条规划 | 先试 Flash 开高强度思考,不够再上 Pro | 先用最便宜的方案跑你自己的评测,用数据决定是否升级 |
| 交互式、用户在等 | Flash,视情况关思考 | 思考会增加首字延迟,简单问题没必要 |
| 代码补全(FIM) | 非思考模式 | FIM 只在非思考模式下可用 |
| 错误成本高、结果要人工兜底前尽量准 | Pro,思考开启 | 多花的钱换更低的返工率,是否值得由你的评测数据决定 |
这张表里“先试 Flash,再决定是否升级”出现了好几次。我不建议默认选最大的模型:多数任务 Flash 就够,升级前应该有数据支持,而不是凭名字的印象。
7. 用自己的任务做评测
公开的跑分和你的任务关系有限。我的做法很朴素,半天就能做完:
- 收集 30 到 50 条真实输入,包括几条你知道会出问题的边界样例。
- 为每条写一个能自动判定的标准:JSON 能否解析、字段是否齐全、关键数值是否等于人工答案。判定不了的,人工打 0/1 分。
- 同一批输入,分别用 Flash(关思考)、Flash(开思考)、Pro 各跑一遍,记录成功率、平均延迟和
usage里的 token 数。 - 算“每成功一条的成本”,不是“每次调用的成本”。成功率低的便宜方案,加上重试后可能反而更贵。
import time
def run_case(model, thinking, case):
t0 = time.time()
r = client.chat.completions.create(
model=model,
messages=case["messages"],
extra_body={"thinking": {"type": "enabled" if thinking else "disabled"}},
)
return {
"ok": case["check"](r.choices[0].message.content),
"sec": time.time() - t0,
"in": r.usage.prompt_tokens,
"out": r.usage.completion_tokens,
}
8. 实践中遇到的几个问题
结构化输出偶发不合规
我有一个每天自动运行的小任务,要求模型输出 JSON。用 Flash 跑起来后,偶尔会出现字符串里的引号没转义、多出一段说明文字,导致解析失败。后来的处理是三层:
- 解析前先做确定性的清理,比如处理字符串内部未转义的引号;
- 解析失败时,用 JSON 修复库尝试修复;
- 还是失败,就把错误信息和原输出一起发回给模型,让它修正一次,再失败才放弃,并把出错的片段打印到日志里。
另外,官方接口支持 JSON 输出功能(见第 2 节的表),在提示词里明确给出期望的结构和一个完整示例,再配合这个功能,可以进一步降低出错概率。这是值得优先尝试的第一层,我还没有系统比较过启用前后的失败率,所以这里不下数字结论。
这套办法把失败率压到了可以接受的程度,成本几乎不变,比“换更大的模型”划算得多。结构化输出的可靠性,主要靠工程手段保证,而不是靠模型“更聪明”。
别名背后的版本会变
前面提到过:同一个 deepseek-flash,过一阵子背后可能是新版本。有一天你发现输出风格变了,先查日志里的模型版本,再怀疑自己的代码。
别忘了限流与重试
并发上限是官方给的硬数字,批量任务要自己控制并发度(比如用信号量限制在上限的一半以内),并对 429 和 5xx 做带退避的重试。