mcpField
P
paper-search-pro

paper-search-pro

github.com/o0000-code生产力21867 次安装4 周前更新
代码仓库

关于 paper-search-pro

paper-search-pro 是用于多来源学术文献检索的 Skill,可按需求调整检索深度,面向研究者和 Agent。Python 辅助脚本负责确定性检索与评分;面向人工的流程还包含并行 LLM 分类和报告输出。

主要功能

  1. 01提供四档检索深度
  2. 02检索五个文献来源
  3. 03去重并评估相关性
  4. 04并行 SubAgent 分类
  5. 05生成 HTML 报告和数据导出

适用场景

  1. 01为论文提案梳理研究范围
  2. 02收集文献综述资料
  3. 03开展深入的系统综述检索
  4. 04为 Agent 推理获取结构化结果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/o0000-code/paper-search-pro --skill paper-search-pro

安装后在 Claude Code 中输入/paper-search-pro确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
.gitignore
NOTICE.md
THIRD_PARTY.md
.skillignore
LICENSE.txt
README.zh.md
.github/workflows/
tests.yml
assets/
md_template.md.jinja
default_config.yaml
assets/benchmark_queries/
sparbench_subset.json
litsearch_subset.json
custom_zh_queries.json
assets/webartifacts_app/paper-report/
.parcelrc
components.json
index.html
eslint.config.js
package.json
postcss.config.js
pnpm-lock.yaml
.gitignore
README.md
assets/webartifacts_app/paper-report/src/
App.css
App.tsx
assets/webartifacts_app/paper-report/src/components/adapters/
SegmentedToggle.tsx
SearchInput.tsx
KickerAccordion.tsx
KickerAlert.tsx
assets/webartifacts_app/paper-report/src/components/audit/
ComplianceSummary.tsx
PrismaRow.tsx

详细介绍

paper-search-pro

多源文献搜索,深度可调。由你(主 Agent)协调四个层级、五个数据源。Python 辅助脚本处理确定性任务;LLM 分类则委托给并行 Inline SubAgents,无需外部 API 密钥。

何时使用此技能

  • 用户想查找学术论文 / 找文献 / 论文搜索
  • 用户正在准备文献综述、系统综述(SR)、范围综述或荟萃分析
  • 用户想为论文 / 提案 / 课程作业 / 新闻报道梳理某个主题的研究
  • 用户询问“关于 X 有哪些研究” / “帮我找一些关于 Y 的论文”
  • 用户上传的查询内容表明需要搜集文献(PICO、SPIDER、MeSH、RCT 等)

何时不使用

  • 用户想要阅读某篇特定论文(使用 PDF 阅读器 / 下载工具)
  • 用户想要总结一篇已知论文(使用摘要工具)
  • 用户想要根据 DOI 下载 PDF(使用 paper-downloader-portable)
  • 用户已有一组文献,想撰写综述(使用 literature-set-review / factor-outcome-review)
  • 用户想了解概念,而不是查找论文(“什么是前景理论” → 直接回答)

🤖 由另一个 Agent 调用 / 无头模式

如果你是一个调用此 Skill 进行自身推理的 Agent(而非为需要 HTML 报告的人类用户服务),请勿手动执行下面的 14 步流程。这里有一个专为你设计的结构化数据通道:

PYTHONPATH=$PSP_HOME python3 -m scripts.agent_search "<query>" > result.json

一条命令即可运行整个确定性核心流程——多策略检索 → 去重 → 启发式相关性评分(为每篇论文计算)→ 饱和度信号 → 配额快照 → 逐篇期刊指标——并输出一个 JSON 信封(无 HTML、无 PRISMA、无 LLM 分类 SubAgent)。下方的人类用户流程不受影响。 该命令为你提供确定性的基础结果,而非最终成果——Agent 模式并非要止步于机器输出;请参阅 references/agent_mode.md,了解如何在此基础上叠加自身的语义判断,达到人工流程的质量(该命令保证基础结果;质量由你把关)。

📖 阅读 references/agent_mode.md,了解完整的信封架构、所有标志(--verify、--min-relevance、--quartile、--min-impact 等)、相关性公式、错误代码 / 退出代码以及数据源选择。此文档是面向 Agent 调用方的 SSOT——本节其余内容都只是指向它。

从这里往下的内容都是面向人类用户的 14 步流程(HTML 报告 + 导出文件)。仅在使用者是人时使用。


🔥 执行规范(运行任何操作前请先阅读)

四条不变原则适用于每个步骤——在实际会话中,忽视这些原则是最常见的失败原因:

  • A — 绝不要 cd 进入 Skill 目录。 cd $PSP_HOME 会将 ./ 重新指向 Skill 资源文件夹,因此 ./paper-search-results/... 会落在 Skill 内,而不是用户的工作区(重新安装时还会被清除)。从用户的当前工作目录运行每个辅助脚本:PYTHONPATH=$PSP_HOME python3 -m scripts.<name> … > "$SEARCH_DIR/..."。$PSP_HOME(STEP 0)是安装目录;$SEARCH_DIR(STEP 0)是用户当前工作目录下的绝对路径。
  • B — 并行分发分类器 SubAgents。 STEP 6 会在一条助手消息中放入最多 5 个 Task 块;串行分发会将 Standard 层级的耗时从约 10 分钟延长到约 17 分钟。完整示例见 STEP 6——其他地方不再重复。
  • C — 每次跳过步骤都要说明。 如果跳过某个 STEP(预算 / 数据为空 / 用户选择),请说明跳过了什么、原因、会损失什么以及如何补做(例如“使用 --tier deep 重新运行”)。跳过步骤没问题;让用户感到意外则不行。
  • D — 当某一步对当前情况并非简单操作时,阅读该步骤引用的参考文档。 每个 STEP 都会列出一个包含未在此处重复说明的边界情况的 references/<file>.md。你不必每次都阅读所有文档,也不应这样做——但如果即将执行某个步骤,却跳过了对应参考文档,就可能遗漏边界知识(字典与列表的数据结构差异、补充而非搜索、DOI 大小写等)。阅读当前步骤对应的参考文档。

架构一览

You (main agent) drive the workflow per this SKILL.md.
Python helpers do deterministic work — NO LLM inside, NO external API key.

  L1 OpenAlex (primary)  → deep top-100 multi-strategy
  L2 PubMed (medical)    → MeSH enricher (mostly; Audit-tier can search independently)
  L2 arXiv (CS/AI)       → last-year recent layer (+ 4-day sentinel on freshness words)
  L2 OpenReview (AI)     → accepted-venue labels (ICLR / NeurIPS / ICML …)
  L3 Semantic Scholar    → influentialCitationCount + abstract fallback
  L3 CrossRef            → funder / license / clinical-trial-number

  Classification         → Inline SubAgents (parallel, file-IPC, 5 per message)
  Output                 → HTML (Shadcn) + MD + BibTeX/RIS/CSV + PRISMA-S log

4 个层级——先选层级

层级实际耗时论文数适用情况
快速~5-8 分钟20-60“查一下” / “几篇” / “明天之前” / 快速确定范围
标准(默认)~10-17 分钟60-180确定主题范围 / 撰写背景 / 常规文献检索
深度~30-45 分钟180-400“全面” / 撰写综述文章 / 综述写作
审计~2-3 小时400-1000+“系统综述” / “PRISMA” / “Cochrane” / “荟萃分析”

📖 选择层级前,请阅读 references/tier_decision.md。 告知用户你的选择及原因。对于审计层级,请先展示限制警告,并在开始前获得明确确认。


操作流程

每次文献检索都要按顺序执行以下步骤。每个步骤都引用了 references/ 中的文件,内含详细说明。只有当某一步对当前情况显然无关紧要时,才可跳过相应文件——并按规则 C 宣布跳过。

步骤 0 — 设置($PSP_HOME + 工作目录)

📖 执行此步骤前,请阅读:references/setup.md。

将 Skill 安装路径解析为 $PSP_HOME(后续每个步骤都会使用 PYTHONPATH=$PSP_HOME)。优先使用显式注入 / Agent 环境变量;否则扫描已知的跨 Agent 安装位置。如果你的运行环境已经提供此 SKILL.md 的绝对路径,只需执行 export PSP_HOME="<that dir>" 并跳过扫描。📖 完整的原因说明、为何不能用脚本完成,以及完整路径列表:references/runtime_bootstrap.md。

