NERVE:神经符号证据审查和验证引擎
一个神经符号、知识图——经过验证的MCP连接LLM生物制剂审核员。NERVE捕获本体论违规、弱或矛盾的声明以及缺失的证据,然后提出最小的修复方案,以保持代理的意图完整。
现场演示: https://nerve.yinjunphua.com/ (基本身份验证: biohack / 2025)
德国生物黑客马拉松2025活动页面: 第四届德国生物黑客马拉松——从文献中检测和提取用于训练机器学习方法的数据集.
这有什么作用
- 将代理输出视为结构化声明,而不仅仅是文本,并根据领域本体/知识图对其进行验证。
- 检测缺失的实体规范化、不可能的关系、未指定的证据和撤回的引用。
- 通过基于规则的解释和置信度评分(通过/警告/失败判断)产生简洁的评论。
- 通过符号规则和来源来解释验证层,而不仅仅是另一个不透明的LLM。
运作原理
┌─────────────────────────────────────────────────────────────────────────────┐
│ NERVE ARCHITECTURE │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ LLM Agent │ │ Free-Text │ │ Fixture │
│ Output │ │ Claim │ │ Claim │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────────┼────────────────────┘
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ 1. CLAIM EXTRACTION (NER + Normalization) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ GLiNER2 │──▶│ ID Lookup │──▶│ Canonical │ │
│ │ NER Model │ │ HGNC/HPO/ │ │ Triple │ │
│ │ │ │ MONDO/etc │ │ (S, P, O) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ 2. EVIDENCE GATHERING (MCP Tools) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │EuropePMC│ │CrossRef │ │DisGeNET │ │ Monarch │ │ SemMed │ │
│ │ search │ │retract. │ │gene-dis │ │ KG │ │ triples │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └───────────┴───────────┴───────────┴───────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Evidence Pool │ │
│ │ PMIDs, scores, │ │
│ │ KG edges, NLI │ │
│ └─────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ 3. RULE ENGINE (Symbolic Reasoning) │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ rules.yaml (152 lines) │ │
│ │ ├── type_domain_range (Biolink validity) │ │
│ │ ├── retraction_gate (FAIL if retracted) │ │
│ │ ├── ontology_closure_hpo (HPO ancestry check) │ │
│ │ ├── multi_source_bonus (+0.3 for ≥2 sources) │ │
│ │ ├── nli_contradiction_gate (FAIL if strong refute) │ │
│ │ └── ... 20+ more rules │ │
│ └────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ 4. SUSPICION GNN (Neural Scoring - Optional) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 2-hop Ego │──▶│ R-GCN │──▶│ Per-Edge │ │
│ │ Subgraph │ │ (16 dim) │ │ Suspicion │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────────┐
│ 5. VERDICT & AUDIT CARD │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ ┌────────┐ Score: 0.72 Rules: 3 fired Evidence: 4 PMIDs │ │
│ │ │ PASS │ ──────────────────────────────────────────────────────- │ │
│ │ └────────┘ Claim: BRCA1 → associated_with → Breast Cancer │ │
│ │ ✓ type_domain_range ✓ multi_source ✓ curated_kg │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
Legend:
──▶ Data flow ┌───┐ Component
MCP Model Context Protocol tools for external API access管道概述
- 摄取:通过MCP提取代理输出(工具调用、思维链、工件)。标准化为审计有效负载。
- 索赔提取:将输出转换为具有类型化实体和来源的原子声明。
- KG+本体检查将实体标准化为精选词汇表(HGNC、UniProt、MONDO、HPO);验证关系和约束;标记未接地的术语。
- 推理:将符号规则与LLM启发式方法相结合,对索赔强度进行评分,检测矛盾,并发现缺失的证据。
- 审计报告:返回结构化的评论(违规、信任、证据需求),并建议进行最小限度的编辑或工具调用以进行修复。
快速启动
使用紫外线(推荐)
- 要求:Python 3.13和
uv. - 创建隔离环境并安装deps:
uv sync --group dev- 运行工具:
uv run ruff check .
uv run mypy src
uv run pytest- 可选(pyenv用户):
pyenv install 3.13.9 && pyenv local 3.13.9—.python-version出于便携性考虑。
使用conda
- 创建并激活conda环境:
conda create -n nerve python=3.13 -y
conda activate nerve- 安装依赖项:
pip install -e ".[dev]"- 运行工具:
ruff check .
mypy src
pytest运行应用程序
启动Streamlit用户界面:
# uv
uv run streamlit run src/nerve/app.py
# conda
streamlit run src/nerve/app.py默认情况下,该应用程序使用预播种的内存迷你KG进行快速离线检查。
命令行CLI(与UI信息相同)
为了快速调试和自动检查,您可以从终端运行相同的审计逻辑。CLI使用与Streamlit UI相同的管道,并生成相同的判决、规则跟踪和证据摘要。
# List demo claims (from fixtures)
uv run python -m nerve --list-demos
# Audit a demo claim by fixture ID (e.g. REAL_D01)
uv run python -m nerve --demo-id REAL_D01
# Audit a custom free-text claim with evidence identifiers
uv run python -m nerve \
--claim-text "TP53 mutations are associated with lung cancer." \
--evidence PMID:12345 PMID:67890
# Optional: JSON output for diffing / automation
uv run python -m nerve --demo-id REAL_D01 --format json启用精心策划的KG信号
您可以使用外部策划的知识源来增强审计。这些提供了“积极证据”信号(例如,验证DisGeNET中存在基因-疾病联系),即使缺乏多次引用,也可以帮助索赔通过。
1.DisGeNET(基因疾病协会) 需要API密钥。注册于 disenet.org 得到一个。
export DISGENET_API_KEY=your_disgenet_token2.君主倡议(策展幼儿园) 在应用程序中默认启用。神经查询Monarch KG API以获得精心策划的关联(基因多态性、基因表型),以补充DisGeNET。
要禁用它(例如,用于离线使用):
export NERVE_USE_MONARCH_KG=false具有完整功能的示例运行:
export DISGENET_API_KEY=your_key_here
uv run streamlit run src/nerve/app.py使用Neo4j后端
要使用本地Neo4j图,请执行以下操作:
- 启动Neo4j:
docker run -d --name nerve-neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password neo4j:5- 设置环境并运行:
export NEO4J_URI=bolt://localhost:7687
export NEO4J_USER=neo4j
export NEO4J_PASSWORD=password
uv run streamlit run src/nerve/app.py # or just: streamlit run ...连接后,侧边栏将显示“使用Neo4j KG后端”。如果缺少配置,应用程序将回退到内存中的迷你KG。
项目结构
src/nerve/--核心库:管道编排、数据模型、规则引擎、NER和来源处理。src/nerve/mcp/--用于外部服务的MCP工具适配器(欧洲PMC、CrossRef、ID规范化)和知识图后端。src/nerve/loader/--统一的数据加载器CLI,用于将生物医学数据下载并加载到Neo4j中。rules.yaml--声明性审计规则(类型约束、本体检查、证据评分)。tests/--模型、规则、MCP工具和整个管道的单元和集成测试。docs/--设计说明、架构决策和路线图。
特点
- 怀疑报告模式:具有完整出处的索赔、调查结果和建议修复的结构化格式(
src/nerve/models.py). - GLiNER2 NER:用于基因、疾病、表型、通路等的神经实体提取,并回退到字典匹配。
- MCP工具 (
src/nerve/mcp/):
- europepmc:搜索和获取出版物元数据(标题、摘要、DOI、引用、开放获取状态) - crossref:撤回状态查找(可用;管道中的启发式集成) - ids:使用本体祖先将标识符规范化为HGNC、UniProt、MONDO、HPO - kg:从内存中的mini-KG查询边缘和自我网络
- 迷你KG切片:带有基因-疾病、基因-表型、基因-基因(PPI)和基因-通路边以及引用元数据的记忆知识图。
- 规则引擎:基于YAML的声明性规则(
rules.yaml)涵盖:
- 类型约束(Biolink有效域/范围) - 本体封闭(HPO/MONDO祖先) - 撤回门(撤回引文的硬失败) - 表示关切的处罚 - 多源奖金/最低证据处罚
- 物源层:缓存对欧洲PMC的查找;API不可用时的优雅回退。
- 流线型UI:带有实体徽章、证据状态、规则痕迹和判决可视化的交互式审计卡。
Docker部署
使用Docker Compose通过单个命令部署NERVE。
快速启动(一个命令)
docker compose up这将开始:
- UI服务 (端口8501):Streamlit网络界面
- Neo4j (端口7474、7687):图形数据库后端
访问UIhttp://localhost:8501
配置
创建一个 .env 自定义设置文件:
# .env
NEO4J_PASSWORD=your_secure_password
DISGENET_API_KEY=your_disgenet_token # Optional: enhances gene-disease evidence运行批处理审核(CLI)
# Run a single audit
docker compose --profile cli run cli --demo-id REAL_D01
# Audit a custom claim
docker compose --profile cli run cli \
--claim-text "TP53 mutations cause lung cancer" \
--evidence PMID:12345
# JSON output
docker compose --profile cli run cli --demo-id REAL_D01 --format json > output/audit.json从源头构建
# Build the image locally
docker compose build
# Run with live code changes (development)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up服务概述
| 服务 | 端口 | 描述 |
|---|---|---|
ui | 8501 | 流线型网页界面 |
neo4j | 74747687 | 图形数据库(HTTP浏览器,Bolt) |
cli | - | 批处理(按需通过 --profile cli) |
API示例
Python:程序化审计
from nerve.pipeline import run_audit_pipeline
from nerve.models import Claim
# Audit a structured claim
claim = Claim(
subject="BRCA1",
predicate="biolink:gene_associated_with_condition",
object="breast cancer",
provenance=["PMID:12345678", "PMID:87654321"],
)
result = run_audit_pipeline(claim)
print(f"Verdict: {result.verdict}") # PASS, WARN, or FAIL
print(f"Score: {result.score:.2f}")
print(f"Rules fired: {[r.name for r in result.rule_traces if r.fired]}")Python:自由文本声明
from nerve.pipeline import run_audit_pipeline
# Audit free-text (NER extracts entities automatically)
result = run_audit_pipeline(
"TP53 mutations are associated with Li-Fraumeni syndrome",
evidence=["PMID:25108026"],
)
# Access normalized entities
print(f"Subject: {result.claim.subject_id}") # e.g., HGNC:11998
print(f"Object: {result.claim.object_id}") # e.g., MONDO:0010545Python:批处理
from nerve.pipeline import run_audit_pipeline
import json
claims = [
{"text": "BRCA1 causes breast cancer", "evidence": ["PMID:12345"]},
{"text": "TP53 is associated with Li-Fraumeni syndrome", "evidence": ["PMID:25108026"]},
{"text": "EGFR mutations drive lung cancer", "evidence": ["PMID:15118073"]},
]
results = []
for c in claims:
result = run_audit_pipeline(c["text"], evidence=c["evidence"])
results.append({
"claim": c["text"],
"verdict": result.verdict,
"score": result.score,
"rules_fired": [r.name for r in result.rule_traces if r.fired],
})
# Export as JSON
with open("audit_results.json", "w") as f:
json.dump(results, f, indent=2)CLI:用于自动化的JSON输出
# Single audit with JSON output
uv run python -m nerve --demo-id REAL_D01 --format json > audit.json
# Process with jq
uv run python -m nerve --demo-id REAL_D01 --format json | jq '.verdict'MCP工具(用于代理集成)
from nerve.mcp import europepmc, ids, kg
# Search literature
papers = europepmc.search("BRCA1 breast cancer", limit=5)
# Normalize identifiers
gene_info = ids.normalize_gene("BRCA1") # Returns HGNC ID, aliases, etc.
disease_info = ids.normalize_disease("breast cancer") # Returns MONDO ID
# Query knowledge graph
edges = kg.query_edge(subject="HGNC:1100", predicate="biolink:gene_associated_with_condition")
# Get ego network for subgraph visualization
subgraph = kg.ego(node_id="HGNC:1100", hops=2)计划的功能
- 评估数据集:精准度/召回率基准测试的种子索赔。
- 校准:网格搜索规则权重和等渗缩放。
- 批处理模式UI:上传索赔清单,下载CSV格式的审计结果。
将数据加载到Neo4j
NERVE提供了一个统一的数据加载器CLI,只需一个命令即可将所有生物医学数据源下载并加载到Neo4j中。
快速启动
# List available data sources
uv run python -m nerve.loader --list-sources
# Load all data (default REPLACE mode - fast, clean slate)
uv run python -m nerve.loader
# Use MERGE mode (idempotent, slower but safe for incremental updates)
uv run python -m nerve.loader --merge配置
创建一个 .env 使用您的凭据文件:
# .env
NEO4J_URI=bolt://localhost:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=password
# Optional: COSMIC Cancer Gene Census (requires registration)
COSMIC_EMAIL=your_email@example.com
COSMIC_PASSWORD=your_cosmic_password
# Optional: DisGeNET API (for enhanced gene-disease associations)
DISGENET_API_KEY=your_disgenet_token
# Optional: NCBI API key (for higher rate limits on PubMed/citation queries)
# Register at https://www.ncbi.nlm.nih.gov/account/ to get a key
# Without key: 3 requests/sec; with key: 10 requests/sec
NCBI_API_KEY=your_ncbi_api_key数据来源和阶段
加载器根据依赖关系将源分为4个阶段:
| 阶段 | 来源 | 描述 | 凭据 |
|---|---|---|---|
| 1 | monarch | Monarch KG(基因、疾病、表型) | 无 |
| 1 | hpo | HPO注释 | 无 |
| 1 | reactome | 反应体途径 | 无 |
| 1 | hgnc | HGNC ID映射 | 无 |
| 2 | disgenet | DisGeNET基因序列关联 | 无(API可选) |
| 2 | cosmic | 癌症基因普查 | COSMIC_EMAIL,COSMIC_PASSWORD |
| 3 | pub_metadata | 发布元数据丰富 | NCBI_API_KEY(可选) |
| 3 | retractions | 从CrossRef撤回状态 | 无 |
| 3 | citations | PubMed | NCBI_API_KEY引用网络(可选) |
| 4 | hpo_siblings | GNN培训的HPO兄弟映射 | 无 |
常见使用模式
# Load only specific sources
uv run python -m nerve.loader --sources monarch,hpo,disgenet
# Skip sources that require credentials
uv run python -m nerve.loader --skip cosmic
# Run only specific stages
uv run python -m nerve.loader --stages 1,2
# Download files only (no Neo4j loading)
uv run python -m nerve.loader --download-only
# Skip download, use existing files
uv run python -m nerve.loader --skip-download
# Force re-download even if files exist
uv run python -m nerve.loader --force-download
# Dry run (show what would be done)
uv run python -m nerve.loader --dry-run
# Load a small sample for testing
uv run python -m nerve.loader --sample 100训练GNN的怀疑
一个小型的合成数据集和训练循环 scripts/train_suspicion_gnn.py:
- 快速冒烟测试(自动保存数据集+模型):
uv run python scripts/train_suspicion_gnn.py --quick - 默认情况下,它会写入:
- 数据集→ data/suspicion_gnn/synthetic_dataset.pt - 模型检查点→ data/suspicion_gnn/model.pt (通过以下方式覆盖 --save-dataset / --save-model 如果需要)
该脚本从迷你KG构建2跳子图,添加扰动变体(方向翻转、表型交换、合成撤回支持),并训练一个微小的R-GCN来产生每边怀疑分数。主管道和Streamlit UI将自动拾取 data/suspicion_gnn/model.pt 当存在时。
预构建HPO兄弟地图(推荐)
GNN训练需要HPO本体信息来检测表型兄弟交换。使用统一数据加载器构建此内容:
# Build HPO sibling map (Stage 4, requires HPO data from Stage 1)
uv run python -m nerve.loader --sources hpo,hpo_siblings这创造了 data/hpo_sibling_map.json。训练脚本会自动使用此缓存。
替代方案:完全跳过在线查找
如果不需要精确的HPO兄弟检测,请使用静态回退:
uv run python scripts/train_suspicion_gnn.py --skip-hpo-online引文网络集成
GNN可以通过在子图中包含PubMed引用网络来学习基于引用的怀疑模式。这使得能够检测引用撤回作品的论文所支持的可疑边缘。
加载引用和撤回数据:
# Load publication metadata, retraction status, and citations (Stage 3)
uv run python -m nerve.loader --sources pub_metadata,retractions,citations训练GNN:
uv run python scripts/train_suspicion_gnn.py
# To disable citation network (faster, smaller subgraphs):
uv run python scripts/train_suspicion_gnn.py --no-publications它是如何工作的:
引文网络集成增加了:
- 发布节点 具有以下特点:
is_retracted,retracted_citation_ratio(引用与撤回论文的比率),log_cites_retracted - CITES边缘 出版物之间(导演:引用→ 引用)
- 支持_BY边 从生物实体到其支持性出版物
GNN使用消息传递通过引用网络传播怀疑。关键设计:所有功能都使用 比率而不是原始计数 为了避免偏向于高引用论文(例如,2/10引用被撤回的论文比10/1000更可疑)。
添加了边缘级别功能:
retracted_support_ratio:被撤回的支持性出版物的比例citing_retracted_ratio:引用被撤回论文的支持性出版物的比例
贡献
- 看
docs/roadmap.md查看当前进度和未完成的任务。 - 保持更改较小且可测试;比起投机性管道,更喜欢有明确TODO的短桩。
- 记录您所依赖的任何本体源或KG模式,以便我们能够重现发现。
