1. 为什么你的 Claude Code 总是“失忆”:从一次真实翻车说起
Claude Code 是 Anthropic 推出的终端 AI 编程代理,它和补全插件最大的区别在于:它能读整个代码库、直接改文件、跑命令、提交 Git。但很多人第一次用就踩坑——明明上一轮说好了“用 Zustand 不用 Redux”,下一轮它又给你写回 Redux;明明项目里 API 层必须走src/api/封装,它偏偏在组件里直接fetch。
这不是模型笨,而是你没给它“项目记忆”。Claude Code 的上下文窗口填满得很快,官方文档里有一句原话:大多数最佳实践都基于一个约束——上下文窗口会迅速填满,性能随填充而下降。换句话说,你不主动管理上下文,它就会在几十轮对话后开始“忘事”。
我试过在一个中型 React 项目里连续对话 40 轮不清理,结果第 35 轮开始它把已经确认过的目录结构又搞错了。后来我把工作流拆成三层:CLAUDE.md 定义项目上下文、MCP 扩展外部能力、Hooks 做确定性自动化。这套组合跑下来,同一个项目连续开发两周,几乎没有再出现“失忆式返工”。
这篇手册就是把这套工程化落地方式完整交付给你:可复制的 CLAUDE.md 模板、MCP 服务注册配置、Hooks 触发脚本,以及每一项的验证动作。适合已经装好 Claude Code、想把它从“玩具”变成“团队生产力工具”的开发者。下面所有配置都基于 CLI 版本,路径和字段名与官方文档保持一致,你可以直接抄。
2. 前置准备:TaoToken 接入与 Claude Code 环境自检
在写 CLAUDE.md 之前,先把“模型从哪来”这件事解决掉。Claude Code 默认走 Anthropic 官方账号,但团队协作场景下,统一走一个可控的 API 入口更省心——计费集中、Key 统一管理、模型版本可锁定。TaoToken 提供的就是这样一个兼容 Anthropic 协议的接入层,你只需要改两个环境变量,CLI 本身不用动。
先说清楚它是什么:TaoToken 是一个大模型 API 聚合入口,对外暴露 Anthropic 兼容的/v1/messages接口,Claude Code 通过ANTHROPIC_BASE_URL指向它即可。适合谁:需要给多个工程师统一发 Key、想按项目隔离用量、或者本地网络访问官方端点不稳定的团队。官网入口在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 基址是 https://taotoken.net/api (注意这个地址不加 UTM 参数,直接填进配置)。
环境自检分三步。第一步确认 CLI 装好了:
claude --version # 期望输出类似:2.x.x (Claude Code)如果提示 command not found,macOS/Linux 用官方脚本curl -fsSL https://code.claude.com/install.sh | sh,Windows 用winget install Anthropic.ClaudeCode。注意 npm 全局安装方式已经废弃,别再用了。
第二步配置接入。推荐写进 shell 的 profile 文件,而不是每次手动 export:
# ~/.zshrc 或 ~/.bashrc export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的TaoToken密钥" export ANTHROPIC_MODEL="claude-sonnet-4-6"改完执行source ~/.zshrc生效。这里有个细节:ANTHROPIC_MODEL建议显式写死,否则 CLI 升级后默认模型可能变化,团队里不同人跑出不同结果,排查起来很痛苦。
第三步验证连通性。不要直接开交互式会话,先用非交互模式打一发最小请求:
claude -p "只回复两个字:通了" --output-format json期望返回一个 JSON,里面result字段是“通了”。如果这里报 401,说明 Key 或 Base URL 有问题;如果报连接超时,检查ANTHROPIC_BASE_URL有没有多写斜杠或漏写/api。这一步过了,再进项目目录跑claude开交互会话。
Key 的获取和轮换在控制台完成,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,新建 Key 时建议按“项目名-用途”命名,比如webapp-dev、webapp-ci,方便后面在 CI 里做用量归因。如果你只是想先验证模型对话效果,不急着接 CLI,可以先用模型对话页面试几条 prompt,地址 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
前置做完,你的 Claude Code 已经能正常对话了。但能对话不等于能干活,接下来才是重点:让它记住你的项目。
3. 可复制配置:CLAUDE.md 模板 + MCP 注册 + Hooks 脚本
这一节是整篇的核心,三块配置我都给你可直接落盘的版本。先说目录结构,这是团队协作的骨架:
your-project/ ├── CLAUDE.md # 项目主上下文(提交 Git) ├── CLAUDE.local.md # 个人本地覆盖(不提交) ├── .mcp.json # MCP 服务注册(提交 Git) └── .claude/ ├── settings.json # 项目共享配置(提交 Git) ├── settings.local.json # 本地配置(不提交) ├── rules/ │ ├── testing.md # 测试规范 │ └── api-design.md # API 设计规范 └── hooks/ ├── security-check.sh └── auto-lint.sh3.1 CLAUDE.md 模板
CLAUDE.md 的黄金法则是:只写“项目独有、Claude 猜不到”的信息。别写“写干净的代码”这种废话,那是浪费 token。控制在 200 行以内,超了就拆到.claude/rules/。
# 项目上下文 这是一个 TypeScript + React 的电商前端,后端 FastAPI。 ## 技术栈 - 前端:React 18 + TypeScript 5 + Vite - 状态管理:Zustand(禁止引入 Redux) - UI:Tailwind CSS + shadcn/ui - 测试:Vitest + React Testing Library ## 关键命令 ```bash pnpm dev # 开发服务器,端口 3000 pnpm typecheck # 类型检查 pnpm test # 单元测试 pnpm lint # ESLint编码规范
- 只用函数式组件 + Hooks,禁止类组件
- 禁止使用 any,必须显式声明类型
- 组件文件用 PascalCase,工具函数用 camelCase
- API 端点命名用 snake_case
结构决策
- UI 状态用 Zustand,服务端状态用 React Query
- 所有 HTTP 请求必须走 src/api/ 下的封装函数,禁止组件内直接 fetch
- 错误统一走 src/utils/errorHandler.ts
注意事项
- 不要修改 src/generated/ 目录(自动生成)
- 环境变量前端前缀必须是 VITE_
- 生产环境禁止 console.log
导入补充规则
@docs/api-conventions.md @docs/testing-guidelines.md
注意最后两行 `@` 导入语法,它会把外部文档内容也加载进上下文,比全塞进 CLAUDE.md 更清爽。层级上,`~/.claude/CLAUDE.md` 是全局规则,项目根的 CLAUDE.md 是项目规则,子目录里的 CLAUDE.md 只在 Claude 操作该目录时加载。 ### 3.2 MCP 服务注册 MCP(Model Context Protocol)是 Anthropic 推出的工具集成标准,类比 USB-C——Claude Code 通过它连接 GitHub、数据库、浏览器等外部系统。项目级注册写在 `.mcp.json`: ```json { "mcpServers": { "github": { "command": "npx", "args": ["@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } }, "filesystem": { "command": "npx", "args": [ "@modelcontextprotocol/server-filesystem", "/home/user/projects" ] }, "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } }也可以用 CLI 临时加:claude mcp add playwright npx @playwright/mcp@latest。但团队协作一定要用.mcp.json,这样每个人 clone 下来就有一致的工具集。注意.mcp.json提交前要 review,因为 MCP 服务器本质是能执行命令的,供应链攻击风险真实存在。
3.3 Hooks 脚本
Hooks 是在 Claude Code 生命周期特定节点自动执行的 shell 命令,它和提示词的本质区别是:提示词是建议,Claude 可能不听;Hook 是保证执行的规则。配置写在.claude/settings.json:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash .claude/hooks/security-check.sh" } ] } ], "PostToolUse": [ { "matcher": "Write|Edit|MultiEdit", "hooks": [ { "type": "command", "command": "bash .claude/hooks/auto-lint.sh" } ] } ] } }安全拦截脚本.claude/hooks/security-check.sh:
#!/bin/bash INPUT=$(cat) COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty') [ -z "$COMMAND" ] && exit 0 DANGEROUS=("rm -rf /" "dd if=/dev/zero" "mkfs" "> /dev/sda") for pattern in "${DANGEROUS[@]}"; do if echo "$COMMAND" | grep -qF "$pattern"; then echo "危险命令已阻断: $COMMAND" >&2 exit 2 fi done if echo "$COMMAND" | grep -qE "(>|>>)\s*(/etc/|~/.ssh/|~/.aws/)"; then echo "禁止写入系统敏感目录" >&2 exit 2 fi exit 0自动 lint 脚本.claude/hooks/auto-lint.sh:
#!/bin/bash INPUT=$(cat) FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty') [ -z "$FILE" ] && exit 0 case "$FILE" in *.ts|*.tsx) npx eslint --fix "$FILE" 2>/dev/null ;; *.py) ruff check --fix "$FILE" 2>/dev/null; black "$FILE" 2>/dev/null ;; *.go) gofmt -w "$FILE" 2>/dev/null ;; esac exit 0两个脚本记得chmod +x。exit 2是 Hooks 的约定:非零退出会阻断工具执行并把 stderr 反馈给 Claude,让它知道被拦了。
4. 验证请求:逐项确认配置真的生效
配置写完不验证,等于没配。这一节给你每一项的验证动作和期望结果,照着做一遍,心里就有底了。
4.1 验证 CLAUDE.md 被加载
在项目根目录启动claude,然后输入斜杠命令:
/memory这会列出当前会话加载的所有记忆文件。期望看到项目根的CLAUDE.md和通过@导入的docs/api-conventions.md。如果没看到,检查文件名大小写——必须是全大写CLAUDE.md,claude.md不生效。
再做一个行为验证:直接问它“这个项目用什么状态管理库”。如果 CLAUDE.md 生效,它会答 Zustand 并强调禁止 Redux;如果答“不确定”或“可能用 Redux”,说明没加载。
4.2 验证 MCP 服务注册成功
在会话里输入:
/mcp期望列出.mcp.json里注册的所有服务器,状态是 connected。如果某个显示 failed,先单独在终端跑一遍它的 command,比如npx @playwright/mcp@latest --help,看是不是包没装或网络问题。
验证工具真的可用:让 Claude 用 playwright 打开一个页面截图,或者用 github MCP 列出仓库的 open issues。能返回真实数据,才算通。
4.3 验证 Hooks 触发
安全 Hook 验证:让 Claude 执行一个危险命令,比如“帮我运行 rm -rf /tmp/test”。期望它被阻断,终端出现“危险命令已阻断”。注意别真让它跑rm -rf /,用/tmp下的测试目录就行。
自动 lint 验证:故意写一个格式错误的 TS 文件,比如少个分号、缩进乱掉,然后让 Claude 编辑它。编辑完成后检查文件,期望已经被 eslint 自动修复。如果没修复,检查脚本路径是不是相对项目根目录——Hooks 的工作目录是项目根,不是.claude/hooks/。
4.4 验证上下文管理
跑一个长任务,比如“分析 src/ 下所有组件的依赖关系”。观察上下文占用,到 70% 左右时执行:
/compact期望它把历史压缩成摘要,上下文占用下降,但关键结论还在。如果压缩后它忘了之前的结论,说明你的 CLAUDE.md 没把关键约束写进去——压缩会丢细节,但 CLAUDE.md 每轮都重新加载,是“防丢”的底线。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
配置过程中最容易撞的几类报错,我按真实日志给你对照排查。
401 Unauthorized。日志长这样:API Error: 401 {"type":"error","error":{"type":"authentication_error"}}。三个原因:Key 写错、Base URL 写错、环境变量没生效。排查顺序:先echo $ANTHROPIC_API_KEY确认非空,再echo $ANTHROPIC_BASE_URL确认是https://taotoken.net/api而不是带/v1或结尾多斜杠。改完 profile 一定要重新source或开新终端,旧终端不会自动继承。
local proxy failed。日志类似Error: connect ECONNREFUSED 127.0.0.1:7890。这是你本地配了 HTTP 代理但代理没开。检查echo $HTTPS_PROXY,如果不需要代理就unset HTTPS_PROXY HTTP_PROXY。注意 Claude Code 会读系统代理环境变量,公司网络环境下这个坑很常见。
reading 'choices'。日志:TypeError: Cannot read properties of undefined (reading 'choices')。这是典型的协议不匹配——你的 Base URL 指向了一个 OpenAI 格式的端点,但 Claude Code 发的是 Anthropic 格式请求。确认ANTHROPIC_BASE_URL指向的是 Anthropic 兼容接口,TaoToken 的/api就是兼容 Anthropic 的,别填成 OpenAI 兼容路径。
OAuth 相关报错。日志含OAuth token expired或invalid_grant。如果你用的是 API Key 模式,不该出现 OAuth 流程。检查是不是之前登录过官方账号,残留了~/.claude/下的凭据文件。执行claude /login重新选择 API Key 方式,或者删掉~/.claude/credentials.json重来。
MCP 服务器启动失败。日志:MCP server github failed to start: spawn npx ENOENT。说明 npx 不在 PATH 里,或者 Node 没装。which npx确认,没有就装 Node 20+。Windows 下还要注意 Git Bash 路径,CLAUDE_CODE_GIT_BASH_PATH要指向真实的 bash.exe。
Hooks 不触发。先确认.claude/settings.json是合法 JSON(用jq . .claude/settings.json校验),再确认脚本有执行权限。还有一个隐蔽点:matcher字段是正则,Write|Edit能匹配,但写成write|edit就匹配不上,大小写敏感。
排查完这些,你的工作流基本就稳了。如果 Key 管理上想更规范,建议在控制台按环境建不同 Key,地址 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,CI 用独立的 Key,本地开发用另一个,出问题能快速定位是哪条链路。
6. 长期编码与团队协作:把工作流固化下来
单机跑通只是开始,团队协作才是这套配置真正的价值。核心思路是:能提交 Git 的都提交,个人的东西放 local 文件。
CLAUDE.md、.mcp.json、.claude/settings.json、.claude/rules/、.claude/hooks/全部提交。CLAUDE.local.md、.claude/settings.local.json加进.gitignore。这样新人 clone 下来,跑一次claude就自动获得一致的上下文、工具集和自动化规则,不用口口相传“我们项目要注意啥”。
对于长期编码和 Agent 类任务,建议走 Coding Plan 而不是按量付费,成本更可控,地址 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。团队里每个人一个 Plan 席位,用量在控制台统一看。
再给几个实战技巧。第一,善用子智能体隔离探索:让 Explore 类型的子智能体去读代码、搜文档,只把结论带回主上下文,避免主窗口被文件内容塞满。第二,同一 bug 纠正超过两次就/clear重来,上下文已经被错误方案污染了,继续聊只会越陷越深。第三,70% 上下文占用就主动/compact,别等自动压缩(95% 才触发),那时质量已经掉了。第四,能用 CLI 工具就别用 MCP,gh、aws、sentry-cli这些比 MCP 调用省 token,在 CLAUDE.md 里写一句“GitHub 操作用 gh CLI”就行。
最后说个我踩过的坑:.mcp.json里用了${GITHUB_TOKEN}这种环境变量引用,但团队成员本地没设这个变量,MCP 启动就静默失败。解决办法是在 CLAUDE.md 里写清楚需要哪些环境变量,或者用.env文件配合 direnv 自动加载。配置这东西,能自动就别靠人记。
整套跑下来,你的 Claude Code 就从“一个会聊天的终端”变成了“记得住项目、连得上工具、守得住规则”的工程化助手。剩下的就是用它干活了。