Skip to content

Daily Pulse 设计原理

这一页解释 Daily Pulse 为什么能主动给出“今天值得看什么”,以及它到底依赖了哪些真实信号。

它的定位不是新闻流,也不是第二个聊天页,而是一个主动策展层。

Daily Pulse 解决的真实问题

很多 AI 产品默认假设用户已经知道自己该怎么问。

但真实情况经常是:

  • 用户今天刚打开 App,还没有明确问题。
  • 用户知道自己最近很忙,但不知道哪件事最值得继续。
  • 用户的长期兴趣、工具能力和最近对话,其实已经足够推导出几个高价值方向。

Daily Pulse 就是把这一步前置掉。

它不是“云端推荐系统”

Daily Pulse 的信号源主要来自本地上下文和本地已经拿到的结果,而不是服务端画像。

它没有依赖统一账号画像去做跨用户推荐,而是围绕这台设备上的真实使用轨迹整理内容。

这意味着:

  • 它更像私人策展,而不是公域信息流。
  • 它的好坏强烈依赖你的实际使用与反馈纪律。
  • 它不会凭空知道外部事实,除非你真的给过相关上下文,或者最近通过 MCP / 快捷指令拿到了外部结果。

输入源有哪些

Daily Pulse 生成时会构建一个 DailyPulseGenerationInput,主要包含八类信息。

1. 用户主动填写的关注焦点

如果你在 Daily Pulse 里写了“今天想重点看什么”,它会直接成为最高优先级的个人信号之一。

2. “明日想看什么”策展输入

这不是立即生效的临时备注,而是偏向下一期的策展要求。

它适合放:

  • 明天想继续推进的方向
  • 想减少的主题
  • 希望多给的卡片类型

3. 最近聊天摘录

Daily Pulse 不会把整库历史全部塞进去,而是只取最近会话的截断片段。

当前实现默认值:

  • 最多取 4 个会话
  • 每个会话最多取 6 条用户/助手消息

这一步的目标不是完整复盘,而是判断你最近到底在忙什么。

4. 长期记忆

它会读取未归档的长期记忆,但不是无限量。

当前实现默认最多取 8 条,并做长度压缩。

这让 Daily Pulse 能记住:

  • 你长期偏好的内容类型
  • 你一贯在做的项目
  • 你经常关心的技术或创作方向

5. 最近请求日志摘要

系统会把最近 7 天的调用轨迹压成一小段摘要,例如:

  • 请求总数
  • 常用提供商
  • 常用模型

这不是给模型看技术统计报表,而是让它知道你最近的使用重心。

6. 未完成的 Pulse 任务

某张卡片如果被你转成任务,它就不再只是“一次性建议”,而会在后续生成里继续参与。

设计意图很明确:

  • Daily Pulse 不只负责发现,还要负责推进。
  • 但它不会机械重复原卡片标题,而是更倾向于“帮你往前走一步”。

7. 反馈偏好画像

Daily Pulse 会把历史反馈整理成三类提示:

  • 更可能喜欢的话题
  • 应尽量避开的主题
  • 最近几天已经出现过的卡片主题

反馈来源不仅包括手动点赞/点踩/隐藏,还包括“保存为会话”这类强正反馈。

8. 外部能力与外部结果

这是最容易被误解的一层。

Daily Pulse 会区分三种东西:

  • 可用能力:例如哪些 MCP 服务器已经选中用于聊天,哪些快捷指令可调用。
  • 最近真实拿到的外部结果快照:例如最近一次快捷指令结果、最近一次 MCP 输出。
  • 公告与趋势信号:例如应用内部公告或趋势类信号。

设计上有一条硬约束:

  • 工具能力描述只代表“可以调用”,不代表已经拿到了实时数据。
  • 只有“最近已获取到的外部结果快照”才代表用户最近真的拿到过的外部内容。

默认开关与保留策略

Daily Pulse 当前实现里有几组非常具体的默认值。

项目默认值
自动生成
MCP 上下文
快捷指令上下文
最近外部结果快照
趋势/公告信号
最终展示卡片数3
模型建议产出候选数6
保留运行记录14 天
反馈历史保留120 条
外部信号保留40 条
任务保留80 条

还要注意一件事:

  • 持久化里会保留最近若干天的数据。
  • 但 UI 默认只展示“今天”的这一期。

也就是说,历史期数主要用于反馈与偏好沉淀,而不是把 Daily Pulse 做成时间轴信息流。

模型选择顺序

Daily Pulse 会先尝试专用模型。