PSP_HOME="${PSP_HOME:-${CLAUDE_SKILL_DIR:-${CODEBUDDY_SKILL_DIR:-}}}"   # explicit / agent-injected
if [ -z "$PSP_HOME" ]; then                                            # else scan known installs
  for base in "$HOME/.claude" "$HOME/.codex" "$HOME/.agents" "$HOME/.config/opencode" \
              "$HOME/.codeium/windsurf" "$HOME/.config/goose" "$HOME/.cline" "$HOME/.roo" \
              "$HOME/.copilot" ./.claude ./.codex ./.agents ./.cursor ./.opencode ./.windsurf; do
    [ -f "$base/skills/paper-search-pro/SKILL.md" ] && PSP_HOME="$base/skills/paper-search-pro" && break
  done
fi
[ -z "$PSP_HOME" ] && { echo "ERROR: paper-search-pro install not found. Set PSP_HOME to the dir containing SKILL.md."; exit 1; }
export PSP_HOME; echo "Using Skill install: $PSP_HOME"

验证配置项(可在任意当前工作目录下执行,切勿 cd 进入 Skill 目录):

PYTHONPATH=$PSP_HOME python3 -c \
  "from scripts.config import load_config; c = load_config(); print('OK' if c.openalex_api_key and c.ncbi_email else 'MISSING — see references/setup.md')"

如果显示“MISSING”,请引导用户阅读 references/setup.md(5 个配置项,全部免费,总共约 15 分钟),然后停止。

设置工作目录变量——后续每个步骤都会使用 $SEARCH_DIR:

SEARCH_ID="<topic_slug>_<tier>_$(date +%Y%m%d_%H%M%S)"   # e.g. clt_education_quick_20260522_103045
SEARCH_DIR="$(pwd)/paper-search-results/$SEARCH_ID"
mkdir -p "$SEARCH_DIR/raw" "$SEARCH_DIR/batches" "$SEARCH_DIR/classifications"
echo "Outputs will land in: $SEARCH_DIR"

$SEARCH_DIR 现在是用户 PWD 下的一个绝对路径。下方每个辅助命令都要使用 "$SEARCH_DIR/..."(加引号并带变量),而不是 ./paper-search-results/...。

步骤 1 — 规划查询(所有层级都必须执行)

📖 执行此步骤前,请阅读:references/query_planner.md。

检测报告 UI 语言——UI_LANG(中文查询为 zh,其他情况均为 en)决定最终 HTML 报告使用哪种 UI 语言。论文标题 / 摘要 / 作者 / 出版物绝不翻译——仅翻译报告的 UI 界面文本。将 --language $UI_LANG 传递给步骤 12b。

UI_LANG=$(PYTHONPATH=$PSP_HOME python3 -m scripts.detect_language "$USER_QUERY")

检测器会将日语 / 韩语 / 欧洲语言查询路由到英语(此工具包仅提供 EN + ZH 词典;英语是国际学术领域的默认语言)。📖 精确的 Unicode 规则,以及为什么要在检查汉字前检查假名,请参阅 references/runtime_bootstrap.md。

确定检索语言范围(search_language,轴 2——指“检索哪个文献领域”,不同于上面的 UI_LANG,后者仅控制“报告界面”)。📖 解析的单一事实来源(SSOT)是 references/source_routing.md 中的 §“语言范围”;请在组织查询措辞前确定范围,因为这会改变步骤 3 中查询的构建方式。这是增量式且选择加入的——纯英语查询会解析为 en 范围,不会增加任何提示或改变行为(R-19);以下所有规则仅适用于中文查询或有明确提示的情况。

  • 读取持久化的默认值 config.search_language(auto | en | zh | both),并按优先级顺序应用:标志 > 查询中的标记 > 配置 > auto。是否含 CJK 字符是上文 detect_language 给出的机械判断;标记(CSSCI、中文文献、SSCI、知网 等)和非信号(中科院一区、关于中国的主题)则根据 §“语言范围”中的表格进行语义判断。

  • auto + 中文(CJK)查询 + 没有语言标记 + 没有持久化值 → 检索前提问一个问题(这是人工路径的职责;CLI/Agent 路径则直接继续)。用两个句子提问,提供保存为默认值的选项,并且本次会话中不要再次询问:

    你用中文提问——文献要英文、中文,还是都要?顺便可以说“以后都这样”,我就记成默认,下次不再问。

    • “中文”/“都要” → 进入该空间(STEP 2 的学科分流流程会接管;在该空间中用一行回复)。
    • “英文” → 使用 v2.2 行为(将中文主题作为英文查询),用一行回复。
    • “无所谓/都行” → 本次使用 both(召回率 > 精确率),不保存设置;如果同一用户第二次回答“无所谓”,则轻描淡写地提出一次可将 both 设为默认选项,此后不再询问。
    • 只有明确说“以后都……”才会将设置保存到 config.search_language(单次回答不会自动保存)。
  • 如果本次还触发了排名歧义(单独的“Q1”),将两个问题合并到同一条消息中——同时询问语言和平台,绝不分两轮询问(过度询问是不可逾越的红线)。

  • 确认空间后,按照 references/query_planner.md §“跨语言查询处理”来组织查询:zh 保留中文搜索词(不翻译),en 使用英文词(v2.2 行为),both 构建两组查询。

每条检索查询都要写成概念块,而不是词语列表。 OpenAlex 会要求每个独立词都匹配,因此把同义词作为普通词语列出,会排除只使用其中一种表达的所有论文(某用户的 11 词查询,在五年间仅通过标题和摘要匹配到一篇论文)。同义词放入 OR 组,使用 2–3 个由 AND 连接的概念块,短语加引号——("short video" OR TikTok OR Douyin) AND (attention OR concentration)——并确保至少有一种策略不包含人群概念块。📖 references/query_planner.md §“OpenAlex 如何读取查询”。

根据领域应用 PICO/SPIDER/PEO:

  • 医学/临床 → PICO(人群/干预/对照/结局)
  • 定性研究 → SPIDER
  • 范围综述 → PEO(人群/暴露/结局)
  • 开放式查询 → 提取 2–4 个概念块,每个概念块包含 2–5 个同义词

期刊分区意图识别(增量功能——仅在查询提及分区时启用)。 提取概念块前,先检查用户的查询是否包含期刊排名/分区表达——“中科院一区”、“Q1”、“JCR Q1”、“SJR Q2”、“顶刊/top journal”。如果有,该表达是筛选条件,而非搜索词,必须在检索前从主题中剔除。这样可以避免导致整个功能诞生的失败案例:“中科院一区 情绪调节”过去会把“中科院一区”作为主题词发送给搜索引擎,于是搜索的是关于中科院一区的论文,而不是关于情绪调节、且筛选为中科院一区的论文。确定性解析器会同时完成两项工作(提取和剔除):

PYTHONPATH=$PSP_HOME python3 -c "
from scripts.rank_intent import parse_rank_intent
i = parse_rank_intent('''<original user query>''')
import json; print(json.dumps({
  'platform': i.platform, 'tiers': i.tiers, 'quartiles': i.quartiles,
  'top': i.top, 'ambiguous': i.ambiguous, 'candidates': i.candidate_platforms,
  'cleaned_query': i.cleaned_query, 'stripped': i.matched}, ensure_ascii=False))
"

然后根据解析结果采取行动:

  • cleaned_query 是剔除排名表达后的检索输入——构建 STEP 3 查询和查询计划时使用它(而非原始查询)。它不会自动成为 SEARCH_TOPIC 或报告标题:下方的语义规划步骤仍会剔除对话性和操作性文本。如果查询中没有排名表达,则 cleaned_query == query,检索行为保持不变(R-19)。
  • platform + tiers/quartiles/top 是你将在 STEP 5 之后立即应用的筛选条件——记住它们(并将其记录为 query_plan.json 中的 rank_filter);此处不要筛选。
  • ambiguous == True(只有分区等级或四分位数、未注明平台,例如单独的“Q1”或“SSCI 一区”——识别器绝不猜测平台):继续操作前,在对话中向用户简短提问,并提供 candidates 中的平台选项——“按 JCR 还是 SJR 的 Q1 筛?”/“按中科院分区还是 JCR 分区?”,并补充“顺便要不要设为以后的默认?”CLI/无头模式无法提问,因此这条内嵌问题专门由面向人工的路径负责。
  • 如果查询中完全没有提及分区,则跳过此步骤——STEP 1 完全按原样进行。

