本文面向:使用 Claude Code 的开发者,想了解 ChatCrystal 如何导入和处理对话数据。 预计阅读时间:8 分钟
Claude Code 的对话存在哪
Claude Code 把每轮对话保存为 JSONL 文件,存放在:
erlang
~/.claude/projects/
├── c--Users-Project-MyApp/
│ ├── abc123.jsonl
│ ├── def456.jsonl
│ └── ...
├── c--Users-Project-AnotherApp/
│ └── ...
└── ...
每个子目录对应一个项目,目录名是项目路径的编码(/ 替换为 -)。每个 .jsonl 文件是一次对话,每行是一个 JSON 对象,包含一条消息。
导入时发生了什么
运行 crystal import 时,ChatCrystal 做了以下事情:
javascript
扫描 ~/.claude/projects/**/*.jsonl
→ 逐行读取 JSONL
→ 过滤噪音消息
→ 清理系统标签
→ 提取 user / assistant 消息
→ 按项目分组
→ 写入 SQLite 数据库
噪音过滤
Claude Code 的 JSONL 里混着大量非对话内容,ChatCrystal 会自动过滤:
| 过滤的消息类型 | 说明 |
|---|---|
file-history-snapshot |
文件历史快照 |
progress / agent_progress |
进度信息 |
tool_use / tool_result |
工具调用流式片段 |
thinking |
思考过程流式片段 |
system |
系统消息(api_error、compact_boundary 等) |
| 流式 delta(无 uuid) | 实时流式传输的中间状态 |
只保留 user 和 assistant 类型的完整消息。
内容清理
Claude Code 的消息内容里有很多系统标签,ChatCrystal 会自动清除:
xml
<!-- 这些会被删除 -->
<system-reminder>...</system-reminder>
<command-name>/help</command-name>
<command-message>...</command-message>
<command-args>...</command-args>
<local-command-stdout>...</local-command-stdout>
<local-command-caveat>...</local-command-caveat>
清理后只保留实际的对话内容。
项目名提取
目录名 c--Users-Project-ChatCrystal 会被解析为 ChatCrystal。规则是找到 Project 或 projects 标记,取后面的部分。
自定义数据目录
如果你的 Claude Code 数据不在默认位置,可以通过环境变量指定:
bash
CLAUDE_PROJECTS_DIR=/path/to/your/claude/projects crystal import
或在 ChatCrystal 设置页面修改 Claude Projects Dir 配置。
文件监听:自动导入
ChatCrystal 启动后会自动监听 Claude Code 数据目录。当你和 Claude Code 产生新对话时,ChatCrystal 会自动检测并导入,不需要手动执行 crystal import。
监听逻辑:
- 使用 chokidar 监听
~/.claude/projects/**/*.jsonl - 新文件或文件变化时触发导入
- 有防抖机制(debounce),避免频繁触发
手动导入 vs 自动导入
| 方式 | 命令 | 适用场景 |
|---|---|---|
| 手动 | crystal import |
首次导入、批量导入历史数据 |
| 自动 | 文件监听(默认开启) | 日常使用,新对话自动同步 |
首次使用建议手动 crystal import 一次,把历史数据全部导入。之后文件监听会自动处理新增对话。
导入结果验证
bash
crystal status
输出示例:
yaml
ChatCrystal Status
Server : running
Database : connected
Conversations: 147
Notes : 89
Tags : 23
如果 Conversations 数量为 0,说明没有检测到对话文件。检查:
- Claude Code 是否有历史对话:
ls ~/.claude/projects/ - 目录下是否有
.jsonl文件 - 如果用了自定义目录,确认
CLAUDE_PROJECTS_DIR配置正确
常见问题
导入后看不到对话
确认导入时没有报错。运行 crystal import 查看输出:
css
Scanning claude-code: found 0 conversations
如果是 0,检查 ~/.claude/projects/ 目录是否存在以及是否有 .jsonl 文件。
对话内容不完整
Claude Code 的 JSONL 是流式写入的,如果对话中途异常退出(比如 kill 进程),最后几条消息可能不完整。ChatCrystal 会跳过格式异常的行,不影响其他消息的导入。
导入速度
纯文本解析非常快,100 个对话文件通常在 1-2 秒内完成。慢的部分是后续的 LLM 摘要生成,不是导入本身。