首页 / Claude Code 入门教程 / 大型代码库与成本管理

Claude Code 入门教程

大型代码库与成本管理

本教程共 34 篇 · 第 31 篇 · 更新于 2026-07-26 · 约 8 分钟阅读

Claude CodeClaude Code 入门教程大型代码库成本管理Prompt CachingToken 优化

31. 大型代码库与成本管理

本节目标:学会在 monorepo 或百万行级代码库中让 Claude Code 只关注你正在处理的代码,同时掌握 token 成本跟踪和优化技巧,让每一分钱花在刀刃上。

当你的项目从几百个文件增长到几万个文件,Claude Code 的默认配置就开始力不从心了。根目录一个巨大的 CLAUDE.md 塞满了所有子系统的规则,Claude 每次读取文件都在无关代码上浪费 token,成本也跟着飙升。这一章就是解决这两个问题:让 Claude 专注于该干的活,同时把成本压下来。

为什么大型代码库需要特殊配置

想象你在一个大型商场找一家店。如果商场没有分区地图,你只能挨个逛,费时费力。Claude Code 在大型代码库里面临同样的问题——默认会读取大量无关文件,上下文窗口(Context Window)被无关内容填满,真正需要的信息反而被挤掉。

核心思路就一句话:限制 Claude 看到的范围,让它只处理你当前任务的代码。

分层 CLAUDE.md:按目录组织指令

小项目里一个根目录 CLAUDE.md 就够了。但 monorepo 有多个包,每个包技术栈不同,把所有规则塞一个文件里,Claude 每次启动都要加载全部,白白浪费上下文。

两级分层是最常见的做法

monorepo/
  CLAUDE.md                     # 根指令:通用规则
  packages/
    api/
      CLAUDE.md                 # API 包的专属指令
      src/
    web/
      CLAUDE.md                 # 前端包的专属指令
      src/
    shared/
      CLAUDE.md                 # 共享库指令
      src/

CLAUDE.md 写全局规则:

这是一个 monorepo,在 packages/ 下有三个包:

- packages/api:使用 Express、TypeScript 和 PostgreSQL 的 Node.js REST API
- packages/web:使用 Vite、TypeScript 和 TailwindCSS 的 React 前端
- packages/shared:由 api 和 web 都使用的共享 TypeScript 实用程序

从包目录运行命令,而不是从 monorepo 根目录。
每个包都有自己的 tsconfig.json、package.json 和测试套件。

子目录的 CLAUDE.md 只写本区域的规则,比如 packages/api/CLAUDE.md

这个包是 REST API 服务器。

- 运行测试:npm test(使用 Vitest)
- 运行开发服务器:npm run dev(端口 3001)
- 数据库迁移:npm run migrate

API 路由在 src/routes/ 中。每个路由文件导出一个 Express 路由器。
数据库查询在 src/db/ 中使用 Knex。永远不要在路由处理程序中写原始 SQL 字符串。

当你从 packages/api/ 启动 Claude,它加载根 CLAUDE.md 加上 packages/api/CLAUDE.md,不会加载 packages/web/ 的指令。

Tip

从哪个目录启动 claude 很关键。从子目录启动,Claude 只能访问该子树的文件,只加载该目录和祖先目录的 CLAUDE.md。从根目录启动,则能访问所有文件,但子目录的 CLAUDE.md 只在 Claude 读取该目录文件时才按需加载。

排除不相关的 CLAUDE.md

如果你从根目录启动,但从不碰某些包(比如别的团队维护的),可以用 claudeMdExcludes 跳过它们:

{
  "claudeMdExcludes": [
    "**/packages/admin-dashboard/**",
    "**/packages/legacy-*/**"
  ]
}

放在 .claude/settings.local.json 里只对自己生效,放在 .claude/settings.json 里对整个团队生效。

减少 Claude 读取的文件

光控制指令还不够,文件读取是另一个 token 消耗大户。

