拓展阅读
记忆范围、版本、过期与冲突
在进程内保存带证据的记忆,按项目与版本查询,排除过期内容,遇到相反结论返回冲突而非擅自择一。
沿着对象与状态理解本章
记忆必须回答两个时间问题:事实什么时候生效,系统什么时候知道。下图用超时配置30秒变20秒追踪来源、有效时间和过期,避免把旧知识以熟悉的口吻重复出来。
下方图解的固定输入在“输入与适用条件”中声明。它用于解释本章机制,不与本章其他独立例子的数值暗中接续。
动态图解 · F31
长期记忆不是永远正确的小纸条
新事实出现后,旧记忆怎样更新而不毁掉历史?
记忆要同时回答:这条信息说的是什么范围、何时有效、系统何时得知、依据在哪里。最新写入的记录不一定描述最新生效的事实。保留时间和来源,才能既回答当前问题,也准确解释过去。
有效时间事实在现实或业务规则中适用的时间。
记录时间系统收到或保存该信息的时间。
作用域信息适用的项目、用户、版本或环境。
输入与适用条件:独立配置案例;月份只用于展示时间顺序,不涉及真实产品当前参数。30秒与20秒属于不同有效期。
1 / 5 · 1月1日 生效
第1步,共5步
窄屏可左右滑动图形,或点击“放大图形”。文字解释紧随图后。
配置超时30秒
保留作用域与来源默认静止。用“下一步”看完解释再继续;播放到最后一步自动停止。键盘聚焦播放器后,可用左右键逐步查看、空格播放/暂停。图中颜色辅助区分,含义同时用文字注明。
为什么需要
跨会话复用有效知识,减少重复查找和重复错误。
怎样实现
保存范围、来源与两个时间;使用前核验;过期、冲突与撤销显式处理。
可能的代价与误解
把一次模型猜测写成通用规则,会在后续检索中放大错误。
如何判断是否做对
同时测试当前查询、历史查询、错误范围查询和来源已失效查询。
怎样观察与验证
固定教学日期为2026-10-17。修改项目或版本观察隔离;新增冲突证据后应返回conflict。此脚本不访问真实用户记忆。
运行命令
python3 reading-notes/experiments/06_memory_lifecycle.py完整教学代码
"""作用域、版本、证据、到期与冲突演示;所有记忆仅在本进程内。"""
from dataclasses import dataclass, asdict
from datetime import date
@dataclass(frozen=True)
class Memory:
key: str
scope: str
version: str
value: str
evidence: tuple[str, ...]
status: str = "verified"
expires: date | None = None
def __post_init__(self):
if not all([self.key,self.scope,self.version,self.value]):
raise ValueError("key/scope/version/value 不能为空")
if self.status not in {"candidate","verified","retired"}:
raise ValueError("未知状态")
if self.status == "verified" and not self.evidence:
raise ValueError("已验证记忆必须带证据引用")
class Store:
def __init__(self):
self.items: list[Memory] = []
def add(self, memory: Memory) -> None:
if memory not in self.items:
self.items.append(memory)
def query(self, key: str, scope: str, version: str, now: date) -> dict:
matches=[m for m in self.items if m.key==key and m.scope==scope
and m.version==version and m.status=="verified"
and (m.expires is None or now < m.expires)]
values=sorted({m.value for m in matches})
if not matches:
return {"status":"not_found","value":None,"evidence":[]}
if len(values)>1:
return {"status":"conflict","value":None,"candidates":values}
return {"status":"usable","value":values[0],
"evidence":sorted({e for m in matches for e in m.evidence})}
def make_store() -> Store:
s=Store()
s.add(Memory("path_base","projectA","v2","config_dir",("D1",)))
s.add(Memory("path_base","projectA","v3","repo_root",("D2","T2")))
s.add(Memory("path_base","projectB","v3","workspace",("B1",)))
s.add(Memory("temporary","projectA","v3","old",("T0",),expires=date(2026,10,1)))
return s
def self_test() -> None:
s=make_store(); now=date(2026,10,17)
assert s.query("path_base","projectA","v3",now)["value"]=="repo_root"
assert s.query("path_base","projectB","v3",now)["value"]=="workspace"
assert s.query("temporary","projectA","v3",now)["status"]=="not_found"
s.add(Memory("path_base","projectA","v3","config_dir",("D3",)))
assert s.query("path_base","projectA","v3",now)["status"]=="conflict"
try:
Memory("x","s","v","y",())
except ValueError:
pass
else:
raise AssertionError("无证据记录不能标为verified")
def run_demo() -> dict:
s=make_store(); now=date(2026,10,17)
before=s.query("path_base","projectA","v3",now)
s.add(Memory("path_base","projectA","v3","config_dir",("D3",)))
return {"性质":"固定教学日期;进程内存储;未连接真实用户记忆",
"正常检索":before,"加入冲突后":s.query("path_base","projectA","v3",now),
"过期条目":s.query("temporary","projectA","v3",now)}
if __name__ == "__main__":
import json
self_test()
print(json.dumps(run_demo(),ensure_ascii=False,indent=2))
运行结果示例
以下结果由随包脚本产生。它们不是LLM或产品性能数据。
{
"性质": "固定教学日期;进程内存储;未连接真实用户记忆",
"正常检索": {
"status": "usable",
"value": "repo_root",
"evidence": [
"D2",
"T2"
]
},
"加入冲突后": {
"status": "conflict",
"value": null,
"candidates": [
"config_dir",
"repo_root"
]
},
"过期条目": {
"status": "not_found",
"value": null,
"evidence": []
}
}