Claude 代码模型选择:默认设置、切换及成本

Claude 代码模型选择:默认设置、切换及成本

在选择 Claude 代码模型时,对于规模较小且可测试的更改,应使用 Haiku;对于常规实现,应使用 Sonnet;而对于存在较大不确定性或需要更多推理的工作,则应使用 Opus。. Anthropic 目前推荐 Opus 5.5 作为广泛适用的入门机型;具体选择是否更适合较小型号,则取决于您的任务需求、审查工作量和预算。.

要切换模型,请打开 /模型. 新闻 进入 要保存默认设置,或者 s 仅切换当前会话。若仅需启动一次,请使用 克劳德——《Opus》模型. 这些选项的持久性各不相同,因此决定开关应保持多长时间,与选择模型同样重要。.

编程工作还涉及研究、说明、文档编写以及创意资源的制作。GlobalGPT 将领先的 AI 模型和多种 AI 工具整合到一个价格实惠的控制台中,而其命令行界面(CLI)则将这些工具与终端及开发工作流相连接。. 使用 GlobalGPT 构建您的工作流 在将想法转化为可运行代码的过程中,将这些相关任务集中管理。.

在 Claude 代码中应该使用哪个模型?

首先从工作内容的形式入手。一个输出预期明确的简短函数,其评估方式与一个分散在多个服务中的间歇性错误是不同的。关键问题在于:该模型是否能在合理的审查和迭代过程中产生可接受的变更。.

当前型号其定位是什么一项实用的入门任务
克劳德俳句 4.5合同范围有限,工作高效快捷一次小规模的重构、重复的转换,或者一个简单的测试用例
克劳德·桑内特 5在日常编程中兼顾智能与速度具有既定模式的功能、例行错误修复或代码说明
Claude Opus 5.5(简体中文(大陆))复杂的推理和较长的能动编码作业一种模棱两可的失败、架构权衡,还是受相互作用的约束影响而产生的变化
Claude Fable 5.1最艰难且持续时间最长的调查当艰巨的工作仍能压倒更强的Opus工作强度时,情况便会升级
基于 Anthropic 文档的当前模型系列及任务适配情况;任务建议是切实可行的起点。.

当错误易于发现且变更幅度较小时,值得考虑使用“Haiku”模式。当日常实现需要更多上下文和判断时,“Sonnet”模式是一个明智的选择。当理解问题是任务的重要组成部分时,值得考虑使用“Opus”模式。对于要求较高的工作,“Fable”模式值得单独决策;它超出了我们这三种编码模型的测试范围。.

这些只是起点,并非质量的自动保证。如果一个价格较低的方案需要多次修改或大量审核,最终反而可能变得昂贵。反之,对于已经通过您检查的简单转换,更大型的模型可能几乎无法带来额外价值。若要将应用范围扩展到 Claude Code 之外,, 比较 Claude 系列型号.

Anthropic 当前针对 Fable 5.1、Opus 5.5、Sonnet 5 和 Haiku 4.5 的机型对比。.
Anthropic 的机型列表,截至 2026 年 9 月 28 日。Claude 代码中的机型供应情况取决于您的运营商和账户。.

"(《世界人权宣言》) 官方车型概览 列出了 Fable 5.1、Opus 5.5 和 Sonnet 5 的 100 万令牌上下文窗口,以及 Haiku 4.5 的 20 万令牌上下文窗口。这些是 API 规范。 您的 Claude 代码提供商、账户和配置将决定会话中可用的上下文选项。较大的上下文窗口对于提供必要的上下文信息很有帮助;但若用无关内容填充该窗口,仍会增加模型的处理负担。.

如何在单次会话中切换模型

在交互式会话中,运行 /模型 以打开模型选择器。选中模型行,然后按 s 如果这是一次性更改,请按 进入 将所选内容保存为您的用户默认设置。输入 /模态十四行诗 在当前版本中,直接操作也会将其保存下来。.

根据更改应持续多长时间来选择相应的命令

已记录的 Claude 代码行为,核查日期:2026年9月28日
你的目标该怎么做已保存默认更改?
仅切换此交互式会话开放 /模型, 选择一款机型,按 s.不.
保存心仪的款式开放 /模型 并按下 进入, ,或输入 /模态十四行诗.是的,当用户设置具有写入权限时。.
在 Opus 上开始单次会话启动 克劳德——《Opus》模型.不.
恢复为该账户的运行时默认值使用 /默认模型.清除模型覆盖;最终确定的默认值可能取决于账户和组织设置。.
检查当前模型运行 /status.不.

项目或受管设置、环境覆盖以及已恢复的会话可能会影响下次启动。当可重现性至关重要时,请检查当前活动的模型。.

来源:Claude 代码模型配置.

在新的终端会话中,请在启动时选择模型。当 Claude Code 在 VS Code 的集成终端中运行时,这些命令同样适用。以下示例明确选择了某个版本:

claude --model claude-opus-5-5
claude --model claude-sonnet-5

针对您想要的会话运行相应命令;示例中提供了多种选择。您可以使用不同的 --模型 无需反复修改共享的已保存默认值即可设置这些值。请使用 /status 以检查当前选中的模型。.

诸如以下这些姓氏: opus 和 十四行诗 可以升级到更新版本。其分辨率还取决于服务提供商:Anthropic API 目前将其映射为 Opus 5.5 和 Sonnet 5,而不同云服务提供商的映射可能有所不同。 当需要可重现的运行结果时,请使用完整的模型 ID;如果您的环境有特定要求,请检查供应商专用的名称。.

Opus 5.5 需要 Claude Code v2.1.280 或更高版本;Sonnet 5 需要 v2.1.197 或更高版本。该 模型配置文档 是当前别名、版本要求和提供程序映射的参考资料。此处的命令仅为文档示例;在“动手实践”部分中,我们将单独评估生成的代码。.

Claude 代码文档,解释了模型选择以及“Enter”和“s”键的功能。.
输入 Enter 可将该模型保存为默认设置;输入 s 仅更改当前会话中的设置。.

如何设置默认模型

若要设置个人默认值,请在 /模型 并按下 进入, ,或者输入如下选项: /模态十四行诗. Claude 代码写入 模型 当该文件可写时,请在用户设置中填写该字段。打开一个新会话,并检查其活动模型以确认结果。.

