关于 studydiff
StudyDiff 比较两篇科学论文,呈现可能与结论冲突有关的研究设计差异,面向需要追溯来源的研究人员。它将无来源支持的字段标为“未报告”,且不会把差异排序为可能原因。
主要功能
- 01提取结构化研究卡片
- 02用来源引文核验每项数值
- 03比较相同与不同的维度
- 04将无依据字段标为未报告
- 05导出可复现的 Markdown 报告
适用场景
- 01比较结论冲突论文的方法
- 02查看提取数值的来源证据
- 03排除报告内容相同的设计维度
- 04让 Agent 调用工具比较研究
MCP 相关
MCP 服务将 StudyDiff 的论文比较引擎作为工具提供给 Agent。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y studydiff-mcpANTHROPIC_API_KEY密钥Anthropic API key, used only by compare_studies for live papers. compare_example and list_examples run offline without it.NCBI_EMAILContact email sent with PubMed/PMC E-utilities requests (NCBI asks callers to identify themselves). Optional.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
3收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| paperA | object | 是 | 第一项研究——{id}(PMID/DOI)或 {citation, text} |
| paperA.id | string | 否 | PMID(例如 "19633673")或 DOI(例如 "10.1126/science.1191996") |
| paperA.text | string | 否 | 用于分析的原始摘要/方法文本,不从 PubMed 获取 |
| paperA.citation | string | 否 | 提供原始文本时使用的简短引文(例如 "Zhou et al. 2009") |
| paperB | object | 是 | 第二项研究——{id}(PMID/DOI)或 {citation, text} |
| paperB.id | string | 否 | PMID(例如 "19633673")或 DOI(例如 "10.1126/science.1191996") |
| paperB.text | string | 否 | 用于分析的原始摘要/方法文本,不从 PubMed 获取 |
| paperB.citation | string | 否 | 提供原始文本时使用的简短引文(例如 "Zhou et al. 2009") |
| question | string | 否 | 要比较的问题,例如 "Is the Treg lineage stable in vivo?" |
详细介绍
StudyDiff
了解两项科学研究为何得出不同结论 —
每项论断均经来源核实。
在线演示 · 快速开始 · 工作原理 · 示例 · MCP 服务 · 路线图 · 参与贡献
两篇设计严谨的论文往往会得出截然相反的结论。通常,原因并不是其中一篇错了,而是方法上的差异(例如细胞类型、剂量、随访时间窗或分析选择),读者必须亲自从方法部分中仔细查找。**StudyDiff 会替你完成这项工作。**提供两项研究后,它会提取各自的设计,找出可能解释结论分歧的差异,并且——至关重要的是——让每项陈述都有原文依据,因此绝不会捏造研究发现。
它专为这样的实验室科学家打造:在规划实验前,需要决定该相信两篇相互矛盾的论文中的哪一篇。
有何不同
大多数“AI 文献”工具都会生成流畅的回答,然后让你相信它。StudyDiff 则反其道而行:
- **先展示证据,再由你判断。**首先列出设计差异;每个数值下方都附有支持它的原文句子——点击任何经过核实的数值,即可在论文原文中查看对应句子的高亮显示。
- **拒绝猜测。**来源中未提及的任何字段都会标为未报告,绝不推断。
- **自行验证。**确定性的依据核验机制(不使用第二个 LLM 充当裁判)会确认每项提取的数值和每项解释都有逐字引文和可追溯数字作为依据。任何未通过核验的内容都会在用作理由之前被降级。
- 清楚自身的能力边界,因为这些边界经过了测量——评测采用了两套独立基准集,第二套作为留出集,仅评分一次。详见下文。
有效吗?基于测量的答案
StudyDiff 过去会对存在差异的设计维度进行排序,并将排名第一的维度列为分歧的可能驱动因素。我们构建了一个基准来检验这一点,结果发现它行不通。
15 个有文献记录的矛盾案例,文献后来已确定论文产生分歧的原因——每个标签都附有自己的引文,这组案例在任何准确率数据出现之前就已盲测构建。根据 StudyDiff 排名第一的驱动因素进行评分:
Top-1 accuracy (strict) 13.3% (95% CI 3.7-37.9%) [2/15]
Baseline "always say assay" 13.3% (95% CI 3.7-37.9%) [2/15]
→ discordant on 0 of 15 cases
Oracle ceiling (reachable) 66.7% (95% CI 41.7-84.8%) [10/15]
Non-assay-labelled cases 0.0% (95% CI 0.0-22.8%) [0/13]
这个排序是一个固定的先验(src/compare.mjs 中的 DRIVER_RANK),其中 assay 的排名高于其他所有维度。两篇论文几乎总会使用略有不同的方法,因此 assay 几乎总会出现差异,所以它在 15 个案例中被选中了 13 次——而命中的两例恰好就是标注为 assay 的两例。它不仅和猜一个固定答案一样好,在这组案例的每一个案例中,它的行为都与猜固定答案完全一致。
首先修复依据(第 2 阶段)之后,这个借口就不成立了。找回 26 次误判拒绝中的 20 次,将 oracle 上限从 33% 提高到了 67%——现在在 15 个案例中,有 10 个案例已将确定的原因列为可选项,而不再是 5 个——但排名第一的准确率毫无变化。排序器又有 5 次拿到了正确答案,却一次也没选中。
**因此发生的变化:**应用不再提名主要驱动因素,而是将存在差异的维度以不排序的列表呈现,因为这个列表有参考价值(15 个案例中有 10 个包含确定的原因),而排序没有。要从中作出选择,需要工具并不具备的领域知识。
**仍然成立的内容:**哪些维度存在差异,哪些维度相同(已排除),以及每个值背后的原文句子。这些都不依赖排序。
在第二组数据上进行确认性盲测
到那时,这 15 个案例已分两个阶段进行过研读——分析了失败案例,并重新审查了证据范围—— 因此,它们所有修复后的数据都属于开发集准确率,而非盲测结果。于是我们构建了第二组数据,并只测量了一次。
eval/cases-heldout.json 包含另外 15 个有文档记录的矛盾案例,依据一份在选定任何案例之前编写并提交的协议进行整理(eval/HELDOUT-PROTOCOL.md),整理者对开发集逐案例的失败情况一无所知;案例来自有意选取的不同领域:微生物组、海洋生态学、毒理学、心理学、重症监护、肿瘤学、传染病。它与开发集没有共享论文或矛盾案例——selftest 会以机械方式强制检查这一点。
Top-1 accuracy (strict) 13.3% (95% CI 3.7-37.9%) [2/15]
Baseline "always say assay" 20.0% (95% CI 7.0-45.2%) [3/15]
→ discordant on 1 of 15 cases
Oracle ceiling (reachable) 73.3% (95% CI 48.0-89.1%) [11/15]
Non-assay-labelled cases 0.0% (95% CI 0.0-24.3%) [0/12]
在未见过的数据上,先验判断的得分低于恒定猜测——恰好少对一个案例。两者的置信区间几乎完全重叠,且两种策略在 15 个案例中只有 1 个意见不同,因此诚实的说法是:它仍无法与每次都猜 assay 区分开来,而不是说它更差。
始终不变的是最后一项。**在两组数据中,已有 25 个案例的既定原因并非 assay,先验判断一个也没识别出来。**而且这里的上限高于开发集——73.3%,而非 66.7%——这说明提取过程更频繁地将正确答案呈现在排序器面前,但它选中正确答案的次数并未增加。这是在开发循环从未见过的数据上重现的 Phase 1–2 结论,也是唯一能增强该结论的方式。
该数值按原样报告,绝不与开发集数值合并:把它们相加成“n=30”的结果,会再次把已读数据洗成盲测数据。src/ 中没有任何内容因该结果而改动。数据集只在一个预先注册的实验组中获取了一次,但评分并非一次干净的完整流程——首次运行报告 n=14,因为有一篇论文未能获取;取回该论文后,才对完整数据集进行评分。两组数值、对抗性验证过程中在评分前发现并修正的 16 处缺陷,以及每个标签背后的推理,都记录在文件自身的来源信息块中,而非被概括省略。
npm run eval:heldout # the blind number, offline and free
npm run eval:selftest:heldout # set integrity, incl. zero overlap with the dev set
完整方法、预先注册的决策,以及所有错误预测见:
eval/README.md 和 eval/PHASE2.md。基准数据集见
eval/cases.json(开发集)和
eval/cases-heldout.json(留出集)。
npm run eval # offline, free, no API key — regenerates the numbers above
npm run eval:selftest # validates the harness maths and set integrity
eval/cache/ 和 eval/cache-heldout/ 是有意提交的。它们不是构建产物,
而是证据:已发布的数值可以通过仓库中的产物复现,而非只能盲目信任。
快速开始
60 秒内即可启动,无需 API 密钥,也无需联网:
git clone https://github.com/nickjlamb/studydiff && cd studydiff
npm install
npm run demo # explains a real, famous contradiction
npm run demo -- resveratrol-sirt1 # a second worked example
npm run demo -- treg-stability # a third: Treg lineage stability
运行 Web 应用:
cp .env.example .env # add ANTHROPIC_API_KEY for live comparisons
npm run serve # http://localhost:4173
内置示例使用缓存数据运行,无需密钥。若要比较实时结果,请添加密钥,并使用 PMID / DOI、上传 PDF 或 粘贴输入项。
工作原理
flowchart LR
IN["Two papers<br/>PMID · DOI · PDF · text"] --> R["Retrieve<br/>PubMed / PMC / PDF"]
R --> E["Extract<br/>Claude → structured study cards"]
E --> V["Verify<br/>deterministic grounding"]
V -- "ungrounded → not reported" --> E
V --> C["Compare<br/>divergent vs. shared design"]
C --> X["Present<br/>divergent dimensions + ruled out"]
- 检索 — PubMed/PMC 客户端支持在全文与摘要之间回退,并标记读取深度(
fulltext/abstract/pasted);上传的 PDF 会在服务端提取文本。 - 提取 — Claude 将每篇论文整理成固定格式的研究卡片(物种、模型、检测方法、剂量、时间、终点、样本量、统计数据、发现、局限性)。每个字段都附有逐字引用作为依据;未提及的字段默认为未报告。
- 验证 — 首先进行依据核验:如果引用内容不在来源中,或数字无法追溯到来源,相应数值就会降级为未报告。StudyDiff 无法引用未经验证的事实。
- 比较 — 采用确定性方式:找出两篇论文都报告了哪些设计维度、其中哪些存在差异,以及哪些完全相同。设计维度的差异通过词语重合度测试判定;结论本身则采用严格不等式判定,因为结论的倾向很重要,而方法列表重要的是其内容。
- 呈现 — 按不排序的方式列出存在差异的维度,为每个维度提供两篇论文中的数值及其背后的逐字原句,并明确指出相同的维度已被排除。StudyDiff 不会指定其中任何一项为原因:它经过了测量,而且并不起作用。
两点保障了这一承诺:API 密钥绝不会离开服务端;验证采用确定性方式——依据核验和比较完全不涉及模型判断,因此相同的已验证证据始终会得出相同的差异维度。
为什么选择 Claude?
StudyDiff 的可靠性来自它如何使用 Claude,而不只是使用了 Claude:
- 通过工具调用进行结构化提取。 每篇论文都会通过强制使用 Claude(Sonnet)工具架构转换为研究卡片,因此每个字段都会经过验证,并附有逐字引用作为依据——无需解析自由文本,也不会出现“差不多是 JSON”的失败情况。
- 推理并将主张对应到证据。 Claude 会阅读方法/摘要文本,识别设计数值及其对应的确切句子——这正是将非结构化论文转化为可比较、可审计卡片的难点。
- Claude 提出,依据核验把关。 StudyDiff 从不使用大模型充当裁判。确定性检查会根据来源验证 Claude 的输出,并在展示之前将任何缺乏依据的内容降级。将 Claude 的工具调用提取与非大模型验证结合,才能让工具信任自身输出,并避开常见的大模型评估器陷阱。
- 使用 Claude Code 构建。 整个应用——从流水线、界面到加固和部署——都通过与 Claude Code 在单个 Agent 循环中迭代完成。
示例
| 问题 | 论文 | StudyDiff 的发现 |
|---|---|---|
| 小鼠模型能否模拟人类炎症? | Seok 2013 vs Takao & Miyakawa 2015 | 使用相同数据集,却得出相反结论——差异源于基因选择策略。 |
| 白藜芦醇能否激活 SIRT1? | Howitz 2003 vs Beher 2009 | 这是检测方法伪影——使用 Fluor de Lys 肽底物,而非天然底物。 |
| Treg 谱系在体内是否稳定? | Zhou 2009 vs Rubtsov 2010 | 一场具有里程碑意义的 T 细胞争议——稳定与不稳定之争,差异源于命运示踪方法。 |
这三个示例均可离线运行(npm run demo / npm run demo -- resveratrol-sirt1 / npm run demo -- treg-stability)。
使用方法
- Web 应用(
npm run serve)——提供示例、PMID/DOI 查询、PDF 上传或粘贴功能;实时显示各个管线步骤,点击任意有依据的值即可在来源中查看其高亮位置,并导出可复现的 Markdown 报告,其中包含每个值对应的原文支持句。 - MCP 服务(
npm run mcp)——让 Claude 或任何 Agent 直接调用矛盾分析引擎。请参阅 MCP 服务。 - CLI——
node src/cli.mjs --q "Does resveratrol activate SIRT1?" 12939617 19843076 - 部署——请参阅 DEPLOY.md(Railway + 自定义域名)。
MCP 服务
StudyDiff 的引擎也提供 Model Context Protocol 服务,因此 Agent 可以通过工具调用询问两篇论文为何存在分歧——使用相同的、有依据的管线,无需浏览器。
已作为 io.github.nickjlamb/studydiff 发布到 官方 MCP Registry,并以 studydiff-mcp 的名称发布到 npm。
| 工具 | 功能 |
|---|---|
compare_studies(paperA, paperB, question?) | 对两篇论文运行完整管线。每篇论文的格式为 {id}(PMID 或 DOI)或 {citation, text}。需要 ANTHROPIC_API_KEY。 |
compare_example(example) | 运行缓存的示例分析——无需 API 密钥,也无需网络。这是查看有依据输出的最快方式。 |
list_examples() | 列出内置的示例分析。 |
它会返回与 Web 应用导出的报告相同、可审查的内容:判定、存在差异的设计维度(不排序)和相同的设计维度(已排除)、每个值及其对应的原文支持句、核验计数,以及解决分歧所需的证据。缺乏依据的字段会标记为未报告,绝不猜测;工具绝不会选出胜者、指定主要驱动因素,也不会报告未计算出的置信度。
将其添加到 Claude Code:
claude mcp add studydiff -- npx -y studydiff-mcp
……或添加到 Claude Desktop(claude_desktop_config.json):
{
"mcpServers": {
"studydiff": {
"command": "npx",
"args": ["-y", "studydiff-mcp"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}
}
}
只有运行 compare_studies 才需要 ANTHROPIC_API_KEY。不配置密钥也仍可使用 list_examples / compare_example——缓存的示例无需密钥和网络即可运行。(若要从本地克隆运行,请将命令替换为 node /absolute/path/to/studydiff/src/mcp.mjs。)
然后直接提问:
使用 studydiff 比较 PMID 19633673 和 20929851——它们为何存在分歧?
手边没有密钥?运行 list_examples,然后运行 compare_example("treg-stability"),即可完全离线使用。
项目结构
src/ncbi.mjs PubMed / PMC retrieval (+ DOI resolution, source-depth tagging)
src/pdf.mjs PDF text extraction (pure JS)
src/extract.mjs Claude tool-use → structured study cards
src/grounding.mjs deterministic verification (OpenGATE)
src/compare.mjs divergence detection (divergent vs. shared design dimensions)
eval/ driver-ranking benchmark: two sets of 15 cited contradictions (dev + held-out) + scorer
src/gaps.mjs bounded "observed across these papers"
src/pipeline.mjs orchestration: retrieve → extract → verify → compare
src/report.mjs shared Markdown report (answer, drivers, quotes, verification)
src/server.mjs web server + streaming API (+ rate limiting, caching)
src/mcp.mjs MCP server: compare_studies / compare_example / list_examples
public/index.html single-file dashboard UI
fixtures/ cached real papers for the offline demos
路线图
关键词搜索和结果选择器、批量比较,以及比较两篇以上论文,都是待探索的方向。基准测试已完成,盲测结果也经受住了检验,因此接下来的工作重点是准确性,而非功能:改进提取,提高测得的上限;并添加蕴含检查,以捕捉确定性依据核验无法发现的文字过度表述。完整列表——包括已尝试并弃用的内容——请参阅 ROADMAP.md。
贡献
欢迎贡献——请参阅 CONTRIBUTING.md,了解设置方法以及确保信任保证不受影响的不变量。
来源说明
StudyDiff 是为 Anthropic 的 Built with Claude: Life Sciences 黑客松(Builder 赛道)开发的。本仓库中的所有应用代码均在活动期间从头编写。依据核验使用 OpenGATE,PDF 提取使用 unpdf,二者均为已发布的依赖项。检索使用公开的 NCBI E-utilities;提取使用 Claude API。
许可证
MIT © Nick Lamb
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。
