症状:会话文件已经生成,但你不知道重启后能否继续、备份是否完整、网络挂载是否会破坏数据库。 最快解法:单人单机或短期试用先验证 JSONL;需要结构化查询时再评估 SQLite;只要存储目录位于网络挂载盘,就先做锁、异常中断和重开测试,不能直接照搬 WAL 默认设置。

这篇文章适合 3 类人:长期保留编码或分析会话、希望逐会话检查和备份的独立开发者;需要在云端 Mac 管理大量会话并执行迁移的运维团队;正在制定会话审计、恢复与存储交付标准的平台负责人。

先按运行场景划分后端,而不是按文件扩展名判断可靠性

截至 2026 年 8 月 19 日,官方仓库明确将 DeepSeek Harness(dsh)定义为开发者预览,并提醒会发生兼容性破坏性变化。因此,JSONL 和 SQLite 都不能仅凭“看起来像普通文件”或“看起来像数据库”来判断是否适合长期运行;真正需要确认的是,写入完成后能否被重新打开,异常退出后是否能继续,会话备份能否在另一份环境中交付。(github.com)

<
决策维度JSONL 会话存储SQLite 会话存储
单人单机、短期试用**优先验证**,文件容易检查、复制和逐行定位可以使用,但初期会增加数据库文件、日志文件和恢复责任
持续追加写入重点检查最后一行、截断记录和续跑行为重点检查事务提交、异常退出和数据库完整性
大量会话筛选需要额外脚本或派生索引更适合按会话、事件或时间条件查询
人工备份复制文件后容易快速抽查需要确认数据库、-wal-shm 等伴随状态是否完整
本地磁盘通常更容易建立清晰的文件边界更适合在稳定本地文件系统上运行
网络挂载盘仍需验证追加、锁和重开行为**不要默认启用 WAL**,先验证文件系统兼容性
迁移与回退旧文件可只读保留,便于回退需要记录数据库版本、日志模式和一致性检查结果
这张表不是性能排名,而是责任分配表。你的选择应当由“谁负责恢复、谁需要查询、数据放在哪里”决定。

单机试用先完成 4 项检查,JSONL 通常更省事

如果你只有一个开发者、一个工作区,或者只是准备运行几天的 DeepSeek Harness 任务,JSONL 会话存储通常是更低复杂度的起点。它的优势不在于官方承诺了更高可靠性,而在于你可以直接看到会话事件,复制单个会话文件,也更容易把一份记录交给其他人复核。

但“文件已经生成”远远不等于“会话已经持久化”。你至少要完成下面 4 项检查:

  1. 确认真实会话根目录。
