feat: 离线反思闭环 + 人设漂移守护(issue #41) #50
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/41-offline-reflection-persona-drift"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
这个 PR 做了什么
实现 issue #41「离线反思闭环 + 人设漂移守护」(ADR-0006/0021)。这是目前
Phase 4 里范围最大的一片,落地前先跟用户核实了三个 ADR 没钉死的关键实现
决策(见下)。
核实过的三个关键决策
连一张持久化的决策快照表都没有(只有
logger.debug)。排除了"零成本复用 Sent Log"(它现在没有 chat_id/时间戳/触发类型字段,字面意义上做
不到),也排除了"顺带把 ADR-0010 完整决策快照建起来"(工作量超出本
ticket 范围)。选择新建一张精简的"主动尝试记录"表(只服务反思:
chat_id + 发送时间 + Sent Log 句柄引用 + 发送时的 valence 快照),判定
完即删除,不是永久审计日志。
——判定"是否已回应"复用的
ReconnectCooldownState两段式状态目前只在这条路径上维护,tier-2 环境信号(issue #39)没有对应的"等回应"窗口
概念,暂不纳入。
inject_skills检索注入工具、不做三级渐进披露——检索侧留给真正需要消费它的后续 ticket(目前 issue 列表里没有)。
反坍缩机制(
proactivity_offset.py)不维护任何"命中率"比值/窗口计数器——每次结局都是独立、有界、不对称步长
的即时调整:
landed小步松弛(step_down),fell-flat/annoyed大步抬高安静倾向(
step_up,噪声坍缩是主风险,ceiling 承重)。无信号时只对"比基值话痨"的负值衰减回 0,不会主动把安静状态推向话痨,也不会因为"从不
尝试"本身被解读成"应该更安静"——用一组序列模拟直接验证两种退化解都被
目标函数本身挡住(
test_low_hit_rate_high_volume_ends_up_quieter_than_high_hit_rate_low_volume等测试),不是靠额外检测逻辑。
结局判定不读原始回复文本
Delta 缓冲会被 Delta 压缩周期自己的调度 drain 走,到反思批处理跑的时候
时序不可靠。改比较"发送时"与"判定时"两个时间点的快情感态 valence:明显
下降视为
annoyed,否则视为landed;距发送已久仍无回应直接判fell-flat(零 LLM,沉默本身自证结局)。共享结局分类器首次真正接线
Outcome(landed/fell-flat/annoyed)和update_fast_state/update_slow_user_state的outcome参数在 issue #34 就建好了,但从来没有真实生产调用方传过非
None的值。本 PR 是第一个真正驱动它的入口:dominance 快路(当轮)+ per-user 慢情感态.dominance(更慢路)都在反思
批处理判定结局的同一时刻更新。
人设漂移守护(
persona_drift_guard.py)独立 LLM-as-judge 调用——全新的 messages 列表,不承接产出候选那条推理链
(防"自我橡皮图章")。喂 persona port 完整结构化人设做二元判断,通过才
真正落库;判否/调用失败一律 fail-closed 丢弃候选,不影响其它候选的判断
结果(画像候选和技能候选各自独立过一次)。管辖范围按 AC 明确要求扩到
Delta 既有的 Knowledge 写入路径——
run_delta_compression_cycle新增可选persona参数,缺省None时行为与之前完全一致(不接入否决闸,已有测试套件零改动),真实生产(
__init__.py)恒传入。技能(
skill.py,写入侧)Qdrant 直接当唯一落盘位置,不建 Postgres 表(技能"本来就活在 Qdrant
里")。查重合并复用 Knowledge 的确定性合并策略(新内容不是已有内容的
子串才拼接),只是匹配信号从关键词交集换成向量相似度。
新增/改动文件
proactive_attempt.py(待判定队列)、proactivity_offset.py(反坍缩机制)、
skill.py(写入侧存储)、persona_drift_guard.py(否决闸)、
reflection.py(LLM 提取 + 批处理编排)gating.py:evaluate_gate新增proactivity_offset参数,叠加在情感态基值之上
delta.py:run_delta_compression_cycle新增可选persona参数storage.py/sent_log.py:三张新表/结构(arise_proactive_attempt/arise_proactivity_offset+ Qdrantarise_skillcollection)的内存版__init__.py:Drive Tick 发送成功后记录主动尝试;新增arise_reflection调度任务;_evaluate_unified_gate现读现衰减offset 传给
evaluate_gateconfig.py:新增反思/offset/技能相关的静态阈值配置测试
新增 9 个测试文件,覆盖纯函数(含反坍缩性质测试)、存储契约(内存版 +
持久化版共用测试)、独立判断调用(含调用失败 fail-closed)、完整批处理
编排(12 个场景:awaiting 跳过、cold/replied 两条结局分支、offset 方向、
dominance 更新、候选落库/丢弃、LLM 失败仍不阻塞核心机制、多尝试并发处理)
全部 751 个测试通过,
ty check/ruff check干净。