关于 ref-verify
ref-verify 是面向研究者和写作者的论文引文与事实核查技能,通过 CLI 和手动流程,要求论述依据实时获取的摘要或全文。
主要功能
- 01快速筛查 DOI 和元数据
- 02核查摘要是否支持论述
- 03检查 BibTeX、RIS 和参考文献
- 04执行五层完整审计流程
- 05CLI 不可用时采用手动核查
适用场景
- 01检查带 DOI 的参考文献
- 02确认摘要是否支持引用论述
- 03投稿前审查参考文献
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ moonweave-research/ ref-verify --skill ref-verify安装后在 Claude Code 中输入/ref-verify确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
.gitignoreAGENT_USAGE.mdREADME.mdSECURITY.mdCODE_OF_CONDUCT.mdCONTRIBUTING.mdLICENSECHANGELOG.mdREADME.ko.md.github/PULL_REQUEST_TEMPLATE.md.github/ISSUE_TEMPLATE/feature_request.mdfalse_positive.mdmissed_hallucination.md.github/workflows/ci.ymlpages.ymlpublish-pypi.ymllive-smoke.ymlbenchmarks/README.mdclaims-copy-v1.jsonlclaims-v1.jsonlbenchmarks/e2e/adjudication.jsonREADME.mdbuild_truth.pyengine_only.pybenchmarks/e2e/manuscripts/m4_physics_en.mdm2_vaccine_en.mdm1_dea_en.mdm3_ml_en.mdbenchmarks/e2e/manuscripts/m5_dea_latex/main.texreferences.bib详细介绍
ref-verify — 参考文献幻觉防护
此技能要防止的具体问题:大模型根据训练数据中的记忆来描述论文内容,而不是依据摘要的实际表述。论文被归因了其并未包含的研究发现,或被引用来支持正文中根本没有出现的论点。解决办法是一条始终如一地遵循的规则:
关于论文的每一条内容陈述,都必须来自实时获取的来源——摘要用于主要/核心结论,全文用于机制/实现/程序性论述——并逐字引用或转述。如果无法获取所需来源,请明确说明;绝不要用记忆中的描述填补空缺,也绝不要用主题相关的摘要来代替机制层面的论据。
模式选择
开始任何工作前,先选择模式。模式决定成本和深度。
User provides DOI(s) for sanity check?
└─ ≤10 refs → Quick Screen all
└─ >10 refs → Quick Screen all; Full Audit only MISMATCH/DEAD results
User says "find papers on X" or "cite papers supporting claim Y"?
└─ Full Audit (searching from scratch requires content verification)
User says "verify/check my reference list" or pre-submission audit?
└─ CLI available → Pre-submission sweep (below) first: check-bib, then check-file
└─ ≤5 refs → Full Audit all
└─ >5 refs → Quick Screen all first; Full Audit MISMATCH/DEAD + any ref
cited for a specific factual claim
User is writing inline and adds a single citation from memory?
└─ Quick Screen minimum; Full Audit if citing for a specific claim
成本较高的部分是完整审计(5 层、获取源深度证据)。快速筛查每篇论文约需 5 秒。只有任务确实需要核实内容时,才升级到完整审计。
可执行引擎
将此作为技能级工作流使用。此路径不需要构建或要求 MCP。 CLI 是技能可从终端调用的执行引擎;对于 CLI 尚未涵盖的层,手动 协议仍是备用方案和事实依据。
CLI 可用性检查
此技能自带引擎:npx skills add 会将 src/ 文件夹复制到此 SKILL.md
所在目录。进行基于 DOI 的检查前,按以下顺序解析一次引擎,并保留第一个
能够输出帮助信息的命令:
-
与此技能捆绑(与此 SKILL.md 版本相同;无需安装,设置时无需 联网):
PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli --help$SKILL_DIR是包含此 SKILL.md 的文件夹的绝对路径(Claude Code 会将其显示为技能的基础目录;npx skills add -g会将其安装到~/.agents/skills/ref-verify)。绝不要使用相对src路径:工作目录是用户的项目,而不是技能文件夹。 需要 Python 3.10 或更高版本。 -
已安装的控制台脚本(
pip install ref-verify或pipx install ref-verify):ref-verify --helpnpx skills add不会通过 pip 安装 Python CLI,因此通常没有此脚本。 -
通过 uv 从 PyPI 获取:
uvx --from 'ref-verify>=1.3.2' ref-verify --help
以下命令使用捆绑版本;若使用引擎 2 或 3,请将
PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli 替换为 ref-verify(或
uvx 形式)。引擎不可用不代表核实结果。如果三种方式都失败,请遵循下方的
手动备用协议。不要假装 CLI 已运行,也不要凭记忆捏造结果。
CLI 优先工作流
当用户提供 DOI,或询问由 DOI 支持的摘要是否支持某项具体事实论点时,优先使用 CLI。 当前 CLI 的范围包括 CrossRef 元数据核实,以及与 DOI 绑定的摘要论点检查。论点检查会先查询 CrossRef;若 CrossRef 没有摘要,则会依次尝试与 DOI 绑定的 OpenAlex、Semantic Scholar 和 PubMed。
CrossRef 元数据筛查:
PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli verify-doi <doi> \
--title "<provided title>" \
--first-author <provided-first-author-last-name> \
--year <provided-year> \
--json
verify-doi 仅在结果为 PASS 时以 0 退出;WARN 和 REJECT 会返回非零值。
仅提供 DOI 只能检查 CrossRef 是否能解析该 DOI,不足以通过元数据核实。
根据结果采取相应操作:
PASS:报告元数据匹配,然后在所选模式要求时,继续进行第 4 层 DOI 落地页解析和第 5 层撤稿检查。WARN:报告缺失或较弱的元数据,然后针对缺失层继续手动备用流程,不要默默接受该参考文献。 如果出现DOI_NOT_IN_CROSSREF,表示该 DOI 注册在 CrossRef 以外(arXiv、Zenodo、KISTI);请在 doi.org 核实标题和作者,绝不要称该 DOI 已失效。REJECT:停止将该引文作为已核实的引文使用;报告不匹配,并要求用户提供更正后的 DOI 或引文,除非用户明确希望获取替代项。
参考文献列表检查(BibTeX、RIS,或纯文本/Markdown 参考文献目录)。用户提供参考文献列表时,先运行此检查,然后再检查论点:
PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli check-bib <references.bib|.ris|.txt|.md>
当用户希望获得可阅读或分享给他人(如顾问、合著者)的内容时,添加
--report <name>.html(或 .md):HTML 会列出需要优先查看的条目,
并用通俗易懂的语言解释每项判定。将报告路径提供给用户。
按以下方式处理各项结果:
PASS:该引用与 CrossRef 记录匹配(通过其 DOI,或通过搜索找到,结果为REFERENCE_RESOLVED且包含resolved_doi)。WARN,并带有REFERENCE_UNMATCHED(status: UNVERIFIED):CrossRef 搜索未找到匹配记录。将其报告为未经验证,并对其执行手动快速筛查;不要仅凭此结果就称其为伪造。WARN,并带有DOI_NOT_IN_CROSSREF(status: UNVERIFIED):该 DOI 已在其他机构注册(arXiv/Zenodo 通过 DataCite、KISTI、JaLC),因此未比较其元数据;请在 doi.org 上确认,绝不要称其为失效。- 其他
WARN:元数据部分不一致、引用文本过于简略而无法确认,或者(status: MISMATCH)纯文本引用的 DOI 属于reason中所述的论文;报告reason并手动核查。 REJECT:DOI 已失效(DOI_NOT_FOUND)、论文已撤稿(PAPER_RETRACTED),或 DOI 指向另一篇论文。不要再将其作为已验证内容使用。
根据 DOI 摘要核查单条论断:
PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli check-claim <doi> --claim "<specific factual claim>" --json
--source crossref|openalex|semantic-scholar|pubmed 强制指定一个来源(绕过 CrossRef),用于调试单个来源的故障。
按以下方式处理结果:
ACCEPT:引用 CLI 证据,并继续完成所需的手动 DOI 解析、第二来源存在性核查和撤稿核查。WARN或PARTIAL:报告所选摘要来源支持和不支持的内容;若还需要核查其他层级,则继续手动回退流程。UNVERIFIABLE:尝试过的 CLI 来源未提供可信的、与 DOI 绑定的摘要证据。请继续执行下方的手动回退流程,而不要将该论断视为已驳回或已获支持。
CLI 的 ACCEPT 仅是摘要层面的证据。它表示论断中的每个数字及其单位、正负号和方向,都得到同一句摘要内容的支持;即使某个数字与摘要匹配,只要句子不支持另一个数字,就不能判为 ACCEPT。如果论断描述的是机制、实现或流程,不要将该结果提升为完整审计结论;应在第 3 层对论断分类,并先获取所需的全文证据。
对于 JSON 输出,请根据 abstract_source、source_attempts 和 error_code 决定下一步:
CLAIM_SUPPORTED:找到明确的摘要支持。CLAIM_NOT_EXPLICIT:摘要可用,但未明确支持该论断。CLAIM_AMBIGUOUS:存在数值证据或上下文,但对应关系不明确。NO_ABSTRACT:尝试过的 DOI 绑定来源未提供摘要文本。DOI_NOT_FOUND:CrossRef 和 doi.org 均不识别该 DOI,或所选来源未找到与 DOI 绑定的记录。PAPER_RETRACTED:CrossRef 列出了该 DOI 的撤稿通知;在读取任何摘要之前即驳回该论断。DOI_MISMATCH:主要记录或明确选定的 DOI 绑定记录与请求的 DOI 不匹配。SOURCE_API_ERROR、SOURCE_TIMEOUT、SOURCE_RATE_LIMITED、SOURCE_UNSUPPORTED:来源查询失败、超时、受到速率限制,或无法使用。REFERENCE_RESOLVED、REFERENCE_UNMATCHED(仅适用于check-bib):不带 DOI 的引用是否匹配到 CrossRef 记录。DOI_NOT_IN_CROSSREF(适用于verify-doi、check-claim、check-file、check-bib):该 DOI 已在其他注册机构(DataCite、KISTI、JaLC)登记,因此属于未经验证,而非失效。若 OpenAlex 或 Semantic Scholar 提供了摘要,check-claim仍会评估该论断;否则请在 doi.org 上确认该作品。
CLI 不能替代第 4 层的 DOI 落地页解析或双来源存在性核查;它也只能检测到 CrossRef 以撤稿通知形式记录的撤稿。若所选模式要求核查这些层级,请继续执行手动流程。
提交前检查
两项工作都使用引擎。它会查询 CrossRef 和 doi.org 核验参考文献,并依次查询 CrossRef、OpenAlex、Semantic Scholar 和 PubMed 获取摘要,且带有缓存;不要手动编写 curl 调用来完成这些工作。
- 参考文献 →
check-bib。 只保存参考文献列表(References 部分或.bib文件)。正文段落会变成多余的 UNVERIFIED 行。文本输出会为每条参考文献提供一个判定和理由。--json的输出太大,无法放在单个工具结果中:将其写入文件(--json > refs-check.json),然后分段读取。 - 数字声明 →
check-file。 编写claims.jsonl,每条带有数字的引用句子对应一行{"id", "doi", "claim"}(DOI 从参考文献或 check-bib 解析出的 DOI 中获取)。照抄稿件中的数字、单位和方向词(\SI{172.3}{\joule\per\mole}即 172.3 J/mol);照抄时绝不要更正声明。运行PYTHONPATH="$SKILL_DIR/src" python3 -m ref_verify.cli check-file claims.jsonl。文本输出会给出每条声明的判定,以及与之匹配的摘要句子(Evidence)。 - 根据该句子判定每条声明,绝不能凭记忆或仅凭标签判定。
- 数值、单位或方向不同 → 即使判定为
ACCEPT,稿件对论文的表述仍有误;引用该句子并给出正确数值。 - 数值、单位和方向相同 → 摘要提供了引用支持,不构成问题(在任何判定表中,标签仍为
WARN)。 - 句子讲的是其他内容,或只涉及声明的一部分 → 在写明摘要未提及该内容之前,先阅读完整摘要(
check-claim会在paper下打印摘要)。
- 数值、单位或方向不同 → 即使判定为
- 仅手动查找引擎未能判定的内容(
REFERENCE_UNMATCHED、DOI_NOT_IN_CROSSREF、UNVERIFIABLE):查阅第 1 层来源和 doi.org。对于不含标题的引文,搜索作者、期刊以及引用该文献的句子中的主题词;如果找到的记录与引文内容相符,但卷号或页码不同,则说明引文中的卷号或页码有误。机制声明仍需通过第 3b 层核验;模式要求时仍须应用第 4–5 层。
快速筛查 — 元数据 + DOI 合理性检查
当用户提供 DOI 或完整引文并希望进行合理性检查时使用。
- 查询 CrossRef:
https://api.crossref.org/works/{DOI} - 将返回的标题和第一作者姓氏与用户提供的信息进行比较
- 获取
https://doi.org/{DOI}——确认链接能解析并指向正确的论文 - 每条参考文献报告一行:
Smith et al. (2021) 10.1234/example — PASS (title/author match, DOI resolves)
Jones (2019) 10.5678/other — MISMATCH (CrossRef: Jones & Lee 2019, not Jones alone)
Kim (2023) 10.9999/fake — DEAD DOI
如果出现以下情况,请升级为完整审查:DOI 解析后指向另一篇论文、任何字段不匹配,或用户引用该文献是为了支持某项具体事实声明。
完整审查 — 适用于文献检索或提交前检查
适用情况:检索可支持某项声明的论文,或进行最终引文检查。
对每篇论文运行全部五层检查。各层按其能够发现的问题排序——不要跳过前面的层级。
第 1 层 — 存在性
独立搜索两个来源:
- CrossRef:
https://api.crossref.org/works?query.bibliographic={title+author}&rows=5 - OpenAlex:
https://api.openalex.org/works?search={title+author}&per-page=5 - 预印本搜索 arXiv:
https://export.arxiv.org/api/query?search_query=ti:{title}&max_results=3 - 仅当这些来源无法确定该条目时,才使用 Semantic Scholar(它会对共享客户端进行速率限制):
https://api.semanticscholar.org/graph/v1/paper/search?query={title+author}&fields=title,authors,year,externalIds,abstract&limit=5
只有当两个来源中的标题基本匹配且第一作者姓氏一致时,才确认论文存在。
- 两个来源均找到 →
CONFIRMED - 一个来源找到 →
SINGLE-SOURCE ⚠— 谨慎处理,并在输出中注明 - 未找到 →
NOT FOUND ✗— 停止;明确报告;不要编造替代项
第 2 层 — 元数据
从已确认的来源中提取并比较:标题、所有作者(姓氏)、年份、期刊全名、DOI、卷号/页码(若缺失则标记 [NOT IN SOURCE])。如果不同来源中的任何字段不一致,请同时列出两者 — 不要默默选取其中一个。
第 3 层 — 内容可追溯性 ← 最重要的一层
这是该技能的核心价值所在。目标不只是判断「这篇论文是否存在」,还要判断「这篇论文是否确实包含归因于它的说法」。
步骤 0 — 对说法分类。
在获取任何内容之前,先对待验证的说法进行分类:
- 总体/标题级说法 — 摘要通常会陈述的发现(总体结果、关键数字、一般性结论)。对于此类说法,摘要可以作为有效的事实依据。
- 机制/实现/程序性说法 — 描述某件事如何运作或完成:具体机制、算法、架构、参数、实验步骤、对照条件,或与表格/图示/方法部分相关而非摘要结果中的数值。即使论文支持这些内容,摘要通常也会省略。提示词包括:「机制」、「如何」、「架构」、「算法」、「实现」、「程序」、「方案」、「参数」、「对照组」、「消融」、「表格」、「图示」,或任何比一段式摘要所陈述内容更具体的说法。
如果说法属于机制/实现类,仅核查摘要并不足够,即使摘要主题相关也是如此。获取摘要作为研究存在和主题匹配的证据,但不要仅凭摘要判定结论 — 继续执行下方第 3b 层。
使用引擎获取摘要(check-claim/check-file 会尝试来源 1–3 和
PubMed)。如果引擎不可用或未找到摘要,则手动按以下优先顺序查找:
- CrossRef 原始 JSON:
https://api.crossref.org/works/{DOI}— 检查abstract字段 - OpenAlex:
https://api.openalex.org/works/doi:{DOI}?mailto={contact_email}— 重建abstract_inverted_index - Semantic Scholar:
https://api.semanticscholar.org/graph/v1/paper/DOI:{DOI}?fields=abstract - 开放获取回退来源:
https://api.unpaywall.org/v2/{DOI}?email={contact_email}— 检查is_oa和oa_locations - 预印本的 arXiv 回退来源:
https://export.arxiv.org/api/query?id_list={arxiv_id} - 生物医学论文的 PubMed Central 来源:
https://www.ncbi.nlm.nih.gov/pmc/articles/{PMCID}/
对于需要联系邮箱的 API,将 {contact_email} 替换为配置中真实且经用户授权的邮箱地址。不要发送占位邮箱地址。
获取内容后,检查摘要是否包含所引用的具体说法。
- 摘要明确包含该说法(逐字引用)→
CONTENT: SUPPORTED - 摘要主题相关,但未提及具体说法 →
CONTENT: PARTIAL — quote what it actually says - 摘要与该说法矛盾 →
CONTENT: CONTRADICTED — do not use this citation - 尝试所有来源后仍无法获取摘要 →
CONTENT: UNVERIFIABLE — user must check full text - 说法属于机制/实现类,且尝试第 3b 层的所有来源后仍无法获取全文 →
CONTENT: ABSTRACT-ONLY — full text unavailable, verification insufficient。此标签绝不能升级为 SUPPORTED/ACCEPT。
不可放宽的规则:如果你描述论文「显示」、「证明」或「报告」了某个内容,就必须在所需深度引用或直接转述已获取的来源文本。即使你确信记忆无误,也不允许凭记忆总结。
第 3b 层 — 全文确认(仅适用于机制/实现类说法)
只要第 0 步将说法归类为机制/实现类,或者对于比摘要总结层级更具体的说法,摘要结论为 PARTIAL,就必须执行。仅当总体级说法直接从摘要获得 CONTENT: SUPPORTED 时,才可跳过。
按以下优先级获取论文正文,成功后即停止:
- 本地 Zotero PDF — 如果已配置 Zotero 文献库,则查询其数据库
中的此 DOI,解析附件键,并读取关联的 PDF。常见默认路径为
~/Zotero/zotero.sqlite,附件位于~/Zotero/storage/{key}/;请查找 实际路径,不要自行假定。 - research-wiki 知识库 — 当
research-wiki技能可用时, 搜索其已配置的知识库,查找已导入的全文副本。不要假定特定机器上的知识库路径。 - 开放获取链接 — 解析并获取实际全文(而不只是可获取标记):
- Unpaywall:
https://api.unpaywall.org/v2/{DOI}?email={contact_email}→ 获取best_oa_location.url_for_pdf(或任意oa_locations[].url_for_pdf)。 - arXiv:
https://export.arxiv.org/api/query?id_list={arxiv_id}→ 获取 论文全文,而不只是<summary>字段。
- Unpaywall:
- 失败 — 如果以上方法均未获得可读的全文,不要将摘要视为足够内容。应用
上文定义的
CONTENT: ABSTRACT-ONLY标签。
获取全文后,引用支持、部分支持或反驳该论断的段落。对于机制/实现类论断,CONTENT: SUPPORTED 必须有全文引文——仅在摘要中提及相关主题并不足以满足要求。
第 4 层 — DOI 解析
获取 https://doi.org/{DOI}。确认落地页与预期论文一致。如果 URL slug 中包含标题和卷号,而页面返回 403(被机器人拦截),这并不代表链接失效——请注明该论文需付费获取。若重定向到不相关页面,则属于严重错误。
第 5 层 — 撤稿情况
搜索 "{first author last name}" "{journal name}" retraction,并检查 DOI 落地页上是否有撤稿横幅。已撤稿的论文不得用作主要来源。
输出格式
快速筛查:每条参考文献一行(见上文)。
提交前检查:首先列出处理结论。对于每个问题,列出引用的参考文献、问题所在、证据(引擎给出的原因、CrossRef 记录或引用的摘要原句)以及修正方法。然后单独简要列出仍未验证的条目,标题为“无法自动确认——请自行查证”(例如学位论文、未被索引的预印本)。不要评论工具、重试或速率限制。
完整审计:每篇论文一张卡片,然后附上汇总表。
REFERENCE AUDIT
────────────────────────────────────────────────
Paper: [Title from live source — not from memory]
DOI: [DOI] — [✓ Resolves | ✗ Dead | ✗ Wrong paper | ⚠ Paywalled-403]
Authors: [Full list from CrossRef/OpenAlex/S2]
Year: [Year] — Source: CrossRef | S2 | arXiv
Journal: [Full name]
EXISTENCE: ✓ Confirmed (sources) | ⚠ Single-source | ✗ Not found
METADATA: ✓ Consistent | ⚠ Discrepancy: [field: value-A vs value-B]
CONTENT: ✓ Supported — "[verbatim excerpt — abstract for topline, full text for mechanism claims]"
⚠ Partial — source says: "[what it actually says]"
⚠ Abstract-only — mechanism/implementation claim, full text unavailable after Zotero/research-wiki/OA attempts
✗ Contradicted | — Unverifiable (tried CrossRef/OpenAlex/S2/Unpaywall/arXiv/PubMed)
RETRACTION: ✓ None found | ✗ Retracted
VERDICT: ACCEPT | WARN | REJECT
Reason: [one sentence — what's missing or wrong]
────────────────────────────────────────────────
CONTENT 字段必须包含逐字引文,或明确标记为不支持的状态,例如 ABSTRACT-ONLY 或 UNVERIFIABLE——不得凭记忆撰写摘要。
ACCEPT:已由两个来源确认;DOI 可解析到正确论文;内容在所需来源深度上得到支持(概要性论断可依据摘要;机制/实现/程序类论断须依据全文);且论文未撤稿。
WARN:存在可解决的问题——仅有一个来源、内容部分匹配、尝试所有备用方法后仍无法获取摘要,或(对于机制/实现类论断)尝试 Zotero/research-wiki/开放获取备用方法后仍无法获取全文。无法获取全文的情况必须在汇总表中标注 ABSTRACT-ONLY(例如 WARN (ABSTRACT-ONLY: mechanism claim, PDF unreachable)),且不得报告为 ACCEPT。用户核实标记的问题后,可安全使用。
REJECT:DOI 已失效或解析到错误论文、在任何地方都找不到论文、内容被反驳,或确认论文已撤稿。
所有卡片之后附上汇总表:
SUMMARY
────────────────────────────────────────────────
1. Smith et al. (2021) — ACCEPT
2. Kim & Park (2019) — WARN (abstract unverifiable; try PMC or institutional access)
3. Zhang (2023) — REJECT (DOI resolves to different paper)
────────────────────────────────────────────────
X / Y verified. Z need attention.
防止幻觉规则
- 切勿凭记忆回想 DOI——请从 CrossRef 或 OpenAlex 获取。
- 若未获取到足以支持所需引用深度的源文本,切勿描述论文内容。
- 切勿猜测或根据模式匹配来补全缺失的元数据。
- 如果两个来源存在分歧,请同时展示,不要擅自选定其中一个。
- 如果经过所有回退尝试后,仍无法访问支持所需论述深度的来源,请按上述定义标记为 UNVERIFIABLE 或 ABSTRACT-ONLY——不要用记忆中的描述代替。
- 切勿仅凭摘要中的主题匹配来判断机制/实现类别相关论述——请通过 Layer 3b 获取全文,否则标记为 ABSTRACT-ONLY 并停止。
边缘情况
预印本与正式发表版本:记录两个 DOI;引用时优先使用正式发表版本;若不同版本的标题有变化,请注明。
作者姓名变体:“J. Smith” 与 “John Smith”——请标记差异,但不要合并;交由用户确认。
会议论文集:CrossRef 中通常缺少卷号/页码;请标记为 [NOT IN SOURCE],不要猜测。
速率限制(HTTP 429,例如 Semantic Scholar):429 不能作为任何一方的证据。请依据其他来源作出判断;仅当它导致某个条目无法定论时才提及,并且绝不能因此弱化结论。