最近给 Codex 配了一个组合:Context7、Serena,再配合合理拆 Session。
这套组合很容易被描述成“省 token 三件套”。但我觉得这个说法不够准确,甚至有一点误导:MCP 不是装得越多越省,Session 也不是拆得越细越省。真正起作用的,是把正确的信息送到正确的阶段,尽量不让无关的文件、文档、日志和历史决策进入当前上下文。
这篇文章用一次真实的前端功能开发流程,把三个工具串起来,也把 token 节省的边界讲清楚。
一句话总结
Context7 负责查对外部文档,Serena 负责缩小代码阅读范围,Session 负责切断已经失去价值的历史上下文。
它们共同优化的不是“工具数量”,而是 context selection:这一轮到底应该让 Codex 看什么。
先看一次真实工作流
假设现在要给一个 React + Midway 的企业工作台增加技能录制状态展示,同时补上接口错误处理。
我不会一上来就让 Codex“直接改好”。更稳的做法是把任务分成三个阶段。
Session 1:只探索,不改代码
第一轮只确定入口、调用链和最小修改范围:
1 | 先不要修改代码。 |
这一轮的目标不是产出代码,而是建立一个足够小的工作集。
Serena 用来找页面、函数、类型和引用关系;Context7 只在需要确认外部框架行为时介入。两者都不应该被用来“把整个项目读一遍”。
Session 2:只实现已经确定的范围
探索完成后,我会把结论压缩成一份 handoff,再开始实现:
1 | 背景: |
这里不需要把上一轮的所有探索日志重新粘进来。保留决策、文件、约束和验收标准就够了。
Session 3:只验证本次改动
实现完成后,如果出现大量构建或测试输出,可以把验证单独放到新的 Session:
1 | 请只验证本次改动: |
这三轮不是固定模板。小改动可以一轮完成;当目标、证据和日志明显发生变化时,再切 Session。
Context7:把“查文档”变成定向查询
Context7 是文档检索 MCP。它解决的问题是:
这个 API 在当前版本到底怎么用?
它适合查:
| 问题 | 适合查的内容 |
|---|---|
| React 行为 | 当前版本的 API、生命周期和边界条件 |
| Umi 配置 | 当前版本的路由、插件和构建配置 |
| Midway 接口 | Controller、Service 和参数校验方式 |
| 第三方依赖 | 当前版本的参数、示例和 breaking change |
它替代的是凭模型记忆猜 API,或者手动把一整篇 README 粘进聊天。
正确的问法是:
1 | 查当前 React 版本中 useEffect cleanup 的官方行为。 |
不太好的问法是:
1 | 把 React 文档都找出来。 |
第二种问法会让工具返回大量当前任务用不到的内容。Context7 本身也消耗 token,所以它的价值取决于查询是否足够窄。
Serena:从“读文件”切换到“读代码结构”
Serena 是代码语义检索和编辑工具。它更适合回答:
这个项目里,真正应该看哪些代码?
它可以帮助定位:
- 函数、类、接口和类型
- 符号引用
- 调用关系
- 实现位置和使用方
- 一个改动可能影响的局部范围
可以用下面这张表理解三个常用工具的分工:
| 工具 | 最擅长的问题 | 不应该承担的工作 |
|---|---|---|
rg | 某个字符串、错误文案、配置项在哪里 | 理解复杂调用关系 |
| Serena | 某个符号怎么定义、被谁引用 | 查外部框架文档 |
| Context7 | 某个依赖的当前版本怎么用 | 理解你的业务代码 |
Serena 的 token 收益,主要来自减少无关文件读取。它不是把代码“压缩”了,而是把阅读入口从目录和全文,缩小到符号和调用链。
当然,Serena 也不是 rg 的替代品。精确字符串搜索仍然是 rg 的强项;语义定位和结构理解才是 Serena 的优势。
Session:真正的上下文边界
一个 Session 里积累的不只是聊天内容,还包括:
- 之前的用户要求
- Codex 的分析过程
- 工具调用结果
- 读过的文件
- 测试日志和构建日志
- 已经被推翻的旧结论
所以 Session 变长以后,常见的问题不是模型“突然变笨”,而是有效信息被噪音埋住了。
这通常表现为:
- 反复重新解释已经确定的背景。
- 继续参考已经过时的探索结论。
- 从旧日志里找错误,而不是看最新结果。
- 改动范围逐渐扩大。
新 Session 的价值,就是把上下文重置成一个更干净的工作面。代码和 Git 工作区不会因为换 Session 消失,但对话里的决策不会自动继承,所以需要一份短 handoff。
token 到底省在哪里
可以把每一轮输入粗略看成:
1 | 本轮输入 |
这套组合主要从四个地方节省 token。
少读文件
Serena 把“扫描整个目录”缩小成“定位相关符号和引用方”。这是最直接的节省。
少重复背景
稳定的项目规则放进 AGENTS.md,就不需要每个任务都重复说明包管理器、构建命令、目录边界和验证要求。
但 AGENTS.md 也不能无限膨胀。它可能在每次相关任务里进入上下文,和当前项目无关的长篇背景会变成固定开销。
少复制历史
新 Session 不会携带上一轮的全部探索过程。用几行 handoff 传递结论,通常比复制几十屏命令输出更划算。
少返回日志
验证时不要让 Codex 每次都接收完整日志,可以明确要求:
1 | 只保留首个错误、错误文件和行号,以及与本次改动相关的 warning。 |
构建产物、依赖安装日志和重复堆栈,往往只增加上下文负担,不增加判断价值。
MCP 越多,token 越省吗?
不是。
每个 MCP 都可能增加:
- 工具定义
- 工具调用
- 工具返回结果
- 额外的错误和重试信息
所以应该按职责选择,而不是把所有工具都打开:
1 | 查外部文档 → Context7 |
如果一个任务只需要改一个 CSS 属性,同时打开多个文档和代码 MCP,成本可能比收益更高。
Session 应该什么时候拆
合理拆 Session 是手动做的。判断标准不是“聊了多少轮”,而是当前上下文是否还服务同一个目标。
保持在同一个 Session
- 目标没有变化。
- 修改的是同一组文件。
- 还没有积累大量日志。
- Codex 仍然能清楚复述当前约束和决策。
新开一个 Session
- 从调查切换到实现。
- 从实现切换到大量测试和排障。
- 开始处理另一个独立问题。
- 当前对话不断重复背景。
- 旧的探索过程已经不再有参考价值。
对一个中等规模功能,我通常会按下面的方式拆:
1 | Session A:探索 / 定位 / 方案 |
但不要为了“省 token”把一个小任务拆成很多 Session。每次新建 Session 都有重新传递背景和重新建立上下文的成本。
要不要用 / 我的判断框架
这套组合值得用,但应该把它当成上下文管理方案,而不是工具收藏。
值得上
- 中大型代码库,文件和调用关系比较复杂。
- 经常需要查 React、Umi、Midway 等版本敏感的文档。
- 任务经常经历探索、实现、验证多个阶段。
- 长 Session 里经常出现重复解释和日志污染。
可以先简单一点
- 小型仓库。
- 单文件修改。
- 不涉及外部依赖行为。
- 一次对话就能完成并验证的任务。
最应该记住的一句话
省 token 的核心不是“少让 Codex 工作”,而是让它少看无关的东西。
Context7 负责文档的准确性,Serena 负责代码阅读的精度,Session 负责上下文的边界。三者放进同一条工作流里,才会把 token 花在真正影响结果的地方。









