Skip to content

Timeflow Product Report

Lupeng Han edited this page Aug 28, 2026 · 1 revision

目录

  1. 产品定位
  2. 目标用户
  3. 核心价值
  4. 竞品对比
  5. 核心场景
  6. 产品功能总览
  7. 核心交互
  8. 日程基本概念
  9. 提醒基本概念
  10. 语音交互
  11. 在线与离线边界
  12. 本地与云端边界
  13. 技术实现概述
  14. 与早期设计的关键差异
  15. 已知限制与待办
  16. 测试与质量状况
  17. 本期明确不包含
  18. 附录:字段与枚举速查

1. 产品定位

TimeFlow 是一款以语音为核心操作方式、以本地可靠提醒为核心价值的个人日程应用。

用户用一句自然语言(例如"明天下午三点和张三开会,提前十五分钟提醒我")完成日程与提醒的创建、查询、修改、删除;提醒在设备本地判定与送达,断网仍可触发。

传统日历页面只承担查看和信息展示,不承担日程或提醒的创建、修改、删除与配置——这些操作只通过语音完成。

2. 目标用户

首期目标用户是有日程任务管理需求、同时容易遗漏时间事项和地点事项的 Android 用户(通勤、开车、做家务等双手被占用场景)。

他们的共同需求:

  • 不希望经过多层 GUI 表单才能记录日程。
  • 希望用一句自然语言完成日程和提醒设置。
  • 不仅需要"到时间提醒",也需要"到达某处时提醒"。
  • 希望重要提醒比普通系统通知更难被忽略。
  • 网络不可用时,已设置的提醒仍然能够触发。

3. 核心价值

  • 语音完成核心操作:日程与提醒通过语音创建、查询、修改、删除。
  • 提醒本地可达:时间判定、地点判定与提醒下发均由设备本地执行,不依赖云端轮询。
  • 提醒强度分级:低 / 中 / 高三级送达方式,重要提醒更难被忽略。
  • 断网保持提醒:离线时不能使用云端语音能力,但已注册的本地提醒继续工作。

4. 竞品对比

TimeFlow 的对比对象分为三类:手机自带语音助手(小爱同学 / Siri / 小艺等)、手机系统自带日历(Apple 日历及各安卓厂商自带日历)与传统日历/待办软件(Google Calendar、Outlook、Todoist、TickTick/滴答清单等)。其中手机语音助手是最贴近的竞品——它也能语音、也能一句话创建,但只能做"单轮命令",做不到多轮追问、消歧、确认。苹果日历仅作为产品能力与交互习惯的参考,TimeFlow 不接入苹果日历或其他任何第三方日历。

4.1 能力对比

维度 TimeFlow 手机语音助手(小爱同学/Siri) 手机系统日历 传统日历/待办软件
核心操作方式 语音(自然语言多轮) 语音(单轮命令) GUI 表单/点选 GUI 表单/点选(少数支持自然语言速记)
时间提醒 ✅ 指定时刻 / 提前 ✅ 一句话创建 ✅ ✅
地点提醒 ✅ 到达地点 ❌ 无 基本没有 少数(需手动设围栏)
提醒强度分级 ✅ 低 / 中 / 高 部分 单一通知/添加闹钟 ❌ 单一通知 部分(简单铃声/震动)
本地判定与断网送达 ✅ 本地判定,断网仍触发 部分 ✅ 系统闹钟本地 多数依赖云端/同步
提醒完成 / 延期 ✅ 内建处置 有限 有限(稍后提醒) 部分
语音多轮追问 / 消歧 / 确认 ✅ ❌ ❌ 极少
日历只读展示 ✅ 只读月历 + 语音浮层 落到系统日历(无语音浮层) 有 有
第三方日历接入 ❌ 明确不做 接入系统日历 本身即系统日历 ✅ 通常是卖点
离线创建 / 编辑 ❌ 仅离线查看 ❌ ✅ 部分

4.2 TimeFlow 的差异化

  • 语音为核心操作方式:一句自然语言完成增删改查,并支持多轮追问、消歧与删除/重复范围确认;手机日历与传统软件仍以 GUI 表单为主。
  • 地点提醒:支持"到达某地提醒",是绝大多数日历软件不具备的能力。
  • 提醒强度分级:低/中/高三级送达(通知 → 震动+弹窗 → 声音+震动+弹窗),比单一日历通知更难被忽略。
  • 本地可靠送达:时间判定、地点判定与提醒下发都在设备本地完成,断网仍触发,不依赖云端轮询。
  • 提醒处置:内建"提醒完成/延期",并区分"已处理本轮"与"日程完成"。

4.3 TimeFlow 的有意取舍

  • 不做 GUI 编辑:日程/提醒的增删改只走语音,日历页与详情页只读——与手机日历、传统软件的 GUI 编辑路径相反。
  • 不做第三方日历接入:不聚合外部日历,定位为独立的语音日程助手,而非"日历聚合器"。
  • 不做多维上下文动态调整(路程耗时/天气/导航等),对应 Proposal #164,明确不实现。

5. 核心场景

三类核心场景:单次时间型、重复时间型、地点型。

5.1 单次时间型

用户点击麦克风按钮说:"明天下午三点和张三开会,提前十五分钟提醒我。"

TimeFlow 创建一次性时间日程与提醒,并在本地注册提醒。到达触发时间后,设备按提醒强度通知。

5.2 重复时间型

用户说:"每周一早上九点开晨会。"

TimeFlow 创建重复时间日程(按重复规则展开),每周一早上九点自动提醒。

5.3 地点型

用户说:"提醒我到学林路地铁站拿快递。"

TimeFlow 创建地点提醒,设备进入地铁站位置范围后,在本地触发提醒。

6. 产品功能总览

以下功能为当前代码已实现并(大部分)已真机验证的能力:

6.1 账号

  • 注册与登录合一:用户名未注册则创建账号,已注册则校验密码。
  • 用户名 3–64 字符;密码至少 8 字符(服务端上限 128)。
  • 认证返回 JWT 访问令牌;密码只存哈希(Argon2)。

6.2 语音管理日程(云端 CRUD)

  • 语音创建 / 查询 / 修改 / 删除日程。
  • 多轮对话:信息缺失时主动追问,目标歧义时列出候选确认,删除与重复范围等高风险操作二次确认。
  • 每次变更经鉴权 → 业务规则 → 幂等 → 云端事务,事务提交成功后返回结果。

6.3 语音配置提醒

  • 每个日程最多配置 1 个提醒(提醒是日程上的字段,不是独立表)。
  • 支持四类提醒触发类型(见第 9 节)与三级强度。

6.4 本地提醒送达

  • 时间与地点提醒在设备本地判定与送达。
  • 三级强度:低(系统通知)/ 中(震动 + 弹窗)/ 高(提示音 + 震动 + 弹窗)。
  • 处置操作:提醒完成 与 提醒延期(默认延期 10 分钟)。
  • 后台与锁屏均可触发(时间型由原生 AlarmManager 独占触发,进程被杀也能拉起;地点型依赖前台服务轮询,见 9.1 节)。

6.5 离线使用与恢复同步

  • 离线可查看本地缓存日程、使用已注册提醒、执行完成/延期。
  • 网络恢复后与云端同步(日程快照作为本地 SQLite 权威状态)。

6.6 日历只读展示

  • 月历首页 + 日程详情(时间型与地点型)。
  • 支持重复日程展开与"仅本次/本次及未来"例外展示。
  • 无任何 GUI 增删改入口。

6.7 其它

  • 地点检索(腾讯地图),支持地点歧义追问。
  • 自动日程分类(创建日程时由 LLM 归类为 8 类之一,用户无需语音指定)。
  • 可观测性:Prometheus 指标 + OpenTelemetry/Tempo 链路追踪。

7. 核心交互

7.1 登录 / 注册

打开 App 后用同一表单登录或注册:新用户名创建账号,已存在用户名校验密码。登录成功后进入日历首页。

7.2 日历首页

  • 月历展示日程,点击查看详情(时间型详情页 / 地点型详情卡片 / 重复日程单次例外详情)。
  • 首页提供两个语音入口:按住说话 与 免提连续对话。

7.3 语音操作

  • 按住说话(push-to-talk):按住麦克风按钮说话,松开发送,一次一轮。
  • 免提连续对话(continuous):进入通话式界面持续监听,多轮对话,支持自然结束(语音指令挂断 / 空闲超时 / 手动静音 / 切后台自动静音)。
  • 语音回复同时通过 TTS 播报 和 屏幕文字 呈现。

7.4 提醒处置

提醒触发后,用户可即时执行:

  • 提醒完成:标记本轮已处理(不等于日程完成)。
  • 提醒延期:默认延后 10 分钟,重新注册提醒。

7.5 权限

麦克风、通知、位置等权限不可用时,展示原因与开启方式,并停止依赖该权限的功能。首次启动提供权限引导页。

8. 日程基本概念

一条日程包含以下字段:

字段 说明
标题 title 字符串,默认「新建日程」
类型 schedule_type time(时间型)/ location(地点型)
是否重复 schedule_kind once(单次)/ recurring(重复)
分类 category 8 类之一或空:work / study / exercise / entertainment / social / rest / personal / other
是否全天 is_all_day 布尔
开始 / 结束时间 时区感知时间戳
时区 timezone IANA 时区标识
重复规则 recurrence_rule RFC 5545 RRULE(仅重复日程)
地点 名称 + 经纬度(NUMERIC(9,6))
提醒配置 见第 9 节,每日程最多 1 个
状态 status active / deleted(软删除)
版本 revision 乐观并发版本号,用于同步

8.1 默认创建规则(语音创建,无明确说明时)

  • 无标题 → 「新建日程」。
  • 无开始时间 → 当前时间之后的下一个整点。
  • 非全天无结束时间 → 开始时间 + 1 小时。
  • 全天仅说一天 → 覆盖整个自然日。
  • 未说重复 → 不重复。
  • 未提地点 → 按时间型处理(不主动搜地点、不编坐标)。
  • 未说提醒 → 默认 medium 强度:非全天用 before_start 提前 15 分钟;全天用 at_time 当天 10:00(带时区偏移)。

8.2 重复日程

  • 重复规则用 RRULE 表达,如 FREQ=WEEKLY;BYDAY=MO。
  • 支持单次例外(occurrence override):cancel(取消某一次)/ replace(替换某一次)。
  • 修改 / 删除重复日程时提供三种范围:
    • this_occurrence 仅本次
    • this_and_future 本次及未来
    • entire_series 整个系列

9. 提醒基本概念

提醒配置是日程上的字段,云端与客户端都没有独立 reminder 表;每个日程最多 1 个提醒(reminder_type 为空 = 未配置提醒)。

9.1 提醒触发类型(3 类)

类型 含义 触发依据
at_time 指定时刻提醒 绝对触发时刻
before_start 开始前提醒 开始时间 + 提前偏移分钟数
arrive_location 到达指定地点提醒 进入目标地点范围

地点类提醒(arrive_location)在客户端通过前台服务 + 距离轮询(Haversine)判定进出围栏,默认围栏半径 400 米;不依赖云端、不依赖系统原生 Geofencing。

9.2 提醒强度(3 级)

强度 送达方式 是否依赖 TTS
low 系统通知 否
medium 震动 + 应用内弹窗 否
high 本地提示音 + 震动 + 弹窗(TTS 可用时由 TTS 充当提示音) 是(可降级)

TTS 不可用时,高强度提醒改用本地提示音,并继续震动、显示弹窗,不丢失提醒。

9.3 处置状态

状态 含义 是否同步云端
pending 待处理 否(本地)
confirmed 用户已处理本轮(不等于日程完成) 是(唯一同步云端的状态)
snoozed 已延期(默认 10 分钟) 否(本地)

10. 语音交互

10.1 交互模式

  • 按住说话(push-to-talk):默认模式,一次一轮。
  • 免提连续对话(continuous):多轮连续,服务端智能断句,支持自然结束。

10.2 对话能力

  • 意图理解:把自然语言转成结构化日程操作(创建 / 查询 / 修改 / 删除)。
  • 追问:缺字段时按 missing_field 追问(一次问一件,能算的不问)。
  • 消歧:目标指代不明时,先查询再以 ambiguous_target 列出候选让用户选。
  • 确认:删除、重复范围等高风险操作以 confirmation 二次确认。
  • 地点解析:带精确地名时调用地点检索,精确匹配直接采用,多条候选对不上时才让用户选;「家/公司」等模糊指代先追问具体地址;「到 X 提醒我」按到达地点提醒处理(不追问时间);搜不到如实说明,不编造坐标。

10.3 服务端两条语音管线(可切换)

服务端由 TIMEFLOW_VOICE_AGENT_MODE 切换两条语音后端,对客户端暴露同一套 WS 协议、同一套日程工具,客户端对模式无感知:

模式 编排 核心模型 音频链路
模式 1(默认,实时端到端) RealtimeAgent 阿里云 Qwen-Audio 实时(qwen-audio-3.0-realtime-plus) 16kHz 音频进 → 24kHz PCM 语音出(单模型完成转写+理解+语音)
模式 2(组合式/级联) ComposedVoiceAgent Qwen3-ASR → OpenAI 兼容 LLM → Qwen-Audio-TTS 16kHz ASR 进 → LLM 文本 → 24kHz TTS 出

10.4 两条管线的优劣对比

能控制的能力

维度 模式 1(实时端到端) 模式 2(组合式)
可独立调优的环节 无(转写/理解/语音融合在一个模型里) ASR、LLM、TTS 三段各自独立可调
LLM 可否更换 否(模型固定) 是(任意 OpenAI 兼容模型,可换更便宜/更强)
系统提示词 / 工具 schema 固定(build_instructions) 完全可控,可随时改
声线(voice) 单一 vendor voice 参数 TTS 段独立 voice 参数
VAD / 断句 vendor turn detection + VAD 阈值/静音 ASR 段 VAD 阈值/静音独立控制
对话历史窗口 max_history_turns(连续 10 / 按住说话 5) 由 LLM 上下文自行管理
长回复截断 模型自行控制 SpeechPipeline 强制截断(约 100 字 +「后面省略」)

成本

维度 模式 1 模式 2
计费方式 单一实时模型(音频+文本 token) 三段分别计费(ASR 音频 + LLM token + TTS 音频)
上下文开销 每次响应都重发 system prompt + 工具 schema LLM 上下文可裁剪(字段裁剪 input token 降约 73%)
降本空间 有限(精简 prompt、会话上下文按体量重建) 大(换 LLM、裁字段、截断回复)

