Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Cite-or-Block 架构下的药名 cross-check 原子 skill。给定报告文本与 .cache/<slug>/sources/,扫描每个药品提及 → 找最近 citation 锚点 → 核对锚点指向的源里是否真的提到了此药(通用名 + 商品名)。无字典、无 fallback、源里没 = critical。
.claude/skills/ethanyoq-drug-citation-verifier/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-21 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 21% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 62% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 320% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 972% | 0% |
> 替代作废的 nmpa-drug-registry-lookup(commit e7cfb83,违反 P0)。
Cite-or-Block 架构下的药名 cross-check 原子 skill。本 skill 是 A11 citation-anchor-resolver 之上的薄包装,专注一件事:
> 报告里写了药名 X + 引用了锚点 Y → 锚点 Y 指向的源里,真的有 X 吗?
源里有 = 通过。源里没 = critical violation,无论 X 是 2018 年的老药、 2026 年新批的药、还是 LLM 编造的药。
绝不维护药品字典。
本 skill 不知道也不需要知道"哪些药存在"。它只做一件事: 报告里的药名 X + 引用锚点 Y → 验证 Y 指向的源里是否真的提到了 X。
源里没 → fail。无论 X 是 2018 年的老药、2026 年新批的药、或编造的药。
替尼/单抗/阿克/沙星/霉素/他汀/...)— 用于抽取疑似药名-tinib/-mab/-statin/...)商品名/剂量/I 级推荐/...)— 用于关联药名与上下文这些是"中文医药命名学",不是"已知药品列表"。任何符合后缀的字符串都 视为药提及,然后必须核对源才能判定真伪。
完整后缀规则表见 references/extraction-heuristics.md。
python# WRONG — 任何具体药名出现在 .py 源代码 = P0 violation KNOWN_DRUGS = {"洛拉替尼": "Lorlatinib", "克唑替尼": "Crizotinib", ...} DRUG_REGISTRY = [...] _known_drugs_fallback = {...}
这类代码 = 立刻停下来重设计。本 skill 的 watchdog 测试 (tests/test_drug_citation_verifier.py::test_no_hardcoded_drug_dict_in_source) 会扫描 scripts/*.py 拒绝任何具体药名出现。
| 场景 | 使用本 skill 吗? | |------|-------------------| | 报告内容生成完毕,需要 cross-check 药名是否真有出处 | ✅ | | Step 8 审计阶段,逐段 scan critical violation | ✅ | | 不知道某药是否存在,想"查一下" | ❌(本 skill 不查表) | | 抓指南后想入药品库 | ❌(本架构不入库,只存原文) |
verify_drug_mentions_in_text(text, sources_dir) -> dictpythonfrom pathlib import Path import sys # 1) 加载 A11(citation-anchor-resolver) A11 = Path.home() / ".claude" / "skills" / "citation-anchor-resolver" / "scripts" sys.path.insert(0, str(A11)) # 2) 加载本 skill A5 = Path.home() / ".claude" / "skills" / "drug-citation-verifier" / "scripts" sys.path.insert(0, str(A5)) from verifier import verify_drug_mentions_in_text text = """ ALK 阳性 NSCLC 一线推荐洛拉替尼(商品名:博瑞纳)。 [guideline:CSCO-2024-NSCLC:§5.5.2] """ sources_dir = Path(".cache/lung-cancer-alk-2026/sources") result = verify_drug_mentions_in_text(text, sources_dir) # { # "ok": True / False, # "drug_mentions": [{ # "text": "洛拉替尼", # "brand_in_context": "商品名:博瑞纳", # "citation": "[guideline:CSCO-2024-NSCLC:§5.5.2]", # "verified": True, # "missing_in_source": [], # "reason": "all keywords matched", # "severity": "none", # }, ...], # "violation_severity": "none" | "warning" | "critical", # }
_drug_extract.extract_drug_mentions_with_context(text) —命名学规则抽取所有"疑似药提及"(含括号内的商品名/英文名)
parse_citations_in_text(text)(A11)— 找文中所有 citation 锚点_citation_match.find_nearest_citation(mention, citations, text) —就近匹配:同句最优,同段次之,跨段则视为 missing
critical(无来源)verify_claim_against_source(name+brand, citation, sources_dir)verified=False → critical(出处不支持)violation_severity:any critical → critical;all verified → none| Severity | 含义 | 报告生成行为 | |----------|------|--------------| | none | 所有药提及都核对通过 | 通过 | | warning| 有非关键问题(本版暂未启用,预留) | 警告 | | critical | 任一药提及无 citation 或源不支持 | 阻断,LLM 重写 |
下游的 A1 / 内容生成层会再做语义级校验
citation-anchor-resolver(commit c2c97b3)— 必须先安装nmpa-drug-registry-lookup(违反 P0,作废)详见 references/failure-modes.md。
常见 4 种:
| Skill | 关系 | |-------|------| | citation-anchor-resolver (A11) | 本 skill 的依赖,提供锚点解析 | | content-verification-layer (A6') | 本 skill 的下游协调层,统管全报告 cross-check | | nmpa-drug-registry-lookup | 作废(违反 P0,保 git 历史作反例) |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-21 | fail→pass | 11,074 | 11,864 | +7% | 1 | 1 | 0% | 2,121 | 4,005 | +89% | 0 | 0 | — |
case-22 | pass→pass | 15,671 | 12,809 | -18% | 1 | 1 | 0% | 3,035 | 4,846 | +60% | 0 | 0 | — |
case-01 | fail→pass | 26,825 | 13,618 | -49% | 1 | 1 | 0% | 3,664 | 4,428 | +21% | 0 | 0 | — |
case-02 | fail→pass | 12,019 | 11,406 | -5% | 1 | 1 | 0% | 2,855 | 4,632 | +62% | 0 | 0 | — |
case-03 | pass→pass | 4,262 | 6,113 | +43% | 1 | 1 | 0% | 848 | 3,018 | +256% | 0 | 0 | — |
case-04 | fail→pass | 4,077 | 8,587 | +111% | 1 | 1 | 0% | 860 | 3,613 | +320% | 0 | 0 | — |
case-05 | fail→pass | 1,755 | 9,315 | +431% | 1 | 1 | 0% | 339 | 3,635 | +972% | 0 | 0 | — |
case-06 | fail→pass | 17,566 | 12,162 | -31% | 1 | 1 | 0% | 4,443 | 4,577 | +3% | 0 | 0 | — |
case-07 | fail→pass | 8,566 | 4,862 | -43% | 1 | 1 | 0% | 1,864 | 2,941 | +58% | 0 | 0 | — |
case-08 | fail→pass | 5,215 | 3,003 | -42% | 1 | 1 | 0% | 1,107 | 2,474 | +123% | 0 | 0 | — |
case-09 | fail→pass | 2,520 | 4,352 | +73% | 1 | 1 | 0% | 638 | 2,915 | +357% | 0 | 0 | — |
case-10 | pass→pass | 9,031 | 6,643 | -26% | 1 | 1 | 0% | 1,943 | 3,283 | +69% | 0 | 0 | — |
case-11 | fail→pass | 9,876 | 5,408 | -45% | 1 | 1 | 0% | 2,041 | 2,955 | +45% | 0 | 0 | — |
case-12 | pass→pass | 13,666 | 13,891 | +2% | 1 | 1 | 0% | 2,828 | 4,885 | +73% | 0 | 0 | — |
case-13 | pass→pass | 15,099 | 12,912 | -14% | 1 | 1 | 0% | 3,155 | 4,831 | +53% | 0 | 0 | — |
case-14 | fail→pass | 26,010 | 7,722 | -70% | 1 | 1 | 0% | 1,090 | 3,513 | +222% | 0 | 0 | — |
case-15 | fail→fail | 6,667 | 2,324 | -65% | 1 | 1 | 0% | 1,352 | 2,256 | +67% | 0 | 0 | — |
case-16 | fail→pass | 7,212 | 5,239 | -27% | 1 | 1 | 0% | 1,531 | 3,278 | +114% | 0 | 0 | — |
case-17 | fail→pass | 13,209 | 11,515 | -13% | 1 | 1 | 0% | 2,612 | 4,464 | +71% | 0 | 0 | — |
case-18 | pass→pass | 8,667 | 4,890 | -44% | 1 | 1 | 0% | 1,685 | 2,964 | +76% | 0 | 0 | — |
case-19 | fail→pass | 4,623 | 4,806 | +4% | 1 | 1 | 0% | 943 | 2,904 | +208% | 0 | 0 | — |
case-20 | pass→pass | 11,490 | 9,218 | -20% | 1 | 1 | 0% | 2,399 | 3,953 | +65% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +64 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.