记忆深度搜索:search_memory 核心工具 #74
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feature/69-search-memory"
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?
Closes #69
What
新增模型可主动调用的 core 原生工具
search_memory(query),补齐 arise 三块注入里缺失的 L3(无限深度语义搜索,ADR-0031)——冻结快照只在会话起始算一次 top-K 就冻结、触发注入只认关键词精确匹配,用户提模糊回指("还记得我们聊过的那个想法吗")时模型此前没有任何主动深挖手段。实现要点
_recall_events抽出_scored_events(chat_id, query_text, *, limit)(embed → 向量检索 →is_event_visible兜底复核 → 四因子打分),两个消费入口只差候选池大小。recall.py零改动,_recall_events可观察行为逐行不变(同样的存储调用、同样的顺序与实参)。arise_search_candidate_pool(默认 20)与arise_recall_top_k(默认 5)并列。两者都做成 config 是有意的——"池子比常驻 top-K 宽"这条不变量牵涉两个数,只把其中一个做成可配的,运维调大 top_k 就会让工具静默退化成比快照还窄。context[2],工具结果只 append 在尾部,handler 不写任何存储,后续轮次重算的快照也捞不到它。MAX_QUERY_CHARS=200——模型真要违规裹挟上下文,精炼后的意图通常落在末尾。run_limit:ADR-0031 明确它是推理工具,不属send_message类豁免——刻意不加进RUN_LIMIT_EXEMPT_TOOL_NAMES。content+time+importance(ADR-0031 留实现期定):模型据此才能判断"这是半年前的事了"并在措辞上自然表达不确定性;刻意不回召回分数——那是内部权重调参的产物(ADR-0011"待标定"),暴露等于把不稳定的内部量纲写进对外契约。delegate_task/register_callback先例):它服务于回答用户追问而非自发行为,且天然自限——冷启动库里没事件就搜不到。Review
/code-review两轴(Standards + Spec)已跑,两轴都抓到真问题:test_a_sensitive_event_from_another_chat_is_not_searchable是空转的——SentLog.search_events自己就带同一条可见性过滤,事件在存储层就被滤掉,新增的"防御性冗余"那层根本没被触达;reviewer 把那层删掉,9 个测试照样全绿。改为用故意不过滤的假存储把泄漏事件直接喂进去,才真正锁住兜底层;另补一条反向测试防"什么都返回不了"式假通过。已变异复核:删掉过滤层,新测试确实挂。complete()的冻结快照逐字节相同(泄漏真要发生正是在第二次调用的下标 2 上)。arise_recall_top_k构成半硬编码的不变量——挪进 config(见上)。> 3不对应任何配置的近重言式断言。Tests
全仓库 977 个测试通过(新增 20 个:
sanitize_query/render_search_hits纯函数、工具分发(查询→结果、空/缺失参数、超长截断落到 embedding 调用上)、run_limit 计入、不受 top-K 限制的核心差异点、prefix-cache 不泄漏、可见性兜底两向)。变异测试复核了三处守卫:候选池调成 3 挂 3 条;关掉截断分支挂 3 条;删掉可见性兜底过滤挂新写的那条(旧版不挂——这正是修它的原因)。