外观
数据模型与版本关系
| 表 | 主键/唯一约束 | 保存内容 | 学习时观察 |
|---|---|---|---|
| jobs | id | 请求、当前版本、流程epoch、状态、模式 | 编辑或恢复为何改变epoch |
| versions | job_id+version;job_id+node_key | 教材、父版本、来源与规则快照、批准状态 | 修订只增加版本;新版本默认未批准 |
| reviews | job_id+version | 评审报告、评审上下文hash | 报告不能混用旧版本 |
| documents | name+level+language+region+namespace+version | 元数据、显式facts、namespace、active | 更新后旧版本active=false但仍可追踪 |
| chunks | id;document_id+ordinal | 原文、字符offset、向量 | 字符切分不等于Token切分 |
| rules | region | 强制规则及版本号 | 新规则不得覆写旧版本号 |
| node_results | job_id+node_key | 节点已完成结果 | checkpoint重放如何避免重复业务版本 |
| tasks | id;dedup_key | 依赖、版本、尝试、lease_token、错误 | 重试与结果不明的区别 |
| assets | hash | 文件路径、sha256、receipt | 内容寻址复用与核对 |
| events | 自增id | 可观察事件payload、时间 | role/version/task_id/context_hash |
LangGraph的checkpoint表由PostgresSaver.setup()创建。不要手工猜表结构或用它代替业务版本表。迁移入口python -m app.cli migrate先执行migrations/001_initial.sql,再初始化checkpointer。
三种版本不要混淆
资料version说明检索证据来自哪次导入;教材version说明文字是哪次生成/修订;epoch说明LangGraph运行线程是哪次编辑或终止恢复。thread_id=job_id:epoch,不可只用用户ID。素材引用教材version并用输入hash识别内容是否实际变化。
规则更新不会自动改变在审教材的规则快照;新任务使用新规则。若需要给旧书应用新政策,应显式创建重新生成任务、复核内容并保留旧版本审计,不把规则“热更新”偷偷套入旧交付物。
事务与唯一约束
API创建job与workflow task在同一事务,避免只有业务记录而没有可领取任务。媒体计划为同一版本一次插入所有依赖任务,dedup_key保证重复计划不产生新任务。结果提交需要原lease_token;新内容版本会把旧的未完成素材任务标记为superseded。
文件与数据库没有分布式事务。实现顺序是临时文件写入与fsync → 原子rename → receipt原子写入 → assets登记。若登记前进程死亡,可以从receipt核对恢复;若外部服务已经执行但回执尚未落盘,只能标为unknown,不能宣称自动去重。