Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

长会话生存指南

你可能遇到过这种情况

你开了一个长会话,AI 帮你做了很多事。到第 50 轮对话的时候,你发现:

  • AI 开始问你之前已经回答过的问题
  • 它重新提了一个已经被否决的方案
  • 它的代码质量明显下降——少了错误处理、类型定义
  • 有时候它甚至开始“幻觉“——编造不存在的函数和文件

最极端的情况:AI 直接报错了——“上下文窗口超出限制”(context window exceeded),整个会话崩溃。

💡 这就是“上下文膨胀“问题:AI 的“工作记忆“有容量上限,装太多东西就会溢出。

问题的根源

AI 的上下文窗口是一个固定大小的“工作台“:

上下文窗口(例如 128K tokens)
┌──────────────────────────────────────┐
│ 系统提示(System Prompt)    ≈ 5K     │
│ 工具定义(Tools)            ≈ 8K     │
│ 记忆注入(Memory)           ≈ 2K     │
│ ─────────────────────────────        │
│ 对话历史(前 50 轮)         ≈ 80K    │ ← 膨胀的主要来源
│ 工具返回结果                 ≈ 30K    │ ← 工具返回的内容可能很大
│ ─────────────────────────────        │
│ 剩余可用空间                 ≈ 3K     │ ← 快满了!
└──────────────────────────────────────┘

问题在于:

  1. 对话历史只增不减:每轮对话都往上下文里加内容,从不删除
  2. 工具返回结果可能巨大read 一个 1000 行的文件可能就占 5K tokens
  3. 重复信息累积:AI 多次读取同一个文件,每次都占空间

两件工具:Smart Compact 和 Context Manager

你可能会问:这两个包都要装吗?答案是:推荐都装,它们解决不同层面的问题:

维度pi-smart-compactpi-context-manager
做什么压缩历史对话诊断 token 消耗 + 压缩工具返回
主动/被动全自动触发诊断需你叫 AI 跑,distill 自动
解决什么“历史对话太长”“工具返回太多” + “为什么这么慢”
能互相替代吗❌ 不能❌ 不能

💡 一句话总结:context-manager 帮你发现问题(token 都花哪了),smart-compact 帮你自动解决问题(压缩历史)。两个配合使用效果最佳。

pi-smart-compact — 智能压缩

Smart Compact 在上下文快满的时候自动“压缩“历史对话:

压缩前(80K tokens 的对话历史):
┌─────────────────────────────────┐
│ 用户:帮我看看 auth.ts          │
│ AI:我读取了 auth.ts...(500字) │
│ 用户:加个空值检查               │
│ AI:好的,我修改了...(300字)    │
│ 用户:测试一下                   │
│ AI:测试结果...(200字)         │
│ ... 重复 50 轮 ...               │
└─────────────────────────────────┘

压缩后(15K tokens 的摘要):
┌─────────────────────────────────┐
│ 摘要:                          │
│ - 在 auth.ts 中添加了空值检查    │
│ - 修改了对应的测试文件           │
│ - 所有测试通过                   │
│ - 使用了 JWT 认证方案            │
│ ... 关键信息保留 ...              │
└─────────────────────────────────┘

两阶段压缩策略:

阶段方法说明
Phase 1提取关键信息(如决策、文件修改、结论)遍历对话,生成结构化意图摘要
Phase 2丢弃低价值信息(如重复的文件读取、中间调试输出)让 LLM 逐批判断工具结果去留

pi-context-manager — 诊断工具

pi-context-manager 提供了 payload_analyze 工具,帮你看清 token 到底花在哪了:

📊 Token 预算分析

System Prompt:    4,200 tokens ( 3.2%)
Tool Definitions: 8,100 tokens ( 6.2%)
Memory Injection: 2,300 tokens ( 1.8%)
Conversation:    52,400 tokens (40.0%)
Tool Results:    64,800 tokens (49.5%)  ← 大头在这!
──────────────────────────────────────
Total:          131,800 / 128,000      ← 超了!

Top 3 最贵的工具调用:
1. read(src/database/schema.ts)  — 8,200 tokens
2. code_graph_module_overview    — 6,400 tokens
3. grep("TODO|FIXME")           — 4,100 tokens

实际案例:诊断上下文崩溃

真实场景回顾

有一次,一个会话在上下文使用率只有 34.8% 的时候就崩溃了。看起来不应该——才用了三分之一啊?

用 pi-context-manager 的 budget 模式分析后发现:

问题根因:
工具返回结果中有 34.8% 是 error 输出
→ 大量重复的 "Command not found" 错误信息
→ 每次错误都消耗了 token 但没有有价值的信息
→ 累积导致上下文提前耗尽

