Skip to main content

lit-search

Runs an exhaustive time-windowed literature search over a research topic and delivers a quality-tiered DOI list plus a matching formatted reference list, with measurable recall (gold-set recall, PRISMA counts, citation-closure saturation). Use for systematic reviews / SLR, the literature-retrieval half of 开题报告 (the writing half is the research-proposal skill, which consumes this skill's dois.md / references), 挑战赛调研, or any "把某方向近 N 年文献检索全/理一遍/梳理一遍/查全" request. Builds the corpus — not for reading or summarizing the papers themselves, and not for writing the review text. Not for casual "find me a few papers" lookups.

Quellinformationen

Repository
luwill/research-skills
Letzte Quellaktivität
30. September 2026 um 15:57
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
858
Forks
99

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
100 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
lit-search
description
Runs an exhaustive time-windowed literature search over a research topic and delivers a quality-tiered DOI list plus a matching formatted reference list, with measurable recall (gold-set recall, PRISMA counts, citation-closure saturation). Use for systematic reviews / SLR, the literature-retrieval half of 开题报告 (the writing half is the research-proposal skill, which consumes this skill's dois.md / references), 挑战赛调研, or any "把某方向近 N 年文献检索全/理一遍/梳理一遍/查全" request. Builds the corpus — not for reading or summarizing the papers themselves, and not for writing the review text. Not for casual "find me a few papers" lookups.
# 时间窗受限的高召回文献检索 驱动 `literature-search/` 这条流水线。核心前提:**召回率不是提示词问题,是检索工程问题。** 反复 WebSearch 得到的是"相关度排序的前若干条",既不可复现,也无法说明漏了什么。 ## 工具位置与产物去向(第一步,别跳过) CLI 就装在**本 skill 目录里**(`src/litsearch/` + `pyproject.toml`)。 所有命令都要在这个目录下执行——它是 `uv` 找得到项目的地方: ```bash SKILL_DIR=~/.claude/skills/lit-search # 本 SKILL.md 所在目录 cd "$SKILL_DIR" && uv run lit --help # 跑不通就先跑一次 ./install.sh ``` `$LITSEARCH_HOME` 若已设置则优先用它(把工具装在别处的人靠这个覆盖)。 两处都找不到 `src/litsearch/cli.py` → **问用户,不要猜**。 > **产物必须写到用户的项目里,不是 skill 目录里。** > `--runs-root` 默认是相对路径 `runs/`,而命令的工作目录是 skill 目录—— > 不显式指定的话,几百 MB 的采集结果会堆进 `~/.claude/skills/lit-search/runs/`, > 用户既找不到,也想不到要去那里清理。**每一条命令都要带上绝对路径**: ```bash PROJ=/abs/path/to/用户的项目 # 开工前先跟用户确认这个位置 cd "$SKILL_DIR" && uv run lit harvest --topic "$PROJ/topics/<id>.yaml" \ --runs-root "$PROJ/runs" --depth standard ``` 协议 YAML 同理——写在用户项目的 `topics/` 下,不要写进 skill 目录。 本目录的 `examples/` 有两份真实协议(生物医学、纯 CS 各一份)可以照抄。 下文命令块为了可读省略了这两个路径参数,**实际执行时必须补上**。 ## 判断要不要用 **用**:系统综述、开题报告的文献检索部分、挑战赛调研——需要**说得清召回边界**的场合。 (开题报告的**写作**由 research-proposal skill 负责——它消费本 skill 的 `dois.md`/`references.bib`,不要在这里写正文。) **不用**:用户只想快速看几篇代表作。那种情况直接 WebSearch 更快,别拖他走完整条流水线。 ## 契约 **输入**:一句话研究主题 + 可选时间范围(不给就默认近 5 年)。 **输出**: | 文件 | 内容 | |---|---| | `dois.md` | 全量 DOI 清单,按质量层分节,每条带证据标记 | | `references.md` | 参考文献列表,顺序与 `dois.md` 一致 | | `references.bib` | BibTeX(`--bibtex`,需额外一遍抓取) | | `PRISMA.md` / `coverage_report.md` | 计数与召回率证据 | **全量交付,分层只决定顺序,不决定去留。** 两份参考文件,按需读,不要预先读: `references/topic-template.yaml`(写协议用)、 `references/evidence.md`(下面每条规则背后的实测数字,用户追问或排查时才需要)。 --- ## 阶段 0|写协议(这一步是模型的核心工作) 没有 `lit init` 命令——把主题变成协议需要判断力,不是代码。模板在 `references/topic-template.yaml`,复制到 `topics/<id>.yaml` 后按四步填。 **① 拆概念块。** 3–5 块,标出哪些 `required`。 > **第一个 required 块会成为无布尔检索能力源(CVF/OpenReview/Zenodo)的锚点短语。** > 把区分度最高的概念放第一位——通常是疾病/对象/材料。放成 "segmentation" 这类泛词, > 会把整届 CVPR(约 9,200 篇)拉回本地过滤。 **② 提名金标准——5–10 篇,DOI 必须先验证再写入。** `gold_set` 是整条流水线里唯一能**证伪**的东西。所以: ```bash curl -sI -o /dev/null -w "%{http_code}\n" -L "https://doi.org/<doi>" # 200 才许写进协议 ``` **走 doi.org,不要走 Crossref。** arXiv 的 `10.48550/arXiv.*` 注册在 DataCite, `api.crossref.org` 对它一律 404——用 Crossref 验证会把真实存在的预印本当成编造的 DOI 拒掉, 而 CS/AI 主题的金标准**几乎全是 arXiv**。 编一个格式合法但不存在的 DOI,代价不是"少一篇文献",是**验证链条整个失效**—— 你会看到 8/9 的召回,然后花半天排查一个根本不存在的漏检。 **数量不能凑合。** 少于 5 条时 `coverage_report.md` 会自己标注"证据偏弱": 3/3 和 9/9 印出来一模一样,但前者能证伪的检索缺陷少得多。 同时提名 1–2 篇**窗口外**的真实论文当 `out_of_window_controls`,验证日期过滤真的生效。 **③ 干跑校准量级。** ```bash uv run lit strategies --topic topics/<id>.yaml # 只看检索式,不发请求 uv run lit plan --topic topics/<id>.yaml # 各源预计命中数 ``` | 命中量级 | 判断 | 动作 | |---|---|---| | > 50,000 | 概念太宽 | 加 required 块,或收紧通配符 | | 200 – 20,000 | 合适 | 冻结 | | < 200 | 太窄 | 补同义词;检查英美拼写变体(ischemic/ischaemic) | **这是唯一允许调参的窗口。** 一旦开始采集,改术语会变更语义指纹,作废整轮。 **④ 领域判断。** 生物医学之外的主题(纯 CS / 工程 / 材料)要主动提醒用户**两件事**: 1. **摘要覆盖会下降。** 这条流水线对闭源出版商的摘要覆盖实质上是 PubMed 撑起来的 (实测 Elsevier 95.6%、Springer 80.4%,而 Crossref 上这些条目根本没有摘要)。 PubMed 用不上时初筛退化成只看标题。**Semantic Scholar 本该补这个位,但当前版本尚未实现** ——协议里写 `semantic_scholar: enabled` 会被丢弃(CLI 会红字提示)。不要向用户 声称补上了覆盖面。 2. **捕获-再捕获会结构性不可得。** 它需要 PubMed × OpenAlex 两个源同时在场。 关掉 PubMed 后,召回证据就**只剩金标准一个点位**——所以这类主题的 `gold_set` 更要提满 5–10 条。 --- ## 阶段 1–7|流水线 每一步跑完都要把数字念给用户听,不要静默推进。 先让用户选深度——**代价必须先于执行可见**: ```bash uv run lit depths # 三档的规模、耗时、成本对照 ``` | 档 | 源 | 滚雪球 | 规模 | 耗时 | API 成本 | |---|---|---|---|---|---| | `quick` | 主干四源 | 不跑 | ≤2,000 | ~10 min | $0.1–0.3 | | `standard`(默认) | 全源 | 1 轮 | 2k–8k | ~40 min | $0.3–1.2 | | `systematic` | 全源 | 至饱和 | 10k+ | 2–4 h | $3.4–10.4 | 三档的差别只在**跑多少源、滚几轮雪球**。判定规则、去重、时间窗、召回率证据 三档完全一致——**降档降的是覆盖面,不是严谨度**。 `systematic` 必须显式指定并等用户确认。 **`<run>` 从哪来**:`lit harvest` 跑完第一行会打印 run 目录,那就是它。 后续命令也接受 `<topic>/<run_id>`,或**只给协议里的 topic id 自动取最新一次**—— 后者最省事。忘了跑到哪一步用 `lit show <run>`。 ```bash # 1 采集 uv run lit harvest --topic topics/<id>.yaml --depth standard uv run lit proceedings <run> --topic ... # 仅 MICCAI/LNCS 类主题;语料里没有 LNCS 会自动跳过 # 2 筛选(三级放量,见下) uv run lit screen <run> --topic ... --limit 4 uv run lit screen <run> --topic ... --limit 100 uv run lit screen <run> --topic ... # 在 human_queue.csv 填 decision/reviewer/reason 后导回(可分批) uv run lit adjudicate <run> --topic ... --kind screening --input human_queue.csv # 在 boundary_cases.csv 填 decision/reviewer/reason 后导回 uv run lit adjudicate <run> --topic ... --kind date --input boundary_cases.csv # 3 引文闭包(必须在筛选之后) uv run lit snowball <run> --topic ... --seeds included uv run lit screen <run> --topic ... --resume # 只补新增记录,不重判已判过的 # 4 证据与报告 uv run lit validate <run> --topic ... uv run lit report <run> --topic ... uv run lit verify <run> --strict # 5 分层与交付(--ccf 可选,先问用户要目录路径) uv run lit rank <run> --ccf CCF.pdf --included uv run lit deliver <run> --topic ... --ccf CCF.pdf --style gbt7714 --bibtex ``` **滚雪球循环怎么收。** `snowball` → `screen --resume` → `snowball` → …,交替进行。 三种终止,只有第一种能宣称闭包完成: | CLI 打印 | 含义 | 动作 | |---|---|---| | 「已达饱和」 | 连续 2 轮新纳入 < 5% | 停,可以说闭包完成 | | 「没有新的合格种子」 | 自然枯竭 | 停,可以说闭包完成 | | 「已达最大轮数但尚未饱和」 | 撞上限了 | **不能说闭包完成**——要么加 `--max-rounds`,要么在报告里写明 | `--depth quick` 不跑滚雪球,`standard` 只滚 1 轮;要滚到饱和用 `systematic` 或显式 `--max-rounds`。**不要照全量重跑 `screen`**——那会把几千条已判定的再判一遍, 钱翻倍,还可能触发"新一轮判定数少于上一轮"的护栏而拒绝写入。 **补源不能靠续跑。** `harvest --resume` 只重跑上一轮未完成的检索式,它**没有能力** 覆盖一个从没跑过的源。先跑了 quick、之后想补顶会源,用: ```bash uv run lit harvest --topic ... --into <run> --phase stage3 --sources cvf,openreview,grey ``` ## 放量前必须先冒烟、再校准 不要直接对上万条跑筛选。三级放量,每级只花上一级十倍的钱,发现的却是完全不同的问题: - **`--limit 4`(约 $0.003)验 API 契约。** 假客户端测得了你的代码,测不了服务端约束。 实测就是在这一步撞到 `Thinking mode does not support this tool_choice`。 - **`--limit 100`(约 $0.02)验任务设计。** 两根轴都要看,缺一根都会放过问题: **成因**——大量 `unclear` 且理由雷同 = 把全文阶段的标准用在了标题摘要阶段, 该改**提示词**而不是改协议(改协议会变更语义指纹,挡住后续滚雪球并入)。 健康的队列应以"通道分歧"和"低置信度"为主。 **体量**——队列占比超过 **15%** 就要停下来改标准,不管成因分布多"健康"。 实测一次 4,000 条的运行队列率 24.6%(973 条),成因分布完全正常, 但 973 条**没有人会真去看**。`lit adjudicate` 能把裁定结果导回, 可它是给几十条用的;上千条时正确动作是回来改判定标准,不是把队列丢给用户。 在裁定导回之前,这些记录不进 `included`,也不进交付物。 - **放量。** 判定 API 后端同样三级:`--limit 4`(约 $0.0002)验服务端约束,`--limit 100` (约 $0.005)验任务设计,再放量。这一步不能省——**假客户端测得了你的代码, 测不了服务端,也测不了运行时**:十项 CLI 测试用 respx 全绿,真跑第一次就抛了 `Event loop is closed`(httpx 的连接池绑在创建它的事件循环上,而 respx 在传输层 拦截、根本不建真实连接)。 `--limit` 的结果写 `screening_trial.json` 和 `human_queue_trial.csv`(判定 API 则写 `jev_scores_trial.jsonl`),**不占正式轮次**——否则一次校准会盖掉全量结果。 校准时打开的是这三个 `*_trial` 文件,不是 `human_queue.csv` / `jev_scores.jsonl`。 > ⚠️ **`--limit N` 取的是语料前 N 条,不是随机抽样。** 前缀里几乎全是最先被采集、 > 也最典型的记录,而撑爆人工队列的永远是后面那些边缘记录。实测一次:前缀样本 > 100/100 含锚点关键词、仅 12% 无摘要,报出队列率 9%;而全语料是 22.9% 和 75.7%, > 换同分布随机样本重测真实值 **18%**,超红线。 > > 跑过 `lit proceedings` 或滚过雪球之后差距最大——那两步追加的记录全排在语料尾部。 > **校准前先核样本构成**(关键词命中率、无摘要占比与全语料是否相当); > 不相当就把 run 复制到临时目录、把 `corpus.jsonl` 换成随机 N 条再跑,别改原 run。 ## 不能跳过的顺序 **筛选必须在滚雪球之前。** 实测:从未筛选的 13,920 条种子出发,后向候选是 134,317 条; 而最终会纳入的只有几百条。跳过筛选去滚雪球 = 把噪声放大一个数量级,还要为此付十倍筛选费。 用户催的时候也不要改成 `--seeds in_window`——先把成本讲清楚,让他自己决定。 **滚雪球与筛选必须交替。** 种子是"已纳入",不筛就没有种子。 实测饱和曲线 34.7% → 4.1% → 0.4%,而 snowball 独有贡献占 92%—— 这是纯关键词检索会漏成什么样的直接证据。 **成本必须先于执行可见。** `lit screen --dry-run` 给出 token 数与美元金额。 无凭据时是字符粗估**并明确标注**。不要替用户跳过这一步。 --- ## 分层与交付 **只标注与排序,绝不过滤。** 阈值会把"没被评价过"和"质量低"变成同一个动作—— 实测以 4.0 切,1,487 条只剩 390 条,其中被删的 340 条是**没有指标**而非指标低。 分层取**所有可用尺子里最好的那个**: | 层 | 判据 | |---|---| | S 顶会顶刊 | CCF-A,或论文引用进入同领域前 1% | | A 高水平 | CCF-B,或期刊指标 ≥ 8.0,或引用前 10% | | B 优质 | CCF-C,或期刊指标 4.0–8.0 | | C 最新预印本 | 预印本 / 仓库,≤ 18 个月 | | D 会议(未评级) | CCF 目录里没有——**未评级,不是低等级** | | E 其它期刊 | 期刊指标 < 4.0 | | F 其余 | 无任何评价依据——**未被评价,不是低质量** | 四条必须讲清楚的事: 1. **CCF 与影响力指标测的不是同一件事,取较优。** 实测 Medical Image Analysis 是 CCF-C,而它的 OpenAlex 指标 10.14 全语料最高。 2. **OpenAlex `2yr_mean_citedness` 不是 JIF。** JIF 分母只算 citable items, OpenAlex 分母算全部条目;发大量学会年会摘要的刊被系统性低估三到五倍 (实测 Stroke 1.81、Neurology 1.11)。**阈值不能跨标度搬运。** 3. **排行榜数据由用户提供,不随仓库分发。** CCF 目录是公开文档但仍走 `--ccf` 槽位; JCR / 中科院分区是商业授权数据,**绝对不能打包进仓库**。 4. **没有目录就不猜等级。** 目录里没有的会议标"未评级"。 编出来的 CCF-A 和真的长得一模一样,这是最危险的地方。 **引文格式化免 key**:`lit deliver` 走 doi.org 内容协商,支持 `apa / ieee / gbt7714 / nature / ama / bibtex`。 (期刊匹配走 ISSN 而非刊名、样式名发请求前先校验——这两条是 `lit rank` / `lit deliver` 内部的护栏,你没有对应操作。想知道为什么见 `references/evidence.md`。) --- ## 凭据 从 `.env` 或环境变量读(真实环境变量优先)。缺哪个的后果各不相同,要说清楚: | 缺 | 后果 | |---|---| | `LITSEARCH_LLM_API_KEY` | **不致命**——用 `--model host` 走宿主模型,零配置 | | `OPENALEX_API` | 采集中途 `QuotaExhausted`;捕获-再捕获算不出,召回证据只剩金标准一个点 | | `CONTACT_EMAIL` | `lit fulltext` 直接拒绝跑——Unpaywall 与 Crossref 都要求声明身份 | ### 筛选后端:三条路 **API 后端**(默认):任何 OpenAI 兼容端点。三个环境变量 `LITSEARCH_LLM_MODEL` / `_BASE_URL` / `_API_KEY`。内置 DeepSeek 的实测价目, 其它厂商的价目由 `LITSEARCH_PRICING` 提供——**没有价目时 `--dry-run` 会如实报 「无法估算」,不会报一个假的 $0.00**。 **宿主后端**(`--model host`):调本机 `claude -p`,**不需要任何 key**。 clone 完就能跑,这是给社区用户的零配置入口。三件事要说清楚: - 每次调用有约 **20,000 token 的框架开销**,所以批次自动放大到 60 条 - 它**不是免费的**:实测 60 条记录约 $0.30 API 等价成本(haiku;用 opus 是 $1.44)。 订阅用户不额外付费,但会消耗额度——**别说成 "$0"** - `--host-model` 默认 haiku。上万条规模请改用 API 后端 **判定 API 后端**(`--model jev`):TypeSafe Jev 不生成文本,对每条纳排标准 返回校准过的概率。$0.042/百万输入 token、输出免费,比生成式 LLM 便宜一个量级。 **但它没有通用默认阈值,配置文件必填。** 实测同一套阈值在 pediatric 课题上把 人工队列从 18.3% 压到 11.2%(AUC 0.987),在 ISLES 课题上反而比现有 LLM 更差 (8.5% vs 基线 7.2%)。失效原因查得到:`X1`「仅做出血性卒中……**且无**缺血性 卒中数据」这类多跳间接 + 隐含否定的标准,单看 AUC 只有 0.675。 所以放量前必须先过准入,三条门槛缺一不可: 1. 金标种子 100% 保留(被自动排除会直接退 1,不用你判断) 2. 人工队列 ≤15% 3. **不劣于该课题现有 LLM 基线**——这条最容易被忽略,也是 ISLES 栽的那条 ```bash lit screen-eval <run> --topic ... --reference-round <人工裁决过的轮次> \ --candidate-scores jev_scores.jsonl --score-keys I1,I2 ``` 报告会分开给金标(真人裁决)与银标(模型判定)的数字,并把银标标注为天花板—— 实测某课题银标纳入约 21% 被真人推翻。每个比率带 Wilson 区间。 打分落在 `jev_scores.jsonl`,改阈值只是重新路由,不重新花钱。 **OpenAlex 有日配额。** `lit deliver` 默认复用 `ranked.jsonl`,不重取元数据; 要刷新加 `--refresh`。配额耗尽时 `QuotaExhausted` 会带上重置秒数——降速无效,别重试。 --- ## learnings:复盘先于重试 改判定逻辑、阈值、采集行为或产物契约之前,先扫一遍 [`learnings/`](learnings/)—— 里面是一次次实测换来的事故清单(数字、代价、当时的判断),不是风格建议。 新的事故(返工、静默少召回、文档与实现打架)事后追加一篇,日期命名。 ## 报数字的纪律 - **"本次没执行的部分"必须念给用户听。** `lit report` 会把它算出来写进 `coverage_report.md` 的第一节,终端也会黄字列出来。**不要跳过这一段去讲纳入数**: 「跑了没成功」有 partial 告警管着,「压根没跑」曾经在整套产物里没有任何痕迹—— 实测一次交付的 manifest 声明了 4 个源、实际只访问了 2 个,而当时没有一份产物提到。 - **partial/failed 的源要点名。** 它的召回数字是下界,不是实际值。 - **标题摘要初筛通过也不是最终纳入。** 尚未筛选时,窗口内记录数不是相关文献数; 初筛完成后,`include` 也只是进入全文资格审查的候选报告。`lit report` 在没有全文 获取、排除理由与最终资格记录时会止于 Eligibility input,你也不要在话里补上终局。 - **被测出来的零要说出来。** "CVPR/ICCV/WACV 2021–2026 共 9,200 篇里一篇都没有" 是有价值的结论,和"我觉得那里没有"完全不同。 - **金标准漏检必须逐条归因**到具体检索式或源缺陷,不能笼统说"召回率不错"。 - **Chapman 只用于两源重叠诊断。** PubMed 与 OpenAlex 不独立,正相关会使两源并集 覆盖度偏乐观;它没有验证主题相关性,也不是多源流水线召回率。 ## 三条硬规则 **① 200 不代表拿到的是你要的东西。** 枚举源"200 但解析出 0 条"必须报失败; 内容协商拿回 HTML 必须判定为失败。实测这两种都真实发生过, 而且第二次是我只挡了"见过的坏样本"(JSON 错误)导致的复发。 **校验要写成"确认它是我要的",不是"排除我见过的坏样本"。** **② 跑砸的一轮不能覆盖跑成的一轮。** 新一轮判定数少于上一轮 = 拒绝写入、非零退出。 断点续跑所需的信息(如通道号)必须在第一次跑的时候就存下来——事后要么补不出来, 要么只能靠猜,而猜出来的和真的长得一样。 > 撞到这个护栏时(退出码 1 + "不写入新轮次"):**不要重试全量**。先看失败样例定位 > 原因(配额耗尽 / 网络 / 端点变更),修好之后用 `screen --resume` 只补缺的判定。 **③ 规则演进后不要重采。** `lit reclassify` 用当前规则从 `records*.jsonl` 重新去重 与判定窗口,一次请求都不发。某个源的解析缺陷修好后,用 `lit harvest --into <run> --phase fix --labels <那几条>` 定点补跑。 采集是昂贵的一次性动作,判定不是。 ## 两个人工队列怎么交代 `human_queue.csv`(判定分歧 / 低置信度)和 `boundary_cases.csv`(日期精度不足) 现在都能经 `lit adjudicate` 回流,并保留裁定人、时间、理由与原判定。 所以跑完必须做两件事,都不能替用户代劳: 1. 把两个文件的**路径和条数**报给用户,并说明 `decision` 允许值;不要替用户裁定。 `--kind screening` 收 `include` / `exclude`(不接受仍为 `unclear`); `--kind date` 收 `in_window` / `out_of_window`,且**只受理 boundary / undated 的记录** ——裁定是用来消解不确定的,不是用来盖掉已有判定的。已确定的日期判错了, 该修日期证据或 `date_priority` 再跑 `lit reclassify`。 2. 用户填写 `reviewer`、`reason` 后运行相应的 `lit adjudicate --kind ...`。导回后报告
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen