核心真相
数据库记录的消息 ≠ Claude 实际加载的上下文
两者是完全独立的系统!
🔍 深度分析:代码到底做了什么?
🎯 关键发现
1️⃣ 代码从未读取数据库的历史消息
检查整个代码库,没有任何地方从 feishu_message_log 表读取历史消息并传递给 Claude。
数据库的 feishu_message_log 表只是日志记录,用于审计和统计,不参与上下文恢复。
2️⃣ 完全依赖 Claude CLI 的 --resume 机制
当我们传递 --resume=session-abc123 时,Claude CLI 会:
- 从 Anthropic 远程 API 获取该 session_id 的完整对话历史
- 或者从 本地缓存(位置未知)加载会话状态
- 自动拼接历史消息 + 当前消息,一起发送给 API
问题:如果 Claude CLI 的会话过期/清理,--resume 会静默失败,导致丢失上下文!
3️⃣ 数据库统计的 tokens 只是估算,不是真实值
我们统计的"累积字符数 ÷ 3"只是粗略估算,实际情况:
- Claude 实际加载的上下文包含系统提示词(500-1000 tokens)
- 包含工具调用的完整记录(每次 50-200 tokens)
- 包含错误重试的临时消息
- 可能包含内部推理过程(thinking blocks)
真实 tokens 可能是数据库估算的 2-3 倍!
📊 两个独立系统的对比
💾 数据库系统
- 表:feishu_message_log
- 存储:用户消息 + 机器人回复
- 用途:审计、统计、UI 展示
- 局限:只记录文本,不含系统提示
- 生命周期:永久存储(直到手动删除)
🤖 Claude API 会话
- 存储:Anthropic 远程服务器
- 内容:完整对话历史 + 工具调用
- 用途:上下文恢复、记忆管理
- 特性:包含系统提示、thinking blocks
- 生命周期:未知(可能有过期机制)
上下文恢复流程图
feishu_message_log
(只做日志)
只传 session_id
--resume=session-abc123
自己恢复历史
(远程存储)
历史 + 当前消息
⚠️ 潜在问题
❌ 可能出现的问题
- Claude API 会话过期(时间未知)
- --resume 失败但没有错误提示
- 用户以为有上下文,实际已丢失
- 数据库有记录,Claude 已忘记
- 无法验证上下文是否真的恢复
✅ 当前可以确定的
- Claude CLI 的 --resume 机制确实存在
- 数据库日志系统运行正常
- session_id 正确传递和存储
- 短期内(几小时)恢复有效
- YOLO 模式正常工作
💡 改进建议
方案 1:验证机制(推荐)
- 在每次 --resume 前,先测试会话是否有效(发送 "status" 命令)
- 如果会话失效,清空数据库的 claude_session_id,重新创建
- 给用户明确提示:"会话已过期,重新开始对话"
方案 2:手动上下文管理(复杂)
- 从数据库读取最近 N 轮对话(如最近 10 轮)
- 手动拼接成 messages 数组
- 不使用 --resume,直接传递完整历史
- 优点:完全掌控上下文,缺点:增加复杂度
方案 3:混合模式(平衡)
- 优先使用 --resume(快速、简单)
- 定期(如每 10 轮)验证上下文有效性
- 如果发现不一致,切换到手动上下文管理
- 在 UI 显示"上下文健康度"指标
最终结论
数据库统计的 tokens 不准确
实际上下文可能是估算值的 2-3 倍
--resume 机制是黑盒
完全依赖 Claude API 的远程存储
需要增加验证机制
确保用户感知到的上下文与实际一致