不要凭经验猜测默认路径。检查当前配置目录、启动参数和环境变量,确认会话根目录是否落在预期的本地磁盘,而不是临时目录、容器层或自动清理目录。官方仓库的开发者预览状态和配置变化,意味着不同版本之间不能假设路径永远不变。([github.com](https://github.com/deepseek-ai/deepseek-harness))
  1. 确认物理编码与尾部状态。
用文本工具检查文件是否能按行读取,确认非 ASCII 字符、换行、转义和最后一条未完成事件没有被静默截断。不要只看文件大小增长;应该检查最后一条记录是否能被解析,以及重新启动后 Harness 是否愿意继续使用该会话。
  1. 关闭进程后再次读取。
正常退出一次,再强制终止一次。两种退出路径都要重新打开同一会话,并确认最近一次用户输入、工具事件和助手响应的边界没有错位。
  1. 完成一次最小恢复任务。
复制一份会话根目录到临时目录,使用相同 Harness 版本指定该目录,恢复会话并执行一个不会修改生产文件的只读任务。如果只能“看见文件”却不能继续运行,这份备份就不能算交付合格。

因此,JSONL 更适合长期运行吗?答案是:可以,但前提是你把它当作可恢复的事件文件来验收,而不是把“持续追加”当作可靠性证明。 长期 Agent 运行时,异常退出可能留下半条记录、未完成事件或最后一条响应缺失;你需要用断进程、重启和续跑结果确认实现行为。

⚠️ 经验:不要把 .jsonl 文件直接当成唯一备份。普通文件备份解决的是“复制了什么”,会话恢复解决的是“复制后的内容能否被 Harness 正确重新消费”,两者必须分别验收。

长期 Agent 持续写入时,重点观察断进程与冷会话

长期运行的 Agent 通常有 3 个不同状态:正在写入的热会话、进程退出后的冷会话,以及异常中断后等待恢复的会话。每个状态的检查方式不同。

热会话要观察持续追加是否造成单条事件不完整。你可以在任务运行期间复制一份副本,但不要用正在写入的副本直接宣布备份成功;至少要等进程关闭,或使用 Harness 与底层后端明确支持的导出方式生成稳定快照。

冷会话要确认关闭进程后,单个会话仍能被识别、读取和重新打开。对 JSONL 而言,重点是尾部记录和事件顺序;对 SQLite 而言,重点是数据库是否处于一致状态,以及日志文件是否仍然被需要。

异常中断会话要用真实的 kill、系统重启或终端断开模拟,而不是只测试正常退出。恢复后检查 3 个信号:

  • 最近一次已经确认提交的用户输入仍然存在;
  • 工具调用与工具返回没有被重复执行;
  • 续跑时不会从半条事件或错误的上下文位置开始。
这也是为什么不能根据文件扩展名判断可靠性。JSONL 可能在应用层拥有完整事件边界,也可能只是在文件末尾追加未完成内容;SQLite 可能通过事务恢复一致状态,也可能因为错误的复制方式遗漏尚未合并的日志。判断依据必须是恢复证据。

团队查询需求上升后,再把 SQLite 与派生索引分开评估

当你开始按项目、时间、工具事件、错误类型或操作者筛选大量会话时,SQLite 的价值会明显提高。它可以把会话、事件和元数据组织成可查询结构;如果团队需要全文检索,还可以评估 SQLite 的 FTS5 扩展,而不是让每次检索都扫描所有 JSONL 文件。(sqlite.org)

不过,你必须区分 3 个层次:

  • 会话持久化后端: 决定原始事件如何保存;
  • 派生查询索引: 为搜索、筛选和审计建立的辅助结构;
  • 普通文件备份: 将会话目录、配置和交付说明复制到另一位置。
启用搜索索引,不等于必须把全部原始会话从 JSONL 改成 SQLite。更稳妥的架构是保留原始会话作为事实来源,再生成可删除、可重建的查询索引。这样即使索引损坏,你仍然可以从原始会话重新构建;如果后端迁移失败,也能回退到旧数据。

按团队场景给出一个编辑部评分,满分 5 分:

  • JSONL:人工检查 5 分,逐会话备份 5 分,大量条件查询 2 分,迁移可读性 4 分。
  • SQLite:人工直接检查 2 分,结构化查询 5 分,本地持续写入 4 分,网络挂载适配 1 分。
这是决策评分,不是官方性能测试。尤其不能把 SQLite 的查询便利误认为跨主机可靠性。

网络挂载盘必须先验证 WAL、锁和共享文件

SQLite WAL 是否适合部署在网络挂载盘上,不能简单回答“能”或“不能”。SQLite 官方文档明确说明,WAL 需要进程共享一部分内存,因此所有使用同一数据库的进程必须位于同一台主机;WAL 不适用于网络文件系统。WAL 还会产生额外的 -wal-shm 文件,备份时必须考虑它们与主数据库之间的关系。(sqlite.org)

这会带来 3 个经常被忽略的风险:

  1. 锁语义不一致。
网络文件系统可能对文件锁、缓存刷新和主机断开后的状态处理不同。即使首次写入成功,也不能说明并发读写、异常重连和锁释放都符合 SQLite 的假设。
  1. 共享内存文件不可用。
WAL 使用的共享内存索引不是普通的“再复制一个文件”这么简单。SQLite 官方文档指出,WAL 索引依赖同机进程共享;跨主机访问时,默认假设不成立。([sqlite.org](https://www.sqlite.org/wal.html))
  1. 备份快照可能不完整。
如果你只复制主数据库文件,却遗漏仍在使用的 -wal 文件,恢复出来的数据可能落后于最后一次提交。更稳妥的做法是停止写入后执行受控备份,或者使用 SQLite 的备份 API 生成一致性副本。([sqlite.org](https://www.sqlite.org/backup.html))

在本地磁盘上评估 SQLite 时,按下面顺序做验收:

  1. 建立一个代表性会话,持续写入用户事件、工具事件和助手事件。
  2. 在写入期间执行查询,观察读取是否阻塞或返回 SQLITE_BUSY
  3. 强制终止进程,重新启动并打开同一数据库。
  4. 检查数据库完整性、会话数量、最后提交事件和索引状态。
  5. 关闭所有连接后分别复制数据库文件与完整会话目录。
  6. 在另一目录恢复,重新执行查询和续跑任务。
  7. 在网络挂载盘重复上述测试;只要锁、异常退出或重开有一次不稳定,就把 SQLite 数据库留在本地磁盘,网络盘只承担停止写入后的备份交付。
SQLite 官方还说明,WAL 的自动检查点默认会在 WAL 达到 **1000 页**左右时触发,检查点本身会增加同步和写回操作;这不是 DeepSeek Harness 的性能承诺,而是 SQLite 的底层行为,实际效果仍取决于磁盘、文件系统和应用写入模式。([sqlite.org](https://www.sqlite.org/wal.html))

迁移时采用“双轨保留”,不要承诺跨版本直接复用

DeepSeek Harness 仍在开发者预览阶段,官方仓库明确提示会有兼容性破坏性变化。迁移前必须记录 Harness 版本、提交或发布标识、会话根目录、后端配置、日志模式、磁盘类型和最后一次恢复结果。(github.com)

建议采用以下回退流程:

  1. 旧后端只读保留。
迁移前停止写入,复制旧会话目录或生成一致性备份,并设置只读权限,避免新旧进程同时修改同一份数据。
  1. 建立代表性样本。
不要只迁移一条空会话。至少选取包含普通对话、工具调用、异常退出和较长上下文的样本,确保迁移覆盖真正的事件形态。
  1. 小批量导入新后端。
先导入少量会话,验证列表、打开、查询、续跑和导出;通过后再扩大范围。迁移工具报告“成功”不能替代实际重开测试。
  1. 对照关键事件。
比较会话标识、事件数量、最后提交事件、工具调用顺序和附件或引用路径。不要只比较文件数量或数据库行数。
  1. 设置失败回退条件。
如果出现会话无法打开、工具事件重复、最后响应缺失、索引与原始数据不一致,立即停止扩大迁移范围,回到旧后端只读副本。
  1. 记录版本边界。
新版本通过的恢复测试,只能说明该版本和该环境下的结果,不能承诺未来版本或另一种磁盘类型能够直接复用。

你可以把这套记录并入 DeepSeek Harness 会话数据备份与恢复 的交付清单;如果任务运行在远程环境,还应同时记录云端 Mac 的磁盘位置、访问权限和交付方式,而不是只交付一个数据库文件。

云端 Mac 上按“本地写入、停止后备份”设计

在云端 Mac 上,后端选择通常不是“JSONL 还是 SQLite”这一项孤立决定,而是由磁盘类型和运维路径共同决定。

如果会话目录位于云端 Mac 的本地磁盘,单人试用或会话数量有限时,优先验证 JSONL。你可以按会话复制、人工抽查、压缩归档,并在任务结束后把归档交付到备份位置。

如果团队必须快速筛选大量事件,可以让 SQLite 负责本地查询,但不要把数据库文件直接放到共享目录上让多个远程进程同时访问。更稳妥的模式是:数据库在云端 Mac 本地磁盘运行,任务停止或进入可控快照状态后,再把备份交付到网络存储。

如果你还在选择远程 Mac 节点,可以先从 MACGPU 的云端 Mac 方案 了解环境交付方式,再根据会话恢复要求确认实际磁盘路径和权限。不要因为节点是 Mac 就默认文件系统、挂载方式和本地开发机完全一致。

用一轮验收任务决定最终后端

你可以把最终选择压缩成一轮固定测试:

  1. 记录 Harness 版本、后端配置和会话根目录。
  2. 创建一个包含普通消息、工具调用和较长输出的代表任务。
  3. 正常关闭并验证会话可重新打开。
  4. 强制终止并验证重启后能续跑。
  5. 复制停止后的完整会话目录,执行最小恢复任务。
  6. 对 SQLite 检查主数据库、-wal-shm 和索引;对 JSONL 检查尾部记录、编码和事件顺序。
  7. 在目标交付磁盘上重复一次恢复,而不是只在原机上检查。
  8. 如果网络挂载测试失败,采用“本地运行、停止后备份”;如果查询需求不高,回退到 JSONL;如果查询是硬需求,再保留 SQLite 并建立可重建索引。
最终判断可以直接套用:
  • 单人、单机、短期试用、重视逐会话备份:选 JSONL,先完成恢复验收。
  • 长期 Agent、可靠本地磁盘、需要大量结构化查询:评估 SQLite,同时保留独立备份。
  • 网络挂载盘、跨主机共享写入、无法控制锁语义:不要直接采用 WAL SQLite。
  • 正在迁移或版本快速变化:旧后端只读保留,新后端小批量验证,失败立即回退。
如果你当前使用的是随意复制的文件夹、未验证的共享目录或只依赖单一云端快照,真实缺点通常是:异常退出后不知道哪条记录已经提交、数据库日志文件可能没有一起交付、网络挂载的锁行为没有经过验证,出了问题还要由团队自己承担版本和恢复责任。对需要临时算力、远程测试环境或短期迁移验证的任务,租用 MACGPU 的云端 Mac 可以把运行环境、磁盘位置和交付边界先固定下来,再按本文的验收表决定使用 JSONL 或 SQLite;但如果你要承载长期稳定重负载、依赖物理接口,或必须完全掌控底层存储策略,自购 Mac 仍然更适合。