本文へ移動
cccskills
無料GitHub で公開

bioc-fulltext-fetch

给定 PMID / PMCID 取结构化全文(BioC XML/JSON)。封装 NLM BioC PubMed API(标题+摘要)和 BioC PMC OA API(开放获取全文),输出按章节切分的段落、表格上下文、RAG 友好 chunk。适合大批量入向量库。

触发词:全文抽取 / BioC / RAG 入库 / 文献全文 / PMC 开放获取 / structured fulltext / 段落抽取 / 表格抽取 / fulltext to vector store。

インストール方法を見る

含まれるファイル(1)

  • SKILL.md13.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

BioC Fulltext Fetch

封装 NLM BioC API,用于将 PubMed / PMC 文献转换为 RAG 友好的结构化全文 chunk。

1. 职责边界(单一职责)

只做:给定 PMID / PMCID,取结构化全文(BioC XML/JSON 格式),输出段落、章节、表格上下文、RAG chunk。

不做:

  • 检索文献(交给 pubmed-eutils / europepmc-search)
  • 实体标注(交给 pubtator3)
  • 向量化(交给下游的 embedding pipeline / LangChain / LlamaIndex)
  • ID 转换(可调用 pubmed-eutils.elink_pubmed_to_pmc,但本 skill 不实现 elink)

如果需要这些能力,请使用对应的 skill。

2. 何时使用

触发场景:

  • "把这批 PMID 的全文取下来,准备入 ChromaDB"
  • "我有 PMCID 列表,需要按章节切分做 RAG"
  • "提取 Methods 章节段落"
  • "找出表格周围的语义文本"
  • "Build vector index from PMC open access papers"

不要使用本 skill 当:

  • 用户只需要标题/摘要的纯文本 → 用 pubmed-eutils.efetch
  • 用户需要做语义检索 → 用 europepmc-search 或 pubmed-search
  • 用户需要实体标注(基因/疾病/化合物) → 用 PubTator3 类 skill

3. 两个 BioC 端点

端点输入覆盖内容
BioC PubMedPMID全 PubMed (~37M)标题 + 摘要 + MeSH (结构化)
BioC PMC OAPMCIDPMC 开放获取子集 (~10M)全文(章节、段落、表格、图注)

端点示例:

# 摘要级
https://www.ncbi.nlm.nih.gov/research/bionlp/RESTful/pubmed.cgi/BioC_json/{PMID}/unicode

# 全文级
https://www.ncbi.nlm.nih.gov/research/bionlp/RESTful/pmcoa.cgi/BioC_json/{PMCID}/unicode

文档参考:

4. 推荐工作流

用户给 PMID list
  │
  ▼
[可选] elink PMID → PMCID  (调用 pubmed-eutils)
  │
  ├── PMCID 存在 + 是 OA ──► fetch_fulltext_bioc(pmcid)  ← 全文
  │                                  │
  │                                  ▼
  │                          extract_paragraphs / extract_tables_context
  │                                  │
  │                                  ▼
  │                          to_rag_chunks(chunk_size=512, overlap=50)
  │
  └── 不可用 / 非 OA ──────► fetch_abstract_bioc(pmid)   ← 摘要兜底
                                     │
                                     ▼
                              to_rag_chunks (摘要也按段切)

5. 核心能力(5 个函数)

5.1 fetch_abstract_bioc(pmid: str) → BioCDocument

取标题 + 摘要 + MeSH 的 BioC 结构化版本。

doc = fetch_abstract_bioc("39523456")
# doc.passages → [{"infons": {"section_type": "TITLE"}, "text": "..."},
#                 {"infons": {"section_type": "ABSTRACT"}, "text": "..."}]
# doc.infons["mesh"] → ["Leukemia, Myeloid, Acute", "FLT3 Mutation", ...]

5.2 fetch_fulltext_bioc(pmcid: str) → BioCDocument

取 PMC OA 全文,按章节切分(section_type ∈ {TITLE, ABSTRACT, INTRO, METHODS, RESULTS, DISCUSS, CONCL, REF, FIG, TABLE, ...})。

doc = fetch_fulltext_bioc("PMC10234567")
# 不可用时抛 NotOpenAccessError 或 NotFoundError

错误处理:

  • 404 → 该 PMCID 不在 PMC OA 子集 → 抛 NotOpenAccessError,调用方应回退到 fetch_abstract_bioc
  • 429 → 限流 → 退避重试(最多 3 次,指数退避)
  • 网络错误 → 抛 BioCFetchError,记录日志

5.3 extract_paragraphs(doc: BioCDocument) → list[Paragraph]

按 BioC passage 提取段落数组,保留 section 标签 + 字符 offset。

paragraphs = extract_paragraphs(doc)
# [
#   {"section_label": "INTRO", "text": "Acute myeloid leukemia (AML) is...",
#    "offset_start": 1234, "offset_end": 1820},
#   {"section_label": "METHODS", "text": "Flow cytometry was performed...",
#    "offset_start": 2890, "offset_end": 3401},
#   ...
# ]

实现要点:

  • 跳过 section_type ∈ {REF, FIG_LABEL} 的纯标签段
  • 合并连续相同 section 的短 passage(< 50 字符)
  • offset 来自 BioC passage.offset 字段,保持原文索引一致

5.4 extract_tables_context(doc: BioCDocument, window: int = 200) → list[TableContext]

提取每个表格的上下文(前后 200 字),帮助 RAG 给表格打语义标签。

tables = extract_tables_context(doc, window=200)
# [
#   {
#     "table_id": "T1",
#     "caption": "Patient baseline characteristics",
#     "before_context": "...as shown in Table 1, baseline characteristics...",
#     "after_context": "These data confirm that age and ELN risk...",
#     "section": "RESULTS"
#   },
#   ...
# ]

实现要点:

  • BioC 中 table 通常以 section_type=TABLE 或 passage.infons["xml"]="table" 出现
  • 上下文从同 section 内的相邻 passage 拼接
  • 表格本体的结构化数据不解析(交给专门的 table parser),只取 caption + 周围文本

5.5 to_rag_chunks(doc: BioCDocument, chunk_size: int = 512, overlap: int = 50) → list[Chunk]

把 BioC 文档切成 RAG 入库友好的 chunk。

chunks = to_rag_chunks(doc, chunk_size=512, overlap=50)
# 每个 chunk:
{
    "chunk_id": "PMC10234567_METHODS_2890",
    "text": "Flow cytometry was performed on bone marrow aspirates...",
    "metadata": {
        "pmcid": "PMC10234567",
        "pmid": "39523456",
        "section": "METHODS",
        "offset_start": 2890,
        "offset_end": 3401,
        "doi": "10.1038/s41586-024-xxxxx",
        "year": 2024,
        "is_oa": True,
        "title": "Targeting FLT3 in AML: ...",
        "journal": "Nature",
    }
}

切片策略:

  • 单位:tokens(用 tiktoken cl100k_base)而非字符,默认 512 token
  • 不跨章节切:每个 section 独立切片,避免 chunk 跨越 Methods/Results 边界
  • 段落优先:尽量在段落边界切,实在超长再硬切
  • overlap:50 token,保证语义连续性
  • chunk_id 格式:{pmcid}_{section}_{offset_start} 唯一可追溯

6. 速率限制 + 缓存

速率

  • BioC 不强制 RPS,但服务端对滥用 IP 会封禁
  • 建议 ≤ 5 RPS,批量超过 100 篇时降到 3 RPS
  • 用 asyncio.Semaphore(5) 或 aiolimiter 控制并发

缓存

  • 位置:~/.cache/bioc/{pmcid_or_pmid}.json(原始 BioC JSON)
  • 索引:SQLite 元数据表 ~/.cache/bioc/index.db
    CREATE TABLE bioc_cache (
        key TEXT PRIMARY KEY,        -- "pmc:PMC10234567" or "pmid:39523456"
        file_path TEXT,
        fetched_at INTEGER,           -- Unix epoch
        is_oa INTEGER,
        doi TEXT,
        year INTEGER
    );
    
  • 过期:默认 30 天(CACHE_TTL_DAYS=30),可通过环境变量覆盖
  • 命中流程:查 SQLite → 检查 mtime → 未过期则读 JSON;过期或不存在则重新拉取
  • 失效场景:用户传 force_refresh=True 时绕过缓存

7. 错误处理

错误类型处理
HTTP 404 (PMC OA)NotOpenAccessError调用方回退到 abstract
HTTP 404 (PubMed)NotFoundError该 PMID 不存在,记录并跳过
HTTP 429RateLimitError指数退避重试 (1s, 2s, 4s),最多 3 次
HTTP 5xxBioCServerError重试 3 次后抛出
JSON 解析失败BioCParseError记录原始响应,跳过
网络超时BioCTimeoutErrortimeout=30s,重试 1 次

所有错误继承 BioCFetchError 基类,调用方可以统一捕获。

8. RAG 集成示例

8.1 LangChain

from langchain.schema import Document
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings

# 1. 取全文 → chunk
pmcids = ["PMC10234567", "PMC11122233", ...]
all_chunks = []
for pmcid in pmcids:
    try:
        doc = fetch_fulltext_bioc(pmcid)
    except NotOpenAccessError:
        # 回退到摘要
        pmid = elink_pmc_to_pubmed(pmcid)  # 调用 pubmed-eutils
        doc = fetch_abstract_bioc(pmid)
    all_chunks.extend(to_rag_chunks(doc, chunk_size=512, overlap=50))

# 2. 转 LangChain Document
lc_docs = [
    Document(page_content=c["text"], metadata=c["metadata"])
    for c in all_chunks
]

# 3. 入向量库
vectorstore = Chroma.from_documents(
    lc_docs,
    embedding=OpenAIEmbeddings(model="text-embedding-3-small"),
    collection_name="aml_literature",
    persist_directory="./chroma_aml",
)

8.2 LlamaIndex

from llama_index.core import Document, VectorStoreIndex
from llama_index.embeddings.openai import OpenAIEmbedding

li_docs = [
    Document(
        text=c["text"],
        metadata=c["metadata"],
        doc_id=c["chunk_id"],
        excluded_llm_metadata_keys=["offset_start", "offset_end"],
    )
    for c in all_chunks
]
index = VectorStoreIndex.from_documents(
    li_docs,
    embed_model=OpenAIEmbedding(model="text-embedding-3-small"),
)
index.storage_context.persist("./li_aml_index")

8.3 元数据过滤检索(LangChain)

# 只在 Methods 章节检索
retriever = vectorstore.as_retriever(
    search_kwargs={"filter": {"section": "METHODS"}, "k": 5}
)
results = retriever.invoke("flow cytometry gating strategy for AML blasts")

9. 与其他 skill 的协作

配合的 skill用途
pubmed-eutilsPMID ↔ PMCID 转换(elink)
europepmc-search / pubmed-search先检索得到 PMID list
pubtator3在 chunk 上叠加实体标注(基因、疾病、化合物)
medical-research上层科研 narrative 生成

典型 pipeline:

europepmc-search ──► PMID list ──► pubmed-eutils.elink ──► PMCID list
                                                              │
                                                              ▼
                                            bioc-fulltext-fetch (本 skill)
                                                              │
                                                              ▼
                                          [可选] pubtator3 实体叠加
                                                              │
                                                              ▼
                                                     LangChain / LlamaIndex

10. 环境与依赖

# pyproject 片段
[project]
dependencies = [
    "httpx>=0.27",          # 异步 HTTP
    "aiolimiter>=1.1",      # RPS 限流
    "tiktoken>=0.7",        # token 计数
    "tenacity>=9.0",        # 退避重试
    "platformdirs>=4.0",    # 缓存目录定位
]

环境变量:

  • BIOC_CACHE_DIR(可选,默认 ~/.cache/bioc)
  • BIOC_CACHE_TTL_DAYS(默认 30)
  • BIOC_MAX_RPS(默认 5)
  • BIOC_TIMEOUT_SEC(默认 30)

11. 测试要点

测试预期
fetch_abstract_bioc("39523456")返回 title + abstract passages
fetch_fulltext_bioc("PMC10234567")返回章节切分的全文
fetch_fulltext_bioc("PMC1") (非 OA)抛 NotOpenAccessError
extract_paragraphs(doc)段落数 ≥ 3,每段有 section_label
extract_tables_context(doc)表格上下文左右各 ≤ 200 字
to_rag_chunks(doc, 512, 50)chunk token ≤ 512,overlap ≈ 50,不跨章节
缓存命中第二次调用 < 50ms,无网络请求
429 退避模拟 429 响应后能在 3 次内成功

最低单元测试覆盖率 80%,集成测试用 5 篇真实 PMCID 跑端到端。