已保存的偏好设置不会覆盖所有其他设置。启动标志,, ANTHROPIC_MODEL 在 shell、项目或托管设置中,或者在配置为覆盖用户选择的组织默认设置下,启动时可能会选择其他内容。恢复的会话也可能保留其已保存记录中的模型。请检查启动信息并 /status 在认定这个选择已经失去之前。.

/默认模型 清除您的模型覆盖设置,并恢复为您的账户和配置对应的运行时默认值。该词 默认 这是一个重置值,并非某个固定 Claude 模型的名称。不应将其用作可重现的模型标识符。.

如需进行高级配置,, ANTHROPIC_DEFAULT_MODEL 从 v2.1.236 版本起,该选项提供了备用初始选择。它位于显式启动、环境、设置和组织选项之下,并忽略包括以下在内的值: 俳句 和 opusplan. 对于一般的个人偏好而言,选择器更容易验证。参见 Claude 代码设置 当涉及共享配置时。.

Opusplan 实际上是做什么的

opusplan 在规划模式下使用Opus,在执行阶段使用Sonnet。其吸引力不言而喻:先利用更强大的推理模型来制定方案,再借助日常编码模型来执行该计划。.

Opusplan 采用以下工作模式

计划模式作品逐步实践这一方法。.
执行十四行诗执行该计划。.

已记录的路由行为。这些名称所对应的版本取决于您的服务提供商和配置。.

来源:Claude 代码模型配置

这是一条取决于模式的规则。它不会检查每个提示,也不会自动选择最经济的合适模型族。提供商的映射和访问限制仍然适用于底层模型。此外,名称本身也不能保证能节省成本:总成本取决于任务所需的规划、实现、修订和上下文处理的工作量。.

不妨换个角度考虑:当设计能从更深入的分析中获益,且实现过程遵循明确的计划时,这种做法就值得采纳。但如果是小幅修改,那么额外的规划可能就没必要了。.

这两项编码任务揭示了什么

为了更具体地说明模型选择,我们测试了一个针对Unicode的局部重构以及一个具有交互式要求的路由选择器修复方案。结果表明,正确函数与完整交付结果之间的区别,比单纯的分数更为重要。.

我们如何测试编码结果

2026年9月28日,我们向Claude Haiku 4.5、Claude Sonnet 5和Claude Opus 5.5分发了相同的两项JavaScript任务,直至GlobalGPT。 每个模型都返回了源代码;我们检查了代码并运行了固定的本地检查。本指南中关于Claude Code模型切换的说明摘自其官方文档。.

每次请求的输出限制为 4,096 个令牌,不使用任何工具,也没有对话历史记录,且采用默认模型设置。我们保留了第一个可评估的响应,包括不完整的响应。Sonnet 的路由任务中出现了一次服务错误,允许重试一次:七次请求共产生了六条输出。.

这两项小型任务用于衡量返回代码和交付完整性。它们并未衡量 Claude Code 的代理执行、代码库探索或整个开发会话。实际费用未予披露。每项任务仅有一项观察结果,不足以确定总体速度或可靠性排名。.

查看确切的模型 ID 和评估条件

请求的ID: claude-haiku-4-5-20251001, 克劳德·十四行诗-5, 和 克劳德-作品第5号-第5首. 本地测试是在 Node.js v24.19.0 环境下进行的。提示信息针对的是 Node.js 18 及以上版本;Node.js 18 本身未经过测试。.

在“蛞蝓任务”中设定了8个行为组,在“路径选择器”任务中设定了12个行为组。格式符合性和完整交付情况分别进行报告。后续的代码审查检查被单独标注,且不会改变上述统计数据。我们并未编辑返回的源代码以使其通过审查。.

任务 1:在小型 slug 重构中保留 Unicode

该函数必须保留非拉丁字母和组合符号,规范分解后的重音符号,并保持其现有的 ASCII 行为。.

首先返回结果,并包含固定的本地行为检查
模型行为检查响应格式完成要求的送货
克劳德俳句 4.58/8错误:Markdown 包装器是:完整函数
克劳德·桑内特 58/8参数:原始 JSON是:完整函数
Claude Opus 5.5(简体中文(大陆))8/8参数:原始 JSON是:完整函数

观测结果: 这三个函数都通过了相同的八组测试。Sonnet 和 Opus 也符合原始 JSON 响应的要求。Haiku 将其响应包装在 Markdown 中,且其审查说明错误地将 NFC 描述为字符分解;但其代码正确地调用了 NFC。.

就这次局部的重构而言,升级并未改善被测试函数的行为。格式要求及随附说明的准确性仍需审核。.

查看完整的共享提示和输入代码
SYSTEM
You are completing a bounded JavaScript coding task. Return only the requested JSON object with complete source files and brief review notes. Do not claim to have edited files, run commands, or used tools. You have no tool access. Do not include hidden reasoning.

USER
Implement the following Node.js 18+ CommonJS function from its current source. Return complete replacement source for src/slugify.js. Do not add dependencies, imports, I/O, or other files.

Required behavior:
1. slugify(value) returns an empty string for every non-string input.
2. Normalize string input to Unicode NFC, then lowercase it using JavaScript toLowerCase().
3. Preserve Unicode letters, numbers, and combining marks. Replace each consecutive run of all other characters with one ASCII hyphen.
4. Trim leading and trailing hyphens. Preserve the CommonJS export { slugify }.
5. Existing ASCII behavior must continue to work. Examples: Hello, World! -> hello-world; two   words -> two-words; null -> empty string.
6. Additional examples: Café déjà vu -> café-déjà-vu; decomposed Cafe\u0301 -> café; 中文 测试 42 -> 中文-测试-42; **hi___there** -> hi-there; only punctuation or whitespace -> empty string.

Current src/slugify.js:
```javascript
function slugify(value) {
  if (typeof value !== "string") return "";
  return value
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

module.exports = { slugify };


```

