ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Claude Code 上下文失控的五种常见姿势,用 CLAUDE.md 和 hooks 管住它

Claude Code 上下文失控的五种常见姿势,用 CLAUDE.md 和 hooks 管住它 1. 长会话里 Claude Code 为什么会“越用越飘”Claude Code 上下文失控本质上是把 coding agent 当成聊天窗口用。它和普通对话最大的区别在于它不只是回答问题它会读文件、跑命令、改代码、提交实现。官方文档把 context window 称为最重要的资源因为对话历史、文件读取、命令输出都会塞进同一个窗口。窗口越满早期约束越容易被稀释模型开始遗忘你最开始定的边界。我见过最典型的场景是这样的上午让 Claude Code 排查 Angular 21 standalone SSR 的 injector 层级问题中间顺手问了一句 ABAP RAP draft table 的设计过一会儿又切回 Angular SSR。表面上看它一直在线省了重新描述背景的时间。实际效果像把调试日志、设计会议纪要、数据库表结构一起塞进一个 issue 里后面每个判断都要从一堆无关内容里捞线索。官方 Slash Commands 文档把/clear标为 reset conversation context 的常用命令和/compact这种压缩历史的命令区分开来。/clear不是礼貌性清屏而是把旧 conversation context 清掉让新任务不被旧任务污染。判断标准不是时间而是主题边界Angular SSR 的SERVER_REQUEST_ORIGIN、skipSelf、EnvironmentInjector可以连续推进因为它们共享同一条推理链一旦引入 SAP NetWeaver、RAP unmanaged save sequence它就已经是另一条线了。五种常见失控姿势可以归纳为厨房水槽式会话、反复纠错污染上下文、CLAUDE.md 写成百科全书、只相信实现不给验收信号、无边界调查烧光窗口。这五种问题放在普通聊天里只是体验变差放在 coding agent 里就会变成真实的工程风险因为它会改文件、跑脚本、提交实现。这篇要解决的就是把失控姿势转化为可观测、可拦截的工程约束。核心手段有两个用分层 CLAUDE.md 管住“什么规则必须常驻”用 hooks 管住“什么动作必须零例外执行”。同时通过 TaoToken 统一 Key 通道让上下文压缩前后的行为差异可以被稳定复现和对比。适合谁看已经在用 Claude Code 做真实项目、遇到过指令漂移或上下文膨胀、想把 agent 工作流工程化的开发者。如果你还在单次问答阶段这篇的配置模板同样可以先收藏等进入长会话场景再逐条启用。2. TaoToken 前置统一 Key 通道让上下文实验可复现做上下文压缩前后对比实验最怕的不是模型表现差异而是请求通道本身不稳定。如果今天用这个 Key、明天换那个端点模型 ID 又对不上你根本分不清行为变化是上下文管理起了作用还是通道切换带来的噪声。TaoToken 在这里的角色是统一 Key 通道一个 API Key 走同一个 Base URL模型 ID 固定这样上下文压缩前后的行为差异才有可比性。TaoToken 是一个面向开发者的模型调用聚合入口官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 端点是 https://taotoken.net/api 。它的价值不在于“多一个渠道”而在于把 Claude Code、Cline、Codex 这类工具的接入参数收敛成一套Base URL 固定、Key 固定、Model ID 固定。这样你在做 CLAUDE.md 分层和 hooks 拦截实验时变量只剩上下文管理本身。具体到 Claude Code 的接入需要三件套对齐Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiKey 在控制台生成Model ID 按你实际调用的模型填写。这三者必须同时出现在配置里缺一个就会出现 401 或 model not found。很多人只改了 Base URL 忘了 Model ID结果请求打到了默认模型上上下文实验的结论直接失真。拿 Key 的路径是进入控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面创建新 Key。建议给 Claude Code 单独建一个 Key命名带上用途比如claude-code-ctx-lab这样后面排查 401 时能快速定位是哪个 Key 失效。Key 只在创建时完整显示一次复制后立刻写进环境变量或配置文件不要留在聊天记录里。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有各客户端的参数对照。Claude Code 走的是 Anthropic 兼容协议所以 Base URL 后面不需要再拼/v1直接填https://taotoken.net/api即可。这一点和 OpenAI 兼容协议的写法不同填错会直接 404。为什么强调“统一 Key 通道”而不是“随便找个能用的”因为上下文实验需要重复运行。同一段 prompt、同一份 CLAUDE.md、同一个 hooks 配置跑三次结果应该收敛。如果通道本身在换你无法判断第三次结果变好是因为/clear起了作用还是因为这次恰好路由到了更稳的模型。TaoToken 把通道固定下来实验才有意义。如果你要做长期编码或 Agent 类任务可以了解 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它适合需要持续会话、频繁调用、多 subagent 并行的场景。单纯做上下文对比实验按量调用就够了不必一上来就上套餐。验证模型是否通可以用模型对话页面直接发一条测试 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。发一句“回复 OK 两个字母”能正常返回就说明 Key 和通道没问题。这一步要在配置 Claude Code 之前做避免把通道问题和配置问题混在一起排查。3. 可复制配置分层 CLAUDE.md 与 hooks 拦截片段这一节给可直接复制的配置。分三块分层 CLAUDE.md 模板、settings.json 里的 hooks 配置、以及 Claude Code 接入 TaoToken 的配置片段。路径按 Claude Code 默认约定写你按自己项目结构调整。先说 CLAUDE.md 分层。官方 memory 文档说明CLAUDE.md 和 CLAUDE.local.md 会按目录层级加载多个文件会被拼接进上下文而不是互相覆盖。所以正确做法是分层而不是把所有规则堆在根目录一个文件里。根目录只放全局铁律子目录放局部规则。根目录CLAUDE.md模板# 项目铁律 ## 必须遵守 - 改任何文件后运行 pnpm format不要手动调整缩进 - 提交前必须运行 pnpm lint 和 pnpm test:unit - 禁止写入 migrations/ 目录迁移脚本由人工编写 - 禁止修改 pnpm-lock.yaml依赖变更需单独提 PR ## 验收标准 - 每个 bug 修复必须附带一个失败测试先复现再修复 - 完成后必须贴出测试命令和输出不接受“已完成”口头结论 - UI 改动必须提供截图或浏览器工具截图对比 ## 上下文纪律 - 同一问题纠正超过两次停止纠错整理新 prompt 后重开 - 调查型任务交给 subagent主会话只接收结论 - 切换无关任务前执行 /clear子目录packages/web/CLAUDE.md模板# web 包局部规则 ## 技术栈约束 - Angular 21 standalone不使用 NgModule - SSR 相关改动必须同时验证 server side 和 browser side - 注入层级问题优先检查 skipSelf 和 EnvironmentInjector ## 调查范围 - 查 token provider 时只读 server.ts、app.config.server.ts、main.server.ts - 不遍历整个 repo调用链调查交给 explore subagentCLAUDE.local.md放个人偏好不进版本库# 个人偏好不提交 - 解释代码时用中文代码注释用英文 - 输出 diff 时保留上下文 3 行然后是 hooks。官方 hooks 文档把 hooks 定义为在 Claude Code 生命周期特定点自动执行的 shell command、HTTP endpoint 或 LLM prompt。适合处理零例外的动作比 CLAUDE.md 里的软性提醒更确定。配置文件在.claude/settings.json{ hooks: { PostToolUse: [ { matcher: Edit|Write, hooks: [ { type: command, command: pnpm format --write $CLAUDE_FILE_PATHS } ] } ], PreToolUse: [ { matcher: Write, hooks: [ { type: command, command: bash .claude/hooks/block-migrations.sh } ] } ], Stop: [ { hooks: [ { type: command, command: bash .claude/hooks/verify-tests.sh } ] } ] } }.claude/hooks/block-migrations.sh内容#!/usr/bin/env bash set -euo pipefail for path in $CLAUDE_FILE_PATHS; do case $path in */migrations/*) echo BLOCKED: migrations 目录禁止写入请人工编写迁移脚本 2 exit 2 ;; esac done exit 0.claude/hooks/verify-tests.sh内容#!/usr/bin/env bash set -euo pipefail if ! pnpm test:unit --run /tmp/claude-test.log 21; then echo VERIFY FAILED: 单元测试未通过输出如下 2 tail -n 40 /tmp/claude-test.log 2 exit 2 fi echo VERIFY OK: 单元测试通过 exit 0注意 hooks 的退出码语义exit 2表示阻断并把 stderr 反馈给 Claudeexit 0表示放行。PreToolUse里用exit 2拦截写 migrationsStop里用exit 2让 Claude 知道验收没过它会继续修而不是停下。最后是 Claude Code 接入 TaoToken 的配置。Claude Code 走 Anthropic 兼容协议环境变量方式export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoTokenKey export ANTHROPIC_MODEL你的ModelID如果你用settings.json管理可以写成{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoTokenKey, ANTHROPIC_MODEL: 你的ModelID } }三件套必须同时出现Base URL、Key、Model ID。只改 Base URL 不改 Model ID请求会打到默认模型只填 Key 不填 Base URL请求会走官方端点你的 Key 直接 401。这两个是最常见的配置事故。4. 验证请求上下文压缩前后的行为差异对比配置写完必须验证否则你不知道 CLAUDE.md 和 hooks 到底有没有生效。这一节给一套可复现的对比流程先制造上下文膨胀再执行压缩观察行为差异。全程走 TaoToken 统一通道保证变量只有上下文管理本身。第一步确认通道通。在项目根目录执行claude -p 回复 OK 两个字母不要多余内容预期输出就是OK。如果报 401检查ANTHROPIC_API_KEY是否填了 TaoToken 的 Key如果报 model not found检查ANTHROPIC_MODEL是否和 TaoToken 控制台里的模型 ID 一致。这一步不通后面所有实验都没意义。第二步制造上下文膨胀。开一个会话连续做三件不相干的事claude 帮我看看 packages/web/server.ts 里 SERVER_REQUEST_ORIGIN 是怎么注入的 顺便分析一下 ABAP RAP 里 draft table 的保存顺序 回到刚才的 Angular SSRskipSelf 会不会跳过当前 EnvironmentInjector跑完后问一个探针问题 我最开始让你查的是哪个文件只回答文件名在膨胀上下文里Claude 经常答错或答得含糊因为它要从 Angular、ABAP、Angular 三段无关内容里捞最早的线索。这就是“厨房水槽式会话”的可观测症状。第三步执行/clear后重开用收束后的 prompt/clear 只分析 packages/web/server.ts 中 SERVER_REQUEST_ORIGIN 的注入层级。 不讨论 NgModule不讨论 ABAP。 重点检查 skipSelf 是否跳过当前 ElementInjector 或 EnvironmentInjector。 给出最小复现代码和验证命令。再问同一个探针问题回答会明显收敛。差异不在模型能力而在上下文里没有无关噪声。这一步就是官方建议的“失败两轮后重开并重写 prompt”的实操版。第四步验证 hooks 是否真的拦截。让 Claude 尝试写 migrations 目录 在 migrations/ 下新建一个 9999_test.sql写一句 SELECT 1如果PreToolUsehook 生效你会看到BLOCKED: migrations 目录禁止写入Claude 会收到这个反馈并停止写入。如果它真的写进去了检查.claude/settings.json的 matcher 是否写成了Write以及脚本是否有执行权限chmod x .claude/hooks/block-migrations.sh chmod x .claude/hooks/verify-tests.sh第五步验证 Stop hook 的验收闭环。故意让 Claude 改一个会破坏测试的文件然后看它停下时是否触发verify-tests.sh。如果测试失败你应该看到VERIFY FAILED加测试输出尾部Claude 会继续修而不是宣布完成。这就是把“只相信实现”变成“必须给验收信号”的机制。第六步验证 subagent 隔离。让主会话发起一个调查任务 用 explore subagent 查一下 SERVER_REQUEST_ORIGIN 在哪些文件里被 provide 只返回文件列表和层级结论不要把文件内容带回主会话跑完后用/context或观察主会话长度确认主窗口没有被大量文件内容塞满。官方 subagents 博客说明 subagent 是独立 Claude instance有自己的 context window完成后只把相关结果返回主 conversation。这一步验证的就是“无边界调查”是否被隔离。把六步跑完你手里就有了一组可对比的数据膨胀上下文下的探针回答、/clear后的探针回答、hooks 拦截日志、Stop hook 验收输出、subagent 隔离后的主会话长度。这些是可观测证据不是感觉。后面调 CLAUDE.md 和 hooks 时用同一套流程回归就能判断改动是否真的有效。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置和验证过程中会撞到几类固定报错。这一节按真实报错逐条给排查路径每条都对应到具体文件和参数。401 Unauthorized。最常见的原因是 Key 没生效或 Base URL 和 Key 不匹配。先确认环境变量echo $ANTHROPIC_BASE_URL echo $ANTHROPIC_API_KEY | head -c 8Base URL 应该是https://taotoken.net/apiKey 前缀能对上你在控制台创建的那把。如果 Base URL 末尾多写了/v1Anthropic 兼容协议下会 404 而不是 401但有些客户端会把它包装成 401。另一个原因是 Key 被撤销或额度耗尽去控制台 API Keys 页面确认状态。如果同时设了ANTHROPIC_API_KEY和ANTHROPIC_AUTH_TOKEN后者会覆盖前者检查有没有残留的旧变量。local proxy failed。这个报错通常出现在客户端尝试走本地代理端口但代理没起来。Claude Code 本身不需要本地代理如果你在settings.json或环境变量里配了HTTP_PROXY、HTTPS_PROXY指向127.0.0.1:某端口而那个端口没有服务在听就会报 local proxy failed。排查env | grep -i proxy把指向本地端口的代理变量清掉或者确认对应服务在运行。TaoToken 的接入不需要额外代理层Base URL 直连即可。清掉后重跑claude -p 回复 OK验证。reading choices 相关报错。这类报错通常出现在响应体解析阶段提示读取choices字段失败。原因是客户端按 OpenAI 兼容格式解析但实际走的是 Anthropic 兼容协议响应结构里没有choices。检查你的客户端类型Claude Code 用 Anthropic 协议Cline 用 OpenAI 协议两者 Base URL 写法不同。如果你在 Claude Code 里填了 OpenAI 风格的配置或者反过来就会在解析阶段炸掉。确认ANTHROPIC_BASE_URL用于 Claude CodeOpenAI 兼容客户端才用/v1后缀。OAuth 相关报错。Claude Code 某些版本会尝试 OAuth 登录流程如果你已经用 API Key 接入OAuth 流程应该被跳过。如果仍然报 OAuth 错误检查是否有残留的登录态文件通常在~/.claude/下。清理后重新用环境变量方式启动rm -rf ~/.claude/credentials.json export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoTokenKey export ANTHROPIC_MODEL你的ModelID claude -p 回复 OK如果用了 CC Switch 这类配置切换工具确认它写入的三件套完整Base URL、Key、Model ID。CC Switch 切换配置时最容易漏掉 Model ID导致请求打到默认模型表现为“能通但行为不对”。Cline 的 MCP 配置同理MCP server 的 env 里也要带全三件套。Codex 的auth.json如果出现检查里面的base_url和api_key是否和 TaoToken 控制台一致model字段是否填了有效 ID。hooks 不生效。症状是 Claude 写了 migrations 目录但没被拦截。排查顺序确认.claude/settings.json是合法 JSON用jq . .claude/settings.json验证确认 matcher 写的是Write而不是write大小写敏感确认脚本有执行权限确认CLAUDE_FILE_PATHS环境变量在 hook 执行时可用如果为空脚本里的 for 循环不会拦截任何路径。可以在脚本开头加一行echo paths: $CLAUDE_FILE_PATHS 2调试。Stop hook 导致会话卡住。如果verify-tests.sh一直返回exit 2Claude 会反复尝试修复可能陷入循环。给脚本加一个最大重试计数或者把验收失败改成警告而非阻断if ! pnpm test:unit --run /tmp/claude-test.log 21; then echo VERIFY WARN: 测试未通过请人工确认 2 exit 0 fi阻断还是警告取决于你对“零例外”的要求。迁移目录写入适合阻断测试失败适合先警告再人工介入。上下文压缩后行为反而变差。/compact和/clear不同/compact是压缩历史可能丢掉你需要的约束。如果压缩后 Claude 忘了关键规则说明那些规则不该只存在于对话历史里应该写进 CLAUDE.md 或 hooks。这也是分层 CLAUDE.md 的意义常驻规则不依赖对话历史存活。6. 把上下文卫生变成日常工程习惯回到最开始的问题Claude Code 的质量不只由模型能力决定也由上下文卫生决定。五种失控姿势对应五个可拦截点厨房水槽式会话用/clear和主题边界拦截反复纠错用“两轮后重开”拦截CLAUDE.md 膨胀用分层模板拦截缺少验收用 Stop hook 拦截无边界调查用 subagent 拦截。判断是否进入危险区看三个信号它开始引用和当前任务无关的旧背景说明 session 该清了它在同一个错误上绕圈说明纠错记录已经污染上下文它给出一个很像完成品的实现却没有任何测试输出或截图说明验收环节缺席。出现这三个信号时继续追问通常不会更快清理、收束、重开反而更像专业工程师的选择。日常操作上把 CLAUDE.md 当 lint config 而不是项目 Wiki只写每次都要生效的规则把零例外的动作交给 hooks不要写成软性提醒把调查型任务交给 subagent主会话只接收结论把验收标准写成可执行命令而不是口头描述。这四条做到上下文膨胀和指令漂移会明显减少。如果你还没接入统一通道先去控制台拿 Key https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 然后按接入文档配好三件套 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。通道固定后再跑第 4 节的六步验证流程你就能拿到自己项目的第一组上下文对比数据。长期做编码和 Agent 任务的话Coding Plan 的持续会话能力会更合适 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。最后留一个我常用的习惯每次开新 session 前先花十秒写一句“这个 session 只服务哪条主线”贴在 prompt 最前面。这十秒能省掉后面半小时的上下文清理。Claude Code 像一个高速运转的工程搭档前提是你不给它塞过量会议纪要。
返回列表