$ cat zh/blog/completion-event-session-state

完成事件不等于会话状态

完成标记只是某个回合的证据。监控器还要判断这个新鲜会话现在是否真的需要用户。

日志里的终止标记回答的是“某个回合曾经结束”,界面上的“轮到你”回答的是“此刻是否需要你回来”。两者之间至少隔着语义解析、身份关联、时间判断和覆盖规则。

先解析含义,再看时间

相同外壳可能包着正常结束、限流、认证错误或取消。解析器应先检查错误字段、事件类型和来源,确认它是否真的是可交互回合的完成,再进入时间逻辑。

文件时间只能作为降级

文件可能因为索引、同步或归档而被重新触碰。事件自带时间时必须优先使用;只有缺失语义时间时才使用修改时间,并标记较低置信度。

单调推理仍有边界

更晚的用户输入、新回合开始或错误事件会覆盖旧完成。不同来源的时钟可能偏移,因此最好在同一会话内结合顺序号、回合标识和时间,而不是对所有文件做全局时间排序。

提醒必须过期

周五的完成事件不应在周一重新把用户叫回来。产品需要明确注意状态的有效期,并在用户恢复互动后立即清除。重复读取同一事件也不得再次提醒。

我们验证什么

  • 正常完成与错误结束分开。
  • 后续活动能撤销旧状态。
  • 重复事件只产生一次提醒。
  • 后台来源不会冒充互动线程。
  • 重启恢复不会复活过期提醒。

这套规则在七状态分类与测试清单中被扩展成完整模型。

一个最小状态记录

{ session, turn, state, reason,
  event_time, observed_at, source,
  confidence, expires_at }

event_time 表示事情何时发生,observed_at 表示监控器何时看到它。两者分开,才能解释应用重启后读到旧事件的情况。expires_at 则确保一次旧完成不会永久占据状态栏。

覆盖关系比“最新文件”更可靠

如果完成事件之后出现同会话的新用户输入,状态应进入新回合,而不是比较两个文件谁更新得更晚。归档进程可能最后触碰旧文件,但它没有新的回合语义,不能推翻真实交互顺序。