08 · 下一阶段执行路线
排序原则:先止血 → 再修数据正确性 → 再补部署韧性 → 最后做任务书阶段 5–9。
每个阶段都标注:前置条件 / 要动的文件 / 验收 / 回滚 / 是否需要用户批准。
⚠️ 本文件只是路线,不代表已经开工。
阶段 0 · 只读调查(无需批准,随时可做)
| # |
事项 |
方法 |
产出 |
| 0.1 |
确认三端是否仍跑同一份代码 |
CF API 拉 zhai/zhai-v2 bundle,与本地 cat-chat-all-in-one.js 比对;国内版 GET / 看 data.notice |
一致性结论 |
| 0.2 |
等 KV list 配额恢复(北京时间 08:00 后),枚举 v1/v2 精确键数 |
REST keys 分页(注意:每次调用都消耗配额,分批) |
数据量基线 |
| 0.3 |
核对 v1 的 307 条与国内版 320 条的差集 |
按 mid 对比(导出两份 id 列表) |
哪些只在一边 |
| 0.4 |
查清 v1 数据是何时/哪个入口同步进去的 |
msg 的 created_at 分布 + source_id + meta_lastTs 历史 |
数据来源结论 |
| 0.5 |
复核 279 条软删的内容与时间分布 |
只读 SQL / KV 抽样 |
清理清单 |
不做:不写库、不删键、不部署。
阶段 A · 止血(1 次部署,约 30 分钟)
| 项 |
内容 |
| 目标 |
修掉「一改就全坏」的低级陷阱,不改业务语义 |
| 前置 |
无 |
| 文件 |
worker.js(json() 增加 request/env 参数并合并 corsHeaders;validateApiUrl 保留 query;env.API_KEY \|\| env.DEEPSEEK_API_KEY;serveFrontend 桩)、index.html(无需改) |
| 具体 |
① P1-5 CORS ② P1-1 Key 兼容 ③ P2-5 query ④ P2-13 兜底函数 |
| 验收 |
跨源 OPTIONS + POST 都有 ACAO;?a=1 的 API URL 不被截断;先 node build.js 再部署;/health 200;本地 10 个测试全过 |
| 回滚 |
wrangler rollback <上一版本>;v1 a3ef2a33、v2 8c6fe98a |
| 批准 |
需要(涉及部署) |
阶段 B · 数据正确性(本阶段最关键,必须先做决策)
B0 先决策(用户拍板,二选一)
| 选项 |
含义 |
代价 |
| B-方案 1(推荐) |
检索数据源统一到 msg:,mem: 停写、只读兼容 |
改动中等;需一次性对齐存量;删除天然彻底 |
| B-方案 2(保守) |
保留双写,硬删时扫 mem: 找 mid 删除 |
改动小;每次删除多 1 次 list;库越大越慢 |
B1 修 P0-2(彻底删除)
- 前置:B0 决策;KV 配额充足(方案 2 需要批量写)
- 文件:
worker.js(saveMemory 增加 mid / retrieveMemory 改数据源 / hardDeleteRefs 增补)
- 验收:删一条 →
mem 与 msg 都查不到该内容 → 再聊相关话题不出现;/export/full 的 memories 不含;测试补 3 条断言
- 回滚:保留旧
mem: 不删(只改读路径),可一键切回
- 批准:需要
B2 修 P0-1(前后端寻址统一)
- 前置:确认「多后端」是否真实需求
- 文件:
index.html(apiBase() + 8 处调用点)、worker.js(无需)
- 验收:把设置里的地址改成另一个域 → Network 面板可见所有 API 都跟着走;或按方案 B 直接禁用输入
- 回滚:纯前端改动,回滚页面即可
- 批准:需要(会影响用户习惯)
B3 修 P1-2(检索 1000 键截断)
- 前置:B0 决策(若改读
msg:,本条随之解决一半)
- 文件:
worker.js(listMemoryKeys / retrieveMemory)
- 方案:按月分片
mem:<p>:<YYYYMM>: 或维护 mem_recent 索引键
- 验收:造 1200 条记忆,确认最新 300 条可被检索
- 回滚:双读(新分片 + 旧前缀)一个版本,观察后再切
- 批准:需要
阶段 C · 部署韧性(国内版优先)
| # |
事项 |
前置 |
文件 |
验收 |
| C1 |
P1-3 数据落持久盘 + 快照异地 |
平台是否有持久卷 |
server.js、start-domestic.sh |
重启容器后 kv.count() 不变;快照可下载 |
| C2 |
P1-3 同源基准兜底 |
无 |
server.js(PUBLIC_ORIGIN 读取顺序 + 403 中文页) |
换域名访问不再「发送失败」,而是明确提示 |
| C3 |
P1-4 备份口径统一 |
无 |
index.html(去掉 isWebMode 限制)、worker.js(无需) |
v1/v2 也能导出/导入 schema:2 |
| C4 |
P1-7 分批同步 |
无 |
index.html(cloudSyncToServer 分批 + lastSyncTs) |
1000 条同步不一次打满写配额 |
| C5 |
P1-6 图片策略(先决策) |
用户决定:接受 / R2 / 缩略图 |
index.html 文案;R2 需 worker.js + 绑定 |
用户明确知道「图不同步」或图可恢复 |
阶段 D · 访问控制(P0-3)
| 选项 |
工作量 |
说明 |
| D-A Cloudflare Access(推荐) |
小 |
在 CF 面板给 zhai/zhai-v2 加策略,只允许指定邮箱;国内版视平台能力 |
| D-B 自建口令登录 |
中 |
POST /login → 签名 HttpOnly cookie;页面不再注入 token;三端同款 |
| D-C 最低成本 |
小 |
页面不再明文注入 token,改「首次输入访问码」存 localStorage;GET / 也只返回壳页 |
- 验收:未登录访问 API 一律 401/302;登录后功能不变
- 回滚:Access 可在面板一键关闭;自建登录保留旧 token 分支一个版本
- 批准:需要(会影响所有设备)
阶段 E · 历史数据清理(279 条软删)
| 项 |
内容 |
| 前置 |
阶段 A 完成;配额充足;先导出全量备份 |
| 步骤 |
① 导出 /export/full 存档 ② 生成待删清单(mid)③ 每批 ≤200 条:POST /messages/delete {mode:'hard', force:true} ④ 每批后抽查墓碑与残留 ⑤ 记录每批结果 |
| 配额 |
每条硬删 ≈ 2 写 + 1–2 list;200 条约 400–600 写 → 一天最多 1 批 |
| 验收 |
tomb: 数量 = 279;msg: 剩 41 条;/export/full 的 counts 与预期一致 |
| 回滚 |
备份可 /import/full 恢复(但墓碑会阻止恢复被删项——这正是设计目的;如需恢复须先删对应墓碑) |
| 批准 |
需要(不可逆) |
阶段 F · 任务书阶段 5–9
| 阶段 |
先决条件 |
主要产出 |
验收要点 |
| 5 人设版本 |
决定人设存储结构(KV persona:<p>:<ver> + 当前指针) |
版本列表/对比/回滚;聊天只用「当前版本」 |
核心人设不被单次聊天覆盖;改动留版本 |
| 6 成长分析 |
阶段 5 完成;记忆可更新(v4 能力) |
定时任务(CF Cron 或国内 cron)+ 候选建议 + 审核队列 |
不在每轮聊天跑;失败可重试;建议带证据/反例;未审核不生效 |
| 7 后台管理 |
阶段 D 完成(强认证) |
档案/记忆/人设/任务/备份的移动端管理页 |
有鉴权、有操作日志、关键操作二次确认 |
| 8 沈屿迁移 |
阶段 5 + 7;旧数据已整理 |
导入真实历史/人设/记忆;角色隔离 |
数量与内容核验;记忆可追溯来源;备份恢复实测 |
| 9 测试清理 |
阶段 8 验收通过 |
删测试 profile 数据与测试专用资源 |
正式数据完整;测试数据不参与检索;通用代码保留 |
给新 AI 的开工建议(按顺序)
- 先读:
README_交接索引.md → 01 → 04 → 07(先知道哪里有坑)→ 03 → 05。
- 先只读核对:阶段 0 的 5 项,不要一上来改代码。
- 第一批改代码只做阶段 A(4 个小修),一次部署,观察 1 天。
- 等用户对 B0 拍板再做 P0-2/P0-1/P1-2;这三项会动检索与前端寻址,必须一起设计。
- 不要在没得到批准时:部署、清理数据、改密钥、动 v1 历史库。
- 任何批量操作都按「≤200 条/批、跨天、先备份」执行。
明确不建议现在做的事
| 事 |
原因 |
| 大规模重构 / 换框架 |
违反用户第一约束;现有三端在跑 |
直接把 mem: 全删 |
会丢历史记忆;先改读路径,再决定是否清 |
| 立刻上向量检索 / Mem0 |
成本与复杂度高;先把删除与检索正确性修好 |
| 把 v1 数据整体覆盖到 v2 |
用户没要求;v2 是「全新环境」的定位 |
| 用 R2 存图 |
涉及付费,未获授权 |