AI 助理的时间幻觉:为什么跨日对话会产生虚假的'今夜'
从一次凌晨收到含错误日期任务摘要的真实事故切入,揭示AI长会话时间感知失效的系统性机制
- LLM 对「现在是几点」没有任何感知能力,时间信息必须显式注入
- 跨日长会话会把不同天的「今天」合并成同一个「今天」输出
- 三层时间锚定:结构化时间戳 + 跨日续签标记 + 禁用相对时间词
- 自动化工作流里的时间错误会被下游系统继承,排查成本极高
- 好的 AI 工程 = 把所有隐式时间假设变成显式约束
凌晨两点的错误摘要
那封邮件是周四凌晨两点到的,自动化工作流按时触发,格式也完全正确。邮件标题写着「今日工作摘要(周四)」,但摘要正文里列出的三件事——审查三个 PR、更新产品路线图、与设计团队同步——是我周二在同一个会话线程里提到的内容。Claude 把 48 小时前的事情,用「今日完成」的口吻打包汇报给了我。
我盯着这封邮件看了将近五分钟,反复确认日期,才意识到这不是模型偶发的幻觉,而是一个可以被稳定复现的架构漏洞。更让我警觉的是:如果我没有记住周二具体做了什么,这封摘要完全可能就这么被我接受了。
为什么这个问题难排查
我们一开始以为,只要在 system prompt 里注入当前时间戳,时间感知问题就解决了。实际调查之后发现,注入时间戳只解决了「模型不知道现在是几点」这个问题的最浅层,完全没有触及跨日会话里「今天」指代歧义的核心。
问题的隐蔽性在于:错误的时间信息不会像代码报错那样触发任何警报。它混在正确内容里,格式完整,语言流畅,只有熟悉那段时间具体做了什么的人才能发现错误。在我询问了四位同样在用 Claude 搭建自动化工作流的工程师朋友后,其中三位都经历过类似的「日期漂移」,但他们都把它归因为「模型偶尔出错」,没有系统性地追查根因。当这类错误进入项目管理工具,错误的日期标签会被下游系统继承,最终你会发现任务记录里有一批日期混乱的条目,而你已经无法还原错误最初是在哪个节点产生的。
根因:没有时钟的房间,以及三种失效模式
训练完成后,模型的参数被冻结,它对「现在是什么时间」没有任何原生感知能力。模型获取时间信息只有两条路:系统提示里注入当前时间戳,或用户在对话里显式告知。如果这两条路都没有,模型活在一种「永恒现在」里——它能处理关于时间的语言,却不知道自己所处的那个「现在」在哪里。
长会话让这个问题指数级恶化。一个跨越三天的对话线程,在模型眼里是一段扁平的 token 序列。周一说的话和周四说的话在语义层面没有本质区别。当你在周四问「帮我整理今天的工作」,模型会扫描整个上下文窗口里所有带「今天」「今日」「今晚」的内容做归因——包括周二那句「今天开了个会」。这不是模型在撒谎,这是它用语义相似性替代时间感知,因为它没有其他工具可用。具体表现为三种失效模式:
- 日期漂移:时间戳注入后随对话延伸逐渐失效,模型将早期消息的时间上下文当成「当前时间」参考
- 今天合并:不同天提到的「今天」被归并为同一个「今天」输出,正是我遇到的案例
- 时区蒸发:即便注入了时间戳,模型在生成摘要时忽略时区信息,把 UTC 当本地时间处理
修复这个问题需要工程层面的主动干预。我目前采用的三层时间锚定策略如下:
第一层:结构化时间戳注入。不是「现在是下午」这种模糊表述,而是 ISO 8601 格式加时区,放在 system prompt 最顶部:
# system_prompt 片段
system: |
当前时间:{timestamp_iso8601}({weekday})
时区:Asia/Shanghai(UTC+8)
请在所有涉及日期的输出中使用具体日期,不使用「今天」「今晚」等相对时间词。
# 注入示例
timestamp_iso8601: "2025-06-12T14:30:00+08:00"
weekday: "周四"
第二层:跨日续签标记。这是最关键的一层。如果一个对话线程跨越了午夜,由定时任务在第二天第一条消息前自动插入时间更新标记,不依赖用户手动操作:
# 伪代码:跨日续签注入逻辑
def inject_day_boundary_marker(conversation, new_timestamp):
marker = (
f"[时间更新 {new_timestamp}] "
f"以下内容发生在新的一天,"
f"请不要将此前对话中的「今天」归入当前日期。"
)
conversation.insert_system_message(marker)
return conversation
第三层:输出层约束。在需要时间归因的任务 prompt 里,显式要求模型使用具体日期而非相对时间词:
SUMMARY_PROMPT = """
请整理今天的工作摘要。
要求:
- 使用具体日期(如「6月12日」),不使用「今天」「今晚」「昨天」等相对时间词
- 如果某事项的发生时间无法从上下文确认,标注「时间待确认」而非猜测
"""
可移植的原则
如果你在构建任何依赖 AI 生成时间相关内容的系统,把「模型不知道现在是什么时候」当成默认假设,而不是例外情况——每一个没有显式时间戳的请求,都是在让模型猜。
- 如果你在使用长会话线程,每次跨越午夜后的第一条消息前必须插入时间更新标记,不能依赖用户手动说明。
- 如果你的工作流输出会进入下游系统(项目管理工具、数据库、日历),在 prompt 层面强制要求输出绝对日期,在接收层面做日期格式校验,两道防线都不能省。
- 如果你在注入时间戳,使用 ISO 8601 加显式时区,不要用「今天下午」「明天」这类依赖读者上下文理解的表述——模型没有你的上下文。
- 如果你发现 AI 输出里出现了时间错误,不要假设这是偶发事件,用相同的会话长度和跨日条件复现一次,大概率能稳定复现。
问题比「今天」更宽
时间感知只是 AI 工具里所有「隐式假设」问题的一个切面。我们在这个问题上花了两周时间把三层锚定跑稳,期间还发现了几个和时区处理相关的边界情况,记录在我们的工程日志里。如果你在自己的工作流里也遇到了跨日时间混乱,或者在多轮会话状态管理上有具体问题,欢迎在评论区聊——我更感兴趣的是你遇到的具体失效场景,而不是泛泛的「AI 会犯错」。