我最早接触 Claude Code,完全是被“终端里跟代码仓库对话”这个场景吸引的。那时候我的日常是反复切编辑器、跑测试、看报错日志,整个人像是代码库的搬运工,而不是开发者。Claude Code 这类 CLI 工具的价值不在于把代码写得多快,而是把“改代码—跑命令—看结果—再改”这个循环从手动操作变成了模型自主推进的闭环。
一开始我用的是 Anthropic 订阅账号,用了大概三周,痛点就来了:额度用尽、团队协作时没法统一管理权限,月底看见账单又说不清到底让模型干了哪些活。更麻烦的是,当账号受组织策略限制而无法激活 Claude 订阅访问时,整个 CLI 会直接拒绝初始化。后来我把整套环境迁到 AWS Bedrock,问题基本清零。这篇文章就把我在迁移、配置、使用和成本控制过程中的完整经验拆开讲,覆盖 shell 执行机制、权限边界、VSCode 协同、本地模型分流,以及最容易被忽视的成本优化细节。
如果你正在纠结要不要从订阅切到 Bedrock,或者已经接上了但总觉得 token 烧得太快,这篇文章应该能帮你省下真金白银。
1. 我为什么把 Claude Code 从订阅账号迁到 AWS Bedrock
1.1 Claude Code 解决的真实痛点
先说清楚 Claude Code 到底是什么。它是一个运行在终端里的 AI 编程代理,不是简单的代码补全插件。给它一个任务,比如“帮我定位这个测试为什么超时并修复它”,它会自己规划步骤:读文件、搜代码、写补丁、跑测试、分析失败原因、迭代修改。整个过程它可以调用 shell 命令、读写文件、调用工具,本质上是一个能操控电脑执行命令的智能体。
我在实际使用中的感受是,它最适合三类场景:一是有明确的工程化任务,比如批量替换 API、处理编译错误;二是已经写好测试的代码库,让模型在测试约束下反复调整;三是研究陌生代码库,让它做结构分析和模块梳理。相比之下,在编辑器里手动框选代码让模型续写,那只是“带 AI 的编辑器”,不是 agentic coding。
早期我用订阅账号,最大的门槛不在技术,在管理和额度。订阅账号绑定到个人身份,团队成员如果想用,得各自解决账号问题;组织一旦禁用了 Claude 订阅访问,CLI 直接无法启动。而且订阅模型的可用性和并发都受限,真的到了连续几小时的重构任务里,经常做到一半就因为额度中断,体验非常断裂。
1.2 Bedrock 接入的核心优势与代价
转投 AWS Bedrock 之后,我最大的感受是三点。
第一,按量付费,成本可预测。订阅是固定金额换取固定额度,超额就断供;Bedrock 是完全按 token 计费,调用多少收多少,没有“用完了”这种说法。对长期高频使用来说,账单曲线更平滑,也能通过控制台查看每次调用量。
第二,IAM 权限体系可以精确管住模型能做什么。我可以给每个环境配置最小权限,比如某个 CI 任务只能调用特定的 Claude 模型、不能删除 S3 对象。这个能力在团队协作和生产环境里非常重要。
第三,和 AWS 生态打通。日志可以进 CloudWatch,调用元数据可以过 Bedrock 的模型调用记录,后续做审计、做成本归因都有原始数据支持。
当然,Bedrock 也不是没有代价。首先是概念更多,你得懂 IAM、VPC 这些基础名词,上手门槛比订阅高;其次是模型版本和 Anthropic 官方直连存在时间差,某些新功能可能要等模型上线 Bedrock 后才可用;最后是网络链路,如果你的服务器在海外区域,从本地终端访问会有额外延迟,但通过合理的区域配置可以缓解。
我当时做了一个很简单的对比:如果把一个月 20 美元订阅换成 Bedrock 按量付费,我做同样规模的代码重构,成本大约能省 30% 到 50%,这还是没启用提示词缓存的情况。启用之后差距更大。这个数字后续会专门讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境开通与模型权限:动手前的三件套检查
2.1 开通 Bedrock 与申请模型访问
很多人第一步就卡住了,不是不会配,而是忘了 Bedrock 控制台里的模型访问必须手动申请。这和 Anthropic 官方 API 不一样,不是开通服务就能调用全部模型。
流程是这样的:
- 登录 AWS 控制台,进入 Amazon Bedrock 服务页面。
- 在左侧菜单点击“Model access”(模型访问权限)。
- 点击“Manage model access”,勾选你需要的 Claude 模型,提交请求。
- 等待状态变为“Access granted”。
这里要特别注意,不同区域的模型列表不同,我常用的区域是 us-east-1(弗吉尼亚北部)和 us-west-2(俄勒冈)。如果你在某个区域搜不到某个模型 ID,切换区域再试。
另外,请求模型访问后,状态更新通常需要几分钟到几个小时不等。我第一次申请时在控制台等了一个多小时还没通过,差点怀疑自己操作错了,其实就是排队。
2.2 IAM 角色与最小权限策略配置
模型访问开好了,接下来是 IAM。这一步是 Bedrock 和其他 API 服务最大的区别,也是安全边界最清晰的地方。
我的建议是永远不要用管理员的 Access Key 跑 Claude Code。按最小权限原则,配置一个专用用户,只给它调用模型的权限就够了。
json复制{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
}
]
}
这个策略里的 Resource 指定了具体的模型 ARN,意思是这个用户只能调用这一个模型。如果你用的模型 ID 不同,比如换了 Claude Haiku 或 Claude 4,必须同步修改 ARN,否则调用会被拒绝。
还要说的是,Claude Code 在推理时需要连续接收模型的流式输出,所以 InvokeModelWithResponseStream 这个权限必须给,只给 InvokeModel 会出现“调用成功但没有后续输出”的怪异现象。这个坑我踩过,排查了半天才意识到是少了一个 action。
2.3 本地安装 CLI 与初始化验证
执行环境方面,Claude Code 本质上是 Node.js 的 npm 包,全局安装命令:
bash复制npm install -g @anthropic-ai/claude-code
安装完成后先验证:
bash复制claude --version
如果终端提示 claude: command not found,通常不是安装失败,而是 npm 的全局 bin 目录没有加进 PATH。这个太常见了,后面的排错章节专门讲。验证完版本,再用 AWS CLI 确认身份能正常获取:
bash复制aws sts get-caller-identity
这一步能看到你当前用的是哪个账号和哪个 IAM 用户。如果 AWS CLI 没有配置,Claude Code 后续启动时会因为找不到凭据直接报错。我建议在任何复杂配置之前,先确保这两条命令都能正常返回。
3. 认证链路详解:profile、环境变量与 Bedrock 模式启动
3.1 用 AWS Profile 管理多环境凭据
Claude Code 启动时如果启用了 Bedrock 模式,它会去找 AWS 凭据。凭据的来源很多:环境变量、shared credentials 文件、实例角色等等。我在本地最推荐的方式是用 profile,而不是把 Access Key 写死到环境变量里。
假设你有两个环境,一个开发一个生产,在 ~/.aws/credentials 里分别为它们创建 profile:
ini复制[bedrock-dev]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
[bedrock-prod]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
使用时显式指定:
bash复制export AWS_PROFILE=bedrock-dev
这样即使用错了 profile,也不会影响另一个环境。环境变量的优先级高于 shared credentials 文件,如果你发现明明改了 profile 但调用还是走之前那个账号,检查一下是不是环境变量里残留了 AWS_ACCESS_KEY_ID。
3.2 Bedrock 模式的启动方式与模型 ID 注意点
Claude Code 官方支持通过 Bedrock 模式接入,核心就是设置环境变量 ANTHROPIC_BEDROCK=1,然后指定模型 ID。
我平时是这样启动的:
bash复制export ANTHROPIC_BEDROCK=1
export AWS_PROFILE=bedrock-dev
export AWS_REGION=us-east-1
export ANTHROPIC_MODEL=anthropic.claude-3-5-sonnet-20241022-v2:0
claude
注意 ANTHROPIC_MODEL 必须填 Bedrock 的模型 ID,不能填 Anthropic 官方 API 的模型别名。前者类似 anthropic.claude-3-5-sonnet-20241022-v2:0,后者是 claude-sonnet-4-20250514。填错会导致模型找不到或者直接走默认的 Anthropic API 认证流程。
如果你不想每次敲 export,可以把这些变量写进 shell 的 profile 文件,或者封装成一个启动脚本。
3.3 常见认证错误:凭据找到了但权限不足
有一次我启动 Claude Code,控制台直接抛了这样的异常:AccessDeniedException: User: arn:aws:iam::xxx:user/claude-bot is not authorized to perform: bedrock:InvokeModel。
看到这个信息,我第一反应是查 IAM 策略,但检查了一遍发现 action 没问题。后来才发现,策略里的 Resource 写死了 us-east-1 区域,而环境变量 AWS_REGION 被设成了 us-west-2,模型 ARN 对应不上,请求就被拒绝了。
排查这类问题的标准链路是:先用 AWS CLI 手动调一次模型,确认 IAM 本身没问题,再回来看 Claude Code 的环境配置。
bash复制aws bedrock-runtime invoke-model \
--model-id anthropic.claude-3-5-sonnet-20241022-v2:0 \
--body '{"anthropic_version":"bedrock-2023-05-31","max_tokens":64,"messages":[{"role":"user","content":"ping"}]}' \
--region us-east-1 \
/tmp/ping.json
如果这条命令正常返回,说明 IAM 和模型访问都没问题,问题出在 Claude Code 的启动环境。如果这条命令也报 AccessDenied,那就是 IAM 策略写错了,按这个方向查准没错。
4. shell 执行机制:Claude Code 的“手”如何被安全地约束
4.1 Bash 工具与权限模式的对应关系
Claude Code 之所以能自主完成代码任务,是因为它能执行 shell 命令。这些命令通过一个内置的 Bash 工具运行。每次执行命令之前,系统会检查这条命令是否在允许列表里;如果不在,就会弹出确认提示,让我选择是否放行。
这里的权限模式大致分几档,从严格到宽松:
| 模式 | 行为 | 适用场景 |
|---|---|---|
| 默认交互模式 | 每次执行关键命令前询问用户 | 日常本地开发 |
| 计划模式(plan) | 只读,禁止执行修改类命令 | 需求分析、代码调研 |
| 自动接受编辑模式 | 自动同意文件编辑,但命令仍需确认 | 批量修改代码 |
| 跳过全部权限 | 所有命令不再确认 | 受限 CI 环境,风险高 |
我个人非常推荐在进入需要在代码库到处翻找的阶段时,先用计划模式让它“只看不动”。这个模式下 Claude Code 可以读文件、搜索、分析,但不会执行写操作和危险命令。看完它的分析后再切换到执行模式,能有效避免模型在理解不足的情况下开始乱改。
4.2 “忽略错误继续执行”到底是怎么回事
很多人在搜索“shell 忽略错误继续执行”这个话题,其实这是 Claude Code 执行策略里的一个重要设计:某条命令失败后,模型不一定会终止任务,而是会把错误输出吸收进去,继续判断下一步怎么做。
举个例子,我让它跑 npm test,测试编译报错了,它不会直接放弃,而是读 stderr,发现是某个类型定义缺失,然后自动去补类型定义,再重新跑测试。这个“失败—分析—修正—重试”的循环,正是 agentic 编程和普通脚本最大的区别。
但从安全角度看,这也意味着“命令失败”不等于“任务停止”。如果你希望它在某个关键命令失败后立即停下,可以在 CLAUDE.md 里约定行为,比如:“当遇到明确的编译错误时,先停止所有操作并汇报,不要自行修改代码”。模型会遵循项目级指令来调整执行策略。
4.3 通过 CLAUDE.md 约束 shell 行为
CLAUDE.md 是 Claude Code 的项目记忆文件,放在仓库根目录,每次会话启动时模型都会先读它。这个文件是配置 shell 行为和执行策略最有效的地方。
我自己的一份 CLAUDE.md 大致是这样的:
markdown复制# 项目规则
- 测试命令统一使用 npm test,不要使用 yarn test
- 所有改造必须先通过 lint 再提交
- 修改公共接口时,同步更新对应文档
- 执行命令失败时,先分析 stderr,最多重试两次,仍失败则停止并汇报
- 禁止执行 rm -rf 类删除命令
把这类规则写进 CLAUDE.md 之后,模型的执行行为会稳定很多,不会每次会话都靠临场发挥。特别是团队协作时,这个文件等于把每个人的偏好固化成了项目规范。
4.4 危险命令的兜底设计
虽然 Claude Code 提供了权限确认机制,但它并不能代替人的判断。默认交互模式下,像 rm -rf / 这种命令大概率会被拦截,但如果我手滑点了允许,后果就不好说了。
所以我自己的兜底策略是三层:第一层,CLAUDE.md 里明令禁止危险命令;第二层,尽量在容器或沙箱环境里跑它,即使模型误操作,破坏面可控;第三层,生产环境的凭据永远不配给本地 Claude Code,给它一个只能调用模型的只读 IAM 用户。这样即使 shell 被穿透,也拿不到生产资源。
5. 与 VSCode、本地模型的协同:从命令行到 IDE 的实用配置
5.1 VSCode 集成的两种方式
Claude Code 最早是纯 CLI 工具,现在也有了桌面端和编辑器插件。在 VSCode 里,我常用两种方式。
第一种是官方 VS Code 扩展,装好后侧边栏会出现一个面板,可以直接在当前工程目录下启动会话。这种方式的好处是保留了 IDE 的文件树和差异对比,模型改完代码后我能直接看 diff,不用切回终端。
第二种是在集成终端里直接跑 claude,让 AI 和手动命令共存。这种方式好处是灵活,适合我自己想在某个窗口里跑一下测试,另一个窗口在跟模型对话。
实际体验下来,日常开发我用第二种多一点,因为我已经习惯终端工作流。但如果你是从 Cursor 这类 AI 编辑器转过来的,直接用 VS Code 扩展会更顺手。
5.2 用 cc-switch 在多配置之间切换
Claude Code 的配置切换有一个很现实的问题:官方 API、Bedrock、本地 Ollama,每种接入方式的模型 ID、认证方式和环境变量都不一样。如果全部写死在 shell profile 里,每次切换要改一堆变量。
社区里有个叫 cc-switch 的开源工具,专门解决这个问题。它可以预设多套配置,比如“bedrock-prod”“bedrock-dev”“ollama-local”,一键切换,底层本质上是在帮你管理环境变量和配置文件的读写。
我现在的本地工作流是:开发环境切到 Bedrock + Sonnet,简单任务或离线环境切到 Ollama + 本地模型。切换只需要在 cc-switch 里点一下,然后重新打开终端启动 claude 即可。
5.3 什么时候把任务交给本地模型
本地部署 Ollama 是很多人的省钱法宝,但我要说句实话:本地模型和 Claude 的能力差距依然明显。对我而言,本地模型只接两类任务:一类是完全无敏感风险的格式转换、批量文本处理;另一类是极度追求隐私、不能出本机的场景。
在 Claude Code 里接 Ollama,本质也是通过 Anthropic 兼容接口映射到本地模型的 HTTP 服务。你可以把 Ollama 跑在本地 11434 端口,然后在配置里指向它。这样做的好处是响应速度快、完全免费,坏处是复杂代码推理基本不可用。
我的建议是把它当成“降级方案”,而不是主力。主力任务用 Bedrock + Sonnet,本地模型只在带宽受限或者需要隐私隔离的时候顶上。
5.4 终端乱码问题
搜索热词里有“claude code 乱码问题”,这其实是个非常普遍的小坑。原因是 Claude Code 在终端里输出的是 UTF-8 编码,而 Windows PowerShell 的默认编码可能不是 UTF-8,导致中文内容变成乱码。
我的解决办法是在 PowerShell 里执行:
powershell复制[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [Console]::OutputEncoding
或者直接在 VSCode 集成终端里把默认编码改成 UTF-8。改完之后重启 claude,中文输出就正常了。
6. 成本优化的核心手段:每一分 token 都花在刀刃上
6.1 先看懂 Bedrock 的计费边界
Bedrock 的计费核心是输入 token、输出 token 和缓存 token 三块。输入是指你发给模型的内容,包括系统提示、CLAUDE.md、读取的文件内容、对话历史;输出是模型写的代码和回复;缓存是提示词缓存被命中时读取的 token。
Sonnet 级别的模型,我按当时公开定价粗略估算,输入每百万 token 约 3 美元,输出约 15 美元。但这只是参考,具体价格以 Bedrock 控制台当前展示和账单为准。
成本优化的核心逻辑就一句话:减少输入 token、减少无效输出、善用缓存。
6.2 提示词缓存与上下文压缩
提示词缓存是 Bedrock 上最容易忽略的省钱功能。Claude Code 在同一个会话里会把系统提示、工具定义、CLAUDE.md 等内容重复发送,如果这些内容能被缓存命中,读取成本远低于重新计费。
我在使用中观察到的效果是,开启缓存后,长会话的输入成本下降非常明显。比如我让 Claude Code 在一个大型代码库里连续做 10 轮重构,如果不缓存,每轮都要把项目背景重新算一遍;有缓存之后,只有新增内容按照完整输入计费,命中部分按更低费率计。
另外,上下文压缩也很重要。Claude Code 在会话变长时会把之前的对话摘要化,而不是无限保留完整历史。你可以在会话里用 /compact 手动触发压缩,尤其在对话已经很长、模型开始“忘事”的时候,压缩一下反而更省钱也更准确。
6.3 模型分级:不同任务用不同模型
成本优化不是一味用便宜模型,而是按任务难度分级。我的分法是:
| 任务类型 | 推荐模型 | 理由 |
|---|---|---|
| 代码重构、跨文件诊断 | Sonnet | 能力和成本平衡 |
| 简单脚本生成、格式转换 | Haiku | 响应快、成本低 |
| 极端复杂架构设计 | Opus | 罕见,按需启用 |
| 隐私敏感小任务 | 本地 Ollama | 零成本不出网 |
把“让 Haiku 先干粗活”这个思路落实后,我的月成本下降了一截。比如批量重命名变量、生成单元测试模板、整理 Markdown 文档这类任务,Haiku 完全够用。真正值得用 Sonnet 的是涉及多文件依赖、需要深入理解业务逻辑的重构任务。
在 Claude Code 里切换模型,可以用环境变量 ANTHROPIC_MODEL 指向不同的 Bedrock 模型 ID,或者在会话里使用 /model 命令切换。
6.4 让 Claude Code 少读文件、少啰嗦
Claude Code 每次读取文件都会产生输入 token,所以“少读文件”是成本优化的关键。做法是:
第一,在任务描述里尽量缩小范围,明确告诉它“只需要看 src/modules/order 目录下的代码”,而不是笼统地说“帮我看看这个项目哪里有问题”。
第二,把 CLAUDE.md 写得精练。CLAUDE.md 每次都会进入上下文,写得越长,每次请求的固定成本就越高。我见过有人把几百行的规范塞进去,那等于每轮对话都在付费读一本小册子。
第三,通过权限配置限制它能调用的工具。比如只允许它读 src 目录,不允许读 node_modules,这样既避免它读一些没用的文件,也在某种程度上保护了上下文质量。
输出端也一样。如果你只想要最终改动,不要让它在每次循环里打一大堆分析和总结。CLAUDE.md 里可以写“不要输出中间过程的解释,直接给出代码改动”,这样输出 token 会显著下降。
6.5 一次真实重构的成本数据
拿我最近一次中型项目重构举例。仓库约 800 个文件,需要从一个过期 API 迁移到新 API。我的做法是先让模型用计划模式分析迁移范围,再分模块执行。
整个过程中,模型累计读取了约 400 万输入 token,输出了约 18 万 token。由于长会话命中了提示词缓存,实际有效输入计费大约是 120 万 token。我按 Sonnet 的公开定价粗略一算,这次重构的成本在 6 到 8 美元之间。
如果没有用 Bedrock 而是订阅额度,我很难把这个成本量化,更别说控制。有了 Bedrock 的按量计费和 CloudWatch 日志,每一次调用都在账单上有迹可循。
7. 高频报错与排错链路:从 PATH 到会话恢复的完整排查思路
7.1 could not locate the claude cli on path
这个报错信息很典型:failed to run claude code: error: could not locate the claude cli on path。通常不是 Claude Code 本身的问题,而是系统找不到这个命令。
排查步骤如下:
- 先确认是否真的全局安装了:
npm ls -g @anthropic-ai/claude-code。 - 找到 npm 全局 bin 目录:
npm prefix -g,然后看bin子目录。 - 把这个目录加入 PATH,Linux/Mac 可以写在
~/.zshrc,Windows 在“系统环境变量”里加。 - 重新打开终端,再执行
claude --version。
如果你是用 PowerShell 安装的,很可能 npm 生成了一个 .ps1 脚本,但执行策略禁止运行外部脚本。这时候需要:
powershell复制Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
然后重试。这个操作本质上是信任本机生成的脚本,不涉及任何外部风险,但你要明白自己在做什么。
7.2 组织禁用订阅访问的提示
如果你看到 your organization has disabled claude subscription access for claude code,说明当前账号被组织策略限制,无法使用 Claude 订阅服务。这时候不用去折腾账号,解决思路很清晰:改用 API Key 或接入 Bedrock。
基于我的经验,直接切到 Bedrock 是更稳妥的做法。因为你不需要依赖 Anthropic 账号的状态,只要有 AWS 凭据和模型权限就能启动。具体配置方法参考第 3 节,只需要在环境变量中设置 ANTHROPIC_BEDROCK=1。
7.3 保存与恢复会话
Claude Code 会在本地保存会话历史,默认位置是用户目录下的 ~/.claude/projects/,里面按项目路径哈希分目录,每个会话对应一个 JSONL 文件。这个设计有几个实际用处。
一是恢复上下文。如果我不小心关闭了终端,重新执行 claude --resume,就能回到最近一次的会话,上下文没有丢。
二是分享和审计。因为历史记录是文本文件,团队里可以做简单的代码审查,看模型当时为什么做了某个修改。
三是控制成本。与其开新对话让模型重新读一遍代码库,不如 --continue 延续上一轮已经压缩好的上下文。
7.4 代码库很大时的卡顿与超时
最后一个实际问题是,代码库特别大时,Claude Code 的扫描和搜索会明显变慢,甚至超时。我的经验是在仓库根目录添加 .claudeignore 文件,把 node_modules、dist、build、vendor 这类目录排除掉。这和 .gitignore 是一个思路,让模型只关注真正需要理解的源码。
我最初没有配这个文件,结果模型在一次文件搜索里把整个 node_modules 遍历了一遍,既不安全又浪费 token。配置之后,无论是搜索速度还是上下文质量都有明显提升。
这样做还有一个隐藏的好处:减少模型被无关文件干扰的概率。大型依赖目录里什么代码都有,模型读了之后容易混淆判断。让它的视野聚焦在业务代码上,准确率会高很多。
最后再分享一个小技巧。如果你和我一样经常在多台机器间切换,建议把 Bedrock 相关的环境变量写成一个 claude-bedrock.sh 脚本,放在 git 仓库外,而不是散落在各个 shell 的 profile 里。这样换机器时只需要配一次 AWS 凭据,再 source 这个脚本就能以完全一致的方式启动。踩过几次坑之后,我现在最深的体会是:Claude Code 这类工具真正考验人的不是会不会敲命令,而是有没有一套清晰的权限和成本边界。边界设好了,它就是一个非常得力的工程助手;边界没设好,它会还你一份昂贵的账单。