时间范围——在检索前确定年份区间。 📖 references/query_planner.md §“年份筛选启发式”。将请求归为以下四种情况之一:

  • 明确范围(“2020–2024”“近两年”“2023 年以后”“last 3 years”“只要 2026 年的”)→ 设置 year_min / year_max;相对范围从当前年份往前计算(“近两年” = 当前年份 − 1 … 当前年份)。不提问。用一行说明:“本次限定 2025–2026。”

  • 未带数字的“最新”(“最新”“最近”“近年”“前沿”“recent”“latest”“cutting-edge”)→ “多近”确实存在歧义,而且会改变结果集。如果设置了 config.recent_years,就使用该值,并用一行说明。否则,提出一个问题——与上述任何语言或排名问题放在同一条消息中,不要再进行第二轮提问:

    「最新」想要多近?近一年 / 近两年 / 近三年 / 近五年,或者直接给区间(如 2023–2026)。说「以后都这样」我就记成默认。

    只有明确说“以后都……”才会持久保存(~/.paper-search-pro/config.yaml 中的 recent_years: <N>,机制与 search_language 相同)。

  • 经典文献(“经典”“奠基”“起源”“seminal”“classic”)→ 不设年份窗口;在 STEP 3 中添加 seminal。

  • 未提及时间范围(大多数请求)→ 不设年份窗口,且不要提问:STEP 3 中近期文献部分仍会提供过去一年和之前两年里最相关的论文。用一行说明:“未说明时间范围:本次不限年份,并单独补一层近一年的新文献。只要近几年的,说「只要近两年」即可。” 如果本来就要询问语言或排名问题,可以在同一条消息中提供时间范围选项。

  • 审计级别:日期限制属于协议的一部分(PRISMA-S 会报告这些限制)——将范围确认纳入你原本就要进行的审计确认中。

如果宿主提供结构化选项工具(Claude Code 的 AskUserQuestion;在可用工具列表中时使用 Codex 的 request_user_input),就用这些选项加上自由输入的方式提问;否则用文本提问。Agent/无头流程绝不提问——按给定值使用 --year-min / --year-max。

即使是 Quick 级别,也需要轻量执行此步骤——绝不能悄无声息地跳过。输出:1-3 个检索策略(概念块 + 年份范围 + 作品类型筛选器)。将内容写入 "$SEARCH_DIR/query_plan.json",格式为 {"strategies": [{"query": "..."}, ...], "year_min": …, "year_max": …, "rank_filter": {"platform": "cas", "tiers": [1, 2]}, "work_type_filter": …}(也可以包含其他键;不适用的键省略)。报告的审计选项卡和 PRISMA-S 日志(STEP 12a、13)会从中读取查询和筛选器。

定义 SEARCH_TOPIC,但暂时不要确定报告标题。 阅读 references/report_title.md §"STEP 1"。SEARCH_TOPIC 是根据概念块提取的、经过规范化的语义检索范围,而不是删除了几处正则匹配内容后的用户原话。去掉问候语、工具/输出指令、级别/语言/日期/数据库限制及其他操作指示;仅保留作为科学概念的人群、暴露/干预、结局、机制和场景。将用户原始消息完整保留为 USER_QUERY,用于 PRISMA-S。最终的可视化标题将在 STEP 11 中、了解保留的证据后撰写。

STEP 2 — 在 STEP-1 确定的语言范围内路由补充来源

📖 执行此步骤前,请阅读:references/source_routing.md。

你需要根据查询领域判断这些路由;参考文档中的关键词表仅用于校准,不是匹配清单(机械事实——CJK 检测、显式 --flags——保持确定性)。在 STEP 1 确定的语言范围内,路由各学科的补充来源:

  • 英语范围(en,或 both 中的英语部分)——与 v2.2 相同:
    • 医学信号(RCT、PRISMA、MeSH、临床、疾病名称)→ 启用 PubMed
    • CS / AI 主题(机器学习、LLM、transformer、NeurIPS、计算机视觉,……)→ 启用 arXiv 的近期论文层 和 OpenReview(ICLR / NeurIPS / ICML / COLM / TMLR 评审平台——会添加诸如“ICLR 2026 Oral”的录用会议信息标签,并收录少量仅此平台有的论文)
    • 时效性信号(预印本、“最新”、“本周”)→ 另启用 4 天 arXiv 哨兵
    • 跨领域(例如“放射学中的 AI”)→ 两者都启用
    • 纯社会科学 / 人文学科 → 仅 OpenAlex
    • (判断提示:核心 AI/CS 查询也可能需要将主引擎提升为 Semantic Scholar——参见 source_routing.md §“AI / CS 查询 → 考虑将 Semantic Scholar 作为主引擎”。)
  • 中文范围(zh,或 both 中的中文部分)——同样按学科路由中文补充来源:
    • 有社会科学 / 人文学科信号 → 添加 NSSD(国家哲社文献中心;带有 OpenAlex 基本没有覆盖的 CSSCI 收录标识)
    • 有医学信号 → 添加 yiigle(中华医学期刊全文数据库);PubMed 仍覆盖被 MEDLINE 收录的中华期刊,两者互为补充
    • 纯科技,且两类信号都没有 → 中文侧仅使用 OpenAlex(中文科技核心期刊大多有 DOI,因此 OpenAlex 覆盖良好)

报告一行(axis-3 风格——陈述句,不是问题;22 §6.3)。仅英语检索时,这一行是 PubMed/arXiv 提示(“我检测到医学 + AI 信号——还会检索 PubMed、arXiv(去年)和 OpenReview。可用 --no-pubmed 覆盖。”)。中文范围的示例:

本次按「中英都要」检索;中文侧检测到社科主题,已添加 NSSD(国家哲社文献中心)。想去掉的话说 --no-nssd,只查一边的话说“只要英文/中文”。

**同时在提示中如实说明覆盖范围:**如果中文范围涉及社会科学主题,但用户拒绝使用 NSSD,请补充说明 OpenAlex 对 CSSCI 核心期刊(经济研究 / 管理世界……)的检索命中率约为 0,因此缺少这一层覆盖。用户可以通过明确指示覆盖以上任何设置(针对单次查询的覆盖指示优先级最高)。

关于上述 --flag 简写(--no-nssd、--no-pubmed、--source …):在这条人工操作路径中,它们是自然语言覆盖指示的记法——用简短形式表达用户可以说的话(“去掉 NSSD” / “只查 OpenAlex”),由你(LLM)理解。它们不是可执行的 CLI 标志——这里没有脚本解析它们。真正由脚本解析的标志仅存在于 Agent / 无头模式路径(agent_search)中;该路径中的中文来源控制采用选择加入方式:--with-nssd / --with-yiigle(不支持 --no-nssd / --source)。参见 references/agent_mode.md。

步骤 3 — 从 OpenAlex 检索(深度)

📖 执行此步骤前,请先阅读:references/openalex_helper_cheatsheet.md。

始终先运行 OpenAlex。(OpenAlex 是默认的主要来源;config.yaml 中的 primary_source 可以更改此设置 — 请参阅 references/source_routing.md 中的 主要来源选择与配额回退。)

当 OpenAlex 无法处理某次调用时(每日预算已用完、持续受到限流或服务中断),openalex_helper 会改用 Semantic Scholar 处理同一次调用,并仍然输出相同的 JSON 格式 — 无需标志或配置。它会在一行以 [paper-search-pro] OpenAlex unavailable 开头的 stderr 信息中说明这一点:用一句话告知用户(规则 C)并继续;不要停下来询问。如果 Semantic Scholar 也无法处理,则调用的行为与以往 OpenAlex 出错时相同:退出状态为 3(stdout 仍是有效的 JSON),stderr 信息会说明发生了什么以及 OpenAlex 何时重置 — 像报告其他 OpenAlex 错误一样告知用户。journal-list 是例外:与之前一样,它会返回空结果,退出状态为 0。

对于 Standard+ 层级,使用多策略深度爬取:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.openalex_helper double-sort "<query>" \
    --n 50 \
    > "$SEARCH_DIR/raw/openalex.json"

三路检索,一个文件:引用量(该主题被引最多的作品)、近期(过去 12 个月内最相关的作品,然后是此前两年内的作品)、相关性(总体上最匹配的作品)。近期检索可以找到今年的论文 — 相关性排序倾向于依赖引用量,因此没有近期检索,新作品几乎不会出现。

对于 Quick 层级,使用相关性检索,并辅以规模较小的近期检索:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.openalex_helper search "<query>" \
    --limit 30 --recent 20 \
    > "$SEARCH_DIR/raw/openalex.json"

然后记录 OpenAlex 中主查询匹配到的作品数量 — 在报告的年份图表下方添加一行,避免将近期数据条过短误读为该领域规模很小(统计 STEP 1 时间范围内标题和摘要匹配的结果;如果未指定时间范围,则统计过去两年):

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.openalex_helper count "<query>" [--year-min YYYY] [--year-max YYYY] \
    > "$SEARCH_DIR/pool_count.json"

如果 count 报告的作品少于 30 个,或 helper 提示查询包含一长串孤立词语,则查询范围过窄(除非该主题确实非常小众):按照 STEP 1 的方法重新组合查询,并在分类前重新执行检索。

