registry_upsert
Persists research records—sources, videos, insights, topics, protocols, clusters, rejections—into a staging registry, then commits them to the permanent asset library so findings and grades carry across tasks.
Instructions
写资产库。每次任务结束必须调用,否则"资产积累"是空话。
kind="source":{mid, name, domains[], grade(A–F), grade_basis, notes}
grade_basis 必须写依据,不写就等于没评级——半年后看到"A"也想不起为什么。
重复写入且评级变了,工具会自动追加一条 conflicts 记录。
kind="video":{bvid, title, mid, topics[], grade(如 A1/D4), redundancy(原创/冗余/冲突),
key_findings[], transcript_pulled(bool), verdict}
verdict 是一句话定性:这条在议题里是什么角色。
kind="insight":{section: "领域"|"信源"|"方法", text},需要同时给 topic。
这是"越用越好用"的真正来源:不是又一份报告,而是下次能直接用的判断。
写入标准只有一个——它对下一个议题有用吗?不会帮忙的就别写。
范例:
领域:「B站财经区的收益预期普遍锚在 8–10%,任何'提前退休'测算先查这个锚」
信源:「某 UP 的数据都是二手转述,引用前必须找他引的原报告」
方法:「热点词族会带入大量番剧分集,40 条候选里 12 条无效,需在阶段 0 预判」
kind="topic":{topic, core_questions[], searched_axes[], covered[], gaps[],
open_conflicts[], user_adopted[], next_entry}
议题档案——跨任务记忆 + 反馈闭环。user_adopted 记录用户在本议题上
采纳了哪些发现(等价于"你点了赞"),这样"下轮往哪深挖"就有外部信号。
kind="protocol":{topic, core_questions[], keyword_families[], include_criteria[],
exclude_criteria[], budget{}, known_assets[], run_funnel{}}
阶段 0 的检索协议落盘。写进 .registry/topics/<议题>/protocol.md
(+ protocol.sha256 版本账本 + run-<日期>.json 漏斗数字)。
报告 §五「检索范围与偏差声明」从这里读出来,不再手写。
升级规矩同 DSH 插件:你没改过就自动升级;改过就保留你那份、新版另存 protocol.md.new。
kind="cluster":{bvid, cluster(簇名), stance(一句话主张), member_rpids[],
evidence[]("<赞数>赞/<楼层>楼|<原文摘录>"), axis{prevalence,agreement,controversy}(可选)}
需要同时给 topic。这是「去黑箱化」的落点:
归簇由你做判断(代码不聚类),但结果必须落盘——否则半年后
看到报告里的「A 派占据评论区最高赞」,既不知道由哪几条评论支撑,
也无法判断换个模型会不会归出别的簇。
落盘位置 .registry/topics/<议题>/clusters.json,主键 (bvid, cluster)。
读回:registry_get(kind="clusters", topic="…")。
kind="rejected":{bvid, title, grade, reason, stage?},需要同时给 topic。
报告 §6.3 的淘汰清单必须走这条入库——只写在报告里,下一轮就排不掉,
会把同一批候选重新扫一遍、重新分诊一遍。读回:registry_get(kind="rejected", topic="…"),
返回里的 exclude_bvids 可直接喂给 scan_topic(exclude_bvids=...)。
kind="commit":收尾时调用一次,把暂存区合并进正式库;
同时自动打 run-end 并回传 final_cost.md_line(最终单轮开销,此后不变)。
⇒ 收尾顺序固定为:commit → 把 final_cost.md_line 贴进报告 §五 → 渲染。
kind="discard":丢弃暂存区(这轮白跑了,不要写进资产库)。
kind="run-start":阶段 0 结束时调用一次,在调用账本里打「本轮从这里开始」标记
(records 不用给)。零上游调用、零成本,但它是
registry_get(kind="cost", window="run") 能把这一轮与历史分开的唯一依据——
没有它,「这轮花了多少」就永远算不出来,报告 §五 只能写"跑了很久"。
返回里的 run 是这一轮的编号。
🔴 写侧闸门(批次 C1):上面所有 kind 默认只进暂存区
(.registry/staging/),正式库在你调用 kind="commit" 之前不会被改动。
这是 DSH 插件「能力最小化」范式的等价实现:写侧始终可用(不打断"边挖边记"),
但碰不到正式库。收尾时 kind="commit" 一次合并,可预览、可回滚。
想看暂存区里有什么:registry_get(kind="staging")。
⚠️ 写入边界会做入参归一化:MCP 客户端层实测会把记录里的数组压成
{"item": X}、把布尔转成字符串、把整数转成字符串。工具会在落盘前还原,
所以 topics/domains/key_findings 一定是字符串列表、transcript_pulled 一定是布尔。
形状还原不了的(例如 topics 传成数字)会直接报错而不是静默写坏数据。
⚠️ kind="insight" 会做指令注入拦截:命中注入特征的条目被拒写,
并在返回的 injection_rejected 里说明原因。经验库是跨任务读取的,
写进去等于把注入持久化。改写成不含祈使句的判断句即可重试。
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| kind | Yes | ||
| topic | No | ||
| records | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |