# Self Verify

> 学术写作过程中的实时引用核查。对 Claude 刚输出的内容（或用户指定的文本）中的文献引用做存在性验证：作者、年份、标题是否指向一篇真实的 PubMed 文献。定位为写作中的随手抽查，不是全量核查（全量用 ref-verifier）。当用户说"verify 一下""self-verify""核查一下引用""check citations""查一下刚才的引用"时触发。仅显式触发，不自动执行。

- Skill: `skydooooog0221/self-verify` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add skydooooog0221/self-verify`
- Raw SKILL.md: https://api.skillmd.com/api/skills/skydooooog0221/self-verify/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Skydooooog0221 (https://skillmd.com/u/skydooooog0221)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/skydooooog0221/self-verify

---


# self-verify — 学术写作实时引用核查

## 定位

写作过程中的引用快速抽查。验证 Claude 输出的文献引用是否指向真实存在的 PubMed 文献。

**不是什么**：
- 不是通用幻觉抑制工具
- 不是 claim-摘要语义比对（那是 ref-verifier 的 Step C）
- 不验证引用的语义准确性（"这篇文章是不是真的说了这个观点"），只验证引用的存在性（"这篇文章是不是真的存在"）

**与 ref-verifier 的关系**：ref-verifier 是论文完稿后的系统性体检（全量 bib、逐条 claim-摘要比对、生成报告）。self-verify 是写作中的随身血压计（几条引用、几秒出结果）。

## 触发条件

仅显式触发：
- `verify 一下` / `self-verify` / `self-check`
- `核查一下` / `查一下刚才的引用` / `check citations`

**半自动提示**：当 Claude 输出的内容包含 ≥2 条来自训练知识（非本次对话中 API/工具调用返回）的文献引用时，在输出末尾追加一行提示："本段包含 N 条来自训练知识的引用，建议 `verify` 核查。"仅提示，不自动执行。

不触发的情况：引用来自本次对话中的 Entrez 搜索结果或用户提供的文献列表时，不提示。

## 验证范围

**能查的**：
- 文献引用中的作者姓氏、发表年份、标题关键词 → Entrez 三重匹配
- 明确给出的 PMID → Entrez 直接查询

**不查的**（标 UNVERIFIABLE，附原因）：
- 数值声明（样本量、p 值、百分比）
- 方法描述（统计方法、软件版本）
- 概念定义
- 非 PubMed 收录的文献（CS 会议论文、arXiv 预印本等）

## 工作流（三步）

### Step 1: 引用提取

从目标文本中识别所有文献引用，提取结构化 anchor。

**目标文本来源**（按优先级）：
1. 用户指定的文本（"verify 一下这段：……"）
2. 当前对话中 Claude 最近一条包含引用的输出

**提取规则**：
- 识别模式：`Author et al. (YYYY)`、`Author YYYY`、`Author and Author (YYYY)`、`PMID XXXXXXXX`、`[N]` 编号引用（如能从上下文推断对应文献）
- 对每条引用生成 anchor：

```json
{
  "id": 1,
  "citation_text": "Treece et al. (2010)",
  "anchor": {
    "author_surname": "Treece",
    "year": "2010",
    "title_keywords": "cortical bone mapping"
  }
}
```

- `title_keywords` 从引用的上下文语境中推断（被引用时提到的方法名、主题词等），取 2-5 个实词
- anchor 字段不完整时（如缺年份、缺作者），该条直接标 UNVERIFIABLE，reason 注明缺什么
- 非文献性质的事实声明不提取

**提取质量自检**：
- 作者姓氏是否为 last name（不是 first name，不是缩写）
- 年份是否为 4 位数字
- 关键词是否来自引用上下文（不是从训练知识中补全的）
- 如果无法从上下文推断关键词，标 UNVERIFIABLE 而不是猜

### Step 2: Entrez 验证

对每条 anchor 调用验证脚本：

```bash
python skills/self-verify/scripts/entrez_verify.py --author <surname> --year <YYYY> --title-keywords "<kw1> <kw2> <kw3>"
```

脚本为确定性 Python，不依赖 LLM 判断。输出 JSON：

```json
{
  "verdict": "PASS",
  "pmid": "20176027",
  "matched_fields": ["author", "year", "title_full"],
  "evidence": "https://pubmed.ncbi.nlm.nih.gov/20176027/",
  "suggested_fix": null
}
```

**四档判定**：

| 档位 | 含义 | 条件 |
|---|---|---|
| PASS | 三重匹配全中 | author + year + 全部 title_keywords 命中同一 PMID |
| PARTIAL | 部分匹配 | author 对但年份偏差 ≤1，或标题关键词部分命中 |
| FAIL | 未找到匹配 | Entrez 无匹配，或匹配到的记录核心字段对不上 |
| UNVERIFIABLE | 无法核查 | anchor 不完整 / Entrez 不可达 / 非 PubMed 文献 |

**关键约束**：
- Entrez 不可达 → UNVERIFIABLE，不回退到训练知识猜测
- 查无结果 → 放宽关键词重试一次，仍无 → FAIL
- UNVERIFIABLE 不算失败

### Step 3: 报告

输出 Markdown 表格：

```markdown
## self-verify 报告
目标: <被核查文本的一句话描述>
引用总数: N | PASS X | PARTIAL Y | FAIL Z | UNVERIFIABLE W

| # | 引用 | verdict | PMID | evidence | suggested_fix |
|---|------|---------|------|----------|---------------|
| 1 | Treece et al. 2010 | PASS | 20176027 | [link] | — |
| 2 | Smith et al. 2023 | FAIL | — | — | 未找到匹配，检查作者拼写 |
```

- FAIL 和 PARTIAL 必须附 `suggested_fix`（基于 Entrez 实际返回的最近匹配）
- UNVERIFIABLE 必须附 `reason`

## 错误处理

- 网络超时 → 该条标 UNVERIFIABLE，reason="entrez timeout"
- 脚本崩溃 → 报告错误信息，不静默跳过
- 目标文本中无引用 → 告知用户"未检测到文献引用"，不生成空报告

## 局限性声明

每次使用时不需要主动声明，但如果用户对结果有疑问，说明：
- PASS 意味着"PubMed 上存在一篇匹配的文献"，不意味着"引用内容语义正确"
- FAIL 可能是提取阶段关键词选取不准导致的假阴性，不一定是引用造假
- 非 PubMed 收录的文献（CS 会议、arXiv）会被标 UNVERIFIABLE