检索命令也要添加 STEP 1 的时间范围:--year-min YYYY / --year-max YYYY(包含边界年份)。未指定时间范围 → 不添加时间筛选(helpers 会自行限制为当前年份)。近期检索仍限定在时间范围内:如果时间范围结束于过去的某一年,则检索该范围内的最后一年。

raw/ 仅存放检索输出 — 每次搜索一个文件,内容须与 helpers 写入的一致。 STEP 7 会根据这些独立搜索重复找到同一论文的频率来估算覆盖率。你衍生出的子集、合并结果或筛选后副本应放入 "$SEARCH_DIR/_working/",而不是 raw/:否则它看起来会像是又一次重新找到所有结果的搜索。

完整的子命令和标志参考(search / double-sort / seminal / reviews / journal-list / citation-network,均已对照 argparse 验证)见 references/openalex_helper_cheatsheet.md — 在尝试上述两个命令之外的任何操作前,请先阅读。对于 Deep+Audit,还要调用特定主题的子命令(例如 seminal、reviews、journal-list),将输出追加到 $SEARCH_DIR/raw/openalex_*.json,并在 STEP 5 中将它们全部联合起来处理。

STEP 4 — 运行 L2 增强器(如果 STEP 2 已启用)

📖 执行此步骤前,请阅读:references/pubmed_helper_cheatsheet.md 和 references/arxiv_helper_cheatsheet.md。

PubMed — 默认模式为 enrich,而非 search:

  • Standard / Deep 层级:为通过 OA 找到的论文补充 MeSH 术语(就地修改 openalex.json 文件):
    PYTHONPATH=$PSP_HOME \
      python3 -m scripts.pubmed_helper enrich \
        --input-file "$SEARCH_DIR/raw/openalex.json" \
        --output-file "$SEARCH_DIR/raw/openalex.json"
    
  • Audit 层级,且明确指定 MeSH 查询:独立进行 MeSH 检索(生成一个新文件,供后续联合):
    PYTHONPATH=$PSP_HOME \
      python3 -m scripts.pubmed_helper search-mesh "Diabetes Mellitus, Type 2" \
        --year-min 2020 --limit 30 --pub-type "Randomized Controlled Trial" \
        > "$SEARCH_DIR/raw/pubmed.json"
    
  • 当不知道 MeSH 术语时,通用的 pubmed_helper search 是备用方案——尽可能优先使用 enrich 或 search-mesh。

arXiv — CS / AI 主题:近期内容层。 最近一年的相关预印本(OpenAlex 对 arXiv 的索引滞后且不完整:一次检查中,OpenReview 最近的 20 篇相关论文有 7 篇不在 OpenAlex 中):

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.arxiv_helper search "<query>" \
    --sort relevance --since-days 365 --limit 30 \
    > "$SEARCH_DIR/raw/arxiv.json"

新鲜度信号(“最新”、预印本、“本周”)——也包括 4 天哨兵,用于检索新到任何索引都未收录的预印本:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.arxiv_helper freshness "<query>" \
    --days 4 --limit 30 \
    > "$SEARCH_DIR/raw/arxiv_fresh.json"

查询中的普通词语都必须满足(arXiv 会对它们进行 OR 检索)。如果 arXiv 失败或超时,两个命令都会输出 [] 和一条 stderr 说明——继续执行即可(规则 C:用一句话说明)。

子命令参考:

  • arxiv_helper freshness <query> --days N --limit M [--all-cats]
  • arxiv_helper search <query> --limit M --sort submitted|relevance|lastUpdated [--since-days N] [--all-cats]
  • arxiv_helper get <arxiv_id>

OpenReview — 仅限 CS / AI 主题。 📖 references/openreview_helper_cheatsheet.md。ICLR、NeurIPS、ICML、COLM 和 TMLR 的评审平台。该工具仅返回已接收的论文,并标注为“ICLR 2026 Oral”之类的状态标签——OpenAlex 和 Semantic Scholar 没有这类标签(它们会将这些论文列为 arXiv 预印本)。STEP 5 会将每篇论文合并到同一论文的 arXiv/OpenAlex 记录中。

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.openreview_helper --search "<query>" --n 30 \
    [--year-min YYYY] [--year-max YYYY] \
    --output-file "$SEARCH_DIR/raw/openreview.json"

只有其搜索端点允许匿名使用;如果 OpenReview 阻止访问,该工具会返回 []——用一句话说明,然后继续执行。

NSSD / yiigle — 中文增强器(仅当 STEP 1-2 将本次运行置于 zh 空间时,且仅使用学科路由所选的增强器):

对于中文空间,每个来源都是独立的一手来源(作用与 ss_helper --search 相同),并输出与 openalex.json 相同的 UnifiedPaperEntity 结构,因此 STEP 5 会以相同方式联合这些来源。查询请使用中文(不要翻译——参见 query_planner §Cross-language),并写入 raw/nssd.json / raw/yiigle.json:

# NSSD — Chinese social-sciences & humanities (adds the CSSCI-tier layer OpenAlex lacks)
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.nssd_helper --search "<中文检索式>" \
    --n 50 [--year-min YYYY] \
    > "$SEARCH_DIR/raw/nssd.json"

# yiigle — Chinese medical (中华医学期刊全文数据库; native-Chinese titles + abstracts)
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.yiigle_helper --search "<中文检索式>" \
    --n 50 [--year-min YYYY] \
    > "$SEARCH_DIR/raw/yiigle.json"

遇到任何网络 / HTTP 故障时,两者都会优雅降级为 [](不会抛出异常)——空文件不会联合出任何内容。两者仅获取题录 + 摘要(合规要求:不下载全文、不缓存),并将来源归属信息输出到 stderr。--year-min 在客户端进行筛选;如需保留所有年份,请移除该参数。

**配置为 search_language: en,但用户提交了中文查询(硬边界 2):**不要启用中文增强器,但要用一句话说明——绝不能默默翻译(22 §6.4):

根据你的默认设置(仅检索英文),我已将中文主题规划为英文检索式。若这次想要中文文献,请告诉我;若想更改默认设置,请说“以后……”。

**用户提到知网 / CNKI / 万方 / 维普(命中标记 + 合规):**PSP 不会抓取这些需要订阅的封闭数据库。用一句话说明,提供替代方案和检索式,不要反复解释(22 §6.5):

PSP 不抓知网/万方(合规要求,不抓取封闭数据库);中文侧通过 OpenAlex 中文底座 + NSSD(社科,含 CSSCI 标识)/yiigle(医学)覆盖。不过可以帮你写好知网专业检索式——按 CNKI 专业检索语法(SU %= 相关匹配、块内 OR/块间 AND、全英文半角、检索值加单引号)生成可直接粘贴到「专业检索」框中的检索式,粘贴即可检索。中文医学题目还可提供 SinoMed(CMeSH 受控词双轨)。需要导出吗?

“要导出吗?”得到肯定答复 = STEP 11.5 的明确请求触发条件——任何层级都要执行导出。

步骤 5 — 联合(去重 + 合并)

📖 开始此步骤前,请阅读:references/source_routing.md §“字段优先级表”。

将所有检索结果合并为一个去重后的 KG。默认输出为以 canonical_key 为键的字典——这是 rcs_parser 后续所需的格式,因此不要传入 --as-list:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.federated_kg_resolver \
    --input-files "$SEARCH_DIR/raw/openalex.json" \
                  "$SEARCH_DIR/raw/pubmed.json" \
                  "$SEARCH_DIR/raw/arxiv.json" \
                  "$SEARCH_DIR/raw/openreview.json" \
    --output "$SEARCH_DIR/kg.json"

只传入你实际生成的输入文件——跳过步骤 2 未启用的文件(如果运行了 4 天哨兵,则加入 raw/arxiv_fresh.json)。OpenReview 记录不带 DOI;解析器会按标题将每条记录合并到同一论文的 arXiv/OpenAlex 记录中,并赋予其已录用的会议标签。如果步骤 4 运行了中文增强器,将 "$SEARCH_DIR/raw/nssd.json" / "$SEARCH_DIR/raw/yiigle.json" 加入同一个 --input-files 列表——它们具有相同的实体结构,联合方式与其他来源完全相同(Phase 0 的 canonical-key 修复可安全处理 CJK 字符,因此不同的中文标题不会被合并)。仅英文的运行中,这些文件不存在,因此调用与 v2.2(R-19)完全相同。此过程会处理 DOI 规范化(arXiv 的 X→x 大小写转换)、版本号剥离、E5b 防护(标题和年份相同但 DOI 不同的记录会保留为不同条目)以及字段优先级合并。

--as-list 存在的用途仅限于需要按引用数排序列表的使用者;不要在此流水线中使用。

仅当步骤 1 检测到期刊分区请求时才执行——在分类前筛选。 分区筛选是低成本的确定性过滤;对将被筛掉的论文进行分类才是昂贵的部分。📖 references/journal_metrics.md。保留完整论文池 kg.json,并对 kg_ranked.json 进行分类:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.rank_filter --kg "$SEARCH_DIR/kg.json" \
    --output "$SEARCH_DIR/kg_ranked.json" --platform cas --tiers 1,2
# JCR / SJR: --platform jcr --quartiles Q1,Q2 ; Top only: --top

它会为每篇论文标注三个平台的全部结果,保留用户要求的论文,并将其余论文写入 kg_ranked_set_aside.json。用一行话告知用户输出的计数("本次按中科院 1–2 区筛:留 N / 区外 M / 不在该表 K"),并附上它输出的来源说明。步骤 6 中批处理和合并 kg_ranked.json,而不是 kg.json。未请求分区 → 完全跳过;无需更改任何内容。

第 6 步 — 并行批次分类(LLM 在此处运行 — 主 Agent + SubAgents)

📖 执行此步骤前,请阅读:references/classifier_subagent_prompt.md 和 references/rcs_rubric.md。

将 KG 拆分为每批 10 篇论文。写入 "$SEARCH_DIR/batches/batch_NNN.jsonl"。如果论文池超出该层级的分类能力,请在原始文件中均匀删减,绝不能按引用次数删减:新论文几乎没有引用,因此按引用次数删减会恰好移除最近的论文。

分派前,将 $PSP_HOME/references/rcs_rubric.md 展开为实际绝对路径(例如 /Users/alice/.claude/skills/paper-search-pro/references/rcs_rubric.md),并在分类器提示词模板中用该路径替换 {rubric_path}。每个 SubAgent 都在自己的 shell 中运行,其中未导出 $PSP_HOME——传递字面量 $PSP_HOME 标记会导致 SubAgent 无法找到评分标准,从而在不报错的情况下降低评分质量。完整的占位符表请参阅 references/classifier_subagent_prompt.md。

🔥 必须并行处理(规则 B):

你必须在一条助手消息中使用多个 Task tool_use 块,分派最多 5 个分类器 SubAgent。

✅ 正确 — 在一条助手消息中:

Task tool_use #1  → subagent_type="general-purpose", prompt="<classifier prompt for batch_001.jsonl>"
Task tool_use #2  → subagent_type="general-purpose", prompt="<classifier prompt for batch_002.jsonl>"
Task tool_use #3  → subagent_type="general-purpose", prompt="<classifier prompt for batch_003.jsonl>"
Task tool_use #4  → subagent_type="general-purpose", prompt="<classifier prompt for batch_004.jsonl>"
Task tool_use #5  → subagent_type="general-purpose", prompt="<classifier prompt for batch_005.jsonl>"

所有五个 tool_use 块都位于同一条 <assistant> 消息中,因此会并行运行。有些运行环境会一次性返回五个结果;其他运行环境会在后台启动 SubAgent,并在每个 SubAgent 完成时分别报告。无论哪种情况,都要等本轮的所有 batch_NNN_result.json 文件都存在后,再进行一次合并。

❌ 错误 — 分成五条消息(这就是串行分派):

Message N:    Task tool_use #1 ─→ wait for result
Message N+1:  Task tool_use #2 ─→ wait for result   ← SERIAL, makes Standard run 70% slower
Message N+2:  Task tool_use #3 ─→ wait for result
...

如果批次数量超过 5 个,请分多条消息、每次发送 5 个——每条消息仍包含 5 个并行的 Task 块。

每个 SubAgent 读取其批次文件,应用 RCS 评分标准,并写入 "$SEARCH_DIR/classifications/batch_NNN_result.json"。然后将分类结果合并到 KG 中:

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.rcs_parser \
    --input-dir "$SEARCH_DIR/classifications/" \
    --kg "$SEARCH_DIR/kg.json" \
    --output "$SEARCH_DIR/kg_classified.json"
第 7 步 — 计算饱和曲线(所有层级均必须执行)

📖 执行此步骤前,请阅读:references/stop_decision.md。

此步骤不可选,即使是 Quick 也必须执行:第 8 步会根据 curve.json 做出决定,第 12 步也会显示同一估算值。

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.discovery_curve \
    --kg "$SEARCH_DIR/kg_classified.json" \
    --output "$SEARCH_DIR/curve.json"

curve.json 给出 coverage_estimate(0-1)以及 ci_lower / ci_upper,并包含 method:sample_coverage 表示根据本次运行在 raw/ 中的独立搜索重复找到相同高相关论文的频率进行估算(relevance_band 7 = rcs ≥ 7;如果 rcs ≥ 7 的论文太少,估算器无法得出结论,则使用 6 = rcs ≥ 6);prior 表示没有可供测量的数据——搜索次数少于两次、没有找到相关论文,或任一档中的论文过少——因此该值是上限为 50% 的 Undermind 中位先验值,而非测量结果;如果引用该值,请说明这一点。--raw-dir 可覆盖读取搜索结果的位置(默认读取 --kg 同级的 raw/)。

第 8 步 — 决定下一步操作(必须执行)

📖 执行此步骤前,请阅读:references/stop_decision.md。

此步骤不可选。请根据 curve.json、层级预算和用户意图,明确做出决定,并向用户说明理由。不要凭直觉跳过。

决策树(基于 coverage_estimate):

  • coverage < 0.6 且仍有预算,且层级属于 {standard, deep, audit} → 扩展引用(第 9 步)
  • coverage > 0.85 或预算已用尽 → 停止,撰写报告(第 10 步及后续)
  • 情况不明确 → 告知用户具体数值并询问
步骤 9 — 扩展引文(如适用)

📖 执行此步骤前,请阅读:references/citation_chasing.md。

对于 rcs >= 7 的 top-rcs 论文,获取引文网络。若种子论文有 DOI,请传入其 DOI:Semantic Scholar 备用方案也支持 DOI,而单独的 W-ID 无法在 OpenAlex 之外解析。

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.openalex_helper citation-network <doi_or_openalex_id> \
    --refs-limit 25 --cited-by-limit 25 \
    > "$SEARCH_DIR/raw/citations_01.json"      # one file per seed: citations_02.json, ...

然后返回步骤 5:将 raw/citations_*.json 文件添加到 --input-files(解析器会读取其中的 references / cited_by 列表),仅在步骤 6 中重新分类新增条目,然后重新运行步骤 7。

步骤 10 — 丰富 top-N 论文信息(L3,可选但推荐)

📖 执行此步骤前,请阅读:references/ss_helper_cheatsheet.md 和 references/crossref_helper_cheatsheet.md。

对于 rcs >= 6 的论文,使用 Semantic Scholar 丰富信息(influentialCitationCount + 摘要备用方案 + tldr)。两个辅助工具都会读取已分类的 KG,并将新字段写回其中,其他字段保持不变;--min-rcs 6 可将范围限制在热门论文。请在步骤 11 前运行此步骤,以便摘要能够按 influential_citation_count 排序。

对于 Quick 档,跳过步骤 10 可以接受,但必须按规则 C 宣布跳过(“跳过了 L3 丰富 → 没有 influentialCitationCount;请使用 --tier standard 重新运行以纳入此项”)。

# Semantic Scholar — adds influentialCitationCount + abstract fallback + tldr
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.ss_helper \
    --input-file "$SEARCH_DIR/kg_classified.json" \
    --mode enrich --min-rcs 6 \
    --output-file "$SEARCH_DIR/kg_classified.json"

它会在 stderr 输出一行,说明丰富了多少篇论文;若 Semantic Scholar 拒绝请求(密钥被拒或触发速率限制),还会说明原因。数量不足时,请转告用户这一行内容;无论如何,运行都会继续。

仅在确有需要时使用 CrossRef(资助方 / 许可证 / 临床试验编号)——例如临床或资助相关问题,或用户主动提出:报告不会显示这些字段。

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.crossref_helper \
    --input-file "$SEARCH_DIR/kg_classified.json" \
    --mode all --min-rcs 6 \
    --output-file "$SEARCH_DIR/kg_classified.json"

