AI 产出数据架构(AI Output Data Architecture)

状态: 已拍板(Max,2026-06-10)| Schema SoT: callytics-common Drizzle schema + 其 .claude/specs/2026-06-10-ai-output-tables-design.md | 落地: common PR #216(三表)→ D2 writer 接线(infra,后续 PR)

首要原则:可 trace → 可自动 improve

所有 AI 产出必须可追溯,并能据此自动改进。 改进闭环:

provenance(哪版 prompt / 哪次 run)
  × 人的反应(helpful / not_relevant / followed / corrected)
  × 修正对(AI 原文 → 人工改文)
→ golden eval case 从生产失败中生长 → prompt 迭代 → 新版 provenance 可对比

这与 2026 业界共识一致:production trace 与 eval 共用一个数据层;采纳率是 AI 功能价值的核心度量(Salesforce Next Best Action 的 Recommendation + reaction 模式)。

关键认知修正(2026-06-10):ai_usage 是 CloudWatch 结构化日志,有 retention TTL,不是永久层(durable ledger 缺口由 infra#1071 追踪)。推论:重要 AI 产出必须落数据库,不能依赖 log 考古。

统一模式:产出与反应分层,各自 append-only

是什么生命周期规则
产出层AI 生成的内容(建议 / 执行指导)active/current → superseded/staleUPDATE 禁止:新一轮生成 = 旧行标 superseded + 插新行;历史永不被覆盖
反应层人对产出的反应纯 append-only只追加,不修改
修正层人工改写 AI 内容反应层的一种(corrected)AI 原行永不原地编辑;修正版作为反应叠加,展示层 prefer 修正版 — Gong / Observe.AI 同款人工叠加层模式

三张表的职责(字段级设计见 common schema,此处只写逻辑)

task_suggestions(行动建议,提案层) — 替代 tasks 行上 jsonb 的覆盖式存储。一行一条建议;AI 行强制带 provenance;为"一任务多 issue"模型(infra#1090)预留 issue 归属字段,届时回填免迁移。修复的两个洞:历史丢失、零采纳信号(归因链 = closeResult + 当时 active 且被标 followed 的建议)。

task_playbooks(执行指导,产物层) — playbook surface(infra#1084)的存储就绪层。current/stale/superseded 实现缓存语义,一个 task 至多一份 current(唯一性约束)。生成时机(2026-06-10 Max 拍板:eager 在现有 flow 内):任务创建/有意义更新时由现有分析 worker 在任务落库后顺手生成(异步管线无用户等待;Flash 单次成本可忽略;新鲜度钩子与 task 变更天然对齐;复用现有 AI 调用 infra)。打开 Playbook tab 只读 current 行,缺失或 stale 时才现场补生成(兜底,罕见路径)。生成失败仅告警,绝不影响任务写入主链路。

ai_feedback(统一反应层) — 多态 subject(suggestion / playbook / coaching),反应枚举 helpful / not_relevant / followed / corrected,corrected 必须带修正内容。三种 AI surface 一个 pattern:采纳率、不靠谱聚类(prompt 改进线索)、按 prompt 版本聚合(A/B 度量,infra#965 的度量侧)在一处可查。

迁移说明:既有 playbook_feedback 表有 live 消费方(studio-api route + 前端面板),保持不动;#1084 让 playbook 成为持久化实体后,反馈锚点自然切换,届时迁移并入 ai_feedback。

有意保留"覆盖"语义的两处(设计意图,不是漏洞)

  1. contacts 客户画像 — 画像是"当前认知"不是日志,每轮分析整体替换。画像历史的保留方式(2026-06-10 拍板):复用 contact_timeline 既有的 oldValue/newValue 能力,分析完成事件携带前/后画像快照 — 零新表,演变史 = 事件序列。
  2. calls 上的 coaching 输出 — per-call 一次性产出,仅手动 reprocess 覆盖(罕见)。将来人工修改走 ai_feedback 的 corrected 叠加层,不动原行。

时间边界:append-only 自 writer 接线(D2)起生效;之前已被覆盖的历史不可回填。

多租户 / 多品牌就绪

  • 三表统一带 store 隔离列(NOT NULL) + tenant 预留列(NULLABLE,对标 multi-tenant V1 的业务表惯例 —— V1 给业务表加 tenant_id NULLABLE 列、查询仍走 store_id),冗余存储避免回 join。
  • 表存"产物",品牌知识在生成层(prompt / 将来的 per-tenant pack,infra#891):第二品牌进场,表结构零改动。
  • 全库存量评估(2026-06-10)结论:架构与 2026 业界 pooled + tenant 列共识同构;第二品牌前需收口的缺口 = leads 表隔离列 NULLABLE、provider→tenant 映射未实现、calls 缺 prompt 版本列(provenance 不全)。

关联

  • 数据层:callytics-common PR #216(三表)· infra#1071(durable AI ledger)· common#208(task cutover)
  • 产品面:infra#1084(playbook surface)· infra#1090(一任务模型)· studio#464/#1045(前端消费)
  • 度量:infra#965(prompt A/B)· infra#1095(lead 放弃阈值,数据驱动复评)
  • Prompt 层架构:Prompt 架构与接入规则