# 会话 JSON 保存(F058) > 2026-09-17 DMS迁移后,本页仅为历史归档组件契约。API/CLI已停止本地JSON保存,旧文件不删除、不再分析;前端负责DMS逐轮问答保存,后台只读并分析。当前流程见 [DMS会话监视](session-analysis.md)。 API 和 CLI 从功能启用后记录新的会话输入及对应回答,每个 `thread_id` 一份 UTF-8 JSON。同一会话逐轮追加,重启后继续读取原文件并写入,不截断历史或回答;不自动回填旧 Redis 数据。F059已在同一文件接入静默30分钟后的总结和两阶段分析,见 [会话分析](session-analysis.md)。未实现后台页面或查询 HTTP 接口。 ## 配置与文件位置 在 `.env` 配置 `SESSION_DIR=session`,同名进程环境变量优先;未设置时默认 `session`,空值报错。目录不存在时自动创建。 - 相对路径固定相对于项目根目录,不受启动工作目录影响。`session` 在本机对应 `E:\CODE\business-assistant\session`。 - 相对路径支持 `data/session`、`data\session`、中文和空格;可用单引号或双引号包裹路径,反斜杠不作转义。 - Windows 支持 `E:\records\session`、`E:/records/session` 和 UNC 路径;Linux 支持 `/var/lib/business-assistant/session`。 - 绝对路径必须符合运行系统。Linux 上的 Windows 盘符路径、Windows 上的 Linux 根路径、`C:session` 等含糊路径会报错;跨系统部署时应配置部署机器实际挂载路径,不自动猜测盘符映射。 文件名为 `.json`。API支持的普通字母、数字、短横线及下划线ID直接用于文件名;Windows保留名、非安全字符、路径分隔符或实际大小写冲突时,使用 `~SHA256(thread_id).json` 避免覆盖或路径穿越。原始ID始终保留在文件内。旧哈希命名文件在下一次保存时自动读取并迁移到新名,保留历史,成功后移除旧文件;未续写的旧文件也可被观察器分析。默认 `session/` 已被 Git 忽略,自定义仓库内目录需相应配置忽略规则。会话文件包含完整业务内容,沿用部署目录的访问权限,不输出到终端日志。 ## JSON 字段 以下为精简合成示例,实际记录还包含请求耗时、输入类别等元数据: ```json { "schema_version": 1, "thread_id": "example-window", "turns": [ { "request_id": "example-request", "thread_id": "example-window", "question": "你好", "ai_answer": "您好,请问有什么可以帮您?", "received_at": "2026-09-17T16:00:00.000+08:00", "finished_at": "2026-09-17T16:00:01.000+08:00", "status": "completed", "error_code": null, "events": [ {"event": "answer", "data": {"text": "您好,请问有什么可以帮您?"}} ], "result": { "response": "您好,请问有什么可以帮您?", "recommendation": {}, "company_info": {}, "errors": [] } } ] } ``` `turns` 按首次保存顺序排列,`request_id` 用于同次请求的状态更新,不重复追加。`question` 保留当前输入,包括补问回复和重试命令;CLI 自动恢复产生 `input_kind=resume`、`question=null` 的记录,不编造用户问题。 `ai_answer` 为回答正文、总结和补问/错误提示的便于读取的合并文本,保留 Markdown;`events` 保留 answer、summary、interrupt、error 的原始有效内容,候选公司和输入帮助可从 interrupt 读取。`result` 保存完整最终结果(包括卡片、来源和诊断字段),与正文配合查看,不需要把结构化结果重复拼入正文。API 的 `result` 与现有 SSE 最终快照一致;CLI 保存对应字段。 状态包括 `running`、`completed`、`needs_input`、`failed`、`stopped`、`incomplete`。时间统一为上海时区。未产出回答时 `ai_answer` 为空、`result` 为 null;不能把中止或失败当作成功答复。进程突然退出可能留下 running 及部分已生成内容,不能保证尚未生成或未写入的内容可恢复。 ## 保存边界 先保存问题,再随有效回答事件更新,最终文件写入成功后 API 才发送 done。临时文件与目标文件位于同一目录,flush/fsync 后原子替换;失败保留上一个有效 JSON,已有文件损坏时明确失败,不默默清空。存储失败会使请求失败,原始异常和路径不进入用户回答。 沿用 API 的单进程问答部署约定,文件写入与观察器分析提交使用共用的进程内锁及OS文件锁,避免追加问答与分析互相覆盖。文件存储与 Redis 不是跨存储事务,Redis 最终写失败时两侧状态可能不一致,应结合请求错误判断。未接纳请求(例如 422、409、429)不属于已处理会话,不归档。 JSON 无自动过期、删除或容量轮转;Redis 过期及清除检查点不会删除 JSON。后台可直接按文件读取会话及顶层analysis结果和stored_at保存时间,继续提问时旧分析标为stale,再次静默后更新。当前文件验证在 Windows、合成数据和服务替身上完成,未实测 Linux 文件系统或网络共享盘,不代表外部前端验收。重启后端后生效。