Trigger Evolution — 触发系统演进策略

本文档记录 Kept 触发系统从 MVP 到成熟产品的演进路径。 核心约束来自 design-values.md宁可漏提醒,不可多打扰。

1. 问题陈述

当前架构

用户语音 → Speech → 文本 → LLM (prompt) → 结构化 JSON → 触发器注册

LLM 的 system prompt 包含所有分类规则、触发判断逻辑和正反例。每遇到一个 edge case(如"盐没了"该不该触发超市围栏),就需要修改 prompt + 部署。

根本矛盾

同一句话的"正确"触发方式因人而异。

用户说 用户 A(习惯线下) 用户 B(习惯网购)
"盐没了" 路过超市提醒 ✓ 不触发 ✓
"该买猫粮了" 超市围栏 ✓ 不触发(自动订阅) ✓
"洗面奶没了" 药房围栏 ✓ 不触发 ✓

静态 prompt 只能做一种决策。选「猜」→ 过度打扰;选「不猜」→ 错过提醒。两种都不对。

Prompt 膨胀问题

随着 edge case 增加,prompt 会越来越长:

更长的 prompt → 更高的成本 + 更低的遵循度 + 更难维护。

2. 演进路线

Phase 1: MVP(当前)— 保守 + 双保险

策略:宁少勿多,硬规则兜底。

LLM prompt (分类+触发)  →  server-side filter (白名单过滤)  →  iOS 注册触发器

够用就好,不继续膨胀 prompt。

Phase 2: 种子测试期 — 收集数据,建立反馈闭环

策略:让用户行为定义"正确答案"。

2a. 记录完成上下文

当用户滑动"完成"一条记忆时,记录:

// MemoryEntity 新增字段
completedAt: Date?
completedLatitude: Double?
completedLongitude: Double?

这些数据不需要展示给用户,纯后台积累。

2b. 触发置信度分层

LLM 输出的触发器不再是全有/全无,而是分层处理:

置信度 处理方式 用户感知
>= 0.9 直接注册触发器 到了地方自动提醒
0.6 - 0.9 存储但不注册,卡片上显示建议标签 用户看到"超市?"可点击确认
< 0.6 只存储,不推荐 纯记忆,无触发

中间层让用户轻量级确认,既不打扰,又收集了偏好信号。

Phase 3: 用户画像注入 — 从「改 prompt」变成「改 context」

策略:prompt 保持稳定,用户偏好作为动态 context 注入。

当前:  system_prompt (包含所有规则)  +  用户原文
未来:  system_prompt (稳定的基础规则)  +  user_context (动态偏好)  +  用户原文

User Context 结构:

{
  "shopping_habit": "mostly_offline",
  "frequent_places": ["盒马鲜生(超市)", "永辉(超市)"],
  "home_marked": true,
  "office_marked": true,
  "trigger_feedback": {
    "LOCATION_accepted": 12,
    "LOCATION_ignored": 3
  }
}

User Context 生成方式:

关键原则:user context 在端侧生成,不上传到服务器。 隐私底线。

Phase 4: 属性化分类 — 超越固定类型

策略:从「5 种类型」变成「多维属性」。

当前的 ACTION / KNOWLEDGE / INTENT / RECURRING / THOUGHT 是产品设计者的心智模型,不是用户的。一条记忆可以同时具有多种属性。

当前:  type = "ACTION"  (互斥枚举)

未来:  {
         "actionable": 0.8,        // 需要行动的程度
         "time_sensitive": 0.3,    // 时间敏感度
         "location_relevant": 0.6, // 地点相关性
         "recurring_pattern": 0.1, // 周期性
         "informational": 0.2,     // 纯信息性
         "reflective": 0.0         // 思考性
       }

好处:

分类和触发解耦:LLM 只做属性标注,触发决策由端侧规则引擎 + 用户画像共同决定。

Phase 5: 被动智能 — 不猜,而是等

策略:对于模糊场景,不主动触发,而是被动匹配。

"盐没了" → 存储为 actionable 记忆,不注册围栏
用户走到超市附近 → 系统检查是否有匹配的待办记忆
匹配到"盐没了" → 轻提醒:"要不要顺便买盐?"

这是最优雅的解决方案:

实现方式:

与 design-values.md 的对齐:

3. 不同阶段的 Prompt 策略

阶段 Prompt 职责 Prompt 长度趋势
MVP 分类 + 触发判断 + 正反例 持续增长 (不好)
Phase 2 分类 + 触发推荐(含置信度) 略减
Phase 3 分类 + 属性标注 稳定
Phase 4-5 纯语义理解 + 属性标注 精简

终极目标:prompt 只做"理解",不做"决策"。 决策由端侧引擎完成。

4. 对现有架构的影响

不需要改的

需要逐步添加的

5. 时间线建议

MVP / P2 (现在)     →  保守策略,server filter,不再膨胀 prompt
P2.3 种子测试       →  开始记录完成上下文数据
P2.6 记忆生命周期   →  置信度分层 + 轻量确认 UI
P3.5 高级 AI        →  user context 注入 + 属性化分类
P4+                 →  被动智能匹配

6. 核心原则

  1. Prompt 只理解,不决策 — 越早将决策逻辑从 prompt 移到代码,系统越稳定
  2. 用户行为 > 开发者规则 — 10 个用户的完成数据比 100 行 prompt 规则更准确
  3. 被动优于主动 — 等到对的时机再提醒,好过猜测时机
  4. 隐私底线 — 用户画像端侧生成、端侧存储、不上传
  5. 宁少勿多 — 设计价值观的底线,任何演进都不能违反