Return exactly one JSON object with this shape:
{"files":{"src/slugify.js":"complete JavaScript source as a JSON string"},"review_notes":["at most four brief implementation or assumption notes"]}
No Markdown wrapper. You are returning code for someone else to evaluate locally; do not say that tests passed or that you ran them.
查看 Claude Haiku 4.5 提供的完整回复(按原样呈现)
```json
{
  "files": {
    "src/slugify.js": "function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  \n  // Normalize to NFC and lowercase\n  const normalized = value.normalize(\"NFC\").toLowerCase();\n  \n  // Replace consecutive runs of non-letter, non-number, non-combining-mark characters with a single hyphen\n  // Unicode letter categories: L* (Lu, Ll, Lt, Lm, Lo)\n  // Unicode number categories: N* (Nd, Nl, No)\n  // Unicode combining mark categories: M* (Mn, Mc, Me)\n  const slugged = normalized.replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\");\n  \n  // Trim leading and trailing hyphens\n  return slugged.replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };"
  },
  "review_notes": [
    "Uses String.prototype.normalize(\"NFC\") to decompose composed characters like é into base+combining mark, then toLowerCase() applies to normalized string",
    "Unicode property escapes (\\p{L}, \\p{N}, \\p{M}) with /u flag preserve all Unicode letters, numbers, and combining marks while replacing other consecutive characters with single hyphens",
    "Existing ASCII behavior is preserved: punctuation and whitespace are replaced with hyphens, then leading/trailing hyphens are trimmed",
    "Non-string inputs return empty string as required; normalized decomposed characters (e.g., Cafe\\u0301) are handled correctly by NFC normalization"
  ]
}
```
查看 Claude Sonnet 5 返回的完整回复
{"files":{"src/slugify.js":"function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  return value\n    .normalize(\"NFC\")\n    .toLowerCase()\n    .replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\")\n    .replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };\n"},"review_notes":["Used Unicode property escapes (\\p{L}, \\p{N}, \\p{M}) with the u flag to preserve letters, numbers, and combining marks across scripts.","NFC normalization ensures decomposed sequences like Cafe + combining acute compose to café before lowercasing.","Runs of any other characters (punctuation, whitespace, symbols) collapse to a single hyphen, then leading/trailing hyphens are trimmed."]}
查看 Claude Opus 5.5 返回的完整回复
{"files":{"src/slugify.js":"function slugify(value) {\n  if (typeof value !== \"string\") return \"\";\n  return value\n    .normalize(\"NFC\")\n    .toLowerCase()\n    .replace(/[^\\p{L}\\p{N}\\p{M}]+/gu, \"-\")\n    .replace(/^-+|-+$/g, \"\");\n}\n\nmodule.exports = { slugify };\n"},"review_notes":["The input is normalized to NFC before lowercasing, so decomposed input like Cafe\\u0301 composes to café.","A Unicode property regex with the u flag keeps letters (\\p{L}), numbers (\\p{N}) and combining marks (\\p{M}). Each run of any other characters, including underscores and whitespace, becomes one hyphen.","The explicit trim() was removed because the final step strips leading and trailing hyphens, which covers surrounding whitespace.","Lowercasing happens after NFC normalization, as the spec orders. toLowerCase can occasionally produce non-NFC output for rare characters, and it is not re-normalized here."]}

任务 2:修复一个路由选择器并提交其测试用例

该函数必须处理最长前缀匹配、方法优先级、段边界、格式错误的规则以及不可变的输入。请求的响应中还包含了一个新的测试文件。.

首先返回结果,并包含固定的本地行为检查
模型行为检查响应格式完成要求的送货
克劳德俳句 4.5仅针对完整功能,12月12日失败:JSON 内容被截断编号:测试文件被截断
克劳德·桑内特 5仅针对完整功能,12月12日失败:JSON 内容被截断编号:测试文件被截断
Claude Opus 5.5(简体中文(大陆))仅针对完整功能,12月12日失败:JSON 内容被截断编号:测试文件被截断

观测结果: 没有一个模型能在共享的输出限制内完成要求的两个文件的响应。这三个模型均在报告了4,096个完成令牌后停止运行。每个模型此前都已返回了一个完整的路由器函数,该函数通过了十二个固定行为组的测试;而新的测试文件因不完整而未被执行。.

我们仅提取了每个完全封闭的源代码字符串。下文中的原始截断响应保持原样。因此,函数评分合格并不意味着整个请求都成功了。.

代码审查的其他发现:等根平局

在完成相关检查后,我们注意到Haiku已归一化 /// 转换为空字符串,而不是 /. 另一项独立的本地检查使用了两条 GET 规则,其前缀为 /// 和 /, ,目标为 第一次 和 第二 按这个顺序。对于 /任何内容, ,合同规定 第一次.

俳句回归 第二; 《十四行诗》和《作品集》已回归 第一次. 此次额外检查是由代码审查引发的,与测试前设定的十二项检查无关。它不会影响这些检查的分数。.

Sonnet 在其允许的重试返回所示的截断响应之前,曾遇到一次服务错误。该服务故障与代码质量无关。没有任何模型收到过再次尝试改进或完善其回答的请求。.

查看完整的共享提示和输入代码
SYSTEM
You are completing a bounded JavaScript coding task. Return only the requested JSON object with complete source files and brief review notes. Do not claim to have edited files, run commands, or used tools. You have no tool access. Do not include hidden reasoning.

USER
Repair a Node.js 18+ CommonJS route selector. Return complete replacement src/router.js and an additional test/router-added.test.js using node:test and node:assert/strict. Do not add dependencies or edit existing tests. Do not use I/O other than the test runner, network, child processes, timers, or any files beyond the two requested outputs.

Contract for chooseRoute(request, rules):
1. Invalid request or rules returns null, without throwing. Request must be a non-null, non-array object; method must be a nonempty ASCII-letter string; path must be a string beginning with /. Rules must be an array.
2. Before matching, remove the request path's query and fragment starting at the earliest ? or #. Do not URL-decode or collapse interior slashes.
3. Ignore invalid rules. A valid rule is a non-null, non-array object with method '*' or a nonempty ASCII-letter string, prefix a string starting with / containing neither ? nor #, and target a nonempty string.
4. Compare methods case-insensitively. Prefer any matching exact-method rule over all wildcard-method '*' rules, even if a wildcard has a longer prefix. Use wildcard rules only if no exact-method route matches the path.
5. Remove trailing slashes from a rule prefix, except that an all-slash prefix normalizes to /. A prefix matches the path only at a segment boundary: /api matches /api and /api/users, never /apix. Root / matches every valid request path.
6. Within the chosen method group, choose the longest normalized matching prefix. On equal prefix length, choose the earlier rule in the original input array. Return its target. Return null if none matches.
7. Do not mutate the request, rules array, or rule objects, including order or prefix strings. Preserve module.exports = { chooseRoute }.
8. Add tests for segment boundaries, query/fragment removal, method precedence, ties, malformed inputs and immutability. Existing simple GET /api/users and POST-no-match cases must still pass.

