每个编程智能体把会话历史存在哪里
三十四个智能体,一张表
每一个编程智能体都会把你说过的话、它做过的事写到本机的文件里。格式各不相同,位置各不相同,而且没有任何一处把它们写在一起——所以这里就是那一处。表格来自 deja 的解析器所依据的同一份格式登记表。
各自写在哪里
| 智能体 | 会话记录的位置 | 格式 |
|---|---|---|
| aider | ~/.aider.chat.history.md | 一份 Markdown 日志 |
| Amp | ~/.local/share/amp/threads/*.json | 一个会话一个 JSON 文件 |
| Antigravity | ~/.gemini/antigravity*/brain/*/.system_generated/logs/transcript.jsonl | JSONL,一行一条记录 |
| Cherry Studio | <app data>/CherryStudio/Data/Agents/.claude/projects/*/*.jsonl | JSONL,用的是 Claude Code 的格式 |
| Claude Code | ${CLAUDE_CONFIG_DIR:-~/.claude}/projects/**/*.jsonl | JSONL,一行一条记录 |
| Cline | ${CLINE_SESSION_DATA_DIR:-${CLINE_DATA_DIR:-${CLINE_DIR:-~/.cline}/data}/sessions}/*/*.messages.json | JSON 文件 |
| Codex CLI | ${CODEX_HOME:-~/.codex}/sessions/**/rollout-*.jsonl | JSONL rollout,外加一个 history 文件 |
| Command Code | ~/.commandcode/projects/*/*.jsonl | JSONL,一行一条记录 |
| Continue | ${CONTINUE_GLOBAL_DIR:-~/.continue}/sessions/*.json | JSON 文件,每次整份重写 |
| Copilot CLI | ${DEJA_COPILOT_ROOT:-~/.copilot/session-state}/*/events.jsonl | JSONL,一行一条记录 |
| Crush | <project>/.crush/crush.db | SQLite 数据库,每个项目一个 |
| Cursor | ~/Library/Application Support/Cursor/User/{globalStorage,workspaceStorage/*}/state.vscdb | SQLite 键值库,或 JSONL |
| DeepSeek Harness | ${DSH_HOME:-~/.dsh}/sessions/*/session-*/session.jsonl.zstd | JSONL,一行一条记录 |
| gajae-code | ${GJC_CODING_AGENT_DIR:-~/.gjc/agent}/sessions/*/*.jsonl | JSONL,一行一条记录 |
| Gemini CLI | ${GEMINI_CLI_HOME:-~}/.gemini/tmp/*/chats/**/*.{json,jsonl} | JSON 或 JSONL |
| Goose | ${GOOSE_PATH_ROOT}/data/sessions/sessions.db | JSONL,另有一个 SQLite 索引 |
| Grok Build | ${GROK_HOME:-~/.grok}/sessions/**/updates.jsonl | JSONL 事件流,外加 JSON 元数据 |
| Hermes | ~/.hermes/profiles/*/state.db | SQLite 数据库 |
| Kilo Code | <vscode-globalStorage>/kilocode.kilo-code/tasks/*/api_conversation_history.json | JSON 文件,外加命令行版自己的 SQLite 库 |
| Kimchi Coding | ${XDG_CONFIG_HOME:-~/.config}/kimchi/harness/sessions/--<encoded-cwd>--/*.jsonl | JSONL,一行一条记录 |
| Kimi Code | ${KIMI_CODE_HOME:-~/.kimi-code}/sessions/*/*/agents/main/wire.jsonl | JSONL,一行一条记录 |
| Kiro | ~/.kiro/sessions/cli/*.jsonl and ~/.kiro/sessions/*/sess_*/messages.jsonl | JSONL,一行一条记录 |
| omp (Oh My Pi) | ~/.omp/profiles/*/agent/sessions/**/*.jsonl | JSONL,一行一条记录 |
| OpenClaw | ${OPENCLAW_STATE_DIR:-~/.openclaw}/agents/*/sessions/*.jsonl | JSONL,一行一条记录 |
| opencode | ~/.local/share/opencode/opencode.db | SQLite 数据库 |
| pi | ${DEJA_PI_ROOT:-~/.pi/agent/sessions}/**/*.jsonl | JSONL,一行一条记录 |
| prime-agent (PrimeIntellect) | ${DEJA_PRIME_ROOT:-~/.prime/agent/sessions}/**/*.jsonl | JSONL,一行一条记录 |
| Qwen Code | ${DEJA_QWEN_ROOT:-~/.qwen}/projects/*/chats/*.jsonl | JSONL,一行一条记录 |
| Roo Code | | JSON 文件 |
| Senpi | ${SENPI_CODING_AGENT_DIR:-~/.senpi/agent}/sessions/*/*.jsonl | JSONL,一行一条记录 |
| VS Code Copilot Chat | <vscode-User>/workspaceStorage/*/chatSessions/*.{json,jsonl} | JSON 或 JSONL |
| ZCode | ~/.zcode/projects/*/*.jsonl | JSONL,外加命令行版自己的 SQLite 库 |
| Zed | ~/Library/Application Support/Zed/threads/threads.db | SQLite 数据库 |
每一行都链到会话格式登记表里对应的页面:记录的字段结构、角色怎么映射、有哪些环境变量可以改路径,以及 deja 没能核实的部分。每条记录都带着最后一次对着真实存储核对的日期。
自己读它们
多数是 JSONL —— 一行一个 JSON 对象,会话进行时不断追加:
ls -t ~/.claude/projects/*/*.jsonl | head -1 | xargs tail -5 | jq -r '.message.content'
有几个是数据库而不是文件。opencode 用 opencode.db,Hermes 每个 profile 一个 state.db,Zed 把所有会话放进一个 SQLite 库、并把每条正文压成 zstd 帧——所以光用 sqlite3 看到的是一堆二进制,要读正文还需要 zstd。Cursor 最别扭:旧版本把内容塞进 state.vscdb 的键值里,命令行版写的才是 JSONL。
两点实用提醒。路径是会变的:Claude Code 认 CLAUDE_CONFIG_DIR,Codex 认 CODEX_HOME,Kimi 认 KIMI_CODE_HOME,Goose 和 opencode 跟随 XDG_DATA_HOME。另外,这些文件里有什么,取决于当时会话里有什么——包括粘贴进去或打印出来的密钥,所以请把它们当日志对待。
然后能拿它们做什么
读一个文件回答的是「那次会话我做了什么」。真正常问的是另一个问题——「是哪一次会话」——而这需要一份跨越全部存储的索引。deja 建的就是这个:在本机为上面每一个存储建一份索引,命令行能查,智能体也能通过 MCP 自己查。
curl -fsSL https://raw.githubusercontent.com/vshulcz/deja-vu/main/install.sh | sh deja "connection pool exhausted"
没有需要提前打开的记录开关:文件本来就在那里,包括你装任何东西之前的那几个月。索引和检索都在本地,凭据在建索引时就被脱敏。