长对话里真正棘手的不是“忘了一个词”,而是旧事实仍然像新事实一样有权威。用户先说端口8000,后来改9000,又撤回部署任务。把三句话压成一段摘要,可能留下两个端口,也可能把撤回丢掉。
我更愿意先把这类更新写成事件。事件记录发生了什么,当前状态由回放得到。这样既能给模型提供简短事实,也能回答“为什么现在采用这个值”。它不会让模型自动理解所有偏好,却能减少状态维护中的一类歧义。
IBM Research 的记忆实验讨论了记忆注入量与模型能力之间的关系,结果并非“存得越多越好”。这里借用的是设计问题:哪些信息应该进入当前上下文,而非照搬其实验成绩。研究说明
事件与当前事实要分开存
每个事件至少包含键、操作、值和来源轮次。set表示更新,revoke表示撤销。不能把没有出现过的值补成默认值,也不应只改当前字典而丢失历史来源。
from dataclasses import dataclass @dataclass(frozen=True) class Event: round: int key: str op: str value: str = '' def replay(events): state, last_round = {}, -1 for event in events: if event.round < last_round: raise ValueError('events must be ordered') last_round = event.round if event.op == 'set': state[event.key] = (event.value, event.round) elif event.op == 'revoke': state.pop(event.key, None) else: raise ValueError('unknown operation') return state history = [Event(1, 'network', 'set', 'private'), Event(1, 'port', 'set', '8000'), Event(7, 'port', 'set', '9000'), Event(9, 'port', 'revoke')] assert replay(history) == {'network': ('private', 1)} assert replay(history[:3])['port'] == ('9000', 7) assert replay(history) == replay(list(history)) print('replace, revoke, replay determinism: PASS')这还不是语义记忆引擎
例子假定事件已由可信来源确认。真实难点是抽取:一句“测试环境暂时用9000”不能覆盖生产配置;模型建议也不能自动升级为用户授权。可在事件里再加环境、有效期、确认状态和证据片段,把候选事实与已确认事实分开。
Kimi Code 的模型配置说明提醒用户在跨模型切换时新建会话。这种产品层建议与事件账本并不冲突:会话可以换,外部事实记录仍须携带来源与作用域,重新注入时也要检查是否适用于当前任务。
本地例子验证了覆写、撤销和确定性回放,没有调用模型抽取事实,没有进行百轮对话评测。若要验证长期效果,应加入纠正、撤销、临时例外和同名环境的用例,分别统计当前事实正确性与历史来源可追踪性。两项都好,才值得继续谈压缩率。