解决方案:在 shepherd 规则中加入 after_bash 钩子,失败命令的错误输出自动截断,避免无意义的 token 消耗。

用 growth 模式看趋势

📈 上下文增长趋势

请求 #1:  15K  ████
请求 #5:  28K  ███████
请求 #10: 45K  ████████████
请求 #15: 72K  ████████████████████
请求 #20: 98K  ██████████████████████████  ← 接近上限
请求 #23: 💥 崩溃!

关键发现:第 10-15 轮之间增长最快,因为那个阶段做了大量的文件搜索。

优化:用 compact 模式的 code_graph_semantic_code_search(只返回签名和位置)替代 grep(返回完整匹配行),token 消耗减少 70%。

配置 Smart Compact

通过 settings.json 安装:

{
  "packages": ["pi-smart-compact"]
}

安装后默认为 手动模式enabled: false),只在用户执行 /smart-compact 时触发。

/smart-compact-config auto 可开启自动接管模式。

可选的高级配置

.pi/smart-compact.json 中:

{
  "enabled": true
}
  • enabled: true:自动触发(pi 触发 compact 时接管)
  • enabled: false:手动模式(默认,只响应 /smart-compact 命令)

手动触发:在对话中输入 /smart-compact。 配置查看:输入 /smart-compact-config

Payload Analyzer 的常用命令

命令用途何时用
budgetToken 预算分析(system/tools/history 构成)“token 都花哪了”
growth上下文增长趋势(token 随请求变化曲线)“为什么越来越慢”
expensive最贵的工具调用(Top N 排序)“哪个工具最吃 token”
overview逐消息详细分析(含 distill 事件)“精确诊断某个时间点”
messages按索引/范围/关键词定位消息“看看第 10 条消息说了什么”
chain跨 payload 追踪同一个工具调用“这个调用后来怎么样了”
chain-tcid跨 payload 追踪同一个 toolCallId“验证 distill 是否压缩了这条调用”
chain-tcid跨 payload 追踪同一个 toolCallId“验证 distill 行为”
diff对比两个 payload 的差异“这两次请求有什么不同”
stats聚合统计 distill/processor 命中率“压缩效率如何”
single分析单个 payload 文件“深入看一个录制文件”
list列出所有录制文件“有哪些可以分析的”

💡 诊断流程:先用 list 看有哪些录制文件 → budget 看整体分布 → expensive 找大户 → messages 精确定位。

Context Manager 的 Aging 和 Processor

除了 Distill,pi-context-manager 还提供了两个辅助机制:

Aging(老化淘汰)

自动淘汰长期未被引用的旧工具输出。通过 /aging-config 设置淘汰轮数。

特殊豁免:技能文件(SKILL.md)内容不会被 aging 淘汰,确保 AI 始终能看到当前加载的技能。

Tool Result Processor(后处理器)

对特定类型的工具输出做格式化精简(如 code-graph 的 AST 搜索结果、MCP JSON 输出)。通过 /processor-config 设置阈值。

/context TUI 面板

输入 /context 可以打开可视化面板,分类浏览上下文内容,手动标记不需要的内容进行删除。

最佳实践

✅ 保持长会话健康的习惯

  1. 用 compact 模式搜索code_graph_semantic_code_search(compact: true)grep 省 70% token
  2. 及时压缩:不要等到崩溃才处理,上下文接近上限时就应该触发压缩
  3. 避免重复读取:用记忆记住文件内容,不要反复 read 同一个文件
  4. 大文件分块读:用 offset/limit 只读需要的部分,而不是整个文件
  5. 合理配置 aging:设置 8-12 轮淘汰,自动清理过时内容
  6. 定期用 payload_analyze 体检:长会话中途跑一次 budget,提前发现问题

✅ 诊断的优先级

上下文出问题时:
  1. payload_analyze budget → 看总量分布
  2. payload_analyze expensive → 找最贵的调用
  3. payload_analyze growth → 看增长趋势
  4. 针对性优化(换工具、加过滤、调整策略)

❌ 常见误区

  • “上下文还有 50% 空间,不用担心” → 错,工具返回结果可能突然膨胀
  • “压缩会丢失重要信息” → Smart Compact 优先保留决策和结论
  • “重启会话就好了” → 治标不治本,下次还会遇到同样的问题

下一步

现在 AI 有了记忆、规划、规矩、复盘和压缩——它已经是一个相当能干的助手了。但它还是“被动“的——你问它才做。

能不能让 AI 主动工作?比如每天自动检查代码质量,或者自动跑一轮研究分析?

下一章,我们来看如何让 AI 自动化工作

English