关于 paper-search-pro
paper-search-pro 是用于多来源学术文献检索的 Skill,可按需求调整检索深度,面向研究者和 Agent。Python 辅助脚本负责确定性检索与评分;面向人工的流程还包含并行 LLM 分类和报告输出。
主要功能
- 01提供四档检索深度
- 02检索五个文献来源
- 03去重并评估相关性
- 04并行 SubAgent 分类
- 05生成 HTML 报告和数据导出
适用场景
- 01为论文提案梳理研究范围
- 02收集文献综述资料
- 03开展深入的系统综述检索
- 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.gitignoreNOTICE.mdTHIRD_PARTY.md.skillignoreLICENSE.txtREADME.zh.md.github/workflows/tests.ymlassets/md_template.md.jinjadefault_config.yamlassets/benchmark_queries/sparbench_subset.jsonlitsearch_subset.jsoncustom_zh_queries.jsonassets/webartifacts_app/paper-report/.parcelrccomponents.jsonindex.htmleslint.config.jspackage.jsonpostcss.config.jspnpm-lock.yaml.gitignoreREADME.mdassets/webartifacts_app/paper-report/src/App.cssApp.tsxassets/webartifacts_app/paper-report/src/components/adapters/SegmentedToggle.tsxSearchInput.tsxKickerAccordion.tsxKickerAlert.tsxassets/webartifacts_app/paper-report/src/components/audit/ComplianceSummary.tsxPrismaRow.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);脚本只负责组装语法:
- 根据方法论中的区块规范,基于
"$SEARCH_DIR/query_plan.json"重建概念区块——区块内的 OR 只能表示同一概念的同义词;区块之间用 AND 连接;默认使用 2 个区块(P+I),仅当 C/O 是核心内容且在标题/摘要中持续报告时才纳入;禁止使用 NOT。不要原样复制 query_plan 区块:重建时要修正混合概念区块。 - 按区块扩展同义词和入口词——拼写变体(tumour/tumor)、缩写 + 全称(MBSR + "mindfulness-based stress reduction")、相关术语。
zh/both检索时,还要将中文同义词填入每个区块的free_text_zh(简繁 / 别名 / 全称–缩写变体——中文没有截词功能,因此要逐一明确列出):CJK 数据库(CNKI / 万方 / SinoMed)只读取free_text_zh;区块若缺少该字段,就必须如实省略所有中文检索策略——绝不能将英文词转换成中文数据库检索词。 - 为各平台分别判断受控词表候选词——在每个数据库中独立判断 MeSH / Emtree / CINAHL / APA / CMeSH;绝不要把一个叙词表的符号翻译成另一个叙词表的符号。优先使用第 4 步已回填到 KG 的 MeSH(来自真实检索结果的真实描述词)。
- 按学科缩减平台集合,从审计完整列表中选择(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。 - 检索语域按层级选择(审计 = 倾向召回,受控词 + 自由文本双轨并行)。需要研究设计筛选式(例如 RCT)?📖 阅读
references/search_export/filters_library.md——原样使用经验证的预设筛选式;绝不要自行编写,也绝不要在 CENTRAL 上添加。 - 对第 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 分类器返回无效 JSON | rcs_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.