可选(增补)——期刊分区(中科院 / JCR / SJR)。 多平台分区层会为每篇论文标注全部三个平台的分区。此功能为可选启用,默认关闭——跳过后,报告的字节内容完全不变(R-19)。📖 请先阅读 references/journal_metrics.md(其中汇总了数据来源、ISSN 关联、归属规则和 R-04 命名规范)。

  • 首次使用需要抓取一次数据(仅初始化一次;数据会在运行时下载到 ~/.paper-search-pro/ranks/,不会打包进仓库)。如果之前没有 抓取过,请运行一次(并告知用户这只是一次性步骤):
    PYTHONPATH=$PSP_HOME python3 -m scripts.journal_rank fetch          # all three
    # or a single platform: ... journal_rank fetch --platform cas
    PYTHONPATH=$PSP_HOME python3 -m scripts.journal_rank info           # what's cached
    
  • 用户已指定分区档位 → 论文已在步骤 5 后立即完成标注和筛选;此处无需操作。
  • 用户未指定分区档位,但想查看分区 → 仅标注(不筛选):
    PYTHONPATH=$PSP_HOME python3 -m scripts.rank_filter \
      --kg "$SEARCH_DIR/kg_classified.json" --output "$SEARCH_DIR/kg_classified.json"
    
    如果没有缓存数据,它会输出一行提示且不做任何更改;请告知用户可以运行 journal_rank fetch 来启用分区。
  • R-04 命名规范已在序列化字典中自动执行:只有 JCR 会公开 impact_factor(实际 IF);中科院“区”和 SJR 四分位数均属于分区 / quartile。
步骤 11 — 撰写执行摘要

📖 开始此步骤前,请阅读:references/summary_writer.md。

📖 另请阅读:references/report_title.md,然后在撰写摘要时一并拟定 DISPLAY_TITLE。这应是一个基于保留语料、受证据范围约束的学术报告标题,而不是照搬 USER_QUERY、SEARCH_TOPIC 或筛选列表。标题应体现报告的核心叙事和视觉形象。语言、日期、数据库、期刊分区、导出和工作流要求应留在 Methods / PRISMA-S 中,除非它们本身具有科学意义。如果证据不足以支持一个具体标题,请使用本地化的安全回退标题(文献检索报告 / Literature Search Report),不要将原始请求放进 H1。在步骤 12 前,按照参考文档执行预渲染验收检查。

根据分类后的论文,用自己的话撰写一篇约 300 字的执行摘要,涵盖:

  • 该领域的主要共识
  • 关键方法 / 理论框架
  • 值得注意的分歧或未解问题
  • 最具影响力的 3–5 篇论文(按 influential_citation_count 排序,如有此数据)
  • (可选) 领先论文的期刊分区,前提是你已在步骤 10 附加 SJR 指标——表述为“SJR 分区 / 期刊影响力”,绝不能写“影响因子 / JCR”(R-04)。未附加指标时,完全跳过此项。

保存到 "$SEARCH_DIR/summary.md"。

分区默认值 / 询问 / 筛选 / 报告 / 切换流程(补充规则 — 仅在启用分区时适用)。 如果启用了期刊分区(在步骤 5 后进行了筛选,或在步骤 10 标注了分区),请遵循此流程;该流程完全可选,不会改变未启用分区时的默认路径(R-19):

  • 出厂默认标准 = JCR。 持久化默认值位于配置 rank.default_platform 中(开箱默认值:jcr;用户可将其设为 cas / sjr)。默认平台只为每篇论文标注分区,除非用户实际要求按分区筛选,否则不会进行筛选。
  • 未提及分区 → 不要筛选。 只需显示每篇论文在三个平台上的分区标签(步骤 10 的标注操作已完成此项),让用户自行查看 / 调整。绝不要擅自添加用户未要求的分区筛选条件。
  • 用户要求了分区(来自步骤 1 的意图或本轮用户指令)→ 分类前筛选一次(步骤 5 之后立即使用 rank_filter)。使用步骤 1 的解析结果:platform + tiers / quartiles / top。单次请求的分区筛选是临时的——绝不自动将其保存到配置中。只有用户明确表示“以后都用 X”时,才更改持久化默认值。
  • 只说了“Q1”但未指定平台,且没有持久化默认值 → 提出一个简短问题(你应该已在步骤 1 询问;如果没有,现在询问):“按 JCR 还是 SJR?顺带设默认吗?”可以进行简短确认,但不要过度追问。
  • 始终报告本次运行的操作。 筛选后,用一行告知用户:“本次按 {platform} 筛选(保留 N / 筛除 M)”,并简单提示:“可换中科院 / JCR / SJR 或换档位,也可设为以后的默认值。”同时注明各平台的来源说明(journal_rank.ATTRIBUTION[platform])。
  • 切换标准或分区 = 对论文池重新筛选,而非重新检索。 用户随后表示“换成中科院二区”或“看看 SJR Q1”时,不要重新运行检索:使用新平台 / 分区对完整的 kg.json 论文池重新运行 rank_filter(只需几秒)。新纳入的论文尚无评分——仅对这些论文进行分类(步骤 6),然后使用 --kg kg_ranked.json 对所有 classifications/ 重新运行 rcs_parser。只有重新筛选后剩余论文过少时,才返回步骤 3 深入检索。“切换 = 重筛不重搜”这一规则让分区探索成本低廉。
  • 持久化默认值(仅在用户明确表示“以后都用 X”时):在 ~/.paper-search-pro/config.yaml 中设置 rank.default_platform。分区档位永不持久化——只持久化平台默认值。
  • 摘要条目中的 R-04 命名也适用: 中科院“区”和 SJR quartile 应称为分区 / quartile;只有 JCR IF(2024) 才是影响因子 / Impact Factor。OpenAlex 2yr-mean-citedness 数值称为“期刊影响力”(open),绝不能称为 JIF。
第 11.5 步 —— 导出检索策略(可选——绝不走默认路径)

触发矩阵——先默默判断,再进行任何操作:

运行类型导出行为
快速不运行。不要提及,也不要询问——直接进入第 12 步。此处静默跳过是规则 C 的唯一例外:宣布跳过本身就会干扰未触碰的默认路径(R-19)。
标准搜索期间不运行——不询问,直接进入第 12 步。**在第 14 步,仅当本次运行存在可由导出弥补的缺口时,用一句话提出:**检索范围包含中文(zh / both:知网 / 万方覆盖了 PSP 无法触及的大量内容),或 coverage_estimate < 0.6(其他数据库可以补充覆盖)。没有此类缺口 → 不要提及。如果第 4 步本次运行中已经提出过,则跳过此提议。接受 → 运行本步骤,然后重新运行 12a–12c,让报告增加导出选项卡。
深度提出一次,用一句轻描淡写的话:“要不要顺带导出各平台可粘贴的专业检索式?” 接受 → 运行;拒绝或未回应 → 跳过,不再提及。
审计默认运行——这是审计免责声明所承诺的交付内容(示例 4)。
明确提出要求,任意层级“给我 WOS 检索式” / “我要去知网查” / “导出检索式” / 接受第 4 步的知网提议 → 立即运行,不受层级影响。

📖 执行本步骤前(满足触发条件时),阅读:references/search_export/methodology.md——以下所有语义判断的规则手册。只要 zh / both 检索范围会导出 CNKI / 万方 / SinoMed,就还要阅读 references/search_export/chinese_methodology.md(中文检索策略并非西方布尔检索的逐字翻译)。

第 1 层——语义。这是你的工作(主 Agent);脚本只负责组装语法:

  1. 根据方法论中的区块规范,基于 "$SEARCH_DIR/query_plan.json" 重建概念区块——区块内的 OR 只能表示同一概念的同义词;区块之间用 AND 连接;默认使用 2 个区块(P+I),仅当 C/O 是核心内容且在标题/摘要中持续报告时才纳入;禁止使用 NOT。不要原样复制 query_plan 区块:重建时要修正混合概念区块。
  2. 按区块扩展同义词和入口词——拼写变体(tumour/tumor)、缩写 + 全称(MBSR + "mindfulness-based stress reduction")、相关术语。zh / both 检索时,还要将中文同义词填入每个区块的 free_text_zh(简繁 / 别名 / 全称–缩写变体——中文没有截词功能,因此要逐一明确列出):CJK 数据库(CNKI / 万方 / SinoMed)只读取 free_text_zh;区块若缺少该字段,就必须如实省略所有中文检索策略——绝不能将英文词转换成中文数据库检索词。
  3. 为各平台分别判断受控词表候选词——在每个数据库中独立判断 MeSH / Emtree / CINAHL / APA / CMeSH;绝不要把一个叙词表的符号翻译成另一个叙词表的符号。优先使用第 4 步已回填到 KG 的 MeSH(来自真实检索结果的真实描述词)。
  4. 按学科缩减平台集合,从审计完整列表中选择(PubMed、WOS、Scopus、Embase、Cochrane CENTRAL、PsycINFO、CINAHL、ERIC、IEEE Xplore、ACM DL、EconLit、CNKI、万方、SinoMed、ClinicalTrials.gov)——医学主题不需要 IEEE/ACM;社会科学主题不需要 Cochrane/SinoMed。zh / both 检索始终包含 CNKI + 万方 + SinoMed。
  5. 检索语域按层级选择(审计 = 倾向召回,受控词 + 自由文本双轨并行)。需要研究设计筛选式(例如 RCT)?📖 阅读 references/search_export/filters_library.md——原样使用经验证的预设筛选式;绝不要自行编写,也绝不要在 CENTRAL 上添加。
  6. 对第 1–5 项进行 PRESS 六领域自查,然后才能开始编写任何语法。📖 阅读 references/search_export/press_checklist.md。 将结果写入 "$SEARCH_DIR/concept_model.json",使用生成器的封装格式:{topic, framework, register, language_space, search_id, platforms, concept_model: {blocks (free_text + free_text_zh on zh/both + controlled_vocab_candidates), operator_logic, omitted_blocks + reasons, register_notes}}。请使用用户的语言撰写 omitted_blocks.reason 和 register_notes——它们会原样显示在面向用户的 search_strategies.md 中(中文用户看到的是中文说明,而不是直接显示英文)。

