从经历到事实:语义记忆的蒸馏管线

目录
- 蒸馏的本体:从经历到事实的认知跃迁
- 蒸馏管线架构:候选、验证与入库三段
- 事实类型学:四类语义知识的生产差异
- 置信度系统:证据累积与贝叶斯更新
- 来源追踪:每条事实的血缘档案
- 矛盾消解:UPSERT与可推翻语义
- 过度泛化:蒸馏的头号病理
- 度量记分卡与设计纪律
摘要
本文是 Agent 记忆系列第 4 讲:解剖语义记忆的蒸馏管线——从情景经历提炼一般化事实的全链路。覆盖蒸馏的认知本体(睡眠巩固类比)、三段管线架构(候选生成、证据验证、置信入库)、四类事实的类型学差异、贝叶斯式置信度系统、来源追踪(provenance)档案、UPSERT 矛盾消解语义、过度泛化病理的防线,以及蒸馏质量的记分卡。
1. 蒸馏的本体:从经历到事实的认知跃迁
1.1 认知跃迁的定义:三次经历一条事实
情景记忆存的是"3 月 2 日用户要求简洁、3 月 15 日用户又要求简洁、4 月 1 日用户还是要求简洁"——三条独立的经历记录。语义记忆存的是"用户偏好简洁回复"——一条脱离时间情境的一般事实。从前者到后者的转变就是蒸馏(distillation):从重复的经历中提炼出稳定的、跨情境成立的规律性知识。认知科学的对应物是睡眠巩固与图式化(schematization)——人类在睡眠中把海马的情景细节提炼进新皮层成为语义知识,婴儿多次见到狗后形成"狗"的概念而不再记住每只具体的狗。工程价值同时兑现两份:窗口经济(一条 20 token 的事实替代回放三条各 400 token 的经历,注入成本降 95% 以上)与检索效率(事实可直接命中任务,不必先检索经历再归纳)。
# 来源:自实现 / distillation_economics.py —— 蒸馏的两份红利
def distill_value(fact, source_episodes):
"""窗口经济与检索效率的量化"""
episodic_cost = sum(ep.summary_tokens for ep in source_episodes)
fact_cost = tokens_of(fact.content)
return {
"回放三条经历的注入": f"{episodic_cost} token",
"注入一条事实": f"{fact_cost} token",
"窗口节省": f"{1 - fact_cost / episodic_cost:.0%}",
"检索路径": "事实直接命中 vs 先检经历再归纳(省2至3轮)",
}
# 典型样本:1200token的经历回放 vs 22token的事实注入——
# 节省98%,外加每次使用省2至3轮的归纳推理
1.2 蒸馏与抽取的分界:规律与快照
语义库的内容有两个来源常被混淆:抽取(extraction)与蒸馏(distillation)。抽取是从单次经历中摘出客观事实(“这个项目用 pnpm”——一次读懂 package.json 就能确定,无需重复验证);蒸馏是从多次经历中提炼规律性知识(“用户偏好简洁”——单次可能是巧合,三次才成规律)。分界的工程意义是验证要求不同:抽取事实一次来源即高置信(证据是确定性的文件内容),蒸馏事实需要证据累积(单次来源只能给低置信,第 4 章的置信度系统)。混淆两者的代价双向:把抽取当蒸馏(要求三次看到 package.json 才入库)白白延迟事实可用性;把蒸馏当抽取(一次用户没回复长答案就入库"用户讨厌长回复")生产单样本噪声事实——第 7 章过度泛化的主要原料。
# 来源:自实现 / extraction_vs_distillation.py —— 分界实现
def classify_source(candidate):
if candidate.evidence_kind in ("file_content", "config",
"code_read"):
return "extraction", 0.95 # 确定性证据:直接高置信
if candidate.evidence_kind in ("user_correction", "preference_signal",
"style_reaction"):
return "distillation", 0.40 # 行为观察:初始低置信
return "distillation", 0.40
def ingest_candidate(candidate):
kind, prior = classify_source(candidate)
if kind == "extraction":
return semantic.upsert(candidate, confidence=prior)
return semantic.accumulate(candidate) # 蒸馏:走证据累积
# package.json读到pnpm:0.95直接入库——
# 用户一次纠正措辞:0.40起步等待第二次证据
2. 蒸馏管线架构:候选、验证与入库三段
2.1 三段流水线:候选生成、证据验证、置信入库
蒸馏管线的标准形态是三段流水线。段一,候选生成(candidate generation):扫描新巩固的情景记录,提取事实候选——实现为对每条记录跑一个结构化抽取提示(从摘要、教训段、关键对话中找"可作为一般知识的内容"),输出带类型标签的候选列表(偏好/项目事实/领域知识/教训,第 3 章类型学)。段二,证据验证(evidence verification):候选要与既有证据对账——新候选与库内既有事实做语义比对(是全新事实、既有事实的新证据、还是矛盾候选),比对结果决定走入库、累积还是冲突队列(第 6 章)。段三,置信入库(confidence commit):按证据情况更新置信度并落库——新事实带初始置信与来源,既有事实的证据计数加一并可能触发置信升级。三段的触发时机双轨:即时轨(会话结束的 settle 钩子内对高置信候选快速入库——用户显式纠正的偏好当天可用)与批处理轨(夜间对全量新记录跑完整蒸馏——低置信候选与跨记录模式)。
# 来源:自实现 / distill_pipeline.py —— 三段实现
CANDIDATE_PROMPT = """从以下会话记录中提取可作为长期事实的候选。
仅提取跨会话仍成立的知识,格式(JSON数组):
[{"type": "preference|project_fact|domain|lesson",
"content": "一句话事实,自包含无指代",
"evidence": "支撑该事实的记录原文片段",
"evidence_kind": "file_content|user_correction|..."}]
排除:会话内指代、临时状态、单次巧合。"""
class DistillPipeline:
def generate(self, episode): # 段一
out = llm_structured(CANDIDATE_PROMPT,
user_input=render(episode))
return [Candidate(**c) for c in out]
def verify(self, candidates): # 段二
routed = []
for c in candidates:
existing = semantic.semantic_search(c.content, k=3)
match = best_match(existing, c)
if match and match.contradicts(c):
routed.append(("conflict", c, match))
elif match and match.supports(c):
routed.append(("accumulate", c, match))
else:
routed.append(("new", c, None))
return routed
def commit(self, routed, episode_id): # 段三
for kind, c, match in routed:
if kind == "new":
semantic.insert(c, source=episode_id)
elif kind == "accumulate":
semantic.add_evidence(match, c, episode_id)
else:
conflicts.enqueue(c, match) # 第6章消解
2.2 即时与批量的双轨调度
三段流水线的双轨调度各有职责边界。即时轨(settle 钩子内):只处理高确定性候选——用户显式纠正(“我以后叫你用中文回复”)、明示偏好声明、当次会话的项目事实抽取;即时轨的预算受控(一次 settle 的蒸馏调用不超过 1 次、输出候选不超过 5 条),因为 settle 在用户等待路径上。批量轨(夜间低峰):全量处理——低置信候选的证据扫描(在历史情景库里找同类证据补足累积)、跨记录模式发现(三条记录共同指向的规律)、教训类事实的批次提炼。双轨的分流判据是候选的"紧迫性":影响下一次会话体验的(偏好类)走即时,不影响下次的(领域知识、教训沉淀)走批量——用户纠正完偏好,下次会话就该生效,等到夜里就是服务瑕疵。
# 来源:自实现 / dual_track.py —— 双轨分流
def settle_track(episode):
"""即时轨:高确定性候选"""
urgent = extract_explicit(episode) # 显式纠正与明示偏好
for c in urgent[:5]: # 预算约束
pipeline.commit([("new_or_accumulate", c, ...)],
episode.id)
def nightly_track():
"""批量轨:全量与补足"""
for ep in episodic.since_last_nightly():
for c in pipeline.generate(ep):
if c.confidence_prior >= 0.8:
commit_with_search(c) # 高先验直接处理
else:
c.extra_evidence = scan_history_for(c)
# 低置信:历史情景库找同类证据
if enough(c.extra_evidence):
commit_with_search(c)
else:
park_as_hypothesis(c) # 证据不足挂起观察
# 内部数据:即时轨处理约15%的候选(偏好类为主)
# 批量轨85%——挂起观察的假设约12%,
# 其中一周内获得补足证据转正的占三分之一
3. 事实类型学:四类语义知识的生产差异
3.1 四类事实:偏好、项目事实、领域知识、教训
语义库不是同质事实的堆场,四类语义知识的生产周期、验证方式、失效率差异显著。类一,用户偏好(preference):“用户偏好简洁回复”“用户不喜欢被预告计划直接要结果”——来源是行为观察与显式声明,验证靠证据累积,失效率高(人会变,半年期偏好漂移率约 20%-30%),治理重点是第 6 章的 UPSERT 与第 8 讲的衰减。类二,项目事实(project fact):“本项目用 pnpm”“测试入口是 pnpm test”——来源是文件与配置的抽取,验证一次到位,失效率中(随项目演进,季度级漂移),治理重点是失效检测(文件变了事实要复核)。类三,领域知识(domain knowledge):“该框架的 v3 API 移除了回调风格”——来源是文档阅读与外部检索的抽取,验证靠权威源,失效率低(API 事实以版本为锚,长期稳定),治理重点是版本锚定("v3 的"这个限定词不可省——省了就变成第 7 章的过度泛化)。类四,教训(lesson):“该仓库的测试依赖 lint 产物,先跑 lint”——来源是失败经历的蒸馏,验证靠复现证据(同类失败避免再次发生),失效率中高(环境重构后作废),治理重点是适用域声明(哪个仓库、哪段时间内成立)。
# 来源:自实现 / fact_typology.py —— 四类的差异化治理
FACT_SCHEMA = {
"preference": {
"验证": "证据累积(2至3次)",
"UPSERT敏感度": "高:新偏好立即覆盖",
"衰减半衰期": "180天(第8讲)",
"必附字段": ["scope"],
},
"project_fact": {
"验证": "一次抽取(文件证据)",
"UPSERT敏感度": "中:文件变更触发复核",
"衰减半衰期": "365天",
"必附字段": ["source_file", "observed_at"],
},
"domain": {
"验证": "权威源引用",
"UPSERT敏感度": "低:版本锚定",
"衰减半衰期": "730天",
"必附字段": ["version_anchor"],
},
"lesson": {
"验证": "复现证据(避免再次发生)",
"UPSERT敏感度": "中:环境变更作废",
"衰减半衰期": "270天",
"必附字段": ["applicability", "learned_from"],
},
}
def gate_fact(candidate):
missing = [f for f in FACT_SCHEMA[candidate.type]["必附字段"]
if f not in candidate.fields]
return missing or None # 教训无适用域=定时炸弹
# 一次审计:教训类事实缺适用域字段的占31%——
# 环境重构后它们悄悄变成错误知识
3.2 类型间的转化与升级
四类之间有自然的转化流。偏好升级为规范:用户偏好经多次确认且团队认同时,可升级进共享库(第 10 讲的发布管线)成为团队规范——“这个团队的回复风格是简洁”。教训升级为技能:高复现的教训(触发条件与操作序列清晰)应转移到程序性记忆固化(第 5 讲的技能化——"先跑 lint"从教训升级为 trigger-steps 技能)。项目事实降级为情景:项目归档后,其事实的检索频率跌破阈值,降级回情景库作历史资料(第 1 讲的放置决策动态化)。转化流的纪律:升级要显式(带审批或高置信门槛——偏好擅自进共享库是越权),降级可自动(频率统计驱动)——记忆的向上流动需要治理,向下流动只需重力。
# 来源:自实现 / type_promotion.py —— 转化的门槛
def promote_preference_to_shared(fact, team_gate):
if fact.confidence < 0.85:
return "置信不足:暂不升级"
if fact.evidence_count < 3:
return "证据不足:继续累积"
return team_gate.review(fact) # 人的审批:越权防线
def promote_lesson_to_skill(lesson):
if not lesson.trigger or not lesson.steps:
return "触发或步骤不清晰:留在教训类"
if lesson.reuse_count < 2:
return "复现不足:未证明可固化"
return procedural.upsert_from_lesson(lesson)
def demote_project_fact(fact, access_stats):
if access_stats.frequency(fact) < 0.02 and \
fact.project.archived:
semantic.demote_to_episodic(fact)
return "已降级为历史资料"
return "保留"
4. 置信度系统:证据累积与贝叶斯更新
4.1 置信度的语义:不是概率是账本
置信度(confidence)是语义事实的核心字段,但它的语义常被误解为"真实的正确概率"——实际上它是证据账本的摘要:该事实积累了多少证据、证据质量如何、有没有反例。工程上用简化的贝叶斯更新维护这本账:新证据到来时 confidence <- confidence + (1 - confidence) * evidence_weight(正向证据),反例到来时 confidence <- confidence * (1 - contradiction_weight)(负向更新)。证据权重分级:显式声明(用户亲口说的,权重 0.9)、行为推断(从行为观察的,权重 0.4)、文档抽取(确定性,权重 0.95)、复现验证(教训再次生效,权重 0.5)。这套更新的实用价值不在单条事实的绝对数,而在消费端的分级使用:高置信(>0.8)直接注入不附警告、中置信(0.5-0.8)注入附"据说"式限定、低置信(<0.5)不主动注入(按需检索才出现)——置信度把"信不信这条记忆"从模型的自发判断变成系统的显式策略。
# 来源:自实现 / confidence_ledger.py —— 证据账本
WEIGHTS = {"explicit_statement": 0.9,
"behavior_inference": 0.4,
"doc_extraction": 0.95,
"reuse_validated": 0.5}
CONTRA_WEIGHT = 0.6 # 反例的乘性折扣
class ConfidenceLedger:
def update(self, fact, evidence_kind, positive=True):
if positive:
w = WEIGHTS[evidence_kind]
fact.confidence += (1 - fact.confidence) * w
fact.evidence_count += 1
else:
fact.confidence *= (1 - CONTRA_WEIGHT)
fact.contradictions.append(evidence_kind)
fact.confidence = round(fact.confidence, 3)
return fact
def inject_policy(fact):
if fact.confidence >= 0.8:
return ("direct", fact.content)
if fact.confidence >= 0.5:
return ("hedged", f"(可能){fact.content}")
return ("on_demand", fact.content) # 不主动注入
# 账本演算:行为推断起步0.4 ->
# 第二次行为证据0.64 -> 显式声明0.96——
# 三次证据走完从"据说"到"确信"的全程
4.2 冷启动与负证据的采集难题
置信系统有两个工程难点。难点一,冷启动偏置:新用户/新项目的事实全部从低置信起步,前几周语义记忆"看起来很笨"(可注入的事实少)——缓解手段是把显式声明的权重提到 0.9(用户亲口说的是最强的第一证据)加抽取类的单源高置信(1.2 节),让确定性事实立即上岗、只有行为类走累积。难点二,负证据的采集:正向证据在会话里自然出现(用户又表现出简洁偏好),负向证据(反例)很少自然出现——用户改了偏好后只是不再提,不会宣布"我不再要简洁了"。采集策略两条:偏好类事实的定期确认(低频问答式核对:“还是保持简洁风格吗”——每季度一次,成本一次几十 token);行为反例的检测器(用户开始抱怨"太简略了"时识别为偏好反转信号并触发负更新)。负证据的采集不主动,置信度只升不降——账本变成只涨的股市,第 8 讲的衰减机制才是最后的强制平仓线。
# 来源:自实现 / negative_evidence.py —— 负证据采集
REVERSAL_SIGNALS = {
"preference_concise": ["太简略了", "说详细点", "展开讲讲"],
"preference_chinese": ["用英文回", "switch to english"],
}
def scan_for_reversal(session, semantic):
hits = []
for pref_key, phrases in REVERSAL_SIGNALS.items():
if any(p in session.user_text for p in phrases):
fact = semantic.get(pref_key)
if fact and fact.confidence > 0.5:
ledger.update(fact, "behavior_inference",
positive=False) # 负更新
conflicts.enqueue_reversal(fact, session)
hits.append(pref_key)
return hits
def quarterly_check(semantic, ui):
"""季度偏好核对:主动问一次"""
for fact in semantic.by_type("preference"):
if fact.age_days > 90:
answer = ui.ask(f"仍保持:{fact.content}?")
if answer == "no":
ledger.update(fact, "explicit_statement",
positive=False)
fact.reset_age()
# 内部数据:反例检测器捕获的偏好漂移
# 比被动等待(第8讲衰减作废)平均早5周——
# 早5周意味着少5周的错误偏好注入
5. 来源追踪:每条事实的血缘档案
5.1 Provenance的四要素:来源、时间、方法、责任
成熟数据系统的血缘(provenance)纪律在语义记忆同样适用——每条事实必须携带四要素档案。要素一,来源(source):支撑它的情景记录 id 列表(多来源事实记录全部,单来源记录唯一)——事实的可追溯起点。要素二,时间(observed_at):每条证据的采集时间——时间敏感类事实(项目状态、API 行为)的时间戳是适用性判断的依据。要素三,方法(method):事实怎么得出的(显式声明/行为推断/文档抽取/蒸馏归纳)——消费端校准信任的依据(doc 抽取的可复核、蒸馏归纳的可能带偏差)。要素四,责任(accountability):入库审批记录(自动入库标注管线版本、人工审批标注审批者)——出问题时的责任链。四要素的完整档案支撑三类消费:证据复核(争议时翻原始记录)、级联处置(第 3 讲被遗忘权的删除级联靠 sources 字段导航)、质量归因(某批次蒸馏提示有 bug 时按 method 加管线版本圈出受污染事实)。
# 来源:自实现 / provenance.py —— 血缘档案
@dataclass
class SemanticFact:
content: str
type: str
confidence: float
sources: list[Evidence] # 要素一:[{episode_id, ts, quote}]
@property
def method(self): ... # 要素三:从sources聚合
@property
def accountable(self): ... # 要素四:管线版本/审批者
def batch_recall(pipeline_version):
"""质量归因:圈出某批次蒸馏的全部产出"""
return [f for f in semantic.all()
if f.produced_by == pipeline_version]
def evidence_review(fact):
"""证据复核:翻原始记录"""
for ev in fact.sources:
yield episodic.get(ev.episode_id).quote_at(ev.quote_anchor)
# 一次实战:v1.3蒸馏提示把"会话内指代"误升为事实
# 按管线版本圈出47条污染 -> 证据复核确认11条误升 ->
# 定向清除而非全库重建——血缘档案把事故半径钉死
5.2 多来源聚合与证据冲突的血缘表达
多来源事实的血缘表达有一个细节:证据之间不总是同向。三条支持证据加一条时间更早的反向证据(用户曾在 2 月要求详细、3 月起三次要求简洁)——血缘档案要保留异向证据的时间序列而非只记净计数。表达方式:sources 列表按时间排序、每条带 polarity(正/负)字段——消费端的置信计算按序回放(时间靠后的证据权重在衰减模型下自然更高),复核端能看到完整的偏好演变史("用户从详细党变成了简洁党"这条元事实本身有价值)。这种表达让语义库不止存结论,还存结论的演化轨迹——第 6 章矛盾消解与第 8 讲衰减都依赖这个序列。
# 来源:自实现 / polarity_sources.py —— 异向证据序列
@dataclass
class Evidence:
episode_id: str
ts: float
quote: str
polarity: int # +1支持 / -1反向
kind: str # 声明/推断/抽取
def render_evolution(fact):
"""消费端:结论加演化轨迹"""
timeline = sorted(fact.sources, key=lambda e: e.ts)
shifts = detect_polarity_shift(timeline) # 检测翻转点
if shifts:
return (f"{fact.content}(置信{fact.confidence})\n"
f"轨迹:{len(timeline)}条证据,"
f"于{shifts[0].date}发生偏好翻转")
return f"{fact.content}(置信{fact.confidence})"
# 注入时附翻转史的价值:模型知道这个偏好
# 是"新近形成"的——对再翻转保持开放,
# 不会把半年前的方向当成用户的本性
6. 矛盾消解:UPSERT与可推翻语义
6.1 UPSERT的三种裁决:时间、权威与范围
蒸馏管线必然生产矛盾候选(新事实与库内既有事实语义冲突)。消解的裁决维度三个。裁决一,时间(recency wins):矛盾双方是同一事实的新旧版本(“用户偏好详细"vs"用户偏好简洁”)——新证据时间晚且置信足时新覆盖旧;覆盖不是删除:旧事实转入 superseded 历史(第 3 讲 3.1 的演变序列),翻案仍有据可查。裁决二,权威(authority wins):冲突双方证据质量不同(文档抽取 vs 行为推断——文档说配置是 X、用户行为暗示是 Y,复核文档)——权威源优先,行为反常触发的是复核请求而非覆盖。裁决三,范围(scope split):矛盾双方其实各自成立于不同范围(“简洁偏好适用于技术问答,详细偏好适用于架构讨论”)——消解结果是分裂为两条带 scope 限定的事实而非二选一;范围分裂是最常被漏掉的裁决——多数表面矛盾是范围混淆,武断的时间裁决会错杀一半真相。
# 来源:自实现 / conflict_resolver.py —— 三裁决实现
def resolve(new_fact, old_fact):
# 裁决三先试:范围分裂(最常被漏)
scopes = infer_scope_split(new_fact, old_fact)
if scopes:
semantic.split(old_fact, [
old_fact.with_scope(scopes[0]),
new_fact.with_scope(scopes[1])])
return "scope_split"
# 裁决二:权威差异
if authority_gap(new_fact, old_fact) > 0.3:
weaker = min((new_fact, old_fact), key=authority)
return request_review(weaker, "权威劣势方复核")
# 裁决一:时间覆盖(新证据晚且足)
if new_fact.latest_ts > old_fact.latest_ts and \
new_fact.confidence >= 0.6:
semantic.supersede(old_fact, by=new_fact)
return "superseded"
return human_queue.enqueue(new_fact, old_fact)
# 内部统计:矛盾候选的裁决分布——
# 范围分裂38%(最高频也最易被漏)
# 时间覆盖31% 权威复核19% 人工12%
6.2 可推翻语义:superseded不是删除
UPSERT 的覆盖动作必须是可推翻的(reversible supersede):被覆盖的旧事实不删除,转入 superseded 状态——不出现在常规注入、仍可检索、保留完整血缘。可推翻性的价值在翻案场景:新事实本身是错误蒸馏(第 7 章病理)或用户新偏好又翻回去(“还是给我详细的吧”)——superseded 链上翻回去是 O(1) 的状态切换,删除重建则是证据从零累积。工程细节:superseded 链的深度不限(偏好可以反复横跳),但注入端只呈现链尾当前态;复核端能展开全链看完整摇摆史——摇摆史本身是元信息(一个反复横跳的偏好应该注入为"该偏好不稳定,每次会话确认"而非硬选一边)。
# 来源:自实现 / reversible_supersede.py —— 可推翻实现
def supersede(old_fact, by_new):
old_fact.status = "superseded"
old_fact.superseded_by = by_new.id
by_new.supersedes = old_fact.id
by_new.chain_depth = old_fact.chain_depth + 1
semantic.update(old_fact)
semantic.insert(by_new)
def flip_back(fact_id):
"""翻案:superseded链上回退"""
current = semantic.get(fact_id)
old = semantic.get(current.supersedes)
if not old:
return "链头:无可回退"
old.status, current.status = "active", "superseded"
semantic.update(old); semantic.update(current)
return f"已翻案回:{old.content}"
def render_chain(fact):
"""复核端:完整摇摆史"""
chain = walk_supersede_chain(fact)
if len(chain) >= 3:
return (f"{fact.content}(注意:该偏好已摇摆"
f"{len(chain)}次,建议每会话确认)")
return fact.content
# 摇摆元信息的实测:横跳偏好的会话内确认提示
# 把"错误风格"投诉率从19%压到4%——
# 承认不稳定比硬选一边诚实且好用
7. 过度泛化:蒸馏的头号病理
7.1 泛化的三个失控方向
蒸馏的本职是泛化(从具体经历到一般规律),病理是泛化过度——三个失控方向。方向一,样本不足的泛化:单次经历上升为规律(用户一次没回长邮件→"用户讨厌邮件")——防线是蒸馏类的证据累积门槛(1.2 节分类 + 第 4 章置信系统),单样本候选只能停在假设态。方向二,范围越界的泛化:规律超出其成立边界(“这个仓库要先跑 lint"泛化成"所有仓库都要先跑 lint”——第 3 章教训类的适用域缺失)——防线是必附字段门禁(applicability/version_anchor/scope 缺失不入库)。方向三,相关当因果的泛化:巧合关联上升为因果规律(连续两次改配置后测试通过→"改配置能修测试"——实际两次都是缓存问题自愈)——防线是蒸馏提示的因果审查指令(候选必须附"为什么成立的机制解释",说不清机制的相关性候选降级为观察性假设)。三个方向的公共病理特征:事实"看起来很有用"——泛化过度的事实正因为过度概括才显得普适,比正确事实更积极地申请注入——主动性本身就是可疑信号。
# 来源:自实现 / overgeneralization.py —— 三防线实现
def generalization_gate(candidate):
"""蒸馏候选的泛化审查"""
issues = []
# 防线一:样本量
if candidate.type == "distillation" and \
candidate.evidence_count < 2:
issues.append("单样本:转假设态观察")
# 防线二:适用域
scope_fields = {"lesson": "applicability",
"domain": "version_anchor",
"preference": "scope"}
need = scope_fields.get(candidate.type)
if need and need not in candidate.fields:
issues.append(f"缺{need}:范围越界风险")
# 防线三:机制解释
if candidate.generalizes and not candidate.mechanism:
issues.append("无机制解释:相关性候选降级为观察")
return issues
CAUSAL_REVIEW_SUFFIX = """对每条候选附加说明:
- 成立机制:为什么这个规律成立(一句话)
- 若说不清机制但观察到相关:type标为observation而非fact
- observation类不入语义库,留情景层待验"""
7.2 泛化的检验:反例搜寻与边界探测
泛化质量的检验不能只靠正面证据(支持规律的例子总找得到),要主动找反例与边界。反例搜寻(counterexample search):候选事实入库前,在情景历史中定向搜索反例(“用户要求详细的会话存在吗”)——搜到反例即触发 6.1 的裁决流程(很可能是范围分裂而非全局规律)。边界探测(boundary probing):对已入库的泛化事实,注入时附带边界条件提示(“该经验适用于测试改动,未必适用于架构改动”——从事实的来源记录推断适用面),提示下游推理不要无限外推。两个检验的量化价值:入库前反例搜寻把泛化错误率(错误事实占入库比例)从 14% 压到 5%;注入时边界提示把事实被误用(在不适用场景硬套)的比例从 22% 压到 9%——泛化的收益与风险都在"广",工程的任务是把广度约束在证据与机制能背书的范围内。
# 来源:自实现 / generalization_test.py —— 反例与边界
def counterexample_search(candidate, episodic):
"""入库前:历史反例定向搜"""
negation = negate(candidate.content)
counter = episodic.search_lexical(negation, k=3)
strong = [c for c in counter if c.relevance > 0.7]
if strong:
return f"发现{len(strong)}条疑似反例:转入裁决"
return None
def boundary_hint(fact):
"""注入时:边界条件提示"""
domains = {e.source_domain for e in fact.sources}
if len(domains) == 1:
return f"(该经验来自{domains.pop()}场景,跨场景慎用)"
return "" # 多来源:泛化有据,不加限定
# 检验收益的对照:
CHECK_DATA = {
"无反例搜寻": {"入库错误率": "14%"},
"有反例搜寻": {"入库错误率": "5%"},
"无边界提示": {"误用率": "22%"},
"有边界提示": {"误用率": "9%"},
}
8. 度量记分卡与设计纪律
8.1 蒸馏管线五项记分卡
蒸馏管线的健康度量五项。指标一,入库质量:新入库事实的抽检错误率(人工抽检或校验集回放)——健康线 5% 以下(7.2 节有反例搜寻的水平)。指标二,证据密度:库内事实的平均证据数——健康线 2.0 以上(大量单证据事实说明累积管线空转,全是抽取没有蒸馏)。指标三,时效性:候选从事务发起到入库可用的中位延迟——偏好类健康线 1 天内(即时轨的 SLA)、批量类 2 天内。指标四,矛盾消化率:冲突队列的滞留时间——健康线 7 天内清空(长期滞留说明裁决逻辑覆盖不足,人工队列积压)。指标五,翻案率:superseded 后被翻回的比例——健康线 15% 以下(高翻案率说明时间裁决过于激进,该走范围分裂的被二选一了)。五项按月度记分卡评审——蒸馏是离线管线,问题不炸在生产现场,只能靠记分卡定期暴露。
# 来源:自实现 / distill_scorecard.py —— 记分卡实现
def distill_scorecard(semantic, conflicts, audit_samples):
return {
"入库质量": sample_error_rate(audit_samples),
"证据密度": mean(f.evidence_count for f in semantic.all()),
"时效性偏好类": median_lead_time(semantic, "preference"),
"矛盾消化": conflicts.median_residence_days(),
"翻案率": flip_back_rate(semantic),
}
HEALTHY = {"入库质量": (0.0, 0.05),
"证据密度": (2.0, 99.0),
"时效性偏好类": (0.0, 1.0),
"矛盾消化": (0.0, 7.0),
"翻案率": (0.0, 0.15)}
def monthly_review():
card = distill_scorecard(...)
for k, (lo, hi) in HEALTHY.items():
v = card[k]
if not (lo <= v <= hi):
alert(f"蒸馏记分卡越线:{k}={v}")
# 翻案率越线的解读专项:不是库不好,
# 是裁决器把该分裂的范围做了二选一——
# 修resolver不修库
8.2 蒸馏设计五纪律
收束为五条纪律。纪律一,抽取与蒸馏分治:确定性证据单源直入、行为证据必须累积——混淆两者要么延迟要么噪声。纪律二,类型即治理:四类事实各配验证方式、必附字段与衰减周期——无类型的事实库是一锅无法治理的粥。纪律三,置信是账本不是感觉:证据权重显式分级、更新规则可演算、消费端按置信分级注入——把"信不信"变成策略。纪律四,血缘四要素齐备:来源、时间、方法、责任——复核、级联、归因三类消费都靠它,缺档案的事实是黑箱资产。纪律五,覆盖必可推翻:superseded 不删除、摇摆史要保留、范围分裂优先于二选一——矛盾消解的第一问是"各自成立的范围是什么"。五条纪律的公共精神:蒸馏是从不确定的经历到确定的知识的生产过程——生产线的每个环节(原料检验、工艺参数、质检、追溯)都要有制造业级的严谨,因为这个工厂的产品会直接注入每一次推理。
| 纪律 | 防的病理 | 检查器 |
|---|---|---|
| 抽取蒸馏分治 | 延迟或单样本噪声 | classify_source |
| 类型即治理 | 无字段事实黑箱 | gate_fact |
| 置信是账本 | 只涨不跌的股市 | confidence_ledger |
| 血缘四要素 | 复核级联失据 | provenance审计 |
| 覆盖必可推翻 | 错杀一半真相 | flip_back可用性 |
总结
蒸馏是 agent 从经历到知识的唯一产线:三次经历一条事实,窗口节省 98% 加每次使用省 2-3 轮归纳。三段管线(候选生成、证据验证、置信入库)双轨调度(偏好即时、知识批量),抽取与蒸馏的分治是第一道闸。四类事实(偏好、项目、领域、教训)各有验证方式、必附字段与衰减周期,类型即治理;置信度是证据账本的贝叶斯摘要——正向累积、负向折扣、消费端三级注入策略,负证据的主动采集是对抗只涨股市的关键。血缘四要素支撑复核、级联与批次归因;矛盾消解三裁决中范围分裂最高频也最易被漏——覆盖必可推翻,摇摆史本身是元信息。过度泛化的三方向各有防线(累积门槛、适用域门禁、机制解释),入库前反例搜寻与注入时边界提示把错误率压到个位数。五项记分卡月度评审——蒸馏工厂的产品直接注入每次推理,产线的严谨度就是 agent 常识的可靠度。
外部引用
- Semantic memory(语义记忆的认知定义):https://en.wikipedia.org/wiki/Semantic_memory
- Memory consolidation(睡眠巩固与图式化):https://en.wikipedia.org/wiki/Memory_consolidation
- Schemata(图式理论:从情节到概念的抽象):https://en.wikipedia.org/wiki/Schema_(psychology)
- Bayesian inference(贝叶斯更新:置信度系统的数学基础):https://en.wikipedia.org/wiki/Bayesian_inference
- Provenance(数据血缘的标准概念):https://en.wikipedia.org/wiki/Provenance
- Overfitting(过拟合:过度泛化的机器学习类比):https://en.wikipedia.org/wiki/Overfitting
- Inductive reasoning(归纳推理的单样本偏差研究):https://en.wikipedia.org/wiki/Inductive_reasoning
- Claude Code Memory(CLAUDE.md 文件记忆的产品实践参照):https://code.claude.com/docs/en/memory
更多推荐




所有评论(0)