优先级如下:

  1. 用户明确给 Daily Pulse 指定的专用模型
  2. 当前聊天选中的模型,但必须支持聊天
  3. 已激活模型里第一个支持聊天的模型

这让它既能独立调优,也不会在没有专用模型时直接失效。

提示词策略

Daily Pulse 的 system prompt 不是让模型自由发挥,而是明确规定它的职责和边界。

核心规则包括:

  • 基于最近聊天、长期记忆、使用轨迹、反馈、外部能力和用户主动输入做策展。
  • 如果有未完成任务,优先帮助推进,但不要原封不动复述旧标题。
  • 卡片要具体、可继续聊、可直接转成一个新会话。
  • 不要捏造用户经历,也不要凭空编外部事实。
  • 如果给了 MCP / 快捷指令能力,可以优先推荐“能马上借力推进”的卡片。
  • 工具能力描述不等于已经拿到实时外部数据。
  • 输出要有多样性,避免三张卡围着同一件事转。
  • 用户明确不喜欢的主题尽量别再推。

输出结构

模型必须只返回 JSON,不允许 Markdown 代码块。

结构是固定的:

json
{
  "headline": "一句话总标题",
  "cards": [
    {
      "title": "卡片标题",
      "why": "为什么推荐给用户",
      "summary": "一句或两句摘要",
      "details_markdown": "可保存为聊天的详细 Markdown 内容",
      "suggested_prompt": "用户点继续聊时可直接发送的追问"
    }
  ]
}

这五个字段分别解决五个问题:

  • title:列表中先看到什么
  • why:为什么是给你的,不是随机选题
  • summary:快速扫一眼值不值得点开
  • details_markdown:保存为会话后能直接当首条内容
  • suggested_prompt:继续聊时不需要自己重新想问题

模型给候选,客户端再做一轮选择

Daily Pulse 不是完全相信模型原样输出。

实际流程是:

  1. 让模型尽量给出 6 张候选卡。
  2. 客户端把文本做规范化、长度裁剪和兜底。
  3. 客户端再根据偏好画像做打分和筛选,最后只保留 3 张。

本地筛选规则

当前实现里的打分逻辑是可解释的:

  • 与用户当前关注焦点相近:+4
  • 命中过去的正反馈主题:+3
  • 命中最近几天已经展示过的主题:-2
  • 命中过去负反馈主题:-6
  • 详情足够展开:+1

然后再做几件事:

  • 去掉和负反馈高度相似的卡片
  • 去掉彼此过于相似的卡片
  • 尽量避免三张都落在同一类别

这就是为什么 Daily Pulse 看起来像“模型生成”,但实际上又带着明显的产品策展味道。

反馈闭环

一张卡可以触发四类典型反馈:

  • 喜欢
  • 不喜欢
  • 隐藏
  • 保存为会话

这些反馈不会被拿去训练某个远端推荐模型,而是直接沉淀为本地下次生成时的偏好提示。

换句话说,Daily Pulse 的“学习”更像下一轮策展提示,而不是不可解释的黑盒推荐权重。

为什么支持“保存为会话”

这是 Daily Pulse 里一个很关键的设计。

当你把卡片保存为会话时,系统会:

  • 用卡片标题创建一个新会话
  • 把卡片详情 Markdown 作为首条助手消息归档进去
  • 把这次操作记为强正反馈

这意味着 Daily Pulse 不是终点,而是聊天入口生成器。

为什么支持“转任务”

有些卡片不是马上要聊,而是需要后续推进。

所以它还能把卡片转换为内部任务,任务会保留:

  • 标题
  • 摘要
  • 推荐追问
  • 完成状态

后续生成时,未完成任务会继续影响策展方向。

送达机制为什么不是百分百必达

Daily Pulse 的提醒与送达是本地能力,不是服务器推送。

当前默认策略:

  • 晨间提醒默认关闭
  • 默认提醒时间 08:30
  • iPhone 在合适时机会尽量提前准备今天这一期
  • 如果到了提醒时间后才准备完成,会补发一条“已准备好”通知
  • Apple Watch 更偏向在前台恢复时尝试准备

这套设计的本质是 best-effort:

  • 尊重系统调度边界
  • 不假装自己有一个永远在线的云端任务中心

你应该如何理解 Daily Pulse

最准确的说法不是“每日推荐”,而是:

一个由最近聊天、长期记忆、使用轨迹、外部能力、反馈历史和未完成任务共同驱动的主动策展器。

它的价值不在于“替你思考”,而在于把你已经积累过但暂时没组织起来的上下文,重新整理成几个可执行入口。