延时

  • 模式 1:单模型端到端,无 ASR→LLM→TTS 三段串行累加,首字延迟更低(#166 论证端到端的延迟优势)。
  • 模式 2:三段串行累加,延迟更高;真机实测(组合式管线)首播 P95 约 1.5 秒(查询)~ 17 秒(歧义修改)。缓解手段是每一环都流式 + barge-in 打断。

语音的控制

  • 模式 1:语音由端到端模型直接生成,"屏幕文字"与"嘴里说的话"同源,业务层无法单独改写播报文案;声线整会话只能用一个 voice 参数;打断由 vendor turn detection 自动处理。
  • 模式 2:TTS 是独立一段,播报文案 = LLM 输出文本,业务层可在 TTS 前截断/改写;"屏幕文字"(voice.dialogue.reply 流式)与"语音播报"(voice.tts.speech_text)两条通路可分开控制(流式负责显示,speech_text 非空时覆盖一次);打断走 ASR SpeechStarted 检测 + 取消当前 turn。

11. 在线与离线边界

能力 在线 离线
语音管理日程 ✅ ❌
语音提问 / 确认 ✅ ❌
TTS 播报 ✅ ❌
云端同步 ✅ 恢复后同步
查看本地缓存日程 ✅ ✅
已注册提醒触发 ✅ ✅
提醒完成 / 延期 ✅ ✅

离线时不支持 ASR、LLM、TTS,以及日程/提醒的创建、修改、删除。

12. 本地与云端边界

TimeFlow 采用按数据域分权的双层权威模型:

云端保存 / 执行 本地负责
以账号隔离的日程数据(含提醒配置) 日程缓存(SQLite)
同步所需的暂存记录与同步状态 时间 / 地点判断
提醒的最终确认状态(仅 confirmed) 提醒注册、触发、延期
— 通知、弹窗、震动、声音
— 当前提醒实例的运行状态(pending/snoozed 等)

关键区分:提醒配置(云端同步字段)与本地提醒实例/运行状态(永不同步)是两个不同概念。同步只同步配置与同步元数据,不同步提醒运行状态。

13. 技术实现概述

本节仅概述,详细协议与分层见架构文档 Architecture-interface-design v4.0。

13.1 服务端(FastAPI + PostgreSQL)

  • 分层:business(领域)/ data(仓储与模型)/ gateway(HTTP/WebSocket 入站)/ intelligence(语音编排)/ infrastructure(第三方适配与运行时)。
  • 数据模型(3 张表):accounts(账号)、schedules(云端日程,含提醒配置与分类)、schedule_occurrence_overrides(重复日程单次例外)。
  • HTTP 接口(极小):
    • POST /api/v1/auth/access — 注册/登录合一,返回 JWT
    • GET /api/v1/schedule/snapshot — 账号日程全量快照(含例外)
    • PUT /api/v1/schedule/reminder-state — 提醒最终确认状态(仅 confirmed)
    • GET /api/v1/health、GET /metrics
  • WebSocket:/ws 承载认证后的语音会话(音频二进制帧 + JSON 控制消息)。
  • 第三方:通义实时语音 / 通义 ASR / OpenAI 兼容 LLM / 通义 TTS / 腾讯地图检索。

13.2 客户端(Expo / React Native,Android)

  • 功能域:认证、日程(日历只读)、语音助手、提醒送达、同步。
  • 本地存储:SQLite(local_schedules 表,提醒字段在日程上,不建独立 reminder 表)。
  • 原生模块:timeflow-alarm(AlarmManager 独占触发、响铃页、声音服务、开机恢复、厂商权限适配)。
  • 权限:麦克风、通知、位置(后台定位用于地点围栏)。

14. 与早期设计的关键差异

本文档以代码为准,修正了早期产品设计草案中的以下差异(早期表述已过时,不要采用):

主题 早期草案 当前定稿
日程分类 工作 / 家庭 / 生活(3 类) 8 类:work / study / exercise / entertainment / social / rest / personal / other
默认提醒强度 低强度 medium
全天默认提醒时间 当天 10:00 当天 10:00(一致)
重复日程删除范围 2 种 3 种(新增 entire_series)
提醒触发类型 3 种(时间/到达/返回) 3 种(时间拆为 at_time 与 before_start,地点统一为一类)
每个日程提醒数量 早期曾写「最多两个」 最多 1 个(已定稿)
云端日程表 曾讨论新建 schedules_cloud 并存 直接改造 schedules 表(不新建并存表)

15. 已知限制与待办

以下为 2026-08(MS4 收尾)逐条回到代码排查后的当前状态。

仍存在的问题(按影响程度排列):

  1. 实时会话闲置后首轮失败(自愈,不修复):通义 realtime session 在 180 秒无响应后被厂商关闭;服务端能检测到(_next_event 捕获异常 / send_audio 异常上抛 → finally 判定不可复用 → _discard 清出缓存),无需重启后端。代价是 180 秒空隙后的第一次开口会失败一次(报错或无反应),下一次才新建会话成功——体感为「隔一会儿第一次没反应,再试一次即恢复」。决定不修复,不影响正常使用。
  2. 音频消费失败静默(不修复):后台音频消费任务(_drain_to_sink)抛异常时仅记服务端日志、不回错误给客户端,客户端表现为「一直等待结果」直到超时。修复路径明确——给 VoiceStreamHandlers 注入 main.py 已建好的 ConnectionManager(WebSocketResultSink 同款),并复用已有的 ERROR_INTERNAL(INTERNAL_ERROR),无需新增错误码。决定暂不修复,不影响正常使用。
  3. device_id 无下游消费:仅做自证式核对,无多设备/限流/推送定向用途。
  4. 语音质量待优化(真机测试定位):ASR 对近音词/专有名称识别偏差、复杂场景间歇超时、自然语言参数提取偶发截断、同义输入数据规范不一致、歧义修改响应偏长。

已解决 / 不再适用:

  • 时区硬编码:session.hello 的 timezone 已接线(SessionContext → StreamContext → ToolBox),Asia/Shanghai 仅作兜底默认值。
  • 定位监听:LocationMonitorPort 已有真实 ExpoLocationMonitor 实现,地点检索走腾讯地图真实地理编码。
  • 地点提醒:只保留「到达地点」一类(「记住当前位置」已移除)。
  • JS 兜底:已废弃,提醒送达统一走原生模块。

设计取舍(非缺陷):

  • 地点提醒改用前台服务 + 距离轮询(默认 400 米),已移除系统原生 Geofencing(#380);进程被杀后地点提醒在下次启动前不可用,属明确接受的代价。

16. 测试与质量状况

  • 已执行 87 条测试用例,核心功能覆盖 46 条,LLM/语音性能专项 20 项。
  • 固定语音测试 150 次,有效样本 114 个。
  • 测试环境:Android 模拟器 + Android 16 真机(Xiaomi,SDK 36)。
  • 已真机验证:真实麦克风语音输入、ASR、TTS、日程 CRUD、数据同步、后台/锁屏提醒、声音/震动提醒、提醒确认、延期后重新注册。
  • 结论:语音日程 CRUD、数据同步、Android 提醒已形成完整业务闭环。

17. 本期明确不包含

  • GUI 创建 / 修改 / 删除 / 配置日程和提醒(日历页与详情页只读)。
  • 第三方日历接入。
  • 离线 ASR、离线 TTS。
  • 多设备使用与多设备提醒协调。
  • 基于多维上下文(路程耗时 / 天气 / 导航 / 关联日程 / 交互状态)动态调整提醒(对应 Proposal #164,Proposal-NoPlan)。
  • 开放式插件架构。
  • 面向不同人群的可定制产品形态。

18. 附录:字段与枚举速查

18.1 日程枚举

字段 取值
schedule_type time 或 location
schedule_kind once 或 recurring
category work / study / exercise / entertainment / social / rest / personal / other(可空)
status active 或 deleted
reminder_type at_time / before_start / arrive_location(地点提醒,可空)
reminder_strength low / medium / high(有提醒时必填)
reminder_disposition_state confirmed(云端仅存此值)
recurrence_rule RFC 5545 RRULE 正文
删除范围 this_occurrence / this_and_future / entire_series
例外动作 cancel 或 replace

18.2 处置状态(客户端运行时)

状态 同步云端
pending 否
confirmed 是
snoozed(默认 +10 分钟) 否

18.3 语音对话问题类型

missing_field(缺字段)· ambiguous_target(目标歧义)· recurrence_scope(重复范围)· confirmation(确认)

18.4 提醒强度送达矩阵(客户端)

强度 弹窗 震动 声音 / TTS
low ✅ — —
medium ✅ ✅ —
high ✅ ✅ ✅(TTS 可用时)

Clone this wiki locally