1. 长会话里 TodoList 为什么会丢
用 Claude Code 写一个稍微完整点的模块,比如给数据库补一套 CRUD API 加单元测试,很容易聊到三四十轮。前面十几轮一切正常,Claude 记得你定的命名规范、记得你说过"分页用 OFFSET + FETCH"、记得 UserService 已经写完了。然后某一次工具调用返回之后,界面弹出一句上下文窗口接近上限,接着它自动压缩,再回你一句"好的,接下来做什么"。
你让它继续写 UserService 的单元测试,它却重新创建了一遍 UserService。这不是它变笨了,是压缩把"已经做过什么"这件事从记忆里抹掉了。TodoList 之所以经常一起消失,是因为它默认活在对话历史里,而对话历史正是被压缩的对象。这篇就围绕 Claude Code 配 TaoToken 之后,怎么用/compact的压缩时机加CLAUDE.md的持久化约定,把 TodoList 从"靠记忆"改成"靠文件",让长会话不再断片。
适合谁看:已经在用 Claude Code 做多文件、多步骤任务,被上下文膨胀和进度丢失折腾过的人。你需要的基础是会用命令行、知道settings.json大概长什么样、能编辑 Markdown 文件。下面所有配置都可以直接复制,改掉 Key 就能跑。
先说清楚一个前提:TaoToken 在这里的角色是统一 Key 和 API 通道。Claude Code 本身支持通过环境变量或配置文件指定 Anthropic 兼容的接入地址,把通道收敛到一处之后,你换模型、换额度、看用量都在同一个后台,不用在多个 Key 之间来回改配置。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api ,注意 API 这个地址不带 UTM 参数,配置里要写干净。
2. 前置:把 TaoToken 通道接进 Claude Code
2.1 先拿 Key,再决定写哪一层配置
Claude Code 读取接入信息有两个层次:环境变量和项目/用户级settings.json。环境变量适合临时试,settings.json适合长期固定。我建议长期用settings.json,因为环境变量在换终端、换 IDE 内置终端时经常丢,排查起来很烦。
拿 Key 的路径是控制台里的 API Keys 页面,创建之后复制那串以sk-开头的字符串。这一步别把 Key 贴进任何会提交到 Git 的文件里,后面配置里我会用占位符。
- 控制台入口:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
- API Keys 页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
2.2 settings.json 骨架
Claude Code 的配置分用户级和项目级。用户级在~/.claude/settings.json,项目级在项目根目录的.claude/settings.json。通道这种全局信息放用户级,项目相关的规则放项目级。下面这份是用户级骨架,把ANTHROPIC_BASE_URL指向 TaoToken 的 API 地址,ANTHROPIC_AUTH_TOKEN填你的 Key:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的TaoToken密钥", "ANTHROPIC_MODEL": "claude-sonnet-4-5", "CLAUDE_CODE_MAX_OUTPUT_TOKENS": "8192" }, "permissions": { "allow": [ "Read", "Grep", "Glob" ], "deny": [] } }几个参数的实际作用,我按踩过的坑说一下。ANTHROPIC_BASE_URL必须是https://taotoken.net/api,末尾不要多加斜杠,加了有的版本会拼出双斜杠导致 404。ANTHROPIC_MODEL写你实际要用的模型名,写错不会报"模型不存在",而是回退到默认模型,你会以为配置没生效。CLAUDE_CODE_MAX_OUTPUT_TOKENS控制单次回复上限,设太大对上下文没好处,8192 对大多数编码任务够用。
注意:
ANTHROPIC_AUTH_TOKEN和ANTHROPIC_API_KEY是两个不同的变量名,Claude Code 认前者。如果你之前配过ANTHROPIC_API_KEY,两个都留着可能互相覆盖,建议只保留ANTHROPIC_AUTH_TOKEN。
2.3 项目级配置只放规则,不放 Key
项目级.claude/settings.json不要写 Key,因为项目目录大概率会进版本库。它只放权限和本地行为:
{ "permissions": { "allow": [ "Read", "Grep", "Glob", "Edit", "Bash(git status)", "Bash(git diff:*)" ], "deny": [ "Bash(rm -rf:*)", "Bash(git push:*)" ] } }把git push放进 deny 是有意的,长会话里 Claude 容易在你不注意时提交并推送,禁掉之后它只能改本地,你确认完再手动推。
3. 可复制配置:CLAUDE.md 里约定 TodoList 持久化
3.1 为什么 TodoList 要落到文件
Claude Code 内置的 TodoWrite 工具会维护一份任务清单,这份清单在/compact之后通常能保留,但它保留的是"清单结构",不是"每个任务背后的上下文"。也就是说压缩后它可能还记得"第 4 步:实现 UserController",但忘了第 4 步依赖第 3 步里定的某个返回结构。真正稳的做法是:TodoList 的权威副本写在CLAUDE.md里,对话里的 TodoWrite 只是它的运行时视图。
CLAUDE.md在每次会话开始时自动加载,属于系统级内容,不会被/compact压掉。这就是它比对话历史可靠的根本原因。
3.2 CLAUDE.md 片段
把下面这段放进项目根目录的CLAUDE.md,按你的项目改:
# 项目约定 ## 上下文管理规则 - 每完成一个 TodoList 条目,立即把该条目状态从 [ ] 改为 [x],并写一行完成说明。 - 触发 /compact 之前,必须先把当前 TodoList 全量同步到本文件的"任务清单"小节。 - 新会话开始时,先读本文件的"任务清单",再决定下一步,不要凭对话记忆推进。 - 单个任务涉及超过 3 个文件时,拆成子任务,每个子任务单独标记。 ## 任务清单 - [x] 创建 User 实体类(字段:id, email, passwordHash, createdAt) - [x] 创建 UserMapper(MyBatis-Plus,不用 JPA) - [x] 实现 UserService 增删改查(分页用 OFFSET + FETCH) - [ ] 实现 UserController REST 接口 - [ ] 添加参数校验(email 格式、密码强度) - [ ] 编写 UserService 单元测试 ## 技术约束 - 分页查询统一 OFFSET + FETCH,禁止 ROW_NUMBER() - 密码加密 bcrypt,轮次 12 - 所有 SQL 参数化,禁止字符串拼接 - 异常统一抛 BizException3.3 压缩前的固定动作
在CLAUDE.md里约定好之后,压缩前你只需要说一句"按 CLAUDE.md 的规则,先把任务清单同步过去",Claude 就会把当前 TodoList 写回文件。这一步花不了多少 Token,但能省掉压缩后重新对齐进度的几万 Token。
4. 验证:压缩前后 TodoList 是否保留
4.1 先看上下文占用
Claude Code 有/context命令,能看到各部分占用。跑一次:
/context输出大概长这样:
System Prompt: 3,200 tokens (1.6%) CLAUDE.md: 1,900 tokens (1.0%) 对话历史: 48,000 tokens (24.0%) 工具调用结果: 86,000 tokens (43.0%) 文件读取: 51,000 tokens (25.5%) ───────────────────────────────────────── 总计: 190,100 / 200,000 tokens (95.1%)看到没有,对话本身只占 24%,工具调用和文件读取加起来接近 70%。这就是为什么"少聊两句"根本救不了上下文,真正的大户是 Read 和 Grep 的输出。
4.2 压缩前记录基线
在触发/compact之前,先让 Claude 输出当前任务清单:
把当前 TodoList 完整列出来,每条带上状态和一句话说明。记下这份清单。然后执行同步:
按 CLAUDE.md 的规则,把这份 TodoList 同步到文件的"任务清单"小节。确认CLAUDE.md已经更新,再执行:
/compact4.3 压缩后验证
压缩完成后,开一个新会话(或者就在当前会话里)问:
读 CLAUDE.md 的任务清单,告诉我下一步该做什么。如果它准确说出"下一步是实现 UserController REST 接口",说明持久化生效了。如果它说"我不清楚之前做到哪了",说明同步那一步没执行,或者CLAUDE.md没被加载——检查文件是不是放在项目根目录,文件名大小写是不是CLAUDE.md。
再补一个更严格的验证:让它复述技术约束。
根据 CLAUDE.md,分页查询用什么语法?密码加密用什么算法和轮次?正确回答应该是"OFFSET + FETCH"和"bcrypt 12 轮"。这两个答案在压缩后的对话历史里大概率已经没了,能答对只可能来自CLAUDE.md。
4.4 用模型对话快速验证通道
如果你只想确认 TaoToken 通道本身通不通,不用开 Claude Code,直接用模型对话页面发一条消息最快:
- 模型对话入口:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite
发一句"用一句话说明 OFFSET + FETCH 和 ROW_NUMBER 分页的区别",能正常返回就说明 Key 和通道没问题,剩下的问题都在 Claude Code 配置层。
5. 本篇常见错排查
5.1 报 401 或 invalid api key
先确认settings.json里写的是ANTHROPIC_AUTH_TOKEN而不是ANTHROPIC_API_KEY。再确认 Key 没有多余空格,复制时经常带上首尾空白。最后确认ANTHROPIC_BASE_URL是https://taotoken.net/api,不是官网首页地址,也不是带 UTM 的地址。
5.2 报 404 或 model not found
大概率是ANTHROPIC_BASE_URL末尾多了斜杠,或者ANTHROPIC_MODEL写了一个通道不支持的模型名。把模型名去掉,让它用默认模型试一次,能通就说明是模型名的问题。
5.3 压缩后 TodoList 还是丢了
按可能性排序:第一,压缩前没执行同步,对话里的 TodoList 没写回CLAUDE.md;第二,CLAUDE.md不在项目根目录,或者文件名写成了claude.md;第三,CLAUDE.md内容太长,被截断加载。第三种情况把文件控制在 200 行以内,把不常用的规则挪到单独文件里按需引用。
5.4 上下文还是涨得很快
跑/context看是哪一项在涨。如果是"文件读取"占大头,说明 Claude 在全文 Read 大文件。在CLAUDE.md里加一条规则:"读取文件前先用 Grep 定位行号,只读相关区间,单次 Read 不超过 100 行。"如果是"工具调用结果"占大头,多半是 Bash 命令输出了大量日志,让它把输出重定向到文件再读关键行。
5.5 换了 Key 之后旧会话行为异常
settings.json的改动对已经打开的会话不一定立即生效,重启 Claude Code 再试。另外确认没有同时在 shell 里export了旧的ANTHROPIC_AUTH_TOKEN,环境变量优先级高于配置文件,会把你新写的配置盖掉。用echo $ANTHROPIC_AUTH_TOKEN检查一下。
6. 把通道和进度都固定下来
长会话管理的核心不是"怎么压得更狠",而是"怎么让关键信息不依赖对话历史"。TodoList 写进CLAUDE.md、技术约束写进CLAUDE.md、压缩前固定同步一次,这三件事做完,/compact就从"失忆开关"变成了普通的空间回收。
通道这边同理,把 Key 和 API 地址固定在一份settings.json里,比每次开终端重新 export 稳得多。如果你还在多个 Key 之间切换,建议直接收敛到一处:
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
- API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
如果你打算长期用 Claude Code 跑编码和 Agent 类任务,按量计费之外可以看看 Coding Plan,额度包月对高频长会话更划算:
- Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
最后留一个我自己的习惯:每次开新会话,第一句话固定是"读 CLAUDE.md,告诉我任务清单和下一步"。这句话花不到 100 Token,但能让 Claude 在压缩、重启、换窗口之后都从同一个事实源出发,比任何压缩技巧都管用。