第 2+3 层 — 机械组装 + 验证(由脚本负责;切勿手动组装各主机语法):

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.search_export.generate \
    --concept-model "$SEARCH_DIR/concept_model.json" \
    --out "$SEARCH_DIR"

可选标志(已对照 argparse 验证):--platforms pubmed,wos,cnki(csv)覆盖封装文件中的 platforms;--topic / --framework / --register / --language-space / --search-id 覆盖封装文件中的运行级字段;--no-verify-vocab 跳过 MeSH/ERIC 免费 API 检查(术语会标记为未经验证);--live-verify-links 对每个 A 级链接执行实时 GET,以获取最新的 verified_http/日期。

生成 search_strategies.md(可直接粘贴,按平台区分)和 search_strategies.json。在底层,脚本会读取各主机语法卡片(references/search_export/syntax_cards/<host>.md)和邻近算符转换表(n 值绝不手动计算——你也不例外),仅为免费的 A 级平台(PubMed / ERIC / ClinicalTrials.gov)构建可点击的深层链接(链接绝不会绕过登录或验证码墙),通过 API 验证 MeSH/ERIC 术语,将 Emtree/CINAHL/APA/CMeSH 标记为待人工核对,并对每条策略运行 lint 检查——被 lint 拒绝的字符串会被拦截,绝不输出。下游接入:STEP 12a 会自动发现 report_data.json 旁边的 search_strategies.json 并将其纳入(无需额外标志);对于 STEP 13,请在 prisma_s_logger 命令中追加 --search-strategies "$SEARCH_DIR/search_strategies.json",以便据此补充 PRISMA-S 第 8/1/9/10 项。

交付前检查(诚信关卡):.json 中包含每个平台的三态验证标签(🟩机械已验 / 🟨语法已验·词表待核 / 🟦结构参考)和复核点——请确认它们准确无误;面向用户的 .md 会将这些内容呈现为各平台通俗易懂的“使用前请核对”说明(不含内部术语)——请确认每条说明都清晰且可执行;订阅墙平台必须如实标记为“需机构登录,未在墙内实测”;CNKI / 万方 / SinoMed 必须提供可粘贴到检索框的检索策略,而非 URL。质量承诺应为“专业初稿 + 标注复核点”——绝不可声称“可署名直用 / 馆员级”。

STEP 12 — 渲染报告

📖 执行此步骤前,请阅读:references/output_files.md。

# 12a. Materialize data for the renderer (also writes sibling chart_data / paper_list / metadata / prisma_log)
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.data_materialization \
    --kg "$SEARCH_DIR/kg_classified.json" \
    --summary "$SEARCH_DIR/summary.md" \
    --query "<original query>" \
    --search-topic "$SEARCH_TOPIC" \
    --display-title "$DISPLAY_TITLE" \
    --language "$UI_LANG" \
    --tier "<quick|standard|deep|audit>" \
    --search-id "$SEARCH_ID" \
    --snapshots "$SEARCH_DIR/curve.json" \
    --output "$SEARCH_DIR/report_data.json"

# 12b. Render HTML (Shadcn webartifacts — only renderer; no size cap)
#      --language $UI_LANG selects EN vs ZH UI; the bundle ships with both
#      dictionaries inlined, $UI_LANG just picks which one mounts. Resolution
#      order inside the renderer is: explicit --language > metadata.language > en.
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.html_renderer_webartifacts \
    --data "$SEARCH_DIR/report_data.json" \
    --output "$SEARCH_DIR/report.html" \
    --query "<original query>" \
    --search-topic "$SEARCH_TOPIC" \
    --display-title "$DISPLAY_TITLE" \
    --language "$UI_LANG"
#     add --rank-platform cas|jcr|sjr when this run filtered on a platform,
#     so the badges and zone filter show that platform (default: JCR)

# 12c. MD report (uses materialized-dir for speed)
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.md_report \
    --materialized-dir "$SEARCH_DIR" \
    --summary "$SEARCH_DIR/summary.md" \
    --query "<original query>" \
    --search-topic "$SEARCH_TOPIC" \
    --display-title "$DISPLAY_TITLE" \
    --language "$UI_LANG" \
    --tier "<quick|standard|deep|audit>" \
    --output "$SEARCH_DIR/report.md"

# 12d. Exports (BibTeX / RIS / CSV / papers.json — only rcs >= 5 by default)
PYTHONPATH=$PSP_HOME \
  python3 -m scripts.generate_exports \
    --kg "$SEARCH_DIR/kg_classified.json" \
    --output-dir "$SEARCH_DIR/" \
    --min-rcs 5

如果 12a–12c 输出 No scholarly display title was given,则 DISPLAY_TITLE 为空,报告 H1 使用的是通用备用标题。请填写标题(STEP 11,references/report_title.md),然后重新运行 12a–12c;无需重新搜索。

如果你自行跟踪了耗时,data_materialization 可接受 --wall-clock-seconds;否则,在可用时,辅助程序会根据会话时间戳计算耗时。

STEP 13 — 编写 PRISMA-S 日志

📖 执行此步骤前,请阅读:references/prisma_s_checklist.md。

PYTHONPATH=$PSP_HOME \
  python3 -m scripts.prisma_s_logger \
    --search-id "$SEARCH_ID" \
    --kg "$SEARCH_DIR/kg_classified.json" \
    --user-query "<original query>" \
    --tier "<quick|standard|deep|audit>" \
    --query-plan "$SEARCH_DIR/query_plan.json" \
    --snapshots "$SEARCH_DIR/curve.json" \
    --output "$SEARCH_DIR/execution_log.json"

这会记录 PRISMA-S 的 16 个项目,以便透明披露和审计。

第 14 步 —— 打开报告并向用户汇报

首先,在用户的默认浏览器中自动打开 HTML 报告(不要等用户提出要求)。支持平台识别的 Bash:

# macOS — most common dev setup
open "$SEARCH_DIR/report.html"
# Linux fallback — xdg-open "$SEARCH_DIR/report.html"
# Windows fallback — start "" "$SEARCH_DIR/report.html"

在 macOS 上默认使用 open。如果失败(少见——仅在裸 Linux 容器中),则依次尝试 xdg-open 和 start。不要跳过此步骤——用户刚刚等待了 5–30 分钟,报告一准备好就应该让他们看到。

然后告诉用户:

  • “已在默认浏览器中打开报告。”(1 行确认)
  • 报告在磁盘上的位置(绝对路径:$SEARCH_DIR/report.html),方便用户之后查找
  • 主要发现(从执行摘要中摘取 3–5 句话)
  • 任何注意事项——包括依据规则 C 跳过的步骤(例如:“未检测到医学相关信号,因此未查询 PubMed”“因使用 Quick 层级,跳过了第 10 步的 L3 增强;重新运行 Standard 层级即可包含资助方/许可证字段”)
  • 仅当第 11.5 步的 Standard 行发现缺口时:用一句话提出可导出检索策略,并说明缺口和耗时——例如:“这次中文侧主要缺知网、万方的文献;需要的话我把这两个库的专业检索式写好(约 3–4 分钟),粘进检索框就能查。” 或 “估算覆盖率 45%,还有不少没找到;需要的话我把 WOS、Scopus、PubMed 的检索式写好(约 3–4 分钟),你拿去补检。”

输出规范

📖 完整目录结构请参阅 references/output_files.md。以下所有路径均相对于用户的工作目录(PWD)——绝不是 Skill 资源目录。