阻止读取构建产物和供应商代码

Claude 的搜索默认尊重 .gitignore,所以 node_modules/dist/build/ 这些不会出现在搜索结果里。但有些路径已经检入了 git,比如 vendor 目录或生成的代码,需要手动阻止:

{
  "permissions": {
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)",
      "Read(./**/*.generated.*)",
      "Read(./vendor/**)"
    ]
  }
}

这些 deny 规则会阻止 Claude 用内置工具或 catheadgrepfind 等命令读取这些路径。

用代码智能插件替代文件扫描

在大型代码库里找一个函数的定义,传统方式是 grep 搜索加读取多个候选文件,费时费 token。代码智能插件(Code Intelligence Plugin)把 Claude 连到语言服务器,直接跳转定义、查找引用。

# 安装 TypeScript 代码智能插件
/plugin install typescript-lsp@claude-plugins-official

官方市场有 TypeScript、Python、Go、Rust 等语言的插件。一次”转到定义”调用替代了好几次 grep 加文件读取,省下的 token 相当可观。

稀疏工作树:只检出需要的目录

--worktree 标志会在新的 git worktree 中启动会话,让改动与主检出隔离。默认检出整个仓库,在大型仓库里又慢又占空间。

worktree.sparsePaths 用 git sparse-checkout 只检出你指定的目录:

{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  }
}

这样 worktree 只包含 .claude/packages/api/packages/shared/ 和根级文件(如 package.json、锁文件),node_modules 通过符号链接指向主仓库的副本,不重复占用磁盘。

Note

sparsePaths 里列目录而不是单个文件。根级文件(package.jsontsconfig.base.json、锁文件)始终会检出,但根级目录不会——如果你需要根目录的 .claude/,记得在列表里加上 .claude

跨包和跨仓库访问

packages/api/ 启动时,Claude 只能访问这个目录。如果任务需要改 packages/shared/ 里的共享类型,得额外授权。

两种方式:

# 方式一:启动时传参
claude --add-dir ../shared

# 方式二:写在设置里(对整个团队生效)
{
  "permissions": {
    "additionalDirectories": [
      "../shared",
      "../web"
    ]
  }
}

--add-dir 会加载目标目录的 skills,additionalDirectories 只授予文件读写权限,不加载 skills 和 CLAUDE.md

按目录放 Skills

每个子目录可以有自己的 skills,只在 Claude 处理该区域文件时按需加载:

packages/api/.claude/skills/api-testing/SKILL.md
packages/web/.claude/skills/component-patterns/SKILL.md

API 的测试 skill 在前端工作时不会加载,反之亦然。这比把所有指令塞进一个 CLAUDE.md 高效得多。

Tip

目标是把 CLAUDE.md 控制在 200 行以内。特定工作流的详细指令(如 PR 审查流程、数据库迁移步骤)移到 skills 里,只在需要时加载。

成本跟踪:钱花哪了

说完了怎么省,先看看怎么查。不知道钱花在哪,优化就无从谈起。

/usage 查看当前会话

Total cost:            $0.55
Total duration (API):  6m 19.7s
Total duration (wall): 6h 33m 10.2s
Total code changes:    0 lines added, 0 lines removed

在 Pro、Max、Team 或 Enterprise 计划上,/usage 还会显示计划使用量明细,按 skills、subagents、plugins、MCP 服务器分别统计占比。按 d 看过去 24 小时,按 w 看过去 7 天。

Note

/usage 里的美元数字是从 token 计数本地估算的,可能与实际账单有出入。权威计费以 Claude Console 使用情况页面为准。

设置支出限制

Pro 和 Max 计划可以用 /usage-credits 管理使用额度:

  • 启用使用额度
  • 购买更多额度(固定套餐或自定义金额)
  • 设置每月支出限制
  • 配置余额低于阈值时自动充值

Teams 和 Enterprise 通过管理控制台设置组织级支出限制。

组织级成本管理

不同接入方式,查看和限制成本的地方不同:

接入方式查看支出限制支出
Teams/Enterprise组织分析支出报告管理员设置支出限制
Claude Console (API)Console 使用情况页面工作区支出限制
云提供商(Bedrock 等)云计费控制台云预算控制

如果需要近实时的每用户指标,OpenTelemetry 导出是唯一选择,能把 token 和成本指标流式传到你自己的监控系统。

Token 优化实战策略

成本随上下文大小增长:Claude 处理的上下文越多,token 消耗越大。以下是经过验证的降本策略。

主动管理上下文

# 切换到不相关任务前清除上下文
/clear

# 压缩对话时指定保留重点
/compact Focus on code samples and API usage

也可以在 CLAUDE.md 里写默认的压缩指令:

# Compact instructions

When you are using compact, please focus on test output and code changes
Warning

长会话从不清除是成本失控的头号原因。每条消息都带着之前的完整历史,对话越长,单次请求的 token 越多。在任务之间用 /clear 重新开始,用 /rename 给会话起名方便后续 /resume 找回来。

选对模型

Sonnet 处理大多数编码任务效果不错,成本远低于 Opus。把 Opus 留给复杂的架构决策和多步推理。

# 会话中途切换模型
/model sonnet

# 在配置里设默认模型
/config

子代理(Subagent)做简单任务时,可以在配置里指定 model: haiku,更省钱。

减少 MCP 服务器开销

MCP 工具定义默认被延迟加载,只有工具名称进入上下文。但还是建议:

  • 优先用 CLI 工具(ghawsgcloud)而非 MCP 服务器,因为 CLI 不添加工具列表
  • /mcp 查看配置的服务器,禁用没在用的
  • /context 查看什么占了上下文

用 Hooks 预处理数据

Hook 可以在 Claude 看到数据之前先过滤。比如 Claude 要读 10000 行日志找错误,hook 先 grep 出 ERROR 行,只把匹配的几十行返回,token 从几万降到几百。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/filter-test-output.sh"
          }
        ]
      }
    ]
  }
}

过滤脚本把测试命令改成只输出失败项:

#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

if [[ "$cmd" =~ ^(npm test|pytest|go test) ]]; then
  filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"updatedInput\":{\"command\":\"$filtered_cmd\"}}}"
else
  echo "{}"
fi

把冗长操作委托给子代理

跑测试、拉文档、处理日志这类操作输出量大,委托给子代理执行,冗长输出留在子代理的上下文里,只有摘要返回主对话。

调整扩展思考

扩展思考默认启用,对复杂推理很有帮助,但思考 token 按输出 token 计费,一次请求可能消耗数万个 token。简单任务可以降低推理强度或设思考预算上限:

# 降低推理强度
/effort

# 设置思考 token 上限
# 在环境变量中设置
MAX_THINKING_TOKENS=8000

写具体的提示

模糊的请求(如”改进此代码库”)会触发大范围扫描。具体的请求(如”向 auth.ts 中的 login 函数添加输入验证”)让 Claude 精准定位,文件读取最少。

Prompt Caching:自动省钱机制

Prompt caching 是 Claude Code 自动管理的功能,但理解它的工作原理能帮你避免意外让缓存失效。

缓存怎么工作

每次发消息,Claude Code 都重新发送完整上下文给 API。没有缓存的话,每次都要重新处理全部历史。有了缓存,API 重用已处理过的内容,只处理新增部分。

请求内容按层组织,越靠前越少变动:

内容什么时候变
系统提示核心指令、工具定义、输出样式工具集合变化或 Claude Code 升级
项目上下文CLAUDE.md、自动内存会话开始或 /clear/compact
对话你的消息、Claude 响应、工具结果每个回合

对话层的变化不影响前面两层的缓存。系统提示变了,后面全部失效。

哪些操作会让缓存失效

以下操作会导致下一个请求缓存未命中,变得更慢更贵:

  • 切换模型:每个模型有独立缓存,/model 切换后整个对话历史重新处理
  • 更改推理强度:同模型每个 effort 级别也有独立缓存
  • 启用快速模式(Fast Mode):添加了请求头,缓存键改变
  • 连接或断开 MCP 服务器:工具定义变化(延迟加载的工具除外)
  • 启用或禁用插件:提供 MCP 服务器的插件会触发失效
  • 拒绝整个工具:如添加裸 Bash 到 deny 规则,会从系统提示中移除该工具定义
  • 压缩对话/compact 用摘要替换历史,对话层失效
  • 升级 Claude Code:新版本通常更新系统提示
Tip

在会话开始时就选好模型和推理强度,然后在任务之间的自然中断处执行 /compact。任务中途做的改变越少,缓存命中率越高。

哪些操作不破坏缓存

好消息是,这些常见操作是缓存安全的:

  • 编辑仓库中的文件(文件内容只在 Claude 读取时进入上下文)
  • 会话中途编辑 CLAUDE.md(不会失效,但也不会生效,需重启或 /clear
  • 更改输出样式(同上)
  • 切换权限模式(除非用 opusplan 模型设置)
  • 调用 skills 和命令(在调用点注入,不影响前面的内容)
  • 运行 /recap(摘要附加到对话末尾)
  • 重绕对话(/rewind 截断回之前的回合,命中更早的缓存)
  • 生成子代理

缓存生命周期

缓存条目在不活动后过期。每次命中缓存会重置计时器,所以持续工作时缓存保持温暖。

两种 TTL(生存时间):

  • 5 分钟:API 密钥和第三方提供商默认,更便宜
  • 1 小时:Claude 订阅默认自动启用,更长的中断也能保持缓存

API 用户可以用环境变量选择 1 小时 TTL:

ENABLE_PROMPT_CACHING_1H=1
Note

缓存限定在一台机器和一个目录。系统提示嵌入了工作目录、平台、shell 等信息,所以不同目录的会话构建不同前缀,无法共享缓存。同一目录的并行会话可以共享。

Agent 团队的成本控制

Agent 团队生成多个 Claude 实例,每个维护自己的上下文窗口。团队在 Plan Mode 运行时,token 消耗大约是标准会话的 7 倍。

控制成本的要点:

  • 队友用 Sonnet,平衡能力和成本
  • 保持团队规模小,token 使用与团队规模成正比
  • 生成提示要精简,队友会自动加载 CLAUDE.md、MCP 和 skills
  • 工作完成后关闭队友,活跃的队友持续消耗 token

把所有配置整合在一起

一个 packages/api/ 区域的完整配置示例:

{
  "worktree": {
    "sparsePaths": [
      ".claude",
      "packages/api",
      "packages/shared"
    ],
    "symlinkDirectories": [
      "node_modules"
    ]
  },
  "permissions": {
    "additionalDirectories": [
      "../shared"
    ],
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)"
    ]
  }
}

加上按目录的 CLAUDE.md 和 skills,从 packages/api/ 启动 Claude 时:

  • 加载根 CLAUDE.mdpackages/api/CLAUDE.md,跳过 packages/web/
  • 能读写 packages/api/packages/shared/
  • 跳过 dist/build/ 的读取
  • api-testing skill 按需可用
  • worktree 只检出需要的目录

这套配置让 Claude 在大型代码库里依然精准高效,不会在无关代码上浪费 token。

小结

大型代码库和成本管理是两个紧密相关的话题。限制 Claude 看到的范围就是在省钱,而省下的每一 token 都让 Claude 在真正重要的代码上表现更好。记住几个关键习惯:从子目录启动、分层放指令、用 hooks 过滤、选对模型、任务间清除上下文。这些加起来,能让你的成本和企业平均值(约每个开发者每个活跃日 13 美元)持平甚至更低。