Claude Code 的 model 和 effort 两种设置都旨在提升输出,但机制不同。model 越大,模型能力越强(基于行业标准基准测试)。effort 控制 Claude 在请求上的总工作量,包括思考时间、读取文件数、验证程度、多步任务推进深度等。高 effort 时 Claude 会执行更多操作(读文件、跑测试、再检查);低 effort 时更倾向询问上下文。模型选择本质是切换不同的冻结权重集——权重在训练时固定,prompt 和上下文只能引导(steering)而不能改变权重。模型幻觉是权重产生看似合理但错误的 token 序列。
Claude Code 官方这篇把 model 和 effort 的取舍讲得比他处都透,读完就知道什么任务该堆算力、什么任务该降模型省钱。
Claude Code 提供了两种看似都能"让回答变得更好"的设置:模型和努力程度。但这两者对输出结果实际做了什么?你又该如何判断是换一个不同的模型,还是仅仅调整努力程度?
人们很容易认为,选择像 Fable 这样更大的模型会比 Sonnet 给出更聪明的输出,而更高的努力程度只意味着 Claude 在回答前会思考更久。
第一个假设是对的。根据行业标准基准测试,我们最大的模型能力更强。
但努力程度并不仅意味着"思考时间"。努力程度控制着 Claude 对你请求所做的全部工作的总量。这包括它思考多长时间,但也包括:
- 它读取多少个文件;
- 它进行多少验证;以及
- 在执行多步骤任务时,它会推进多远才向你汇报。
在更高努力程度下,Claude 在返回给你之前会执行更多此类操作(读取文件、运行测试、复核)。在较低努力程度下,它宁愿向你要更多上下文,也不愿自己花费 token 来弄明白某些事情。
模型选择是如何工作的
要理解模型设置实际控制什么,最好从头开始,从你按下回车的那一刻说起。
Claude Code 会将你的消息与系统提示词、工具定义、你的 CLAUDE.md 文件、对话历史记录以及上下文中的任何文件组合在一起。所有这些内容都会作为一次请求发送到 API。
不过,模型永远不会将这些看作纯文本。服务器上发生的第一件事是 token 化:文本被拆分成片段,每个片段被映射成模型训练时所使用的固定词汇表中的某个整数。const 可能映射到 1978,await 可能映射到 4293。从此刻起,你的提示词就是一个整数数组。
模型的任务是获取那个数组并预测下一个 token 是什么。它通过计算其词汇表中每个 token 的概率并从顶部选择来完成这一点。在 "const x = await" 之后,一个训练有素的模型会将高概率赋予 "fetch"(非常可能),而将接近零的概率赋予 "banana"(几乎不可能)。
是什么把你的输入 token 转化成那些概率的,是权重(也叫参数):数十亿个数字,排列成庞大的矩阵。为了预测一个 token,模型把你的输入通过这些矩阵运行一遍(一长串矩阵乘法),然后在末尾读取概率。模型“知道”的一切都存在于这些权重之中。
每个模型的权重都是在训练期间确定的,当你发送请求时,它们已经是只读的。你的提示词、你的 CLAUDE.md、或者你的上下文都不会改变它们。如果你遇到过“推理”这个词,那就是它的意思:训练完成后,在权重固定的情况下使用模型。
Claude 知道的关于 TypeScript、流行框架或任何其他通用编程知识的一切,在训练时就已经编码进了这些权重中。
你的提示词和上下文仍然可以引导预测。把你的真实代码放在 Claude 面前就是一种引导,而且效果很好。不过,这并不会向权重本身添加任何东西。
如果某个库在模型训练时还不存在,那它就不在权重中。你可以把文档放进上下文,Claude 会使用它们,但这是引导,而不是教会。Claude 的响应只在那一次请求中受到影响,但底层模型并没有记住任何东西。
当 Claude 自信地调用一个不存在的 API(即模型幻觉)时,那是权重根据训练模式生成一个看起来合理的 token 序列,而不是一次失败的查找。
那么,改变模型实际上在做什么?它是在切换处理你请求的那一组固定权重。
模型并不会一次性生成整个回答。它先预测一个 token,把它添加到序列中,然后重新运行整个计算来得到下一个 token。一个 200 token 的回答需要经过权重处理 200 次。这个循环就是你大部分等待时间(以及你的输出成本)的来源。
模型设置决定了哪些权重来处理你的请求,也决定了每个输出 token 的成本。
但它不决定生成的 token 数量。对于同一个提示词,这个数字可能差别很大,取决于 Claude 决定做多少工作。
而这正是“努力程度”所控制的内容。
努力程度的工作原理
当 Claude Code 在处理一个任务时,它生成的 token 可以分为几类:
- 思考(Thinking):你看到的在操作之前和操作之间流式传输的推理过程。
- 工具调用:结构化的代码块,命名一个工具(如 Read 或 Edit)及其参数,然后由 Claude Code 解析并执行。
- 发送给你的文本:计划、进度更新、最后的总结。
这些都是同一个循环中产出的普通输出 token,按相同费率计费。例如,思考 token 的生成方式与其他输出 token 完全相同,并在该轮次剩余的上下文中保留。
当 Claude 转而编写代码时,它之前的推理已成为输入的一部分,就像它读取过的文件一样。
那么,努力程度如何改变这一切?努力程度是作为请求的一部分发送给模型的,与你的提示词并列。模型经过训练,懂得如何在每个努力级别下表现,而这种学到的行为被固化在冻结的权重中。
当你的请求到达时,努力程度只是模型响应的另一个输入,就像它响应你的提示词文本一样。它设定了 Claude 在认为任务完成之前需要达到的全面程度和确定程度。这一点会在每一轮被权衡,更高的置信度需要消耗更多 token 才能达到。
在更高的努力级别下,Claude 通常会先创建一份计划,而努力级别会影响该计划的深度和广度。但计划并非一成不变。当 Claude 从自己的行动中获取结果后,它会更新自己对已取得进展的认知,以及对累积结果的确定程度。
当包含三个假设的调试计划中的第 1 步找到了 bug 时,“调查假设 2 和 3”可能就不再必要了。Claude 通常会明确说明这一点(例如“第一次检查就找到了,所以剩余检查不需要了”),然后跳过。你在 Claude Code 中看到任务列表在运行中被修订时,就会发生这种情况。
更高的努力级别确实会让 Claude 更可能进行双重检查,比如验证它找到的答案,或者仍然查看它本可以跳过的假设。然而,它通常不会因为努力级别调高,就在一个简单任务上人为地增加使用量。“过度思考”是我们团队在模型训练期间特别关注的问题,因为它会降低效果。
选择努力级别
对于大多数任务,使用模型的默认努力级别。默认级别是 Claude 将其 token 使用量调整到大多数人在任务上愿意花费的水平。
将努力程度视为一个手动开关,用来控制Claude工作的努力程度和时长。当你基于自己的领域或工作类型,对彻底性或速度有强烈偏好时,可以有意识地调整它,并将其视为一种通用偏好,而非逐任务的决定。
在Opus 4.8发布后有一个实用提示:在我们的测试中,对于同一任务,Opus 4.8的默认努力设置在消耗大致相同数量的模型token时,比Opus 4.7的默认努力设置产生更好的结果。
当Claude出错时该调整什么
当Claude出错时,你的第一反应不应该是调整设置。而应该是检查你提供的上下文。你的提示词是否过于模糊?Claude是否连接了正确的工具?它是否具备正确的技能?
如果你为一个本不需要的任务增加了努力程度,修复通常在上游:你的上下文、你的CLAUDE.md文件,或者任务的范围界定。
但假设你提供了清晰的上下文,Claude仍然出错。那么你需要问自己:是它不够努力,还是它知识储备不足?
模型:问题太难
当问题确实困难时——比如微妙的错误、不熟悉的领域或架构决策——选择更大的模型。当较小的模型无论你提供多少上下文都自信地给出错误答案时,你需要的是更大的模型。
更大的模型也更擅长处理歧义。在较小的模型上,指导执行的具体指令才是成功的更好方法。
当工作是常规性的——你可以精确描述的编辑、机械性修改、关于上下文中已有代码的问题——选择较小的模型。没有理由为任务不需要的能力付费。
如果Claude拥有所有相关上下文,明显尝试了,但仍然出错,那就是选择更大模型的信号。而如果你在使用较大模型,并且工作已经常规化一段时间,降低模型大小将提高速度,通常还能降低成本,且不影响输出质量。
努力程度:Claude不够努力
如果Claude因不够努力而出错——比如跳过某个文件、没有运行测试、或没有复核自己的工作——则选择更高的努力程度。这在你选择了低于模型默认努力程度的情况下最为相关。
专才、专家与通才
我喜欢把这两种设定的区别理解为:Fable 是一个专才,能处理几乎没人能搞定的问题;Opus 是专家;而 Sonnet 是非常优秀的通才。努力程度决定了它们当中任何一个愿意花多少时间处理你的任务。
低努力程度下的 Opus,就像给你五分钟时间,去请教一位对你这类问题有深厚经验的专家。他们拥有你代码库里没有的知识——他们以前见过的模式、他们知道要去检查的陷阱,这些经验只有解决过大量类似问题才能积累。但五分钟意味着只能快速扫一眼你的代码,而不是仔细翻阅每一个文件。
高努力程度下的 Sonnet,则像是一个拥有一整个下午的通才。他们很擅长编码,会读遍所有内容、运行代码、复核自己的成果,最终彻底理解你具体的代码。
Fable 是你在所有人都卡住时才会请来的专才。即使是在低努力程度下,他们也能发现别人发现不了的东西。这种识别力也正是你付钱买单的核心,所以值得把它留给真正需要的任务。
没有哪一个在绝对意义上“更好”。模型设定大致决定了能力有多强;努力程度设定大致决定了有多彻底。大多数实际任务需要两者兼备。
努力程度、模型与 token 消耗
那么,模型选择、努力程度和 token 消耗这三者是如何相互作用的呢?这取决于具体任务。
在同样努力程度下的日常工作中,大模型和小模型通常都能做对。大模型会消耗更多 token 用于额外的验证步骤,而且每 token 价格更高。这就是为什么在日常任务中换用更小的模型,可以在不牺牲质量的前提下省下真金白银。
对于更困难、多步骤的工作,情况就反过来了。小模型需要拼命逼近自身能力的极限,反复迭代,而大模型用更少的步骤就能达到相同的质量水平。
大模型的每 token 价格更高,但在那些真正挑战小模型能力的任务上,每个任务的总成本反而可能更低。更重要的是:即使在最高努力程度设定下,小模型完成不了的任务,大模型也能完成。
这一点在 Fable 身上体现得最为明显。在长篇幅、多步骤的工作中,它的领先优势最大。在我们的测试中,它完成了 Opus 和 Sonnet 在任何努力程度下都无法完成的任务。它的每 token 成本也最高,这是另一个需要把它留给真正需要它的任务的原因。
上面图表中的关键点在于:努力程度决定了 Claude 愿意沿着曲线走多远。但这并不意味着 Claude 必须走那么远才能完成任务。
最后,努力程度会影响模型 token 消耗,但并不会限制它。系统中唯一的硬上限是 max_tokens,一旦触及,它会直接切断正在生成的回复,但这是一个非常粗暴的手段,主要与 API 开发者相关。像任务预算或在提示词中请 Claude 保持简洁这类更柔性的控制措施,反而更有用。它们是模型被训练去遵循的指导(当接近上限时,模型会设法收尾),而不是一道它会硬撞上去的墙。
努力程度改变的是 Claude 做了多少工作。模型改变的是 Claude 知道什么。
当你对某个结果不满意时,在调整这两个设置之前,先检查上下文:给 Claude 清晰的提示词、合适的工具和技能,以及一种能验证自身工作的方式。
如果 Claude 仍然出错,问自己:是它知道得不够多,还是它不够努力?知道得不够多是模型问题,不够努力是努力程度问题。
本文由 Claude Code 团队技术成员 @lydiahallie 撰写。
来源:ClaudeDevs · x.com