$(pwd)/paper-search-results/<search_id>/
├── report.html              # Main deliverable (Shadcn style)
├── report.md                # Markdown copy
├── papers.csv               # Spreadsheet export
├── papers.bib               # Citation manager import (BibTeX)
├── papers.ris               # Alternative citation format
├── papers.json              # Full structured data
├── kg_classified.json       # Internal KG with RCS scores
├── summary.md               # Your executive summary
├── metadata.json            # Includes original_user_query / search_topic / display_title
├── execution_log.json       # PRISMA-S 16-item log
├── report_data.json         # Renderer bundle
├── chart_data.json          # Sibling: chart series
├── paper_list.json          # Sibling: per-paper list
├── prisma_log.json          # Sibling: PRISMA log JSON view
├── curve.json               # Coverage snapshot (STEP 7)
├── query_plan.json          # STEP 1 output
├── raw/                     # Retrieval output only, one file per search (openalex.json, pubmed.json, citations_01.json, …)
├── batches/                 # batch_NNN.jsonl files
└── classifications/         # batch_NNN_result.json files

错误处理

📖 请参阅 references/error_handling.md。常见情况:

错误处理方法
配置缺少键指引用户查看 references/setup.md,然后停止
速率限制(SS 429/NCBI 429)Helper 会自动重试;如果持续出现,则移除该增强器
SS 增强打印“0/N papers enriched (…)”Semantic Scholar 拒绝了请求(密钥被拒或触发速率限制),Helper 提前停止;转告用户该行内容,然后继续
OpenAlex 不可用(预算耗尽/被限流/服务宕机)openalex_helper 会自行改用 Semantic Scholar 执行调用;转告用户其 stderr 行,然后继续。退出码 3 = Semantic Scholar 也无法提供服务:按其他 OpenAlex 错误处理(告知用户发生了什么,以及 OpenAlex 何时重置)
OpenAlex DOI 查询返回 404使用标题搜索作为回退方案(Helper 会处理)
L2 booster 返回 0 篇论文静默跳过,并通过第 13 步记录在 PRISMA-S 日志中
SubAgent 分类器返回无效 JSONrcs_parser.py 有 5 层回退机制(正则解析)
HTML 输出大小没有大小上限或回退方案——html_renderer_webartifacts 始终会生成完整的 Shadcn bundle。典型的 250 篇论文报告约为 1.7 MB;极端情况下,包含 1000 篇以上论文的审计报告可能达到 5–10 MB。所有现代浏览器都能顺畅处理 10 MB 以上的 HTML。

参考文档(渐进式披露——进行到哪一步,就阅读对应的文档)

每次运行时,你不必、也不应阅读所有文档。进行到某一步时,如果该步骤对当前情况并非简单明了,请阅读对应的参考文档(规则 D)。核心 = 执行该步骤时必读;条件 = 仅在触发条件满足时阅读。

文件加载方式阅读时机
tier_decision.md核心选择层级时(STEP 0 之前)
setup.md核心STEP 0 — 配置 + 获取 5 个密钥
runtime_bootstrap.md条件STEP 0/1 — 仅当 $PSP_HOME 环境注入失败,或你需要完整的安装路径列表/语言路由依据时
query_planner.md核心STEP 1 — PICO / SPIDER / PEO 框架
source_routing.md核心STEP 1 语言范围(§“Language scope” 单一事实来源)+ STEP 2 路由 + STEP 5 字段优先级合并
openalex_helper_cheatsheet.md核心STEP 3 + STEP 9 — 子命令、参数、注意事项
pubmed_helper_cheatsheet.md条件STEP 4 — 仅当启用 PubMed 时
arxiv_helper_cheatsheet.md条件STEP 4 — 仅当启用 arXiv 时
classifier_subagent_prompt.md、rcs_rubric.md核心STEP 6 — SubAgent 提示词 + RCS 0-10 分评分标准
stop_decision.md核心STEP 7 + STEP 8
citation_chasing.md条件STEP 9 — 仅当扩展引用时
ss_helper_cheatsheet.md、crossref_helper_cheatsheet.md条件STEP 10 — 仅当补充排名前 N 项时
summary_writer.md核心STEP 11
report_title.md核心STEP 1 规范化主题 + STEP 11 基于证据的展示标题;避免使用原始查询作为 H1
search_export/methodology.md条件STEP 11.5 — 仅当触发策略导出时(Audit 默认/明确要求/接受 Deep 提议);语义层规则手册
search_export/chinese_methodology.md条件STEP 11.5 — 仅限 zh/both 路径(CNKI / 万方 / SinoMed 策略;不是对西方布尔检索式的翻译)
search_export/press_checklist.md条件STEP 11.5 — 对概念模型进行 PRESS 六领域自查
search_export/filters_library.md条件STEP 11.5 — 仅当需要研究设计筛选器时(预设的已验证筛选器;绝不自行编写)
search_export/syntax_cards/<host>.md条件STEP 11.5 — 各平台语法事实,由生成器/检查器读取;仅在手动调整单个平台的策略时自行打开
journal_metrics.md(SSOT)条件STEP 1 / STEP 10-11 — 仅当用户需要期刊分区(中科院 / JCR / SJR)或 SJR 指标时;ISSN 合并、归属、R-04 命名
output_files.md核心STEP 12 — 输出目录布局(相对于 PWD)
prisma_s_checklist.md核心STEP 13
agent_mode.md(SSOT)条件仅当其他 Agent/无头模式调用此 Skill 时 — agent_search 封套 + 标志
error_handling.md条件遇到任何意外错误时

示例

示例 1:快速浏览(5-8 分钟)

用户:“找 5-6 篇关于决策中的前景理论的高影响力论文,包含经典论文和几篇近期论文”

你:选择 Quick 层级(信号:“5-6”、“高影响力”、简短查询)。轻量执行 STEP 0-2。STEP 3 使用 openalex_helper seminal 查找经典论文,使用 openalex_helper search 查找近期论文(年份 >= 2020)。STEP 4 不使用 L2 增强工具(纯社会科学)。STEP 6 通过一条消息中的 2 个并行 SubAgent 对 20-30 篇论文进行分类。仍然执行 STEP 7 + 8(曲线会显示在报告中)。根据规则 C,说明跳过 STEP 9 + STEP 10。生成报告。

Example 2: Standard ZH (10-17 min)

User: "用 paper-search-pro 帮我找一些关于工作记忆训练干预的文献 老板让我看 我对这块完全不懂 要给老年人群体的最好 谢谢🙏"

You: Pick Standard tier (default; signals: "找一些", "老板让我看"). Detect medical signal ("干预" + "老年") in STEP 2 → enable PubMed enricher. Query plan: PICO (P=elderly, I=working memory training, O=cognitive outcomes). OpenAlex double-sort top-100 in STEP 3. PubMed enrich of openalex.json in STEP 4. Federate in STEP 5 (dict output). Classify 60-180 papers via 4 batches × 5 SubAgents — all 5 Tasks in one message (Rule B). STEP 7 curve, STEP 8 expand if saturation < 0.6. Render report.

Example 3: Deep × Lit review writing (30-45 min)

User: "I'm writing a proper literature review article on attachment and human-robot interaction in elderly care contexts. Need real depth..."

You: Pick Deep tier ("proper literature review article" + "real depth"). Cross-domain (psychology + CS) in STEP 2 → enable arXiv's recent layer and OpenReview. SPIDER plan in STEP 1. OpenAlex double-sort top-200 + reviews subcommand in STEP 3. Classify 200+ papers via 8 batches in STEP 6 — dispatch 5 parallel Tasks per message, two waves. STEP 9 expand citations 2 hops. STEP 10 enrich top-50 with SS + CrossRef. Render report with PRISMA-S log.

Example 4: Audit × SR-prep (2-3 hr)

User: "Need help — preparing a systematic review on dietary interventions for IBS in adults. Inclusion criteria: RCTs, adult populations (≥18), low-FODMAP or fiber-based interventions, English-language, published 2010-present."

You: Pick Audit tier ("systematic review" + PICO + IC). Show limitations warning first and get user confirmation — the Audit disclaimer is a deliver-on-it promise, fulfilled by STEP 11.5 (which Audit runs by default). At delivery it reads:

这是 SR 前期助手,不是 PRISMA 替代。我已为你写好各平台可粘贴的专业检索式初稿——每个平台附「使用前请核对」清单(已对官方词表核实的 MeSH 主题词、与需要你在库内人工确认的 Emtree 等主题词,都分别写明了);注册制 SR 仍需你在订阅库亲自执行,并补 ClinicalTrials.gov(注册库检索是方法学硬要求,已给检索式+直达链接)与 ICTRP/灰色文献。

(Up front, before the run, phrase the same promise in future tense — "我会为你写好…".) STEP 4 use pubmed_helper search-mesh "Irritable Bowel Syndrome" --pub-type "Randomized Controlled Trial" for independent MeSH search. STEP 3 also call openalex_helper journal-list --preset Cochrane. STEP 10 add CrossRef enrichment for funder + clinical-trial-number. STEP 11.5 exports the per-platform strategies (Audit default). Render with PRISMA flow chart in STEP 12.

评论

支持 Markdown