Current src/router.js:
```javascript
function chooseRoute(request, rules) {
  if (!request || !Array.isArray(rules)) return null;
  for (const rule of rules) {
    if (request.method === rule.method && request.path.startsWith(rule.prefix)) {
      return rule.target;
    }
  }
  return null;
}

module.exports = { chooseRoute };


```

Existing regression cases (unchanged): rules [{method:'GET',prefix:'/api',target:'api'},{method:'GET',prefix:'/api/admin',target:'admin'}]; GET /api/users returns 'api'; POST /api/users returns null.

Return exactly one JSON object with this shape:
{"files":{"src/router.js":"complete JavaScript source as a JSON string","test/router-added.test.js":"complete JavaScript tests as a JSON string"},"review_notes":["at most four brief implementation or assumption notes"]}
No Markdown wrapper. You are returning code for someone else to evaluate locally; do not say you edited files, ran tests, or observed passing results.
查看 Claude Haiku 4.5 提供的完整回复(按原样呈现)

这是收到的完整响应。由于达到了限制,响应在输出中途结束;缺失的内容未被补全。.

```json
{
  "files": {
    "src/router.js": "function chooseRoute(request, rules) {\n  // Validate request\n  if (request === null || Array.isArray(request) || typeof request !== 'object') {\n    return null;\n  }\n  if (typeof request.method !== 'string' || request.method.length === 0 || !/^[a-zA-Z]+$/.test(request.method)) {\n    return null;\n  }\n  if (typeof request.path !== 'string' || !request.path.startsWith('/')) {\n    return null;\n  }\n\n  // Validate rules\n  if (!Array.isArray(rules)) {\n    return null;\n  }\n\n  // Remove query and fragment from path\n  const cleanPath = request.path.split(/[?#]/)[0];\n\n  // Filter and validate rules\n  const validRules = [];\n  for (const rule of rules) {\n    if (rule === null || Array.isArray(rule) || typeof rule !== 'object') {\n      continue;\n    }\n    \n    const method = rule.method;\n    if (typeof method !== 'string' || (method !== '*' && (method.length === 0 || !/^[a-zA-Z]+$/.test(method)))) {\n      continue;\n    }\n    \n    const prefix = rule.prefix;\n    if (typeof prefix !== 'string' || !prefix.startsWith('/') || prefix.includes('?') || prefix.includes('#')) {\n      continue;\n    }\n    \n    const target = rule.target;\n    if (typeof target !== 'string' || target.length === 0) {\n      continue;\n    }\n    \n    validRules.push(rule);\n  }\n\n  // Normalize prefixes and partition into exact-method and wildcard groups\n  const exactMethodRules = [];\n  const wildcardRules = [];\n  \n  for (const rule of validRules) {\n    const normalizedPrefix = rule.prefix === '/' ? '/' : rule.prefix.replace(/\/+$/, '');\n    \n    const entry = {\n      originalRule: rule,\n      normalizedPrefix: normalizedPrefix,\n      method: rule.method\n    };\n    \n    if (rule.method === '*') {\n      wildcardRules.push(entry);\n    } else {\n      exactMethodRules.push(entry);\n    }\n  }\n\n  const requestMethod = request.method.toUpperCase();\n\n  // Helper to check if a prefix matches the path at a segment boundary\n  function prefixMatches(prefix, path) {\n    if (prefix === '/') {\n      return true;\n    }\n    if (!path.startsWith(prefix)) {\n      return false;\n    }\n    // Check segment boundary: next character must be '/' or end of string\n    const nextChar = path[prefix.length];\n    return nextChar === undefined || nextChar === '/';\n  }\n\n  // Try exact-method rules first\n  let bestMatch = null;\n  let bestLength = -1;\n  \n  for (const entry of exactMethodRules) {\n    if (entry.method.toUpperCase() === requestMethod) {\n      if (prefixMatches(entry.normalizedPrefix, cleanPath)) {\n        if (entry.normalizedPrefix.length > bestLength) {\n          bestMatch = entry.originalRule;\n          bestLength = entry.normalizedPrefix.length;\n        }\n      }\n    }\n  }\n  \n  if (bestMatch !== null) {\n    return bestMatch.target;\n  }\n\n  // Try wildcard rules only if no exact-method match\n  bestMatch = null;\n  bestLength = -1;\n  \n  for (const entry of wildcardRules) {\n    if (prefixMatches(entry.normalizedPrefix, cleanPath)) {\n      if (entry.normalizedPrefix.length > bestLength) {\n        bestMatch = entry.originalRule;\n        bestLength = entry.normalizedPrefix.length;\n      }\n    }\n  }\n  \n  if (bestMatch !== null) {\n    return bestMatch.target;\n  }\n\n  return null;\n}\n\nmodule.exports = { chooseRoute };",
    "test/router-added.test.js": "const test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router.js');\n\n// Regression: existing test cases\ntest('GET /api/users matches /api prefix (exact method)', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n    { method: 'GET', prefix: '/api/admin', target: 'admin' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'api');\n});\n\ntest('POST /api/users returns null (no matching method)', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n    { method: 'GET', prefix: '/api/admin', target: 'admin' }\n  ];\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, rules), null);\n});\n\n// Invalid request handling\ntest('null request returns null', () => {\n  assert.equal(chooseRoute(null, []), null);\n});\n\ntest('array request returns null', () => {\n  assert.equal(chooseRoute([], []), null);\n});\n\ntest('request with missing method returns null', () => {\n  assert.equal(chooseRoute({ path: '/api' }, []), null);\n});\n\ntest('request with empty method returns null', () => {\n  assert.equal(chooseRoute({ method: '', path: '/api' }, []), null);\n});\n\ntest('request with non-letter method returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET-POST', path: '/api' }, []), null);\n});\n\ntest('request with numeric method returns null', () => {\n  assert.equal(chooseRoute({ method: '123', path: '/api' }, []), null);\n});\n\ntest('request with missing path returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET' }, []), null);\n});\n\ntest('request with path not starting with / returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: 'api' }, []), null);\n});\n\ntest('null rules returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, null), null);\n});\n\ntest('non-array rules returns null', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, { method: 'GET' }), null);\n});\n\n// Query and fragment removal\ntest('query string is removed before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users?foo=bar' }, rules), 'found');\n});\n\ntest('fragment is removed before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users#section' }, rules), 'found');\n});\n\ntest('earliest ? or # is used as boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users?foo#bar' }, rules), 'found');\n});\n\ntest('fragment before query is used as boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users#foo?bar' }, rules), 'found');\n});\n\n// Segment boundary matching\ntest('prefix /api matches /api/users at segment boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('prefix /api does not match /apix (no segment boundary)', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n});\n\ntest('prefix /api matches /api exactly at segment boundary', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('root / matches any valid path', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/anything/here' }, rules), 'root');\n});\n\ntest('root / matches /', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rules), 'root');\n});\n\n// Prefix normalization (trailing slash removal)\ntest('trailing slash is removed from prefix', () => {\n  const rules = [{ method: 'GET', prefix: '/api/', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('multiple trailing slashes are removed', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'found');\n});\n\ntest('all-slash prefix normalizes to single /', () => {\n  const rules = [{ method: 'GET', prefix: '///', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\n// Method case-insensitivity\ntest('method comparison is case-insensitive', () => {\n  const rules = [{ method: 'get', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('request method case does not affect matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'found' }];\n  assert.equal(chooseRoute({ method: 'get', path: '/api' }, rules), 'found');\n});\n\n// Exact-method vs wildcard precedence\ntest('exact-method rule preferred over wildcard with longer prefix', () => {\n  const rules = [\n    { method: '*', prefix: '/api/admin/users', target: 'wildcard' },\n    { method: 'GET', prefix: '/api', target: 'exact' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/test' }, rules), 'exact');\n});\n\ntest('wildcard rule used when no exact-method matches', () => {\n  const rules = [\n    { method: '*', prefix: '/api', target: 'wildcard' },\n    { method: 'GET', prefix: '/other', target: 'exact' }\n  ];\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, rules), 'wildcard');\n});\n\n// Longest prefix matching\ntest('longest matching prefix is chosen', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'short' },\n    { method: 'GET', prefix: '/api/admin', target: 'long' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/users' }, rules), 'long');\n});\n\n// Tie-breaking (first rule wins on equal prefix length)\ntest('first rule wins on equal prefix length', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'first' },\n    { method: 'GET', prefix: '/api', target: 'second' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'first');\n});\n\n// Invalid rules are ignored\ntest('null rule is ignored', () => {\n  const rules = [\n    null,\n    { method: 'GET', prefix: '/api', target: 'found' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('array rule is ignored', () => {\n  const rules = [\n    [],\n    { method: 'GET', prefix: '/api', target: 'found' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'found');\n});\n\ntest('rule with invalid method is ignored', () => {\n  const rules = [\n    { method: '', prefix: '/api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with non-letter method (if not wildcard) is ignored', () => {\n  const rules = [\n    { method: 'G3T', prefix: '/api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with prefix not starting with / is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: 'api', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with query in prefix is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api?foo=bar', target: 'invalid' },\n    { method: 'GET', prefix: '/api', target: 'valid' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'valid');\n});\n\ntest('rule with fragment in prefix is ignored', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api#section', target: 
查看 Claude Sonnet 5 返回的完整回复

这是收到的完整响应。由于达到了限制,响应在输出中途结束;缺失的内容未被补全。.

{"files":{"src/router.js":"function isValidRequest(request) {\n  return (\n    request !== null &&\n    typeof request === 'object' &&\n    !Array.isArray(request) &&\n    typeof request.method === 'string' &&\n    request.method.length > 0 &&\n    /^[A-Za-z]+$/.test(request.method) &&\n    typeof request.path === 'string' &&\n    request.path.startsWith('/')\n  );\n}\n\nfunction isValidRule(rule) {\n  if (rule === null || typeof rule !== 'object' || Array.isArray(rule)) {\n    return false;\n  }\n  const { method, prefix, target } = rule;\n\n  if (typeof method !== 'string') return false;\n  if (method !== '*' && !(method.length > 0 && /^[A-Za-z]+$/.test(method))) {\n    return false;\n  }\n\n  if (\n    typeof prefix !== 'string' ||\n    !prefix.startsWith('/') ||\n    prefix.includes('?') ||\n    prefix.includes('#')\n  ) {\n    return false;\n  }\n\n  if (typeof target !== 'string' || target.length === 0) return false;\n\n  return true;\n}\n\nfunction normalizePrefix(prefix) {\n  if (/^\/+$/.test(prefix)) return '/';\n  return prefix.replace(/\/+$/, '');\n}\n\nfunction prefixMatches(normalizedPrefix, path) {\n  if (normalizedPrefix === '/') return true;\n  if (path === normalizedPrefix) return true;\n  return path.startsWith(normalizedPrefix + '/');\n}\n\nfunction stripQueryAndFragment(path) {\n  let cutIndex = path.length;\n  for (let i = 0; i < path.length; i++) {\n    const c = path[i];\n    if (c === '?' || c === '#') {\n      cutIndex = i;\n      break;\n    }\n  }\n  return path.slice(0, cutIndex);\n}\n\nfunction chooseRoute(request, rules) {\n  if (!isValidRequest(request) || !Array.isArray(rules)) return null;\n\n  const path = stripQueryAndFragment(request.path);\n  const reqMethodLower = request.method.toLowerCase();\n\n  let bestExact = null; // { len, idx, target }\n  let bestWildcard = null;\n\n  for (let idx = 0; idx < rules.length; idx++) {\n    const rule = rules[idx];\n    if (!isValidRule(rule)) continue;\n\n    const normPrefix = normalizePrefix(rule.prefix);\n    if (!prefixMatches(normPrefix, path)) continue;\n\n    const len = normPrefix.length;\n\n    if (rule.method === '*') {\n      if (\n        bestWildcard === null ||\n        len > bestWildcard.len ||\n        (len === bestWildcard.len && idx < bestWildcard.idx)\n      ) {\n        bestWildcard = { len, idx, target: rule.target };\n      }\n    } else if (rule.method.toLowerCase() === reqMethodLower) {\n      if (\n        bestExact === null ||\n        len > bestExact.len ||\n        (len === bestExact.len && idx < bestExact.idx)\n      ) {\n        bestExact = { len, idx, target: rule.target };\n      }\n    }\n  }\n\n  if (bestExact !== null) return bestExact.target;\n  if (bestWildcard !== null) return bestWildcard.target;\n  return null;\n}\n\nmodule.exports = { chooseRoute };\n","test/router-added.test.js":"const test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router');\n\ntest('segment boundary: prefix matches at slash boundary only', () => {\n  const rules = [\n    { method: 'GET', prefix: '/api', target: 'api' },\n  ];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/apix' }, rules),\n    null\n  );\n});\n\ntest('root prefix matches every valid path', () => {\n  const rules = [{ method: 'GET', prefix: '/', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rules), 'root');\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/anything/here' }, rules),\n    'root'\n  );\n});\n\ntest('trailing slashes in rule prefix are normalized', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'api' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users' }, rules),\n    'api'\n  );\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n});\n\ntest('all-slash prefix normalizes to /', () => {\n  const rules = [{ method: 'GET', prefix: '////', target: 'root' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/whatever' }, rules),\n    'root'\n  );\n});\n\ntest('query and fragment are stripped before matching', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'api' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users?x=1&y=2' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users#section' }, rules),\n    'api'\n  );\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/api/users?x=1#frag' }, rules),\n    'api'\n  );\n});\n\ntest('query/fragment stripping does not decode or collapse slashes', () => {\n  const rules = [{ method: 'GET', prefix: '/a//b', target: 'weird' }];\n  assert.equal(\n    chooseRoute({ method: 'GET', path: '/a//b?x=1' }, rules),
查看 Claude Opus 5.5 返回的完整回复

这是收到的完整响应。由于达到了限制,响应在输出中途结束;缺失的内容未被补全。.

{"files":{"src/router.js":"'use strict';\n\nconst LETTERS = /^[A-Za-z]+$/;\n\nfunction isPlainObject(value) {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isMethodName(value) {\n  return typeof value === 'string' && value.length > 0 && LETTERS.test(value);\n}\n\nfunction stripQueryAndFragment(path) {\n  const q = path.indexOf('?');\n  const h = path.indexOf('#');\n  let cut = -1;\n  if (q !== -1 && h !== -1) cut = Math.min(q, h);\n  else if (q !== -1) cut = q;\n  else if (h !== -1) cut = h;\n  return cut === -1 ? path : path.slice(0, cut);\n}\n\nfunction normalizePrefix(prefix) {\n  let end = prefix.length;\n  while (end > 0 && prefix[end - 1] === '/') end -= 1;\n  return end === 0 ? '/' : prefix.slice(0, end);\n}\n\nfunction prefixMatches(path, prefix) {\n  if (prefix === '/') return true;\n  return path === prefix || path.startsWith(prefix + '/');\n}\n\nfunction chooseRoute(request, rules) {\n  try {\n    if (!isPlainObject(request) || !Array.isArray(rules)) return null;\n    const method = request.method;\n    const rawPath = request.path;\n    if (!isMethodName(method)) return null;\n    if (typeof rawPath !== 'string' || rawPath[0] !== '/') return null;\n\n    const path = stripQueryAndFragment(rawPath);\n    const upperMethod = method.toUpperCase();\n\n    let bestExact = null;\n    let bestWildcard = null;\n\n    const count = rules.length;\n    for (let i = 0; i < count; i += 1) {\n      const rule = rules[i];\n      if (!isPlainObject(rule)) continue;\n      const ruleMethod = rule.method;\n      const prefix = rule.prefix;\n      const target = rule.target;\n      const isWildcard = ruleMethod === '*';\n      if (!isWildcard && !isMethodName(ruleMethod)) continue;\n      if (typeof prefix !== 'string' || prefix[0] !== '/') continue;\n      if (prefix.indexOf('?') !== -1 || prefix.indexOf('#') !== -1) continue;\n      if (typeof target !== 'string' || target.length === 0) continue;\n\n      const normalized = normalizePrefix(prefix);\n      if (!prefixMatches(path, normalized)) continue;\n\n      const candidate = { length: normalized.length, target };\n      if (isWildcard) {\n        if (bestWildcard === null || candidate.length > bestWildcard.length) bestWildcard = candidate;\n      } else if (ruleMethod.toUpperCase() === upperMethod) {\n        if (bestExact === null || candidate.length > bestExact.length) bestExact = candidate;\n      }\n    }\n\n    if (bestExact !== null) return bestExact.target;\n    if (bestWildcard !== null) return bestWildcard.target;\n    return null;\n  } catch (err) {\n    return null;\n  }\n}\n\nmodule.exports = { chooseRoute };\n","test/router-added.test.js":"'use strict';\n\nconst test = require('node:test');\nconst assert = require('node:assert/strict');\nconst { chooseRoute } = require('../src/router.js');\n\nconst baseRules = [\n  { method: 'GET', prefix: '/api', target: 'api' },\n  { method: 'GET', prefix: '/api/admin', target: 'admin' }\n];\n\ntest('existing regression cases still hold', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/users' }, baseRules), null);\n});\n\ntest('longest prefix wins within method group', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/x' }, baseRules), 'admin');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin' }, baseRules), 'admin');\n});\n\ntest('segment boundaries', () => {\n  const rules = [{ method: 'GET', prefix: '/api', target: 'api' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/users' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/ap' }, rules), null);\n});\n\ntest('trailing slashes in prefixes are normalized, all-slash is root', () => {\n  const rules = [{ method: 'GET', prefix: '/api///', target: 'api' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api' }, rules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix' }, rules), null);\n  const rootRules = [{ method: 'GET', prefix: '///', target: 'root' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/' }, rootRules), 'root');\n  assert.equal(chooseRoute({ method: 'GET', path: '/anything/else' }, rootRules), 'root');\n  assert.equal(chooseRoute({ method: 'GET', path: '/x' }, [{ method: 'GET', prefix: '/', target: 'r' }]), 'r');\n});\n\ntest('query and fragment are removed at earliest ? or #', () => {\n  assert.equal(chooseRoute({ method: 'GET', path: '/api?next=/api/admin' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api#/admin' }, baseRules), 'api');\n  assert.equal(chooseRoute({ method: 'GET', path: '/apix?/api' }, baseRules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin#frag?q' }, baseRules), 'admin');\n  assert.equal(chooseRoute({ method: 'GET', path: '/api?q#/admin' }, baseRules), 'api');\n});\n\ntest('no URL decoding and no slash collapsing', () => {\n  const rules = [{ method: 'GET', prefix: '/api/admin', target: 'admin' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api%2Fadmin' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api//admin' }, rules), null);\n  assert.equal(chooseRoute({ method: 'GET', path: '/api//admin' }, baseRules), 'api');\n});\n\ntest('methods compare case-insensitively', () => {\n  const rules = [{ method: 'get', prefix: '/a', target: 'lower' }];\n  assert.equal(chooseRoute({ method: 'GET', path: '/a' }, rules), 'lower');\n  assert.equal(chooseRoute({ method: 'gEt', path: '/a/b' }, rules), 'lower');\n});\n\ntest('exact method beats longer wildcard; wildcard used only as fallback', () => {\n  const rules = [\n    { method: '*', prefix: '/api/admin', target: 'wild-admin' },\n    { method: 'GET', prefix: '/', target: 'get-root' },\n    { method: 'POST', prefix: '/other', target: 'post-other' },\n    { method: '*', prefix: '/api', target: 'wild-api' }\n  ];\n  assert.equal(chooseRoute({ method: 'GET', path: '/api/admin/x' }, rules), 'get-root');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/admin/x' }, rules), 'wild-admin');\n  assert.equal(chooseRoute({ method: 'POST', path: '/api/x' }, rules), 'wild-api');\n  assert.equal(chooseRoute({ method: 'POST', path: '/other/1' }, rules), 'post-other');\n  assert.equal(chooseRoute({ method: 'PUT', path: '/nothing' }, rules), null);\n});\n\ntest('ties go to earlier rule in input order', () => {\n  const rules = [\n    { method: 'GET', pref

4,096 个令牌的上限是本次测试选定的输出预算,并非任何模型的文档中记载的最大值。路由结果表明,在提交更大规模的请求之前,应进行一项实际检查:预估您期望收到的实现、测试结果和解释的规模。 适当的做法可能是拆分交付成果或预留更多输出空间;我们并未采用不同的设置重新运行这些输出。.

在处理自己的任务时,请分别从三个方面进行评估:响应是否完整、代码是否通过了有意义的检查,以及代码审查是否发现了这些检查未能发现的漏洞。即使通过了十二项函数检查,那些被截断的两文件响应也仍不构成完整的交付成果。.

选择不同的模型会对成本产生什么影响

Claude Code 是一款编码工具;Haiku、Sonnet、Opus 和 Fable 是支持环境中的模型选项。身份验证和支付方式也是可选项之一。更改模型不会将订阅转换为 API 账户,也不会消除所有使用限制。.

计费路径看什么如何解读模型选择
Claude 订阅访问权限套餐内流量及任何单独启用的流量额度不同机型对配额的消耗方式可能有所不同;请查看该套餐可选机型及限额
Anthropic API 访问输入/输出令牌、缓存及相应的 API 费用使用当前的费率表和实际使用情况,然后在计费控制台中确认费用
云服务提供商或网关您的服务提供商支持的ID、费率和计费记录Anthropic的标价示例可能与您的服务提供商实际收取的金额不一致
资费方案选择与计费相关,但计费方式决定了如何对使用量进行收费。.

在 Claude 代码中,, /使用 显示会话令牌信息,并在适用时显示订阅使用量条。其中的金额是根据列表价格或配置的费率在本地计算得出的预估数额,并非正式发票。对于 Pro 和 Max 订阅用户,该会话数据并不意味着订阅中增加了额外的 API 费用。了解更多关于 Claude 代码定价和计费路径 如果您正在考虑采用哪种支付方式。.

当前 API 价格及等值代币示例

Anthropic 每百万输入/输出代币的标准基础费率为 Haiku 4.5:$1/$5;Sonnet 5:$2/$10; Opus 5.5:$4/$20;Fable 5.1:$10/$50, ,查阅于2026年9月28日。下图将代币交易量保持不变,以便于进行数据对比。.

相同的代币数量,四种不同的API费用

例如 100,000 个未缓存的输入令牌 + 10,000 个输出令牌, ,采用Anthropic于2026年9月28日核查的常规API目录价格。.

俳句 4.5$0.15
第5首十四行诗$0.30
作品第5.5号$0.60
Fable 5.1$1.50
查看费率及计算方法
每百万枚代币的美元金额及计算示例
模型输入 / 1M输出 / 1M示例总计
俳句 4.5$1$5$0.15
第5首十四行诗$2$10$0.30
作品第5.5号$4$20$0.60
Fable 5.1$10$50$1.50

计算公式:0.1 × 输入速率 + 0.01 × 输出速率。以 Opus 5.5 为例:0.1 × $4 + 0.01 × $20 = $0.60。.

这是一张基于固定令牌数量的示意图。实际任务消耗的令牌总量各不相同;缓存写入和读取、重试、工具、提供商计费以及订阅限制都需要分别进行核算。.

资料来源 Anthropic API定价.

Anthropic 的 API 定价表,其中包含输入、输出和提示词缓存费率。.
API 的常规列表价格按每百万个代币计价;缓存写入和读取的费率各不相同。.

一个真正的 Claude Code 任务是一系列请求。早前的上下文可能会被再次发送,模型可能会进行进一步分析,而工具或额外的代理可能会产生更多工作。提示词缓存还具有不同的写入和读取速率。因此,示例中最低的那条柱状图并不能代表每次被接受的更改的最低成本。.

在不削弱任务效果的前提下控制成本的五种方法

  1. 在选择模型之前,先定义验收标准。. 请说明预期行为、边界情况以及现有限制条件。一个清晰且任务量较小的任务,在经济上更容易分配,也更容易进行审查。.
  2. 提供相关背景信息。. 请附上模型所需的文件和故障详情。对于无关的工作,请开启新的对话,而不是仅仅因为原有对话记录存在就将其延续下去。.
  3. 要区分能力与努力。. Anthropic 建议首先使用模型的默认努力程度。如果模型正确读取了上下文但仍无法解决问题,则使用更强大的模型可能会有所帮助。如果模型跳过了读取或验证步骤,请检查任务设置和努力程度的选择。.
  4. 整个答案的预算。simplified-chinese (mainland). 源代码、测试用例和说明都需要输出空间。我们的第二个任务说明了为什么仅凭一个完整的函数,并不能证明所要求的交付成果符合预算。.
  5. 比较已被采纳的作品。. 记录具有代表性的任务中的有效输出、重试次数、审核时间以及实际计费数据。将提供商错误与模型质量问题区分开来。.

这些策略与 官方费用指南 和 Anthropic的模型与工作量指南. 切换模型后,全计划范围的每周或会话限制仍可能继续生效;而特定模型的限制则属于另一种情况。在反复切换模型之前,请先确认实际限制。.

如果你的工作涉及编程、研究、写作和媒体,也请比较一下你所付费的工作流程。. GlobalGPT的多模型工作区 将这些功能整合到一个仪表盘中,并提供用于开发任务的命令行界面(CLI)访问权限。在评估按量计费的 API 路由时,应综合考虑这种更广泛的工作流价值;上方的 API 图表并非 GlobalGPT 订阅价格表。.

为什么你选择的模型可能无法奏效

症状可能的检查切实可行的下一步措施
下一节将使用旧模型该开关可能仅在当前会话中有效使用选择器的“Enter”操作进行保存,然后检查一个新会话
首选项已保存,但启动的却是另一个模型“启动”、“壳”、“项目”、“托管”或“组织”设置可能具有更高优先级阅读启动信息,并与所有者一起检查相关配置
恢复的对话采用不同的模型已保存的会话可能会恢复其之前的模型检查 /status;在恢复工作时,请慎重选择目标模型
该模型不存在或已被拒绝服务提供商的可用性、组织规则或旧版的Claude代码请检查支持的型号 ID、账户访问权限和版本要求
同一个姓氏在其他地方的写法不同别名与提供程序映射不一致当发布版本必须保持不变时,请使用提供商的正确完整 ID
切换不会清零使用限额该限额可能适用于整个计划请阅读使用说明并重置周期,而不是一味认为仅通过家庭开关即可解决问题
在更改其他设置之前,请先诊断问题的范围。.

如果 Claude Code 无法写入您的用户设置,则交互式选项仅在当前会话中有效,不会持久保存。对于受管或生成的设置文件,可能需要由其所有者进行修改,而非再次尝试选择。请避免仅仅为了让某个选项显示出来而解除组织限制。.

利用 GlobalGPT 构建更全面的工作流程

模型选择是工作流中的一部分。您可能需要研究某个库、编写函数草稿、向团队成员解释更改、编写文档,以及准备可视化素材。GlobalGPT 将多个领先模型和 AI 功能整合到一个经济实惠的工作空间中,因此这些任务可以在同一个仪表盘中完成。.

对于终端操作, GlobalGPT CLI 将该平台的工具与开发环境相连接。其文档中记录的设置方案使用您的 GlobalGPT 账户登录信息和常规账户余额。命令行界面(CLI)能够支持更广泛的编码与创建工作流,而 Claude Code 自身的模型则通过其模型控制功能,仍是一种经过深思熟虑的选择。.

例如,起草并审核实施方案,采用另一种模型进行简明扼要的说明,然后制作随发布附带的文档或资源。请按照指南进行操作: 将 GlobalGPT CLI 连接到 Claude 代码 当您需要实现该工具集成时,请根据编码任务单独设置您的 Claude 代码推理模型。.

选择一个初始模型,写下定义成功的检验标准,并在任务需要时进行升级。在宣布工作完成之前,先对完整的交付成果进行审查。. 使用 GlobalGPT 构建您的工作流 当您希望在日常工作中将模型选择、研究、编码和创意工具无缝整合时。.

常见问题

如何在 Claude Code 中更改模型?

运行 /model 命令以打开选择器。按 s 键仅切换当前会话,或按 Enter 键将所选模型保存为默认模型。若要为单个新会话选择模型,请使用 claude –model 命令并跟上模型名称来启动。.

/model 会更改我保存的默认设置吗?

在当前的交互式版本中,使用 Enter 键选择模型或输入 /model sonnet 命令,会在用户设置可写时将该选择保存下来。在选择器中按下 s 键仅在当前会话中有效。下次启动时,其他设置仍可能具有优先级。.

什么是默认的Claude Code模型?

运行时的默认值取决于您的账户、提供商和配置。该默认值会清除模型覆盖设置;它并非一个固定的模型 ID。请通过 /status 查询当前活跃的模型,并查看选择器,而不是假设每个账户都从同一版本开始。.

Opusplan 是什么?

它在规划模式下使用Opus,在执行模式下使用Sonnet。它遵循模式转换机制,而非针对每个提示自动选择成本最低的模型。实际成本取决于各阶段所执行的工作量。.

为什么选择器中缺少一个模型?

可用性可能取决于您的服务提供商、账户、组织限制以及 Claude Code 的版本。请查阅当前模型的文档以及您所在环境允许使用的模型。此外,同一模型家族的别名在其他服务提供商处可能对应不同的版本。.

更便宜的机型是否总能降低任务成本?

不。代币价格只是其中一个因素。总使用量、不完整的答案、重试次数以及审核工作量都会影响可接受修改的成本。在我们这次小规模重构中,这三个函数均通过了测试,而那三个规模较大的、涉及两个文件的响应则都因达到共享输出限制而被截断。.

资料来源

分享帖子:

相关帖子