ARTICLE DETAIL

资讯详情

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

打开 Claude Code 的黑匣子:从 CLAUDE.md 到 MCP,一次会话的上下文窗口里到底发生了什么?

打开 Claude Code 的黑匣子:从 CLAUDE.md 到 MCP,一次会话的上下文窗口里到底发生了什么? 1. 一次会话里上下文窗口到底被谁塞满了很多人第一次用 Claude Code都会有种错觉它好像记得住整个项目。你随口问一句“上次那个接口改完了吗”它真能翻出对应文件你让它按团队规范写代码它写出来的风格跟项目里已有的代码几乎一致。这种“提前做过功课”的感觉容易让人以为它背后挂着一个持久记忆库。其实不是。Claude Code 没有真正的记忆它所有的“知道”都来自一个东西——上下文窗口。你可以把它想成一块每次会话临时搭起来的白板对话历史、读过的文件、配置指令、工具说明全都被写到这块白板上模型每次回应只看白板此刻摆着什么。白板有容量上限目前大约是 20 万 token 量级听起来很大但真跑起长会话填满速度比想象中快得多。这篇就聚焦单次会话的内部机制拆开看 CLAUDE.md、MCP、子代理各自往窗口里塞了什么、什么时候塞、占多少以及窗口快满时/compact到底做了什么。目标很实在给你一份能直接抄的 CLAUDE.md 骨架、一段 MCP 配置片段再配上/context、/memory这类命令让你能亲眼看到自己的窗口被谁占着。适合已经在用 Claude Code、但总觉得它“时灵时不灵”的开发者。2. 前置准备把 TaoToken 接进 Claude Code在拆窗口机制之前得先让 Claude Code 能正常跑起来。Claude Code 本身是个命令行工具它需要一个能响应 Anthropic 协议的后端。我这边习惯用 TaoToken 来做接入层它的 API 地址是https://taotoken.net/api兼容 Anthropic 的接口格式配置起来不绕。先拿到访问凭证。打开控制台创建 API Key# 控制台地址创建和管理 API Key https://taotoken.net/console创建完 Key 之后把它写进环境变量。Claude Code 读取的是ANTHROPIC_BASE_URL和ANTHROPIC_API_KEY这两个变量指向 TaoToken 的 API 地址即可# 写入 shell 配置按你用的 shell 选一个 echo export ANTHROPIC_BASE_URLhttps://taotoken.net/api ~/.bashrc echo export ANTHROPIC_API_KEYsk-你的key ~/.bashrc source ~/.bashrc # 如果你用 zsh echo export ANTHROPIC_BASE_URLhttps://taotoken.net/api ~/.zshrc echo export ANTHROPIC_API_KEYsk-你的key ~/.zshrc source ~/.zshrc配好之后在项目根目录直接运行claude就能进会话。如果你还没装 Claude Code用 npm 全局装一下npm install -g anthropic-ai/claude-code这里有个细节值得先记住环境变量是在进程启动时读取的所以改完配置要重开终端或者source一下否则 Claude Code 还是用旧值。这个坑我在排查“为什么换了 Key 还是报 401”的时候踩过后来发现是终端没刷新。3. 可复制配置CLAUDE.md 骨架与 MCP 片段3.1 CLAUDE.md 到底该写什么CLAUDE.md 是项目级长期指令的存放处它在会话启动阶段就被静默读入上下文。也就是说你还没敲第一个字它的内容已经躺在白板上了。所以它写得好不好直接决定窗口的“底噪”有多大。一个常见的误区是把 CLAUDE.md 写成项目百科什么都往里塞。结果每次会话一开始几千 token 就被无关内容占掉。我的建议是分层项目根目录放全局规范子目录放局部规则让规则跟着文件路径按需加载。下面是一份可以直接改的骨架# 项目约定 ## 技术栈 - 语言TypeScript 5.x严格模式 - 框架Next.js 14 App Router - 包管理pnpm禁止用 npm 装依赖 ## 代码风格 - 组件用函数式禁止 class 组件 - 所有导出函数必须写 JSDoc 注释 - 错误处理统一用 Result 类型不抛裸异常 ## 目录结构 - src/app 路由与页面 - src/lib 纯工具函数禁止引入 React - src/components 通用组件 ## 禁止事项 - 不要修改 package.json 里的版本号 - 不要自动执行数据库迁移 - 提交前不要跑 git push这份骨架控制在 200 字以内占用的 token 很少但把最关键的约束说清楚了。真正细的规则放到子目录的 CLAUDE.md 里比如src/lib/CLAUDE.md只写工具函数的约定这样只有读到src/lib下的文件时才会加载。3.2 MCP 配置片段MCP 是模型上下文协议它让 Claude Code 能调用外部工具。关键点在于启动时加载的只是工具的名字和描述不是工具本身的逻辑。所以 MCP 对窗口的占用主要来自工具描述文本而不是工具能干什么。配置一般写在项目根目录的.mcp.json里{ mcpServers: { filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, /path/to/project] }, fetch: { command: npx, args: [-y, modelcontextprotocol/server-fetch] } } }每加一个 MCP server它的工具列表就会在启动时进入上下文。工具越多描述文本越长底噪越大。所以别一次性挂十几个 server按当前任务需要开。我实测下来挂 3 到 5 个常用 server 是比较舒服的区间再多就能明显感觉到窗口被描述文本吃掉一块。注意MCP 工具描述是常驻的不会因为你没用它就消失。如果某个 server 这个会话根本用不上直接从配置里去掉比留着更省空间。4. 验证请求用 /context 和 /memory 看窗口占用配置写完了怎么知道窗口里到底装了什么Claude Code 提供了两个命令一个看占用一个看加载。4.1 /context 看实时占用在会话里直接输入/context它会给出一个分类统计大致长这样Context Usage ───────────────────────────── System prompt 2,340 tokens CLAUDE.md 1,120 tokens MCP tools 3,860 tokens Messages 12,450 tokens Files 8,900 tokens ───────────────────────────── Total 28,670 tokens / 200,000这个输出能直接回答“窗口被谁占了”。如果 MCP tools 那一栏特别大说明你挂的 server 太多如果 Files 涨得飞快说明读进来的大文件在累积。我一般会在长会话中途跑一次/context看看是不是该清理了。4.2 /memory 看加载了哪些指令/memory这个命令列出会话启动时成功加载的 CLAUDE.md 文件和自动记忆内容。如果你改了 CLAUDE.md 但感觉没生效先跑这个确认它到底有没有被读进来。常见情况是文件放错了目录或者命名不对导致根本没被识别。4.3 观察文件读取的累积想直观感受文件读取的成本可以做个对比。先跑一次/context记下 Files 的数字然后让 Claude Code 读一个大文件请读取 src/app/page.tsx 并总结它的结构读完再跑一次/contextFiles 那一栏会明显上涨。一个 5000 行的文件读进来占用的 token 相当可观。如果会话里连续读了好几个大文件窗口占用会快速逼近上限。这就是为什么长会话后期Claude Code 的回应质量会下降——不是它变笨了是白板快写满了。5. 本篇常见错排查5.1 改了 CLAUDE.md 但行为没变最常见的原因是文件没被加载。先跑/memory确认。如果列表里没有你的文件检查三点文件名是否严格是CLAUDE.md大小写敏感、是否放在项目根目录或当前工作目录、是否在会话启动前就存在。会话中途新建的 CLAUDE.md 不会自动重载得重开会话。5.2 MCP 工具报连接失败先单独测 server 能不能起来npx -y modelcontextprotocol/server-filesystem /path/to/project如果这条命令本身报错说明是 server 的问题跟 Claude Code 无关。如果命令能跑但 Claude Code 里用不了检查.mcp.json的路径参数是不是绝对路径相对路径在不同工作目录下会解析失败。5.3 窗口很快满了回应变差跑/context看哪一栏最大。如果是 Messages说明对话历史太长用/compact压缩。如果是 Files说明读进来的文件太多考虑用子代理去处理调研类任务让它在独立窗口里读文档只把摘要带回来。如果是 MCP tools砍掉不用的 server。5.4 /compact 之后技能列表丢了这是预期行为。/compact会把对话历史替换成结构化摘要并自动重载 CLAUDE.md 和记忆但技能列表是唯一的例外不会自动重载。如果你依赖某个技能压缩后手动重新触发一次。5.5 子代理的结果没传回主会话子代理有自己独立的上下文窗口它读的大量文档不会占用主会话空间但代价是它只把摘要和少量元数据传回。如果你发现主会话拿不到细节是因为细节本来就没传回来。需要细节的话让子代理在摘要里明确列出关键结论和文件路径。6. 把窗口管起来比换模型更管用拆完这一圈你会发现 Claude Code 的行为其实很好解释它每次回应都只基于白板上此刻的内容。CLAUDE.md 和 MCP 描述是常驻底噪文件读取和对话历史是动态增量子代理是开了一块独立白板只交回结论/compact是擦掉旧讨论换成纪要。想让会话保持高质量重点不是换更强的模型而是管好这块白板。我的习惯是CLAUDE.md 控制在 200 字内MCP server 按需挂长会话中途跑一次/context看到 Messages 涨太快就/compact。调研类任务一律丢给子代理别让主会话去啃大文档。如果你还没配好接入层可以从 API Keys 页面拿一个 Key按第 2 节的命令写进环境变量就能跑。想先验证模型响应是否正常用模型对话页面发一条测试消息最快。要是你打算把 Claude Code 长期用在日常编码和 Agent 流程里Coding Plan 会更省心不用每次单独管额度。接入过程中遇到报错接入文档里有各语言的完整示例对着排查比瞎试快得多。
返回列表