交接档案

04 · 技术架构与当前代码基线

基线时间:2026-10-27 00:45 | 只读核实,未改任何代码 金额/配额口径:Cloudflare Workers 免费版 KV = 每天 1000 次 list、1000 次写、10 万次读(账户级,北京时间 08:00 重置)


1. 仓库与工作区

项 值 证据
本地目录 /workspace/chat 【实测】
远程 github.com/beibbloveme-crypto/yuai git remote -v【代码】
分支 main(当前)、fix/p0-memory-consistency(历史分支) git branch -a【实测】
HEAD 5666a72(2026-10-25 20:36)fix(kv): 修复每日 list 配额烧穿导致聊天 500 git log【实测】
工作区 干净(无已修改文件);未跟踪:handoff-public.md、小手机-完整交付文档.md、2 张 PNG git status【实测】
提交总数 60(10-05 起) git rev-list --count HEAD【实测】
远端同步 本地 main 已包含 10-25 的提交;远端实时状态未验证(沙箱访问 GitHub 受限) 【未验证】

2. 文件与职责

文件 行数 / 大小 角色 纪律
index.html 12,509 行 / 230,966 B 前端唯一真源 改完必须 node build.js
worker.js 2,801 行 / 152,446 B 后端唯一真源 同上;serveFrontend 由构建期注入,源码里未定义
build.js 58 行 构建脚本 worker.js + base64(index.html) + serveFrontend() → 产物
cat-chat-all-in-one.js 2,822 行 / 460,954 B 部署产物 禁止手工编辑
wrangler.toml — v2 配置(zhai-v2 + KV 0a4c…) 含真实账号/KV ID,勿外传
wrangler.v1.toml — v1 配置(zhai + KV ec1a…) 同上
deploy-web/server.js 484 行 国内版平台垫片 + 快照管理 只做适配,不做业务
deploy-web/kv-sqlite.js 155 行 env.CHAT 的 SQLite 实现 对齐 KV 六方法
deploy-web/worker.mjs 2,822 行 / 460,954 B 后端部署副本 与 bundle 逐字节相同(手工同步)
deploy-web/start-domestic.sh — 看门狗(退出 3 秒重启 + pidfile) —
tests/*.mjs 10 个文件 契约测试 全部 Mock,非 E2E
tools/*.mjs 3 个 搬迁/审计脚本 一次性工具

3. 构建链

index.html ─┐
            ├─ node build.js ─► cat-chat-all-in-one.js ─┐
worker.js ──┘                                           ├─ wrangler deploy (v2)  → zhai-v2
                                                        └─ wrangler deploy --config wrangler.v1.toml → zhai

index.html ──► deploy-web/server.js 运行时读取(注入令牌/WEB_MODE/sharecode 垫片)
worker.js ──► cp 成 deploy-web/worker.mjs ──► Node 动态 import

已知脆弱点: - wrangler deploy --config wrangler.v1.toml 不会自动构建 → 忘记 node build.js 就部署旧产物; - deploy-web/worker.mjs 没有自动同步步骤(当前一致,靠人工); - worker.js 单独 import 会因 serveFrontend 未定义在 GET / 时报错。


4. 运行时拓扑

┌──────────────── 浏览器(手机) ────────────────┐
│ index.html(单页,内联 CSS/JS)                 │
│ localStorage:设置/外观/模型 Key/worker_url     │
│ IndexedDB(cat_chat_db/kv):聊天记录、设备快照    │
└───────┬─────────────────────────────┬──────────┘
        │ 聊天:CONFIG.WORKER_URL      │ 记忆/档案/删除:相对路径(同源)
        ▼                             ▼
┌──────────────────┐          ┌──────────────────────┐
│ Cloudflare Worker │          │ Node 垫片(server.js)  │
│ v1: zhai          │          │ + SQLite(/tmp/...db)  │
│ v2: zhai-v2       │          │ 复用同一 worker.js    │
└────────┬──────────┘          └──────────┬───────────┘
         ▼                                ▼
   Cloudflare KV                    SQLite(WAL)
   v1 ec1a / v2 0a4c                652 键
         │
         ▼
   大模型 API(OpenAI 兼容,Key 由前端提供 → Worker 代理)

5. 路由表(worker.js,三端共用)

路径 方法 鉴权 说明
/、未匹配 GET GET 否 返回页面(注入令牌)
任意路径 POST 是 聊天主接口(handleChat)
/manifest.webmanifest、/icon-192.png、/icon-512.png、/apple-touch-icon.png GET 否 PWA 资源(base64 内嵌)
/health GET 否 {ok, service, version:"2.0"}(版本号写死)
/init POST 是 空实现(兼容保留)
/backup GET 是 旧版导出(只含 mem)
/archive GET 是 档案导出;支持 keyword/from/to/speaker/limit/offset
/archive POST 是 档案幂等导入(按 mid)
/export/full GET 是 全量导出(msg/hl/exp/rel/mem)
/import/full POST 是 全量导入(dry_run、幂等、逐条 errors/warnings、墓碑跳过)
/highlights GET/POST/DELETE 是 高光;写入强制引用真实 msg:
/experiences GET/POST/DELETE 是 经历;source_mids 必须存在
/relations GET/POST/DELETE 是 关系;两端必须存在
/proactive POST 是 主动消息(3 次/天、间隔 ≥3h、按 profile)
/messages/delete POST 是 mode=soft\|hard、force;有引用 → 409
/snapshots、/snapshot/now、/snapshot/rollback、/sysinfo GET/POST 令牌 仅国内版(server.js 自处理)

6. KV / SQLite 键位图

键模式 内容 说明
mem:<profile>:<ts>_<rand> 长期记忆(role/content/ts/day_key/hour/period) 聊天检索的数据源
mem_<ts>_<rand> 旧格式(全局) 仅 owner 只读兼容
msg:<profile>:<mid> 结构化档案(含 deleted_at) 导出/恢复/删除的对象
hl:<profile>:<hid> 高光原话(配 mid、content_hash) 记忆库 UI
exp:<profile>:<eid> 经历(active/candidate、source_mids、确定性) 记忆库 UI
rel:<profile>:<rid> 关系(5 种类型) 记忆库 UI;不进提示词
tomb:<profile>:<id> 墓碑(400 天 TTL,只存编号) 硬删防复活
meta_lastTs:<profile> / meta_lastTs 最后聊天时间 后者为旧键
proactive:<profile>:<day> / proactive_<day> 主动消息每日计数 26h TTL
rl_<hash> / rl_global 限流计数 2 天 TTL

<profile> 默认 owner,校验 ^[a-z0-9_]{1,32}$。


7. 三端配置现状(值已脱敏)

项 v1 zhai v2 zhai-v2 国内版
KV 绑定 CHAT = ec1a…7accc CHAT = 0a4c…ce8ad CHAT = SqliteKV 实例
Secret DEEPSEEK_API_KEY(代码不读) AUTH_TOKEN 无(AUTH_TOKEN 由 makeEnv 注入)
令牌 代码默认值(源码内) secret(页面注入) 代码内 cat-web-token
vars API_URL/ALLOWED_API_HOSTS/ALLOW_CUSTOM_API=0/ALLOWED_ORIGINS 同上 + MODEL ALLOW_CUSTOM_API=1、STRICT_MID=1、MEM_READ_LEGACY=1
部署版本 a3ef2a33(10-25 22:54) 8c6fe98a(10-25 20:38) 进程 22:26 启动
代码一致性 线上 = 本地(含修复)【线上核验】 同左(etag 相同) worker.mjs = bundle 逐字节【实测】

8. 数据面(截至 2026-10-27 00:45)

8.1 国内版 SQLite(/tmp/cat-chat-data/chat.db,652 键)

家族 数量 备注
msg: 320 307 条迁移导入 + 13 条 10-25 新聊
mem: 312 迁移带入
hl: 2 —
exp: 1 —
rel: 0 —
tomb: 0 硬删功能尚未在此库使用过
meta 2 meta_lastTs 与 meta_lastTs:owner
proactive 1 —
rl 14 限流计数残留

被删状态:320 条中 279 条带 deleted_at(10-23 22 点 68 条、10-24 13 点 211 条),有效 41 条。 迁移来源:307 条的 mid 前缀 = local_ 217 / c_ 44 / a_ 39 / u_ 7 → 大多数来自本机历史的「云端同步」上传,不是服务端实时聊天记录。 时间跨度:2026-10-14 02:40 → 2026-10-25 22:37。

8.2 Cloudflare KV

库 内容 证据
v1 ec1a… 抽样 4 个 msg:owner:*(local_/c_ 各 2)全部 200 命中;meta_lastTs:owner 读出 10-25 22:31 的时间戳 【实测】
v2 0a4c… 同 4 个键全部 404;meta_lastTs 停在 10-25 18:56 【实测】

精确键数无法枚举:免费版 list 配额已耗尽(code 10048),REST keys 同样被拒。以上为抽样结论,不是全量统计。

8.3 浏览器

每一台设备各有一份 IndexedDB(cat_chat_db/kv,键 messages),含图片 base64;云端不存图。


9. 测试覆盖

文件 断言数 覆盖
test_p0_memory_isolation.mjs 15 profile 隔离(含图片/主动/关键词重叠/旧数据)
test_p0_mid_refs.mjs 21 mid 回写、重试幂等、409、引用校验
test_p0_delete_sync.mjs 36 软/硬删、409、级联、墓碑、防复活
test_p0_export_import.mjs 27 全量导出/导入、dry_run、幂等、错误报告
test_p0_kv_quota.mjs 17 list 缓存、降级、503、写去重
test_p1_memory_context.mjs 13 高光/经历进 prompt、候选分离
test_p1_archive_search.mjs 14 搜索/时间/说话方/分页/软删
test_phase4_v2.mjs 32 阶段 4 回归(源码 + 产物各 16)
test_kv_sqlite.mjs 23 SqliteKV 六方法
test_ui_delete_scope.mjs ~8 删除范围 UI 契约(静态断言)
合计 约 206 全部为 Mock / 静态测试,非生产 E2E

未覆盖:CORS 跨源、令牌注入、WORKER_URL 覆盖、三端联调、真实上游、浏览器 E2E、配额恢复后的行为。


10. 依赖与成本

项 说明
运行时依赖 无 npm 依赖(Workers 原生 + Node 内置 node:sqlite)
外部服务 Cloudflare Workers/KV;国内托管平台(WorkBuddy);大模型 API(用户自选)
成本结构 KV 免费额度(list/写各 1000/天);模型费用由用户 Key 承担
实测约束 一次聊天约 5–6 次 KV 写、约 300 次读、1–2 次 list(热缓存 0–1 次)

11. 与原设计的偏差

设计 现状 偏差原因
D1 或 KV 选 KV 用户选型
单一 Worker v1 + v2 + 国内版三端 重建 + 国内可用性需求
「外置记忆库,原文入库」 mem: 与 msg: 双写 分阶段演进叠加,未合并
「云端完整档案」 图片只存占位 未接 R2
「管理后台 + 强认证」 无 阶段 7 未开始
「人设版本管理」 一段文本 阶段 5 未开始
本页由交接包内的 Markdown 原样转换;内容未改动。源码与完整包请回目录页下载。