12. 已知限制与避坑

  1. OA 子集只占 PMC 的 ~25%:大量 PMID 没有可用全文,务必准备 abstract 兜底路径
  2. 章节标签不统一:不同期刊的 section_type 命名有差异(INTRO vs Introduction),做归一化
  3. 公式与符号:BioC unicode 端点把数学符号转 Unicode,但希腊字母/特殊符号偶尔丢失,关键公式建议从原 XML 端点取
  4. 图与表的图像:BioC 不返回图像,只有 caption 和周围文本;如需图像走 PMC FTP
  5. 大文档内存:单篇 PMC 全文 BioC JSON 可达 1-3 MB,批量处理时注意流式或分批
  6. 非英文文献:BioC PubMed 对非英文摘要支持有限,可能返回原文(西班牙语/中文等),embedding 模型需多语言版本
  7. 历史版本:BioC 端点不返回文章版本号,如需追溯版本变更走 NCBI E-utilities 的 history
  8. 不要直接走 PubTator3 全文端点替代:PubTator3 的 BioC 输出是带实体标注的"加料版",数据量更大且会绑定标注模型版本,本 skill 保持纯净结构化全文,标注由独立 skill 叠加

完成。该 skill 应当与 pubmed-eutils 和 europepmc-search 形成"检索 → ID 转换 → 全文抽取 → RAG 入库"完整闭环。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

使用 AACT (Aggregate Analysis of ClinicalTrials.gov) PostgreSQL 数据仓库进行批量、历史、聚合性临床试验数据挖掘。Use this skill when the user requests bulk SQL analysis over the full clinical trials data warehouse — historical trial trends, disease landscapes, similar-design matching, or multi-year aggregations across hundreds of thousands of NCT records. 触发场景包括:AACT 查询、临床试验批量分析、PostgreSQL 试验数据、全量 NCT 检索、试验数据挖掘、历史试验分析、clinical trials data warehouse、SQL trials、bulk trial analysis、disease landscape、试验设计相似性匹配、跨年度聚合、sponsor/phase/country 多维统计。**与 clinical-trials-v2 差异**:本 skill 走批量 SQL · 离线大数据(PostgreSQL);v2 走实时 API · 单查询。两者互补:单条 NCT 实时状态用 v2,百万级历史挖掘用本 skill。支持云端公共 PostgreSQL(aact-db.ctti-clinicaltrials.org · 零部署)和每日 dump 本地还原(高性能 · 离线)两种连接方式,自动检测优先用本地。跨平台(macOS/Linux/Windows)参数化 SQL 防注入,read-only 强制保护。

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

使用 AACT (Aggregate Analysis of ClinicalTrials.gov) PostgreSQL 数据库进行大批量临床试验历史分析与数据挖掘。触发场景包括:AACT 查询、临床试验批量分析、PostgreSQL 试验数据、全量 NCT 检索、试验数据挖掘、clinical trials data warehouse、疾病领域全景分析、设计相似试验匹配、跨年度试验趋势聚合。本 skill 通过 SQL 接口处理百万级试验记录,支持云端公共 PostgreSQL 服务(aact-db.ctti-clinicaltrials.org)和每日 dump 本地还原两种连接方式,自动检测并优先使用本地高性能模式。

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

Use when work produces a deliverable, factual claim, dataset, code change, decision, publication, deployment, automation, or irreversible action whose failure would matter; when the user asks for a quality gate, acceptance criteria, QA, completeness, validation, audit, evidence, preflight, release readiness, or a definition of done; or before claiming completion on medium- or high-risk work. Automatically decide whether a formal gate is warranted, derive task-specific pass/fail criteria, gather evidence, and block unsupported completion. Make sure to use this skill even when the user does not say "quality gate" if consequential work needs acceptance criteria or completion evidence. Skip formal gating for trivial, reversible, low-impact requests.

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

Create a changeset file in .changeset/ that describes a user-facing change for the release notes

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

Add a new competitor to the AI Visibility Tool Directory — researches the tool, generates data, takes a screenshot, and inserts into the codebase

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

add-lang

無料

Add tree-sitter language support to codegraph end-to-end — wire the grammar + extractor, write tests, then benchmark extraction quality and retrieval value on 3 popular real-world repos. Use when the user runs /add-lang <language> or asks to add/support a new language (e.g. Lua, Elixir, Zig, OCaml) in codegraph.

日本語の概要は準備中です。原文の説明を表示しています。

EthanYoQ/Skill-hub112026年10月5日 更新

EthanYoQ のスキルをすべて見る

このスキルの問題を報告する