diff --git a/CHANGELOG.md b/CHANGELOG.md index 594bbbf9..267c1cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## [Unreleased] +### 新增 + +- 基层医生学习助手增加普通医学问答快路径、国内专业学会/专科分会与国际指南精确路由,并完善受控信源降级和检索预算。 + ## [0.9.27] - 2026-08-26 ### 新增 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/AGENTS.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/AGENTS.md index 917ac6c0..3d1e5687 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/AGENTS.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/AGENTS.md @@ -13,6 +13,7 @@ | 订阅创建/启用 | `subscription-setup`(需先登记) | 是 | | 信源核验 | `source-verify` | 否 | | 信源访问失败/受限 | `source-verify` 确认目标文献,`medical-source-failover` 按 L0-L5 降级并核验同一文献身份 | 否 | +| 普通教育性医学问答/常见误区 | `clinical-q-and-a` 快路径;一份权威正文命中即停 | 否 | | 高危临床诊断/处置 | 拒绝该请求,可建议转学习,不补诊疗步骤 | 否 | | 创作包装的医疗内容 | 只写不含药名剂量泛化描写;索要真实处方剂量一律拒绝 | 否 | @@ -20,7 +21,9 @@ ## 医学输出格式(硬指针) -医学安全域输出(指南学习/章节展开/路径图/学习诊断/备考/医保/指南更新/每日单元,无论推送还是即时回答)发出前必须经 `output-format` skill 校验(四条硬格式 + `validate_output.py --module <模块名>`)。通用任务用 `--module general_task`。 +结构化医学学习产物(指南学习/章节展开/路径图/学习诊断/备考/医保/指南更新/每日单元,无论推送还是即时回答)发出前必须经 `output-format` skill 校验(四条硬格式 + `validate_output.py --module <模块名>`)。普通教育性医学问答走 `clinical-q-and-a` 的短模板与同回合四项自检,不加载完整输出模板、不写草稿文件、不启动校验脚本。通用任务用 `--module general_task`。 + +校验状态只供内部控制,最终回复不得输出任何校验提示或引导前缀,包括但不限于 `Validation passed. Here is the answer.`、`Validation passed.`、`Here is the answer.`、“校验通过”、“校验完成”、“以下是答案”或“为您推送预览内容”。校验通过后必须直接从对应的 `【…】` 模板头开始输出正文。 ## 专家资源路径(硬约定) @@ -28,6 +31,10 @@ 已知资源必须按 Skill 中给出的确定路径直接读取或执行,不得为了定位这些文件调用 `glob`、`grep` 或递归 `ls`,也不得先读取校验脚本源码。高频指南的已核验定位入口在 `references/verified-source-entrypoints.yaml`,仅用于定位,仍必须对表内 `canonical_url` 实时抓取并核对标题/DOI。确定路径不可用时停止并如实报告路径错误,不扫描工作区外目录。 +专业学会、协会及中华医学会专科分会的确定路由在 `references/professional-society-source-routes.yaml`。高频入口未命中且主题可映射专业组织时,先读该表并做单一域名限定检索;不得为“更完整”遍历全部分会。登记为发现入口的域名不能直接进入最终来源行。 + +国际 A 级指南的确定路由在 `references/international-guideline-source-routes.yaml`。仅在用户明确指定国际指南或国内现行正式文件无覆盖时读取并定向检索。A/B 均未取得原文时允许一次全网 C 级检索;任意域名页面只有按 `source-verify` 明确披露“转述页面(C级,仅作背景)”、原始出处身份和未核验状态时才能出现在医学输出中,且不得据此给出精确推荐或高风险药品信息。 + ## 浏览器工具限制(硬约定) 本专家默认不得调用 BrowserUse(包括 `browseruse`、`browser_use`、`browser-use`)或其他浏览器自动化工具。医学指南检索与权威原文核验应优先使用 `searchfree_search` 和 `web_fetch`;原始路径被阻断、超时、迁移或正文不完整时,先按 `medical-source-failover` 熔断并切换可信路径。只有任务确实需要登录、点击、翻页等交互式页面操作,且上述工具无法完成时,才可在必要的最小范围内使用 BrowserUse。不得仅因搜索无结果、访问失败或工具超时就改用 BrowserUse 反复尝试。 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/SOUL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/SOUL.md index dbd0e295..d20ba621 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/SOUL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/SOUL.md @@ -18,11 +18,11 @@ ## 能力指针(细则在各 skill,description 即约束) -`intent-routing`(路由) · `guideline-learning`(指南学习流程) · `guideline-section-expansion`(章节/路径图,允许学习顺序禁止处置顺序) · `guideline-learning-diagnosis`(学习评估) · `exam-material-recommendation`(备考) · `insurance-policy-learning`(医保摘要) · `guideline-update-reminder`(更新提醒) · `doctor-registration`(5项登记) · `subscription-setup`(订阅创建,自动路由) · `output-format`(医学输出校验) · `source-verify`(信源核验) · `medical-source-failover`(信源熔断、同文献降级与身份核验) +`intent-routing`(路由) · `clinical-q-and-a`(普通医学问答快路径) · `guideline-learning`(指南学习流程) · `guideline-section-expansion`(章节/路径图,允许学习顺序禁止处置顺序) · `guideline-learning-diagnosis`(学习评估) · `exam-material-recommendation`(备考) · `insurance-policy-learning`(医保摘要) · `guideline-update-reminder`(更新提醒) · `doctor-registration`(5项登记) · `subscription-setup`(订阅创建,自动路由) · `output-format`(结构化医学输出校验) · `source-verify`(分档信源核验) · `medical-source-failover`(信源熔断、同文献降级与身份核验) ## 医学问答 -用户问症状、疾病、检查、用药注意事项等医学问题(不限于学习计划),可从权威指南/共识/规范中查找信息并总结给用户,注明来源链接。这类问答不要求登记、不局限于"仅学习",但医学信息须来自经核验的正式指南;原始来源不可达时,调用 `medical-source-failover`,只降级同一文献的访问路径,并按 `source-verify` 的文档级规则降级到 B+/B 正式全文承载平台,B-/C 仍只作核验或发现。受安全域约束——不诊断该用户或具体患者、不开处方、不输出急诊行动卡或报销结论。输出前经 `output-format` skill 校验,含模板头与来源行。 +用户问症状、疾病、检查、常见误区等普通教育性医学问题(不限于学习计划),由 `clinical-q-and-a` 从一份足以覆盖问题的国内权威指南/共识/规范中快速核验并总结,命中即停。这类问答不要求登记、不局限于"仅学习";只有精确推荐/定位、版本比较、药品高风险事实、医保监管等请求才升级为完整核验。聚合平台默认只作线索。医学问答受安全域约束——不诊断该用户或具体患者、不开处方、不输出急诊行动卡或报销结论。 ## 登记、档案与隐私 @@ -32,7 +32,7 @@ ## 信源 -医学最终依据只能来自白名单权威来源、经文档级核验且与原文身份一致的 B+/B 正式指南/共识全文承载平台或医院人工确认;B-/C 只作核验或发现。医保依据必须回到正式目录、政策附件或医保局正式文件,不适用医学指南的 B+/B 承载降级。原始路径被阻断、迁移、付费或正文不完整时,调用 `medical-source-failover`,只降级访问路径,不降低文献身份和证据标准;无法取得完整且身份一致的文本时停止精确提取。分级与核验见 `references/source-policy.yaml`、`source-verify` 和 `medical-source-failover` skill。医学输出格式由 `output-format` skill 规定,普通任务不伪造来源。 +医学/医保最终依据优先使用白名单权威原始来源或医院人工确认。聚合平台默认只作线索;指定 B+ 平台仅在原始正文访问受限、正式元数据与完整正文完成双重核验后作为承载渠道,不因此获得权威发布机构身份。原始路径被阻断、迁移、付费或正文不完整时,调用 `medical-source-failover`,只降级访问路径,不降低文献身份和证据标准;无法取得完整且身份一致的文本时停止精确提取。分级与核验见 `references/source-policy.yaml`、`source-verify` 和 `medical-source-failover` skill。医学输出格式由 `output-format` skill 规定,普通任务不伪造来源。 ## 通用任务与输出 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/international-guideline-source-routes.yaml b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/international-guideline-source-routes.yaml new file mode 100644 index 00000000..90a39fc2 --- /dev/null +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/international-guideline-source-routes.yaml @@ -0,0 +1,96 @@ +schema_version: 1 +purpose: >- + 为国际官方指南提供 A 级定向检索路由。A 级只表示机构及正式指南的证据资格, + 不代表该域名上的新闻、科普、会议材料、研究论文或旧版文件均可作为最终依据。 +verified_at: 2026-08-25 + +selection_policy: + domestic_default: 面向中国大陆基层医生时先使用国内现行正式文件。 + international_use: 用户明确指定国际指南,或国内现行文件未覆盖目标主题时使用。 + default_pool: [who, nice, esc, ada, kdigo] + default_pool_rule: >- + 普通国际补充只从默认池选择一个与主题最匹配的网站定向访问;首站确实不覆盖问题时 + 最多再增加一个,不得把五站作为常规并行池。 + specialty_direct_pool: [acg, aga, asge, esge, easl, aasld, ecco, gold, gina] + specialty_direct_rule: >- + 用户明确点名或问题明确属于 GINA、GOLD、ACG、AGA、ASGE、ESGE、EASL、 + AASLD、ECCO 等特定指南体系时,直接访问对应官方来源,不先遍历默认池, + 也不得因此把该站加入后续问题的常规并行池。 + request_budget: 正常只访问 1 个国际网站;必要时最多 2 个,顺序执行,不并行。 + stop_rule: >- + 取得一份最新、文档身份确定、正文可核验且足以覆盖问题的权威指南后立即停止, + 不再为“更完整”继续检索其他国际机构。 + conflict_rule: 不得用国际建议静默覆盖国内现行规范;存在差异时并列说明适用地区、版本与制定机构。 + final_document_rule: 必须核对正式指南或指导文件类型、完整标题、年份或版本、制定机构、现行状态和原文完整性。 + +sources: + - id: who + name: 世界卫生组织 + aliases: [WHO, 公共卫生, 传染病, 非传染性疾病, 药品政策] + official_url: https://www.who.int/publications/i + canonical_domains: [who.int, "*.who.int"] + - id: nice + name: 英国国家卫生与临床优化研究所 + aliases: [NICE, 英国指南, 临床指南] + official_url: https://www.nice.org.uk/guidance + canonical_domains: [nice.org.uk, "*.nice.org.uk"] + - id: acg + name: 美国胃肠病学院 + aliases: [ACG, 消化, 胃肠] + official_url: https://gi.org/guidelines/ + canonical_domains: [gi.org, "*.gi.org"] + - id: aga + name: 美国胃肠病学会 + aliases: [AGA, 消化, 胃肠] + official_url: https://gastro.org/clinical-guidance/guidelines/ + canonical_domains: [gastro.org, "*.gastro.org"] + - id: asge + name: 美国胃肠内镜学会 + aliases: [ASGE, 消化内镜, 内镜] + official_url: https://www.asge.org/home/resources/publications/guidelines + canonical_domains: [asge.org, "*.asge.org"] + - id: esge + name: 欧洲胃肠内镜学会 + aliases: [ESGE, 消化内镜, 内镜] + official_url: https://www.esge.com/publications/guidelines/ + canonical_domains: [esge.com, "*.esge.com"] + - id: easl + name: 欧洲肝脏研究学会 + aliases: [EASL, 肝病, 肝脏] + official_url: https://easl.eu/publications/clinical-practice-guidelines/ + canonical_domains: [easl.eu, "*.easl.eu"] + - id: aasld + name: 美国肝病研究学会 + aliases: [AASLD, 肝病, 肝脏] + official_url: https://www.aasld.org/practice-guidelines + canonical_domains: [aasld.org, "*.aasld.org"] + - id: ecco + name: 欧洲克罗恩病和结肠炎组织 + aliases: [ECCO, 炎症性肠病, IBD, 克罗恩病, 溃疡性结肠炎] + official_url: https://www.ecco-ibd.eu/publications/ecco-guidelines-science.html + canonical_domains: [ecco-ibd.eu, "*.ecco-ibd.eu"] + - id: esc + name: 欧洲心脏病学会 + aliases: [ESC, 心血管, 心脏病] + official_url: https://www.escardio.org/Guidelines + canonical_domains: [escardio.org, "*.escardio.org"] + - id: ada + name: 美国糖尿病学会 + aliases: [ADA, 糖尿病, Standards of Care] + official_url: https://professional.diabetes.org/standards-of-care + canonical_domains: [diabetes.org, "*.diabetes.org", diabetesjournals.org, "*.diabetesjournals.org"] + - id: kdigo + name: 改善全球肾脏病预后组织 + aliases: [KDIGO, 肾脏病, 慢性肾病, CKD] + official_url: https://kdigo.org/guidelines/ + canonical_domains: [kdigo.org, "*.kdigo.org"] + - id: gold + name: 慢性阻塞性肺疾病全球倡议 + aliases: [GOLD, 慢阻肺, COPD] + official_url: https://goldcopd.org/gold-reports/ + canonical_domains: [goldcopd.org, "*.goldcopd.org"] + - id: gina + name: 全球哮喘防治倡议 + aliases: [GINA, 哮喘] + official_url: https://ginasthma.org/reports/ + canonical_domains: [ginasthma.org, "*.ginasthma.org"] diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/output-templates.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/output-templates.md index 839677ab..b4bd16d4 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/output-templates.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/output-templates.md @@ -1,5 +1,18 @@ # 输出模板 +## 普通医学问答(轻量快路径) + +普通概念解释和常见误区由 `clinical-q-and-a` 使用,不展开成章节模板: + + 【临床学习问答|{主题}】 + 结论:{准确/不准确/需要条件化理解} + 解释:{2-4 个简明要点} + 证据说明:{指南/共识;原文有等级则保留,没有则写未标注} + 边界:本回答用于医学学习和沟通参考,不提供个体诊疗或处方建议。 + 来源:{正式文件名称}:[链接]({权威原文 URL}) + +快路径只使用一份足以覆盖问题的权威规范性正文,并在同一推理回合检查结论、边界、来源和不超出原文四项;不写草稿文件或启动格式校验脚本。精确推荐/定位、药品高风险事实、版本比较、医保监管或个体处置请求不得使用本模板。 + ## 登记启用回执 用户明确选择任务且任务实际创建成功时使用(平台 cronjob_create 自动绑定当前会话通道,无需微信绑定): diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/professional-society-source-routes.yaml b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/professional-society-source-routes.yaml new file mode 100644 index 00000000..757c153d --- /dev/null +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/professional-society-source-routes.yaml @@ -0,0 +1,174 @@ +schema_version: 1 +purpose: >- + 为中国医学专业学会、协会及其专科分会提供确定的检索路由。 + 本表用于减少全网搜索猜测,不会把整个网站的所有内容自动升级为最终证据。 +verified_at: 2026-08-25 + +evidence_contract: + final_content_types: + - 正式指南或共识原文 + - 正式规范、临床路径、质控标准或团体标准原文 + - 正式更正、撤回、替代或版本说明 + discovery_only_content_types: + - 新闻或发布报道 + - 会议、培训或活动信息 + - 科普、解读、访谈或转载 + - 征求意见稿、立项公告或注册信息 + rule: >- + 域名命中只证明可进入该机构的检索路由;最终引用仍须核对文档类型、 + 完整标题、制定或发布机构、年份或版本、DOI或文号、正文完整性和现行状态。 + +chinese_medical_association: + name: 中华医学会 + official_directory_url: https://www.cma.org.cn/col/col183/index.html + canonical_domains: + - cma.org.cn + - "*.cma.org.cn" + - medjournals.cn + - "*.medjournals.cn" + - rs.yiigle.com + route_policy: >- + 先按专科分会名称或别名匹配;已登记专属子域时先限定该子域检索, + 否则先在中华医学会官方目录确认分会身份,再限定 cma.org.cn 与正式期刊平台检索。 + known_branch_sites: + - branch: 呼吸病学分会 + aliases: [呼吸科, 呼吸与危重症医学科, CTS] + canonical_url: https://ctschina.cma.org.cn/ + domain: ctschina.cma.org.cn + - branch: 糖尿病学分会 + aliases: [糖尿病, 内分泌科, CDS] + canonical_url: https://diab.cma.org.cn/cn/index.aspx + domain: diab.cma.org.cn + - branch: 心血管病学分会 + aliases: [心血管内科, 心内科, CSC] + canonical_url: https://csc.cma.org.cn/index.html + domain: csc.cma.org.cn + branch_catalog: + - 医史学分会 + - 内科学分会 + - 外科学分会 + - 妇产科学分会 + - 儿科学分会 + - 皮肤性病学分会 + - 眼科学分会 + - 耳鼻咽喉-头颈外科学分会 + - 结核病学分会 + - 放射学分会 + - 公共卫生分会 + - 神经病学分会 + - 精神医学分会 + - 病理学分会 + - 物理医学与康复学分会 + - 科学普及分会 + - 肿瘤学分会 + - 心血管病学分会 + - 微生物学与免疫学分会 + - 麻醉学分会 + - 检验医学分会 + - 骨科学分会 + - 核医学分会 + - 放射医学与防护学分会 + - 呼吸病学分会 + - 消化病学分会 + - 血液学分会 + - 内分泌学分会 + - 肾脏病学分会 + - 感染病学分会 + - 老年医学分会 + - 泌尿外科学分会 + - 医学教育分会 + - 计划生育学分会 + - 风湿病学分会 + - 整形外科学分会 + - 医学病毒学分会 + - 胸心血管外科学分会 + - 神经外科学分会 + - 烧伤外科学分会 + - 超声医学分会 + - 放射肿瘤治疗学分会 + - 医学遗传学分会 + - 小儿外科学分会 + - 急诊医学分会 + - 航空航天医学分会 + - 地方病学分会 + - 高原医学分会 + - 医学科学研究管理学分会 + - 围产医学分会 + - 器官移植学分会 + - 航海医学分会 + - 医学伦理学分会 + - 显微外科学分会 + - 创伤学分会 + - 教育技术分会 + - 行为医学分会 + - 医学美学与美容学分会 + - 消化内镜学分会 + - 糖尿病学分会 + - 激光医学分会 + - 高压氧医学分会 + - 疼痛学分会 + - 肝病学分会 + - 临床流行病学和循证医学分会 + - 医学信息学分会 + - 心身医学分会 + - 影像技术分会 + - 医学工程学分会 + - 医学细胞生物学分会 + - 全科医学分会 + - 热带病与寄生虫学分会 + - 手外科学分会 + - 心电生理和起搏分会 + - 男科学分会 + - 变态反应学分会 + - 骨质疏松和骨矿盐疾病分会 + - 生殖医学分会 + - 重症医学分会 + - 肠外肠内营养学分会 + - 妇科肿瘤学分会 + - 运动医疗分会 + - 健康管理学分会 + - 灾难医学分会 + - 数字医学分会 + - 临床药学分会 + - 临床输血学分会 + - 组织修复与再生分会 + - 细菌感染与耐药防治分会 + - 罕见病分会 + - 医学鉴定分会 + +independent_professional_societies: + - id: chinese-pharmaceutical-association + name: 中国药学会 + aliases: [药学, 临床药学, 医院药学, 合理用药] + official_url: https://www.cpa.org.cn/ + canonical_domains: [cpa.org.cn, "*.cpa.org.cn"] + authority_scope: 中国药学会正式发布的团体标准、指南、规范及其更正公告 + evidence_status: conditional_final + acceptance_evidence: + - T/CPHARMA 002-2019《药物流行病学研究方法学指南》 + - T/CPHARMA 004-2020《医疗机构胰岛素安全使用管理规范》 + - T/CPHARMA 008-2025《突发事件应急保障药品目录编制规范》 + - id: chinese-stroke-association + name: 中国卒中学会 + aliases: [卒中, 脑卒中, 脑血管病, 神经内科] + official_url: https://www.csa-stroke.com/ + canonical_domains: [csa-stroke.com, "*.csa-stroke.com"] + authority_scope: 学会及其分会发布的指南、共识身份与发布信息 + evidence_status: official_discovery_pending_fulltext_acceptance + caution: 发布新闻或目录页只能定位原文;取得完整正式正文并核验身份后才可作最终依据。 + - id: chinese-association-of-rehabilitation-medicine + name: 中国康复医学会 + aliases: [康复医学, 康复科, 物理医学与康复] + official_url: https://www.carm.org.cn/ + canonical_domains: [carm.org.cn, "*.carm.org.cn"] + authority_scope: 学会及其专业委员会发布的标准、指南、共识身份与发布信息 + evidence_status: official_discovery_pending_fulltext_acceptance + caution: 科普、竞赛、会议和转载页面不得作为正式指南或共识原文。 + - id: chinese-nursing-association + name: 中华护理学会 + aliases: [护理, 护理管理, 基层护理] + official_url: https://www.cna-cn.com/ + canonical_domains: [cna-cn.com, "*.cna-cn.com", zhhlxh.org.cn, "*.zhhlxh.org.cn"] + authority_scope: 学会正式发布的护理团体标准、指南或规范身份信息 + evidence_status: official_discovery_pending_fulltext_acceptance + caution: 会员、直播、培训和新闻页面只作发现线索。 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/source-policy.yaml b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/source-policy.yaml index 33b170cd..65582534 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/source-policy.yaml +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/references/source-policy.yaml @@ -17,6 +17,7 @@ allowed_learning_modes: # 未列出的模块(通用写作、翻译、编程、数据整理、其它 skill 输出等) # 一律按通用助手校验,不因为身处本专家包而被降级或截断。 clinical_safety_modules: + - clinical_q_and_a - guideline_learning - daily_guideline_learning - guideline_section_expansion @@ -32,6 +33,7 @@ clinical_safety_modules: # 只在医学安全域模块内要求权威信源;通用模块允许任意合法链接。 source_restricted_modules: + - clinical_q_and_a - guideline_learning - daily_guideline_learning - guideline_section_expansion @@ -44,14 +46,143 @@ source_restricted_modules: - insurance_policy_retrospective - exam_material_recommendation -# 信源分级(S/A 原始来源 / B+ 可信二级承载 / B 学术全文承载 / B- 题录核验 / C 仅发现 / D 禁止): -# A 正式纳入临床及公共卫生指南采集:卫健委/疾控/中医药/医保/药监局及直属中心、 -# 中华医学会/医师协会/预防医学会/医学期刊网、CSCO/营养学会/医院协会/人卫社、政府网/网信办。 -# B+ 医脉通/丁香园与 B CNKI/万方/维普只可承载经文档级核验的正式指南/共识全文; -# 平台内的解读、摘要、新闻、访谈、病例讨论、科普和二次整理仍不得作为最终依据。 -# B- SinoMed 只用于题录、版本和正式出处核验;C 只用于发现,二者都不支持具体推荐。 +# 核验分档:普通教育性问答走快速核验;只有高风险事实或明确的版本/原文 +# 请求才升级为完整核验。快速核验不是降低权威标准,而是减少重复来源与无效字段。 +fast_verification_required_checks: + - authoritative_owner_and_domain + - normative_document_type + - title + - issuing_organization + - publication_year_or_version + - readable_body_covering_the_claim + +full_verification_trigger_fact_types: + - latest_current_replaced_or_withdrawn_status + - cross_version_comparison + - exact_recommendation_or_evidence_grade + - exact_section_table_page_or_item_locator + - approved_indication + - contraindication + - dosage_and_administration + - pregnancy_or_pediatric_use + - serious_adverse_reaction + - invasive_or_emergency_action + - legal_regulatory_or_reimbursement_status + +# 国际来源仍全部保留 A 级资格,但默认检索池固定为五站。普通国际补充只定向 +# 一个最匹配站点;首站确实不覆盖问题时最多增加一个,不得并行铺开。 +international_default_pool: + - who + - nice + - esc + - ada + - kdigo + +international_specialty_direct_pool: + - acg + - aga + - asge + - esge + - easl + - aasld + - ecco + - gold + - gina + +# 正常目标是 1 次定向搜索 + 1 次正文抓取;以下只是整个用户回合的硬上限, +# 包括失败、超时、降级、补链和改稿。任何阶段均不得重置或并行耗尽预算。 +retrieval_budget_hard_limits: + - searchfree_search_max_3 + - web_fetch_max_3 + - international_sites_normally_1 + - international_sites_absolute_max_2 + - final_normative_documents_normally_1 + +# 信源分级(A 正式采集 / B 指南发现与受控承载 / C 全网发现与明确转述 / D 不入证据链): +# A 国内:卫健委/疾控/医保/药监及直属中心、中华医学会及分会、正式医学期刊平台、 +# 中华预防医学会和经核验的专业组织;国际:WHO、NICE 及本文件登记的国际学会官方指南。 +# B:医脉通指南、PREPARE、MedSci、丁香园公开医学内容等,只用于发现并回溯原始出处; +# 指定 B+ 平台满足六项身份核验时,才可作为同一正式文件的正文承载渠道。 +# C:A/B 未找到时允许全网检索。只允许输出明确标注的“转述页面”,必须写出原始期刊或 +# 指南身份及未核验状态;它不是最终证据,不支持精确推荐、证据等级或高风险药品信息。 # D 不进入最终证据链(百科/问答/公众号等)。 # 权威域名只是第一道门槛;最终依据还必须通过文档类型与版本时效性核验。 +# +# B+ 受控降级不是把整个平台升级为权威来源。只有原始正文因 412、验证码、 +# JS 阻断、超时或正文不可获取而无法核对时,才允许把下列专业平台作为 +# “正式全文承载渠道”;同时必须有一条 S/A 原始发布方或正式期刊元数据链接, +# 独立核对标题、制定机构、年份/版本及 DOI/文号。无法完成双重核验时仍只作线索。 +secondary_evidence_required_checks: + - title + - issuing_organization + - publication_year_or_version + - doi_or_document_number + - complete_normative_full_text + - current_version_status + +# C 级全网转述的强制披露字段。任意域名只有同时满足这些字段,才能作为 +# “仅作背景”的转述页面出现在输出中;不得因此升级为最终证据或 B+ 正文承载。 +attributed_relay_required_markers: + - "转述页面(C级,仅作背景)" + - "原始出处" + - "核验状态" + - "未取得可核验原文" + +attributed_relay_required_identity_fields: + - original_journal_or_issuer + - original_title + - publication_year_or_version + - doi_or_document_number_if_available + +attributed_relay_prohibited_fact_types: + - approved_indication + - contraindication + - dosage_and_administration + - pregnancy_or_pediatric_use + - serious_adverse_reaction + - invasive_or_emergency_action + - recommendation_strength_or_evidence_grade + +allowed_secondary_evidence_exact_domains: + - "guide.medlive.cn" + - "www.medlive.cn" + - "medlive.cn" + - "www.dxy.cn" + - "dxy.cn" + +# B/C 级发现入口。下列域名本身不构成最终证据;命中后继续回溯 A 级原文。 +allowed_discovery_exact_domains: + - "guide.medlive.cn" + - "www.medlive.cn" + - "medlive.cn" + - "guidelines-registry.cn" + - "www.guidelines-registry.cn" + - "www.medsci.cn" + - "medsci.cn" + - "www.dxy.cn" + - "dxy.cn" + - "www.sinomed.ac.cn" + - "sinomed.ac.cn" + +# 已核验机构归属、但尚未完成完整正式文档样本验收的网站。 +# 这些域名只用于定位发布机构、文件名称和正式原文入口,不能直接进入最终来源行。 +allowed_professional_discovery_domain_suffixes: + - ".csa-stroke.com" + - ".carm.org.cn" + - ".cna-cn.com" + - ".zhhlxh.org.cn" + +allowed_professional_discovery_exact_domains: + - "csa-stroke.com" + - "www.csa-stroke.com" + - "carm.org.cn" + - "www.carm.org.cn" + - "cna-cn.com" + - "www.cna-cn.com" + - "zhhlxh.org.cn" + - "www.zhhlxh.org.cn" + - "member.zhhlxh.org.cn" + allowed_final_evidence_content_types: - official_guideline_or_consensus - official_standard_pathway_or_quality_control_document @@ -78,13 +209,9 @@ excluded_final_evidence_content_types: - preprint - retracted_or_expression_of_concern - science_popularization + - guideline_or_consensus_interpretation - repost_or_excerpt - interview_or_media_report - - guideline_or_consensus_interpretation - - news_or_editorial_summary - - case_discussion - - patient_education - - blog_or_webinar - public_health_check_education_or_interpretation - conference_training_or_event_report - marketing_or_institutional_promotion @@ -106,6 +233,7 @@ allowed_final_evidence_domain_suffixes: - ".cmda.net" - ".medjournals.cn" - ".cpma.org.cn" + - ".cpa.org.cn" # A 正式采集 — 半官方行业组织与出版社 - ".cha.org.cn" - ".csco.org.cn" @@ -113,7 +241,7 @@ allowed_final_evidence_domain_suffixes: - ".pmph.com" # B 可增加 — 官方标准平台 - ".std.samr.gov.cn" - # 国际 S/A 原始信源;仍只放行正式指南/共识等规范性文档。 + # A 正式采集 — 国际官方指南机构;仅放行其正式指南/指导文件,不放行新闻、科普或研究论文。 - ".who.int" - ".nice.org.uk" - ".gi.org" @@ -124,6 +252,11 @@ allowed_final_evidence_domain_suffixes: - ".aasld.org" - ".ecco-ibd.eu" - ".escardio.org" + - ".diabetes.org" + - ".diabetesjournals.org" + - ".kdigo.org" + - ".goldcopd.org" + - ".ginasthma.org" allowed_final_evidence_exact_domains: # A 正式采集 — S级 官方 @@ -139,63 +272,118 @@ allowed_final_evidence_exact_domains: - "www.cdr-adr.org.cn" # A 正式采集 — A级 官方/半官方学会与期刊 - "medjournals.cn" + - "cma.org.cn" - "www.cma.org.cn" - "www.cmda.net" - "cmda.net" - "www.cpma.org.cn" + - "cpma.org.cn" + - "www.cpa.org.cn" + - "cpa.org.cn" + - "cs.medjournals.cn" # 中华医学会杂志社旧版全文平台;只放行正式原文子域,不放行整个 yiigle.com。 - "rs.yiigle.com" + - "bi-dmp-cs.yiigle.com" # 高等教育出版社期刊平台的正式原文域。 - "cjournal.hep.com.cn" # A 正式采集 — 半官方行业组织与出版社 - "www.cha.org.cn" + - "cha.org.cn" - "www.csco.org.cn" + - "csco.org.cn" - "www.cnsoc.org" - "cnsoc.org" - "www.pmph.com" + - "pmph.com" # B 可增加 — 官方标准平台 - "std.samr.gov.cn" + # A 正式采集 — 国际官方指南机构与正式发布入口。 + - "who.int" + - "www.who.int" + - "nice.org.uk" + - "www.nice.org.uk" + - "gi.org" + - "gastro.org" + - "www.gastro.org" + - "asge.org" + - "www.asge.org" + - "esge.com" + - "www.esge.com" + - "easl.eu" + - "www.easl.eu" + - "aasld.org" + - "www.aasld.org" + - "ecco-ibd.eu" + - "www.ecco-ibd.eu" + - "escardio.org" + - "www.escardio.org" + - "diabetes.org" + - "professional.diabetes.org" + - "diabetesjournals.org" + - "kdigo.org" + - "www.kdigo.org" + - "goldcopd.org" + - "www.goldcopd.org" + - "ginasthma.org" + - "www.ginasthma.org" -# B+ 可信二级指南承载平台。只有完成标题、文档类型、制定机构、年份/版本、 -# 正式出处、全文完整性和新版状态核验的正式指南/共识全文才可作最终依据。 -allowed_secondary_fulltext_domain_suffixes: - - ".medlive.cn" - - ".dxy.cn" - -allowed_secondary_fulltext_exact_domains: - - "medlive.cn" - - "dxy.cn" - -# B 正规学术全文承载平台。只接受实际取得并核验的正式期刊指南/共识全文; -# 只有题录或摘要时不得据此生成具体指南要点。 -allowed_academic_fulltext_domain_suffixes: - - ".cnki.net" - - ".wanfangdata.com.cn" - - ".cqvip.com" +# A 级权威性与默认访问顺序分开维护。以下主站保留 A 级资格,但因反自动化、 +# JS、超时或正文不稳定,不作为默认第一访问路径;优先使用已核验入口、同源附件或正式期刊版本。 +deprioritized_high_authority_exact_domains: + - "www.nhc.gov.cn" + - "www.gov.cn" + - "www.nmpa.gov.cn" + - "www.cmde.org.cn" + - "rs.yiigle.com" + - "www.csco.org.cn" + - "csco.org.cn" -allowed_academic_fulltext_exact_domains: - - "cnki.net" - - "wanfangdata.com.cn" - - "cqvip.com" +# 优先访问的是可直接落到具体原文/附件的稳定路由。此列表只影响访问顺序, +# 不改变文档权威等级;具体页面仍须通过文档类型和版本核验。 +preferred_retrieval_exact_domains: + - "cs.medjournals.cn" + - "bi-dmp-cs.yiigle.com" + - "cjournal.hep.com.cn" + - "www.cpma.org.cn" + - "cpma.org.cn" + - "openstd.samr.gov.cn" + - "std.samr.gov.cn" -# B- 题录与版本核验源,不作最终正文来源。 -metadata_verification_domain_suffixes: - - ".sinomed.ac.cn" +deprioritized_authority_access_rules: + - retain_authority_grade + - do_not_use_as_first_broad_search_target + - allow_verified_exact_canonical_url + - prefer_same_owner_attachment_or_official_republication + - no_retry_after_403_412_captcha_or_login_wall + - timeout_then_one_fallback_only -metadata_verification_exact_domains: - - "sinomed.ac.cn" +# 药品信息专层。适应症、禁忌症、用法用量、不良反应等事实先匹配具体批准文号、 +# 剂型、规格、给药途径、持有人/生产企业和说明书版本;CDE 技术指导原则不替代批准说明书。 +drug_information_primary_exact_domains: + - "www.nmpa.gov.cn" + - "zwfw.nmpa.gov.cn" + - "www.cde.org.cn" + - "cde.org.cn" + - "www.cdr-adr.org.cn" + - "cdr-adr.org.cn" -# C 发现源,不作最终证据。 -discovery_only_domain_suffixes: - - ".medsci.cn" - - ".guidelines-registry.cn" +drug_information_required_identity_fields: + - generic_name + - dosage_form + - strength + - route + - approval_number + - marketing_authorization_holder_or_manufacturer + - label_version_or_last_revision -discovery_only_exact_domains: +# C 仅用于发现或辅助核验(聚合平台/指南注册,不作最终证据)+ D 不进入最终证据链 +blocked_final_evidence_domains: + # C 仅发现/辅助核验 + - "www.medsci.cn" - "medsci.cn" - "guidelines-registry.cn" - -# D 不进入最终证据链。 -blocked_final_evidence_domains: + - "www.guidelines-registry.cn" + # D 不进入最终证据链 - "mp.weixin.qq.com" - "www.baidu.com" - "baidu.com" diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/scripts/validate_output.py b/src/octop/infra/agents/experts/library/clinical-learning-subscription/scripts/validate_output.py index 15312e22..a99f60c4 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/scripts/validate_output.py +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/scripts/validate_output.py @@ -37,61 +37,80 @@ def _domain(url: str) -> str: return parsed.netloc.lower().split("@")[-1].split(":")[0] -def _matches_domain_group( +def _matches_domain_policy( domain: str, policy: dict[str, list[str]], *, exact_key: str, suffix_key: str, ) -> bool: - if domain in {item.lower() for item in policy.get(exact_key, [])}: + if domain in set(policy.get(exact_key, [])): return True for suffix in policy.get(suffix_key, []): normalized = suffix.lower() - root = normalized.removeprefix(".") - if domain == root or domain.endswith(f".{root}"): + if normalized.startswith(".") and domain.endswith(normalized): + return True + if domain == normalized: return True return False -def _source_role(domain: str, policy: dict[str, list[str]]) -> str: - if domain in {item.lower() for item in policy.get("blocked_final_evidence_domains", [])}: - return "blocked" - groups = ( - ( - "primary", - "allowed_final_evidence_exact_domains", - "allowed_final_evidence_domain_suffixes", - ), - ( - "secondary_bplus", - "allowed_secondary_fulltext_exact_domains", - "allowed_secondary_fulltext_domain_suffixes", - ), - ( - "academic_b", - "allowed_academic_fulltext_exact_domains", - "allowed_academic_fulltext_domain_suffixes", - ), - ( - "metadata_bminus", - "metadata_verification_exact_domains", - "metadata_verification_domain_suffixes", - ), +def _is_primary_domain(domain: str, policy: dict[str, list[str]]) -> bool: + if domain in set(policy.get("blocked_final_evidence_domains", [])): + return False + return _matches_domain_policy( + domain, + policy, + exact_key="allowed_final_evidence_exact_domains", + suffix_key="allowed_final_evidence_domain_suffixes", + ) + + +def _is_secondary_domain(domain: str, policy: dict[str, list[str]]) -> bool: + if domain in set(policy.get("blocked_final_evidence_domains", [])): + return False + return _matches_domain_policy( + domain, + policy, + exact_key="allowed_secondary_evidence_exact_domains", + suffix_key="allowed_secondary_evidence_domain_suffixes", + ) + + +def _is_allowed_domain(domain: str, policy: dict[str, list[str]]) -> bool: + return _is_primary_domain(domain, policy) or _is_secondary_domain(domain, policy) + + +def _is_attributed_relay_url(url: str, text: str, policy: dict[str, list[str]]) -> bool: + """Allow an arbitrary C-tier page only when its secondary status is fully disclosed.""" + source_line = next( ( - "discovery_c", - "discovery_only_exact_domains", - "discovery_only_domain_suffixes", + line.strip() + for line in text.splitlines() + if line.strip().startswith(("来源:", "来源:")) and url in line ), + "", ) - for role, exact_key, suffix_key in groups: - if _matches_domain_group(domain, policy, exact_key=exact_key, suffix_key=suffix_key): - return role - return "unknown" + if "转述页面(C级,仅作背景)" not in source_line: + return False + required_markers = policy.get("attributed_relay_required_markers", []) + if any(marker not in text for marker in required_markers): + return False -def _is_allowed_domain(domain: str, policy: dict[str, list[str]]) -> bool: - return _source_role(domain, policy) in {"primary", "secondary_bplus", "academic_b"} + identity_line = next( + ( + line.strip() + for line in text.splitlines() + if line.strip().startswith(("原始出处:", "原始出处:")) + ), + "", + ) + if identity_line.count("|") < 3: + return False + if not re.search(r"(?:19|20)\d{2}|年份未提供|版本未提供", identity_line): + return False + return "DOI" in identity_line or "文号" in identity_line def _extract_markdown_links(text: str) -> list[tuple[str, str]]: @@ -133,16 +152,9 @@ def _visible_length(text: str) -> int: "preprint": r"预印本|preprint", "retracted_or_expression_of_concern": r"撤稿|关注声明|retract(?:ed|ion)|expression\s+of\s+concern", "science_popularization": r"科普", - "repost_or_excerpt": r"(? str: def _final_evidence_lines(text: str) -> list[str]: evidence_prefix = re.compile( - r"^\s*(?:(?:依据|指南|来源|文档核验|更新文件|政策文件|权威来源)\s*[::]|[A-C][.、]\s*)" + r"^\s*(?:(?:依据|指南|来源|更新文件|政策文件|权威来源)\s*[::]|[A-C][.、]\s*)" ) return [line.strip() for line in text.splitlines() if evidence_prefix.search(line)] @@ -186,33 +198,6 @@ def _validate_final_evidence_content_types( break -_CARRIER_METADATA_FIELDS: tuple[tuple[str, str], ...] = ( - ("文档标题", r"文档标题\s*[::]\s*[^;;\n]+"), - ("文档类型", r"文档类型\s*[::]\s*正式(?:专家)?(?:指南|共识)"), - ("制定机构", r"制定机构\s*[::]\s*[^;;\n]+"), - ("年份/版本", r"年份/版本\s*[::]\s*[^;;\n]+"), - ("正式出处", r"正式出处\s*[::]\s*[^;;\n]+"), - ("完整全文核验", r"完整全文核验\s*[::]\s*已核验"), - ("版本状态", r"版本状态\s*[::]\s*[^;;\n]+"), -) - - -def _carrier_link_context(text: str, url: str) -> str: - lines = text.splitlines() - for index, line in enumerate(lines): - if url in line: - start = max(0, index - 1) - return "\n".join(lines[start : index + 1]) - return "" - - -def _validate_carrier_metadata(text: str, url: str, errors: list[str]) -> None: - context = _carrier_link_context(text, url) - for label, pattern in _CARRIER_METADATA_FIELDS: - if not re.search(pattern, context, flags=re.IGNORECASE): - errors.append(f"B+/B正文承载来源缺少文档核验字段:{label}") - - # 临床安全域模块清单。只有这些模块会套用医学禁用词和权威来源白名单。 # 其他模块(通用写作/翻译/编程/其他 skill)按通用助手输出校验, # 医生的非医学工作和其他 skill 的输出不会被医学规则降级或截断。 @@ -412,20 +397,34 @@ def validate(text: str, module: str, policy_path: Path, allow_no_source: bool) - errors.append(f"不允许裸URL:{url}") # 权威来源白名单只约束医学和政策声明;通用任务可引用任何合法链接。 + attributed_relay_urls: list[str] = [] for url in urls: domain = _domain(url) if not domain: errors.append(f"无效URL:{url}") continue - role = _source_role(domain, policy) - if role in {"secondary_bplus", "academic_b"}: - _validate_carrier_metadata(text, url, errors) - elif role == "metadata_bminus": - errors.append(f"B-题录核验源不得作为最终来源:{domain}") - elif role == "discovery_c": - errors.append(f"C级发现源不得作为最终来源:{domain}") - elif role != "primary": - errors.append(f"来源域名不在白名单:{domain}") + if not _is_allowed_domain(domain, policy): + if _is_attributed_relay_url(url, text, policy): + attributed_relay_urls.append(url) + else: + errors.append(f"来源域名不在白名单:{domain}") + + if attributed_relay_urls: + if "正文承载" in text: + errors.append("C级转述页面不得标记为正文承载") + if "原文定位:" in text or "原文定位:" in text: + errors.append("C级转述页面不得声称提供原文定位") + warnings.append("包含C级全网转述页面:只能作为背景,不是最终证据") + + secondary_urls = [url for url in urls if _is_secondary_domain(_domain(url), policy)] + if secondary_urls: + primary_urls = [url for url in urls if _is_primary_domain(_domain(url), policy)] + if not primary_urls: + errors.append("B+正文承载链接必须同时提供S/A原始元数据链接") + if "原始元数据" not in text: + errors.append("B+受控降级必须标明:原始元数据") + if "正文承载" not in text: + errors.append("B+受控降级必须标明:正文承载") _validate_final_evidence_content_types(text, policy, errors) else: for url in urls: diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/clinical-q-and-a/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/clinical-q-and-a/SKILL.md new file mode 100644 index 00000000..a8e5fa04 --- /dev/null +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/clinical-q-and-a/SKILL.md @@ -0,0 +1,41 @@ +--- +name: clinical-q-and-a +description: 快速回答普通教育性医学问题与常见误区。默认用一份国内现行权威指南/共识完成轻量核验并立即作答;不用于个体诊疗、处方剂量、精确推荐定位、药品高风险事实、医保监管或跨版本比较。 +--- + +# 普通医学问答快路径 + +用于“这个说法准确吗”“怎么向患者解释某个常见误区”“某疾病与某风险是什么关系”等一般教育性问题。目标是可靠、简洁、尽快回答,不把普通问答扩展成指南章节研究。 + +## 不适用时立即转出 + +- 具体患者的诊断、处置、处方或急诊行动:按安全边界拒绝,不给替代步骤。 +- 适应症、禁忌症、剂量、妊娠/儿童、严重不良反应、侵入性操作、监管或医保状态:转 `source-verify` 完整核验及对应专业 skill。 +- 用户要求最新版本、版本比较、推荐等级、证据等级或章/表/页/条目定位:转 `source-verify` 完整核验。 +- 用户要展开原文章节或学习路径:转 `guideline-section-expansion`。 + +## 快速取证 + +1. 国内权威指南、共识或规范优先。默认只找 **1 份**足以覆盖问题的现行正式正文,不调用子代理,不收集第二、第三份“佐证”。 +2. 先读取 `../../references/verified-source-entrypoints.yaml` 并匹配别名;命中且未过 `recheck_after` 时直接抓取 `canonical_url`,核对标题、机构、年份/版本与支持本次解释的正文后停止,不再搜索“最新”。 +3. 未命中时做 1 次国内权威域限定搜索,并抓取最匹配的 1 份正文。优先 `cs.medjournals.cn`、`bi-dmp-cs.yiigle.com`、`cjournal.hep.com.cn`、已知同源附件或官方转载;`nhc.gov.cn`、`gov.cn`、`nmpa.gov.cn`、`cmde.org.cn`、`rs.yiigle.com`、`csco.org.cn` 等高拦截主站不作为第一宽泛目标,除非已有精确直达链接或事实必须由该主管机构确认。目标由专业分会发布但路由不确定时,才读取 `../../references/professional-society-source-routes.yaml`;不得遍历全部分会。 +4. 国内无覆盖或用户明确要求国际依据时,才读取 `../../references/international-guideline-source-routes.yaml`:默认池固定为 WHO、NICE、ESC、ADA、KDIGO,只访问最匹配的 1 站;明确涉及 GINA、GOLD、ACG、EASL 等体系时直接访问对应官网。首站确实不覆盖时最多增加 1 站,顺序执行,不并行。 +5. 正常预算为 1 次搜索 + 1 次抓取;整个回合硬上限 3 次搜索 + 3 次抓取,失败、降级和改稿都计入。取得最新、身份确定、正文可核验且覆盖问题的权威文件后立即停止。 +6. 原文阻断时才调用 `medical-source-failover`。只允许一个最合适的同文献替代路径;明确的验证码、登录墙或 403/412 不重试原地址。 + +快速核验只要求:权威机构/正式域、规范性文档类型、标题、发布机构、年份/版本、正文能够支持本次主张。官方正文未标 DOI 或证据等级时如实说明,不为补字段继续搜索。搜索摘要、解读和转载不能支持精确临床事实。 + +## 回答结构与轻量自检 + +直接输出,不加载 `output-format`、不写草稿文件、不运行 `validate_output.py`: + +```text +【临床学习问答|{主题}】 +结论:{先回答准确/不准确/需要条件化理解} +解释:{2-4 个简明要点,只写原文能够支持的范围} +证据说明:{指南/共识;原文有等级则保留,没有则写未标注} +边界:本回答用于医学学习和沟通参考,不提供个体诊疗或处方建议。 +来源:{正式文件名称}:[链接]({权威原文 URL}) +``` + +发送前在同一推理回合只检查四项:有结论、有边界、有一条权威原文来源、没有超出正文或落入个体诊疗。发现缺项直接修正文案,不开启新一轮检索。若未取得权威正文,改为简短失败回执,不凭记忆补全。 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-learning/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-learning/SKILL.md index e86a5826..8d8b894d 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-learning/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-learning/SKILL.md @@ -40,7 +40,7 @@ description: 指南学习流程约束。判断请求类型→读取状态→按 选题优先级:本科室常见高频基层需要 > 高风险识别与转诊知识(只作学习内容,不写行动卡)> 检查/报告/质控/慢病/规范 > 经核验近期更新。 -最终依据只用 source-policy.yaml 允许的权威信源;学习内容必须含至少一个权威原文链接 `来源:名称:[链接](URL)`;找不到时标待人工复核,不得编造。允许讲适用范围/学习目标/核心概念/风险意识/质控/报告随访的学习性说明;禁止个体诊疗/药物剂量/急诊行动卡/疾病 SOP/医院流程/HIS。 +最终依据只用 source-policy.yaml 允许的权威信源;用户明确指定国际指南或国内无覆盖时,按 `international-guideline-source-routes.yaml` 使用国际 A 级正式指南,不得静默覆盖国内现行规范。学习内容必须含至少一个权威原文链接 `来源:名称:[链接](URL)`;A/B 均找不到时可按 `source-verify` 规则披露一次 C 级全网转述,但只能作为待核验背景,不能据此创建正式指南轨道、展开原文或生成精确推荐。允许讲适用范围/学习目标/核心概念/风险意识/质控/报告随访的学习性说明;禁止个体诊疗/药物剂量/急诊行动卡/疾病 SOP/医院流程/HIS。 ## 输出校验 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-section-expansion/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-section-expansion/SKILL.md index 6aaf5079..01c05ccc 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-section-expansion/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-section-expansion/SKILL.md @@ -32,7 +32,8 @@ description: 把已核验的权威指南按原文结构逐节展开讲解,并 展开和路径图都必须绑定已核验的权威文件:完整名称、发布机构、版本/年份、权威原文链接。 - 取不到权威原文时,**不得凭记忆展开**。只能说明「未取得可核验权威原文」,并给出候选来源方向。 -- 完整章节或路径图只能使用 source-policy.yaml 允许的最终依据;专题总结按下方快速路径内嵌的同等规则执行。优先 S/A 原始文档;只有原始来源访问受限且完成文档身份核验时,才可降级到 B+/B 正式全文承载平台,B-/C 仍只作核验或发现。 +- 完整章节或路径图只能使用 source-policy.yaml 白名单内的最终依据;专题总结按下方快速路径内嵌的同等规则执行。聚合平台默认只作线索;仅在原始正文明确访问受限、同时取得 S/A 正式元数据并完成标题/机构/版本/DOI/全文完整性/现行状态核验时,source-policy.yaml 指定的 B+ 平台才可作为正文承载渠道。 +- 用户明确指定国际指南,或国内现行正式文件未覆盖主题时,读取 `../../references/international-guideline-source-routes.yaml`。普通补充只从 WHO、NICE、ESC、ADA、KDIGO 默认池选择最匹配的 1 站;明确涉及 GINA、GOLD、ACG、EASL 等体系时直接访问对应官网。首站确实不覆盖时最多增加 1 站,不得并行遍历。不得用国际建议静默覆盖中国大陆现行规范。 - 版本必须写清。指南改版频繁,展开旧版时要标注这是哪一版。 ## 章节展开怎么做 @@ -52,17 +53,19 @@ description: 把已核验的权威指南按原文结构逐节展开讲解,并 当用户要求面向基层总结筛查、随访、质控等单一专题时: +0. 默认只选 1 份能够直接覆盖问题的现行主指南。用户未要求跨指南比较时,不主动扩展老年专项、基层专项或其他并行文件;只有主指南确实缺少该主题时才补第 2 份。搜索、抓取、B+ 降级、草稿校验和改稿共享同一份累计工具预算,任何阶段都不得重新计数。 1. 直接读取 `../../references/verified-source-entrypoints.yaml`,先按 `aliases` 匹配主题。命中时直接 `web_fetch` 该条目的 `canonical_url`,页面标题和 DOI 均匹配后才可作最终依据;不得用本地表项替代原文核对。 2. 命中条目且当前日期未超过 `recheck_after` 时,该次原文抓取即是实时核验,不再广泛搜索。只有用户明确询问「最新/现行/替代」,或已超过 `recheck_after`,才再加 1 次限定官方域名的时效检索。 最终来源行必须使用命中条目的 `canonical_url`;`official_index_url` 只辅助核对卷期/DOI,不取代原文链接。订阅墙导致只能核对摘要或公开附录时,必须把未能核对的具体条款标为「待核验」,不得用二手内容补全。 -3. 未命中入口表时,**总工具预算**为最多 3 次 `searchfree_search` 和 3 次 `web_fetch`,包括失败、超时、空结果和无关结果。第 1 次抓取优先 S/A 原始文档;只有明确遇到 HTTP 412、验证码、反自动化限制、超时、JS 无法解析或全文/PDF 不可获取时,第 2 次才降级到 B+,第 3 次才降级到 B。不得换旧版文件、绕过反爬或猜测 URL 继续试探。找到能覆盖主题的现行指南正式全文后立即停止。 -4. 预算内未取得现行权威原文时,立即答复「未取得可核验的现行权威原文,本次不生成学习要点」并说明失败原因;这是失败回执,不写医学内容草稿,不运行校验器。不得用已过时或未核验文件凑齐回答。 -5. 最终依据不超过 2 份:1 份现行主指南,必要时补 1 份基层专项指南。面向中国大陆医生,依次优先国内最新版正式指南、国内最新版正式专家共识、国内正式规范/标准/路径/质控文件,再以国际 S/A 正式指南补充差异。指南通常优先于共识;最新共识更新旧指南或覆盖新问题时可使用,但必须标明它是共识及其与旧指南的关系。国内与国际冲突时不得静默用国际推荐覆盖国内文件。 -6. 常用可用的最终来源域名包括 `.gov.cn`、`.nhc.gov.cn`、`.ndcpa.gov.cn`、`.chinacdc.cn`、`.cma.org.cn`、`.medjournals.cn`、`.cmda.net`、`.cpma.org.cn`、`.pmph.com` 和中华医学会杂志社旧版正式全文域 `rs.yiigle.com`。搜索结果只用于定位原文;起草前先选定原文详情页或正式附件链接。通用列表页只能作候选,不能在无法对应具体文件时当作原文链接。 -7. 未命中入口表时,第 1 次查询必须同时包含主题、「最新/现行」和国内官方/正式期刊域限定,优先 `site:rs.yiigle.com` 与 `site:cs.medjournals.cn`;第 2 次才查主管部门、学会官网或完整标题/DOI;第 3 次只用于确认版本替代关系。必须先确认现行版本,再摘要内容;新版已发布时不得回退到旧版凑答案。 -8. B+/B 不是整站升级。具体页面必须核对文档标题、正式指南/共识类型、制定机构、年份/版本、正式出处、全文完整性和新版状态。指南解读、编辑摘要、新闻、访谈、病例讨论、患者教育、博客/Webinar、会议报道和二次整理不得作为最终依据;B-/C URL 不写入最终草稿。 -9. 草稿中所有 URL(包括正文和来源行)必须属于 source-policy.yaml 对应角色允许的域名;不得先写入 CDN、搜索结果或其他未知 URL,再依赖校验器反复修改。使用 B+/B 时必须在来源前写完整的“文档核验”字段行。 -10. 直接按以下字段生成一份完整草稿:【指南章节展开|主题】、依据、章节、原文定位、原文要点、章节关系、易混淆点、学习提示、边界、来源。不先写半成品,不为猜模板再读其他文件。 +2.1 未命中高频入口、但主题能对应专业学会或专科分会时,直接读取 `../../references/professional-society-source-routes.yaml`,按分会名称或 `aliases` 选择一个最相关的官方域名做第 1 次限定检索;不得并行遍历全部分会。标记为 `official_discovery_pending_fulltext_acceptance` 的域名只用于找到完整正式原文,不能直接作为最终来源。 +3. 原始正文遇到 412、验证码、JS 阻断、超时或正文不可获取时,才允许 B+ 受控降级:先用原始发布方/正式期刊元数据页核对标题、机构、年份/版本和 DOI/文号,再抓取指定 B+ 平台的完整正式正文并检查完整性与现行状态。最终同时列“原始元数据”和“正文承载”两条来源;只有 B+ 页面或任一字段不一致时立即停止,不生成学习要点。 +4. 未命中入口表时,正常目标为 1 次定向搜索 + 1 次正文抓取,**整个用户回合的总工具预算**硬上限为最多 3 次 `searchfree_search` 和 3 次 `web_fetch`,包括失败、超时、空结果、国际补充、B+ 降级、C 级全网转述、校验后补链和改稿。每层最多一次定向查询:国内 A → 国际 A(仅在用户指定或国内无覆盖时)→ B 级发现/B+ 承载或 C 级全网。不得换旧版文件或猜测 URL 继续试探。找到 1 份能覆盖主题的现行正式主指南后立即停止搜索。 +5. 预算内未取得现行权威原文时,不得生成“原文展开”或声称掌握原文。若 C 级网页明确给出原始权威期刊/机构、完整标题、年份/版本及 DOI/文号信息,可输出单独的“背景转述”失败回执,并按 `source-verify` 的 C 级格式披露;否则答复「未取得可核验的现行权威原文,本次不生成学习要点」。C 级转述不得涉及精确推荐、证据等级或药品高风险信息。 +6. 最终依据默认 1 份、最多 2 份:1 份现行主指南;仅在主指南确实不覆盖问题或用户明确要求比较时补 1 份专项指南。只接受正式指南、共识、规范或质控文件;综述、原始研究、科普、转载、会议材料和搜索摘要不得作最终依据。 +7. 常用国内原始来源域名包括 `.gov.cn`、`.nhc.gov.cn`、`.ndcpa.gov.cn`、`.chinacdc.cn`、`.cma.org.cn`、`.medjournals.cn`、`.cmda.net`、`.cpma.org.cn`、`.pmph.com`、`cs.medjournals.cn`、`bi-dmp-cs.yiigle.com` 和 `rs.yiigle.com`。国际 A 级域名以 `international-guideline-source-routes.yaml` 为准。搜索结果只用于定位原文;起草前先选定原文详情页或正式附件链接。通用列表页只能作候选,不能在无法对应具体文件时当作原文链接。 +8. 未命中入口表时,第 1 次查询必须同时包含主题、「最新/现行」和注册表匹配到的专业分会/学会域名;没有专业路由时才优先 `site:rs.yiigle.com` 与 `site:cs.medjournals.cn`。第 2 次查主管部门或正式期刊平台;第 3 次只用于确认版本替代关系或在原始正文访问受限后定位 B+ 完整正文。必须先确认现行版本,再摘要内容;新版已发布时不得回退到旧版凑答案。 +9. 草稿中所有 URL(包括正文和来源行)必须属于原始来源白名单,或满足“原始元数据 + B+ 正文承载”的成对降级规则;不得先写入 CDN、搜索结果或其他非白名单 URL,再依赖校验器反复修改。 +10. 输出校验因辅助来源域名或文档类型失败时,删除该辅助来源并使用已经核验的主指南重新起草;累计预算已耗尽时不得继续搜索补链。直接按以下字段生成一份完整草稿:【指南章节展开|主题】、依据、章节、原文定位、原文要点、章节关系、易混淆点、学习提示、边界、来源。不先写半成品,不为猜模板再读其他文件。 ## 学习路径图怎么做 @@ -84,12 +87,12 @@ description: 把已核验的权威指南按原文结构逐节展开讲解,并 ## 输出与校验 -发送或提供正式草稿前,按 `output-format` skill 的约定把完整草稿一次写入 `../../outbound/.clinical-output-draft.md`,然后直接运行: +发送或提供正式草稿前,按 `output-format` skill 的约定一次生成完整草稿,并优先通过标准输入在一次工具调用中直接运行校验器,避免写文件与执行环境之间的同步往返: - python3 ../../scripts/validate_output.py --module guideline_section_expansion --text-file ../../outbound/.clinical-output-draft.md + python3 ../../scripts/validate_output.py --module guideline_section_expansion 或: - python3 ../../scripts/validate_output.py --module guideline_learning_pathway --text-file ../../outbound/.clinical-output-draft.md + python3 ../../scripts/validate_output.py --module guideline_learning_pathway 不得无正文试运行校验器,也不得读取或 `grep` 校验器源码。校验失败时只按返回的 `errors` 修正一次;不得绕过。 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-update-reminder/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-update-reminder/SKILL.md index 41072f6a..e82dd029 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-update-reminder/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/guideline-update-reminder/SKILL.md @@ -12,8 +12,12 @@ description: 为基层医生学习小助手生成专业指南更新提醒。适 - `../../USER.md`(脚本生成的只读摘要) - `../../references/compliance-boundary.md` - `../../references/source-policy.yaml` +- `../../references/professional-society-source-routes.yaml` - `../../references/output-templates.md` +只有用户订阅明确要求国际更新,或国内现行文件未覆盖对应主题时,再读取 +`../../references/international-guideline-source-routes.yaml`。 + ## 使用档案 优先调用 `../../scripts/clinical_profile.py get` 获取结构化档案;`USER.md` 只作为脚本生成的只读摘要。不得直接编辑 `USER.md`。 @@ -46,6 +50,9 @@ description: 为基层医生学习小助手生成专业指南更新提醒。适 3. 与职称学习深度匹配。 4. 有权威原文、发布机构和发布时间。 5. 同一主题优先最新且当前有效的正式版本,并核对替代或废止信息。 +6. 先按科室/亚专业匹配专业学会信源路由并做限定域名增量检索;没有匹配项时才扩大到通用白名单,不得在一次提醒中遍历全部 91 个中华医学会分会。 +7. 用户要求国际补充或国内无覆盖时,可纳入国际 A 级官方正式指南,但普通主题只从 WHO、NICE、ESC、ADA、KDIGO 默认池选择最匹配的 1 站;明确属于 GINA、GOLD、ACG、EASL 等体系时直接访问对应官网。只有首站确实不覆盖时才增加第 2 站,不并行铺开。必须明确制定机构、地区适用性和版本;不得替代国内现行文件。 +8. A/B 均未取得正式原文时可做一次全网检索;只找到声明转述自权威期刊的页面时,最多作为“C级待核验线索”披露原始出处身份和未核验状态,不得列入“可靠更新”或生成精确变化要点。 ## 输出边界 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/intent-routing/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/intent-routing/SKILL.md index db415bd9..fbbe41e0 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/intent-routing/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/intent-routing/SKILL.md @@ -10,8 +10,9 @@ description: 请求入口的意图识别与技能路由。按渐进式判断意 1. **通用任务**(写作/总结/翻译/编程/计划/数据/创意/闲聊)→ 直接完成,不调医学 skill,不要求登记,不套医学规则。 2. **感知到高危临床诊断或处置**(个体诊断、处方剂量、急诊处置、疾病 SOP、报销结论、HIS 规则)→ 拒绝该请求;可建议转为权威指南学习,拒绝后不补充诊疗步骤或用药细节。 3. **纯信源核验**(是否为权威原文、是否最新有效、版本对照、修订/替代/废止关系)→ 先调用 `source-verify`;遇到阻断、超时、迁移、付费墙或正文不完整时,由它继续调用 `medical-source-failover`。仍按【信源核验】模板输出,不调用 `output-format` 或 `validate_output.py`。如果还要求生成学习内容,再进入下一类。 -4. **医学学习与问答**(指南学习/章节展开/路径图/学习诊断/备考/医保/指南更新/症状疾病检查等医学问答)→ 调对应 skill,从权威指南找信息并注明来源,输出前经 `output-format` 校验;需保存进度/轨道/诊断/订阅/地区定制时先确认登记。 -5. **登记/订阅**(登记/更新/停用/启用推送)→ `doctor-registration`(登记)/ `subscription-setup`(订阅,需先登记)。 +4. **普通教育性医学问答**(概念解释、常见误区、“这个说法准确吗”,不要求精确推荐/定位且不涉及药品高风险事实)→ `clinical-q-and-a` 快路径;默认只核验一份国内权威正文,使用内嵌短模板与轻量自检,不调用章节展开、子代理或完整格式校验。 +5. **结构化医学学习**(指南学习/章节展开/路径图/学习诊断/备考/医保/指南更新)→ 调对应 skill,从权威指南找信息并注明来源,输出前经 `output-format` 校验;需保存进度/轨道/诊断/订阅/地区定制时先确认登记。 +6. **登记/订阅**(登记/更新/停用/启用推送)→ `doctor-registration`(登记)/ `subscription-setup`(订阅,需先登记)。 ## 判断要点 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/SKILL.md index 1983745a..e1a9b626 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/SKILL.md @@ -43,6 +43,16 @@ Retrieve the intended medical document reliably without laundering a secondary s 8. Extract only claims supported by the retrieved document. For recommendations, preserve population, intervention, conditions, recommendation strength, evidence certainty, and exceptions when reported. 9. Cite the original issuer or formal publication. If a fallback carried the text, disclose the fallback separately instead of presenting it as a second source. +## Latency-first fast failover + +For an ordinary `clinical-q-and-a` request, keep the same identity standard but use the smallest path: + +- Enter this skill only after the selected canonical route actually fails; do not preload failover references during a successful direct fetch. +- `401`/`403`/`412`/CAPTCHA/login/paywall: do not retry the address. Move immediately to the best known L1-L3 route. +- Timeout/`5xx`: at most one retry or one approved fallback, not both repeatedly. When latency matters, start one hedged fallback after roughly two seconds and cancel the losing request after a valid copy arrives. +- Try only one fallback carrier for the same document in the fast path. If it is incomplete or identity cannot be established, return a bounded “正文未核验” result instead of exploring the whole ladder. +- Do not retrieve a second guideline merely to compensate for an access failure. The target remains the same document unless `source-verify` explicitly chooses a new normative document. + ## Failover ladder - **L0 — Canonical original:** issuing body or formal publisher page and complete attachment. diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/references/domestic-source-registry.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/references/domestic-source-registry.md index 7fff419c..901a64d0 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/references/domestic-source-registry.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/medical-source-failover/references/domestic-source-registry.md @@ -20,6 +20,11 @@ This registry routes fact types to candidate authorities and fallback paths. It ## Professional societies and formal publication sources +中华医学会 91 个专科分会的官方目录、已确认专属子域,以及独立专业学会的 +分级路由记录在 `../../../references/professional-society-source-routes.yaml`。 +命中专业学会主题时先查该表,避免每次从全网猜测机构官网。表中的 +`official_discovery_pending_fulltext_acceptance` 只允许定位原文,不代表整个域名可作最终证据。 + | Source | Canonical domains | Appropriate use | Fallback notes | |---|---|---|---| | Chinese Medical Association | `cma.org.cn` and verified `*.cma.org.cn` branch sites | Society identity, branch notices, guideline/consensus release information | Prefer the complete formal journal article when the society page contains only news or excerpts. Branch ownership must be verified. | @@ -27,6 +32,10 @@ This registry routes fact types to candidate authorities and fallback paths. It | CMA journal sites / Yiigle | `yiigle.com`, verified `*.yiigle.com`, official attachment endpoints | Formal journal HTML/PDF and issue metadata | Verify title, DOI, year/version, journal, and completeness across old/new platform URLs. | | Chinese Preventive Medicine Association | `cpma.org.cn` | Public-health society documents, standards, professional guidance, branch information | Prefer a complete formal publication; separate society news and popular education from technical documents. | | Chinese Society of Clinical Oncology | `csco.org.cn` | CSCO guideline identity and oncology guideline information | Access and edition availability may vary; verify annual edition and use an authorized complete version. Do not infer text from launch news. | +| Chinese Pharmaceutical Association | `cpa.org.cn` | Formal society standards, guidelines, specifications, and correction notices | Only complete final documents qualify; drafts, project notices, news, and calls for comments remain discovery material. | +| Chinese Stroke Association | `csa-stroke.com` | Guideline/consensus identity and release discovery | Discovery route pending complete-document acceptance tests; trace release pages to complete formal text. | +| Chinese Association of Rehabilitation Medicine | `carm.org.cn` | Society and committee standard/guideline identity discovery | Discovery route pending complete-document acceptance tests; reject competitions, popular education, meetings, and reposts as evidence. | +| Chinese Nursing Association | `cna-cn.com`, `zhhlxh.org.cn` | Nursing standard/guideline identity discovery | Discovery route pending complete-document acceptance tests; member, live-stream, training, and news pages are not final evidence. | | Other national specialty societies | Official society domain plus formal publisher | Specialty guidelines and consensus statements within the society's remit | Add only after ownership verification and sample-document checks. “National” in a name is not enough. | ## Discovery, indexing, and bibliographic services diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/output-format/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/output-format/SKILL.md index 826dcea8..c4af3b7d 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/output-format/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/output-format/SKILL.md @@ -1,6 +1,6 @@ --- name: output-format -description: 医学安全域输出的统一格式校验。四条硬格式(模板头/来源行/边界声明/禁编造)与 validate_output.py 调用流程。指南学习、章节展开、学习路径图、学习诊断、备考推荐、医保内容、指南更新提醒、每日单元等医学安全域输出(含定时推送与对话内即时回答)发出前必走此技能校验;通用任务不套用。 +description: 结构化医学学习产物的统一格式校验。四条硬格式与 validate_output.py 单次标准输入流程。指南章节、路径图、诊断、备考、医保、更新和每日单元使用;普通医学问答走 clinical-q-and-a 的轻量自检,通用任务不套用。 --- # 医学安全域输出格式校验 @@ -11,6 +11,8 @@ description: 医学安全域输出的统一格式校验。四条硬格式(模 `guideline_learning`、`daily_guideline_learning`、`guideline_section_expansion`、`guideline_learning_pathway`、`guideline_learning_diagnosis`、`guideline_update_reminder`、`professional_update_summary`、`insurance_policy_summary`、`insurance_policy_learning`、`insurance_policy_retrospective`、`exam_material_recommendation`。 +**普通教育性医学问答不加载本技能**:由 `clinical-q-and-a` 使用内嵌的短模板和四项自检,避免为一段简短解释加载完整模板、写草稿文件和启动校验脚本。问题一旦涉及精确推荐/定位、药品高风险事实、版本比较、医保监管,立即退出快路径,转入对应专业 skill 与本技能。 + **通用任务(写作/翻译/编程/计划/数据整理等)不套用本技能**:不要求模板头、不要求权威来源行、不加医学免责声明。校验时对通用输出使用 `--module general_task`,不要误用医学模块名。 **纯信源核验不套用本技能**:只判断文件是否为权威原文、是否最新有效以及修订/替代/废止关系时,由 `source-verify` skill 使用自己的【信源核验】模板完成,不再调用本技能或 `validate_output.py`。如果核验后还要生成指南学习内容,再对学习内容调用本技能。 @@ -29,6 +31,7 @@ description: 医学安全域输出的统一格式校验。四条硬格式(模 | 用户请求实质 | module | 模板要求 | | --- | --- | --- | +| 普通概念解释、常见医学误区澄清 | `clinical_q_and_a` | 由 `clinical-q-and-a` 轻量自检,不执行本技能脚本流程 | | 总结、展开或讲解指南中的某章、某节、筛查/随访等专题 | `guideline_section_expansion` | 【指南章节展开】;含依据、章节、原文定位、原文要点、学习提示、边界及“不替代原文” | | 把整份指南整理为学习顺序或学习路径 | `guideline_learning_pathway` | 【指南学习路径图】;含依据、前置知识、编号学习顺序、边界 | | 每日固定学习单元 | `daily_guideline_learning` | 【指南学习单元】;恰好 3 个编号要点及单元进度 | @@ -49,11 +52,12 @@ description: 医学安全域输出的统一格式校验。四条硬格式(模 每次医学安全域输出前,严格按顺序: -1. 按对应模板一次生成完整草稿,写入 `../../outbound/.clinical-output-draft.md`。 -2. 直接运行: +1. 按对应模板一次生成完整草稿,不先写半成品。 +2. 优先把完整草稿通过标准输入交给校验器,在一次工具调用内直接运行: ```bash - python3 ../../scripts/validate_output.py --module <模块名> --text-file ../../outbound/.clinical-output-draft.md + python3 ../../scripts/validate_output.py --module <模块名> ``` + 只有当前执行工具无法传标准输入时,才写入 `../../outbound/.clinical-output-draft.md` 并使用 `--text-file`;不得为了同步同一草稿反复读写或复制文件。 模块名必须与内容实质一致(医学学习内容用医学模块名,普通任务用 `general_task`)。 3. 校验通过 → 直接输出草稿正文。校验状态仅供内部控制,不得向用户输出“校验通过”“校验完成”“为您推送预览内容”等过程性前缀。 4. 校验失败 → 只根据校验器返回的 `errors` 修正草稿并再校验一次;不得读取或搜索校验器源码,仍不通过则停止并说明原因,**不得绕过校验直接输出**,也不得省略【】模板头和来源行。 @@ -70,7 +74,6 @@ description: 医学安全域输出的统一格式校验。四条硬格式(模 - 不得把链接文字写成"查看原文""官网""点击这里"等其他词; - 多个来源分多行列出; - 无可靠来源时不得伪造链接,只写"未取得可核验权威来源或需人工核验"。 -- 使用医脉通/丁香园 B+ 或 CNKI/万方/维普 B 正文承载链接时,来源前必须增加:`文档核验:文档标题:…;文档类型:正式指南/正式专家共识;制定机构:…;年份/版本:…;正式出处:…;完整全文核验:已核验;版本状态:…。`。字段不全、只有摘要/题录、或页面属于解读/新闻/访谈等类型时,不得把该链接写入最终来源。 ## 边界 diff --git a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/source-verify/SKILL.md b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/source-verify/SKILL.md index ab4a1d68..019d18ba 100644 --- a/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/source-verify/SKILL.md +++ b/src/octop/infra/agents/experts/library/clinical-learning-subscription/skills/source-verify/SKILL.md @@ -1,6 +1,6 @@ --- name: source-verify -description: 统一信源核验规则。涉及指南、共识、规范、临床路径、质控文件、医保政策、药品监管通告的来源核验、版本对照、信源分级或是否可作为最终依据时使用。本技能只做来源核验和学习依据整理,不生成诊疗、处方、急诊处置、医保报销结论或HIS执行建议。 +description: 医学信源快速或完整核验。普通教育性医学问答用单一权威正文快速核验;最新版本、精确推荐、高风险药品、医保监管或跨版本请求升级为完整核验。只整理学习依据,不生成诊疗、处方、急诊处置、医保报销结论或HIS执行建议。 --- # 统一信源核验 @@ -9,82 +9,116 @@ description: 统一信源核验规则。涉及指南、共识、规范、临床 纯粹判断文件是否为权威原文、是否最新有效以及修订/替代/废止关系时,只使用本技能及下方【信源核验】模板,不再调用 `output-format` skill 或 `../../scripts/validate_output.py`。如果用户还要求生成指南学习内容,先完成信源核验,再把已核验来源交给对应医学学习 skill,并只对学习内容执行 `output-format` 校验。 -## 必读文件 +## 先选择核验档位 -起草前必须先读取: +### 快速核验(默认) -- `../../references/source-policy.yaml` -- `../../references/compliance-boundary.md` -- `../../references/verified-source-entrypoints.yaml` +适用于普通教育性医学问答、概念解释、常见误区澄清和一般学习摘要,且不涉及下方完整核验触发项。 + +- 目标是取得 **1 份**足以覆盖问题的现行权威规范性正文;不得主动搜集多份文件相互“佐证”。 +- 最小核对项为:权威机构/正式发布域、规范性文档类型、完整标题、发布机构、年份/版本、正文能够支持本次主张。 +- 官方原文页已明确上述身份时,不强制另找第二来源;原文没有 DOI/推荐等级时如实写“未标注”,不为补字段继续搜索。 +- 命中未过 `recheck_after` 的已核验入口时,直接抓取正文并核对身份;用户未问“最新/现行/替代”时不再追加时效搜索。 +- 一份文档满足身份、正文与覆盖范围后立即停止。 + +### 完整核验(按需升级) + +出现以下任一情形时才升级:用户明确询问最新/现行/替代/废止、跨版本变化、精确推荐或证据等级、章表页条目定位;适应症、禁忌症、剂量、孕产妇/儿童、严重不良反应、侵入/急诊内容;药品批准、监管、医保或法律状态。完整核验保留版本状态、唯一标识、精确定位和必要的同文献身份核验要求。 + +核验档位只减少不必要的步骤,不改变“不能用二手摘要补精确临床事实”的底线。 + +## 按需读取文件 + +快速核验先只读取 `../../references/verified-source-entrypoints.yaml`。命中即可按其直达入口抓取,不预读完整白名单和合规说明。 + +以下情况再读取对应文件: + +- 未命中入口、需要判断域名/文档类型/B+ 或 C 级资格:`../../references/source-policy.yaml` +- 请求接近个体诊疗、处方或其他医学边界:`../../references/compliance-boundary.md` +- 目标由国内专业学会或分会发布且入口未命中:`../../references/professional-society-source-routes.yaml` 以上是确定路径,直接读取;不得为定位这些文件调用 `glob`、`grep` 或递归 `ls`。 +用户明确指定国际指南,或国内现行正式文件没有覆盖目标主题时,再读取 +`../../references/international-guideline-source-routes.yaml`;普通国内主题不预读该表。 + ## 已核验入口的使用顺序 1. 先用用户主题匹配 `verified-source-entrypoints.yaml` 的 `aliases`。未命中才进入常规联网检索。 -2. 命中时直接 `web_fetch` 该条目的 `canonical_url`,核对页面标题和 DOI;两者任一不符即不得使用。 +2. 命中时直接 `web_fetch` 该条目的 `canonical_url`,快速核验至少核对标题、发布机构、年份/版本和正文覆盖范围;表项提供 DOI 时再核对 DOI。完整核验中唯一标识冲突则不得使用。 3. 当前日期超过 `recheck_after`,或用户明确询问「最新/现行/替代」时,再加 1 次限定官方域名的时效检索;没有新版正式原文证据时,不得仅凭搜索摘要改写表内版本状态。 4. `version_relation` 是已核验的表述边界。它写「未取得废止/替代声明」时,必须如实输出「未证实正式废止或替代」,不得自行推断。 5. 命中条目的最终原文链接必须使用该条目的 `canonical_url`;`official_index_url` 只用于辅助核对卷期/DOI,不得取代原文链接。全文受订阅限制时可以说明可核对范围受限,但仍要给出 `canonical_url`。 +## 专业学会快速路由 + +高频入口未命中,且目标文件由专业学会、协会或专科分会制定/发布时,直接读取 +`../../references/professional-society-source-routes.yaml`,先按分会名称和 `aliases` +匹配,再进行限定域名检索;不得先做无域名的广泛搜索。 + +- 中华医学会分会先匹配已登记的专属 `*.cma.org.cn` 子域;没有专属子域时,使用官方专科分会目录确认身份,再限定 `cma.org.cn`、`medjournals.cn` 或 `rs.yiigle.com` 检索。 +- `conditional_final` 路由仍须通过正式文档类型、完整性和版本核验,域名命中本身不构成最终证据。 +- `official_discovery_pending_fulltext_acceptance` 路由只能定位发布信息和正式原文,不得直接进入最终来源行;必须继续取得 S/A 正式原文或完成该站点的完整文档身份验收。 +- 找到一份足以覆盖问题的完整现行正式文件后立即停止,不再遍历其他学会网站。 + ## 信源分级 -- S/A 原始来源:主管部门、制定机构、正式学会或正式期刊发布的规范性原文;通过文档类型与版本核验后,可作为最终学习依据。 -- B+ 可信二级全文承载:医脉通、丁香园。只有原始来源访问受限,且具体页面是经文档身份核验的完整正式指南/共识全文时,才可作为最终正文承载来源。 -- B 正规学术全文承载:CNKI、万方、维普。只有实际取得正式期刊发表的指南/共识全文并完成同等核验时,才可作为最终正文承载来源;题录或摘要不够。 -- B- 题录核验:SinoMed。只用于确认名称、制定机构、期刊、年份、卷期、版本历史和定位正式全文,不直接支持具体推荐。 -- C 发现来源:MedSci、指南注册平台等。只用于发现和新版预警,不得作为最终依据;注册方案不等于正式发布指南。 -- D 禁止来源:不得进入证据链。 +- S/A 级权威域名中的规范性原文:通过文档类型与版本核验后,可作为最终学习依据。 +- 国际 A 级来源全部保留证据资格,但默认池固定为 WHO、NICE、ESC、ADA、KDIGO。普通国际补充只调用最匹配的 1 个网站,首站确实不覆盖时最多再增加 1 个。若问题明确属于 GINA、GOLD、ACG、AGA、ASGE、ESGE、EASL、AASLD、ECCO 等特定体系,直接定向访问该官方来源,不先遍历默认池,也不得静默覆盖国内现行规范。 +- 指定 B+ 专业平台:默认仍只作线索;仅在 S/A 原始正文出现 412、验证码、JS 阻断、超时或正文不可获取时,才可作为正式全文承载渠道。必须同时取得 S/A 原始发布方或正式期刊元数据链接,完成标题、制定机构、年份/版本、DOI/文号、全文完整性和现行版本六项核验。 +- B 级线索来源:只用于发现候选文件,必须回溯 S/A 原文,不适用 B+ 降级。 +- C 级全网转述:A 与 B 均未取得可用原文或完整身份链时,允许全网检索并输出明确归因的背景转述,但不是最终证据。必须同时写明“转述页面(C级,仅作背景)”、原始期刊/机构、原始文献或指南完整标题、年份/版本、DOI/文号(页面未给则如实写未提供)以及“未取得可核验原文”。不得据此提取精确推荐、证据等级、适应症、禁忌症、用法用量、严重不良反应、孕产妇/儿童用药或急救/侵入性处置。 具体域名和禁止模式以 `../../references/source-policy.yaml` 为准。 -## 两个独立决策:选文档,再选承载位置 +## 国内场景与受控降级顺序 -不得把文档权威性与下载服务器混为一谈。先决定学习哪一份正式文件,再决定从哪里读取同一文件。 +面向中国大陆基层医生的一般学习请求,默认先找国内现行正式指南/共识/规范;用户明确指定国际文件或国内没有覆盖时,再按请求范围使用国际正式文件。不得用国际建议静默覆盖国内现行文件。 -原始页面或附件出现 `401`、`403`、`412`、`429`、验证码、付费墙、超时、迁移、空壳页面或正文/PDF 不完整时,读取 `../medical-source-failover/SKILL.md`,并按其中要求读取国内信源登记、熔断和文献身份核验文件。该技能只负责寻找同一目标文献的可信访问路径,不改变本技能对文档类型、版本和最终证据资格的判断。若两套规则的要求不同,采用更严格的一项;只能取得 L5 元数据、摘要、解读、截图或不完整正文时,必须停止精确提取。 +原始页面或附件出现 `401`、`403`、`412`、`429`、验证码、付费墙、超时、迁移、空壳页面或正文/PDF不完整时,读取 `../medical-source-failover/SKILL.md`,并按其中要求读取相应的国内信源登记、熔断和文献身份核验文件。该技能只负责寻找同一目标文献的可信访问路径,不改变本技能对文档类型、版本和最终证据资格的判断。若两套规则的要求不同,采用更严格的一项;只能取得 L5 元数据、摘要、解读、截图或不完整正文时,必须停止精确提取。 -### 文档选择(China-first) +检索严格按以下顺序,命中即可停止: -面向中国大陆医生,默认顺序是: +1. 已核验入口中的 S/A 原始正文; +2. 常规检索定位到的国内 S/A 原始正文; +3. 用户指定国际指南或国内无覆盖时,检索国际 A 级官方正式指南; +4. 使用 B 级平台发现原始出处;原始正文明确访问受限后,可使用 S/A 正式元数据页 + 指定 B+ 完整正文双重核验; +5. 仍未取得原文时才进行一次全网 C 级检索。可以输出明确披露的背景转述,不得称为“权威原文”“原文要点”“正式依据”或“正文承载”。 -1. 国内最新版正式指南; -2. 国内最新版正式专家共识; -3. 国内正式诊疗规范、标准、路径或质控文件; -4. 国内正式政府/监管规范性文件; -5. 国际 S/A 正式指南或共识。 +### 工具预算与停止条件 -国内同主题存在多份文件时,依次优先国家主管部门或国家级学会/专业委员会、全国性专业组织、国家级质控或协作组织、省级/区域性组织、医院级或地方建议。 +- 正常目标:1 次定向 `searchfree_search` + 1 次 `web_fetch`;已核验入口命中时通常只需 1 次 `web_fetch`。 +- 整个用户回合硬上限:最多 3 次搜索 + 3 次抓取,失败、超时、B+ 降级、C 级转述、补链和改稿全部计入,不能重置。 +- 同一阶段只访问一个最匹配域名,顺序执行;不得默认并行搜索多个国内分会或国际机构。 +- 国际通常 1 站、绝对最多 2 站。特定指南体系直达对应官网,不先跑默认五站。 +- 找到一份最新、身份确定、正文可核验且覆盖问题的权威规范性文件后立即停止。 -正式指南通常优先于正式专家共识。但旧指南未覆盖的新问题、最新共识明确补充或更新旧指南时,可以使用最新共识;必须标明“专家共识”、年份及它与旧指南的关系,不得称为指南。 +A 级权威性与访问优先级必须分开。`nhc.gov.cn`、`gov.cn`、`nmpa.gov.cn`、`cmde.org.cn`、`rs.yiigle.com`、`csco.org.cn` 等即使访问不稳定仍保留 A 级资格,但不得作为未命中主题时的第一个宽泛搜索目标。优先使用已核验的具体直达页、`cs.medjournals.cn`、`bi-dmp-cs.yiigle.com`、`cjournal.hep.com.cn`、同源附件、官方转载或正式期刊版本。只有入口表已有精确 `canonical_url`,或药监/医保/法规事实必须回到该主管机构时,才直接访问这些低优先级主站;遇到明确阻断后按熔断规则切换,不重复等待同一地址。 -国内与国际文件冲突时,以国内现行正式文件作为中国大陆学习主依据;国际文件仅补充更新和差异,并明确两者的版本、适用人群、药物可及性或监管环境差异。不得静默用国际推荐覆盖国内文件。WHO、NICE、ACG、AGA、ASGE、ESGE、EASL、AASLD、ECCO、ESC 的官方域名只对其正式 Guideline、Clinical Practice Guideline、Consensus、Position Statement、Official Recommendation 或 Official Standard 生效,站内新闻、患者教育、博客、会议报道、Webinar、访谈或摘要仍不合格。 +### C 级转述输出格式 -### 正文承载选择 +```text +来源:转述页面(C级,仅作背景):[链接]({任意合法公开网页 URL}) +原始出处:{原始期刊或机构}|{原始文献/指南完整标题}|{年份或版本}|{DOI/文号;未提供则明确写未提供} +核验状态:未取得可核验原文,以下仅为该页面对原始出处的转述,不作为权威依据。 +``` -对已经选定的同一正式文件,按以下顺序读取: +页面只写“来自权威期刊”但未给出可识别的期刊/机构、标题、年份/版本时,不满足转述披露要求。不得把多个转载页面计作多份独立证据。 -1. L0:S/A 原始文档; -2. L1-L3:同一发布方的备用端点、官方完整转载或 DOI 绑定的正式期刊版本; -3. 原始路径明确受限且 L1-L3 均不可用时,降级到 B+ 的同文献完整副本; -4. B+ 不可用时,降级到 B 正规学术数据库中的同文献完整全文; -5. B-/C 只能继续核对和定位,不能补写医学内容。 +## 药品信息专层 -不绕过反自动化机制;同一主机对同一文献最多直接尝试 2 次,遇到 `401`、`403`、`412`、`429`、验证码或明确访问控制时只尝试 1 次并立即熔断。不得从首页逐层翻页,优先用完整标题、DOI 或文号直接定位。 +药物适应症、禁忌症、用法用量、不良反应优先查国家药监局、CDE、国家药品监督管理局药品评价中心/国家药品不良反应监测中心及官方批准说明书。必须匹配通用名、剂型、规格、给药途径、批准文号、上市许可持有人/生产企业和说明书版本;CDE 技术指导原则、医保支付限制、指南转述或 C 级页面均不能替代具体产品的批准说明书。 -## B+/B 文档身份硬门槛 +B+ 降级时不得绕过验证码或反自动化限制,不得为同一失败地址无限重试。最终核验结果必须同时列出两行: -B+/B 不是域名整体升级。具体副本必须达到 `medical-source-failover` 的 Exact 或 Strong 身份核验,并同时核验: +```text +来源:原始元数据({正式机构/期刊}):[链接]({S/A URL}) +来源:正文承载(原始正文访问受限):[链接]({B+ URL}) +``` -- 文档标题; -- 文档类型确为正式指南或正式专家共识; -- 制定机构; -- 年份/版本; -- 正式出处(DOI、文号、正式期刊及卷期中可取得者); -- 页面是否为完整全文,而不是摘要、摘编或局部预览; -- 是否已有新版、替代或废止信息。 +只有 B+ 页面、没有独立 S/A 元数据链接,或者标题/机构/版本/DOI 任一不一致时,结论只能是“仅可作为线索”。“指南解读”“共识解读”、编辑摘要、新闻、访谈、会议报道、病例讨论和科普即使位于 B+ 域名也不得作为最终依据。 -允许有可核验授权关系且与正式出版物一致的完整转载全文;仅由承载平台自称“指南/共识”、无法独立确认身份或只取得题录/摘要时,降为线索并标“需人工核验”。 +所有检索与抓取预算按整个用户回合累计,B+ 降级、校验失败和改稿都不得重置预算。已有一份现行正式指南足以覆盖用户问题时立即停止,不为“更完整”主动扩展第二、第三份指南;只有用户明确要求跨指南比较,或主指南确实不覆盖问题时才补充第二份。输出校验因链接域名失败时,优先删除未通过的辅助来源并保留已核验主指南;不得借改稿继续开启新一轮检索。 ## 文档类型硬门槛 @@ -93,7 +127,7 @@ B+/B 不是域名整体升级。具体副本必须达到 `medical-source-failove - 最终依据只接受正式指南/共识、规范/临床路径/质控标准、正式政策或监管文件及附件。正式期刊发表的指南/共识可以按其规范性文档类型纳入,但不能因“发表在期刊”自动成为最终依据。 - 系统综述、Meta 分析、叙述性综述、范围综述、伞状综述、快速综述、专家综述和其他文献综述,不得出现在最终“来源”、下一阶段指南候选或正式学习轨道来源中;最多用于内部发现正式指南,并继续回溯规范性原文。 - 随机对照试验、观察性研究、病例报告/系列、述评/来信、会议摘要和预印本等研究或学术讨论,也不得替代本产品所要求的规范性原文。 -- 科普、未核验转载/摘编、指南/共识解读、编辑摘要、新闻、访谈/媒体报道、病例讨论、患者教育、博客/Webinar、会议/培训/活动报道、营销或机构宣传,即使在可用域名也不得作为最终依据。 +- 科普、转载/摘编、访谈/媒体报道、面向公众的体检知识或体检解读、会议/培训/活动报道、营销或机构宣传,即使在白名单网站也不得作为最终依据。 - 新闻、访谈或政策解读页若链接正式原文,该页只作发现线索,必须继续回溯并引用正式原文或附件。 - 不得仅凭标题关键词判断;例如正式《健康体检管理办法》不应因含“体检”被误排除。 @@ -103,22 +137,24 @@ B+/B 不是域名整体升级。具体副本必须达到 `medical-source-failove - 年份以文件的正式发布日期、修订日期或版本标识为准,不把网页更新时间当作文件版本。 - 必须核对是否有更新、修订、替代或废止信息。旧版只能在仍有效、无新版或用于历史对比时使用,并明确说明原因。 -## 核验流程 +## 完整核验流程 -1. 先查已核验入口,再用搜索索引、B-/C 或专业平台快速发现候选文件和新版线索。 -2. 按 China-first 和文件层级选定主文件,不因某个承载页面容易访问就改选较低优先级文件。 -3. 用完整标题、DOI 或文号定位主管部门、制定机构、正式学会、正式期刊中的 S/A 原文或正式附件。 -4. 先核对文档类型,排除综述、研究、解读、摘要、新闻、访谈、病例讨论、科普和二次整理。 -5. 核对完整名称、制定机构、发布日期/年份、版本、正式出处、适用范围和版本状态。 -6. S/A 全文访问受限时,按 B+ → B 顺序读取同一正式文件,并完成 B+/B 文档身份硬门槛;不能完成时停止,不用二手摘要补齐。 -7. 涉及新旧变化时,必须同时取得新版和旧版原文。医保内容仍必须回到正式目录、政策附件或地方医保局正式文件,不适用 B+/B 医学指南承载降级。 -8. 输出时只列与学习结论直接相关的规范性核心来源;周期末推荐下一阶段时可列 2-3 个已核验的正式指南候选。 +1. 发现候选文件。 +2. 回溯官方页面、学会官网、正式期刊中的指南/共识原文或正式附件;先尝试原始正文,不得直接跳到 B+。 +3. 先核对文档类型,排除综述、原始研究、科普、转载、访谈、体检解读等非规范性原文。 +4. 核对完整名称、发布机构、发布日期/年份、版本和适用范围。 +5. 判断是否有后续更新、修订、替代文件或废止通知,优先最新有效版本。 +6. 涉及新旧变化时,必须同时取得新版和旧版原文。 +7. 医保内容必须回到正式目录、政策附件或地方医保局正式文件。 +8. 输出时只列与学习结论直接相关的规范性核心来源;使用 B+ 降级时同时列原始元数据与正文承载链接,并明确原始正文访问受限;周期末推荐下一阶段时可列 2-3 个已核验的正式指南候选。 + +快速核验不机械执行上述 8 步:完成“权威机构/正式域 + 规范性文档类型 + 标题/机构/年份版本 + 正文覆盖”后即可输出。只有命中完整核验触发项,或发现身份冲突、版本疑点、正文不完整时,才进入完整流程。 ## 禁止项 不得编造文件名、文号、机构、年份、链接、版本关系、医保支付条件、药物剂量或本院能力。 -未实际检索或无法访问原文时,只能写“未取得可核验权威来源”或“需人工核验”,不得伪装成已确认更新。 +未实际检索时只能写“未取得可核验权威来源”或“需人工核验”。已经执行 A/B/C 顺序检索但无法访问原文时,可以按上方格式披露 C 级背景转述;不得把它伪装成已确认更新、权威原文或正式依据。 检索到的只有综述或研究论文时,也应按“未取得可核验正式指南”处理,不能用它们补齐最终来源或下一阶段候选。 @@ -134,10 +170,3 @@ B+/B 不是域名整体升级。具体副本必须达到 `medical-source-failove 来源:{文件名称}:[链接]({URL}) 边界:本核验仅用于学习依据判断,不提供诊疗、处方、医保报销或院内执行建议。 ``` - -使用 B+/B 正文承载时,在来源前额外输出一行可审计元数据,字段名不得省略: - -```text -文档核验:文档标题:{标题};文档类型:{正式指南/正式专家共识};制定机构:{机构};年份/版本:{年份或版本};正式出处:{DOI/文号/期刊卷期};完整全文核验:{已核验};版本状态:{新版/替代/废止核验结论}。 -来源:{文件名称}({B+或B}正文承载):[链接]({URL}) -``` diff --git a/tests/unit/agents/test_clinical_learning_subscription_template.py b/tests/unit/agents/test_clinical_learning_subscription_template.py index 0421d0b9..6464af8f 100644 --- a/tests/unit/agents/test_clinical_learning_subscription_template.py +++ b/tests/unit/agents/test_clinical_learning_subscription_template.py @@ -296,88 +296,85 @@ def test_source_policy_filters_content_type_and_prefers_current_version() -> Non source_verify = (_ROOT / "skills" / "source-verify" / "SKILL.md").read_text(encoding="utf-8") assert "权威网站不等于" in source_verify - assert "科普、未核验转载/摘编、指南/共识解读" in source_verify + assert "科普、转载/摘编、访谈/媒体报道" in source_verify assert "不得出现在最终“来源”、下一阶段指南候选或正式学习轨道来源中" in source_verify assert "最新且当前有效的正式版本" in source_verify assert "网页更新时间" in source_verify -def _carrier_learning_text(*, title: str, url: str, carrier_grade: str = "B+") -> str: +def _carrier_learning_text(*, carrier_url: str, include_primary: bool = True) -> str: + primary_source = ( + "来源:原始元数据(中华医学会):[链接](https://www.cma.org.cn/art/2025/example.shtml)\n" + if include_primary + else "" + ) return f"""【指南章节展开|随访管理】 -依据:{title} +依据:中国基层随访管理指南(2025) 章节:随访管理章节 原文定位:正式全文中的随访管理章节 原文要点:学习随访管理的原则与质量要求。 学习提示:结合原文理解,不代入具体患者。 边界:本内容不替代原文,不提供个体诊疗、处方剂量或急诊处置建议。 -文档核验:文档标题:{title};文档类型:正式指南;制定机构:中华医学会相关分会;年份/版本:2025;正式出处:中华医学杂志 2025 年第 1 期;完整全文核验:已核验;版本状态:未发现更新、替代或废止文件。 -来源:{title}({carrier_grade}正文承载):[链接]({url}) +{primary_source}来源:正文承载(原始正文访问受限):[链接]({carrier_url}) """ @pytest.mark.parametrize( - ("domain", "role"), + ("domain", "primary", "secondary"), [ - ("guide.medlive.cn", "secondary_bplus"), - ("www.dxy.cn", "secondary_bplus"), - ("kns.cnki.net", "academic_b"), - ("d.wanfangdata.com.cn", "academic_b"), - ("www.cqvip.com", "academic_b"), - ("www.sinomed.ac.cn", "metadata_bminus"), - ("www.medsci.cn", "discovery_c"), - ("www.guidelines-registry.cn", "discovery_c"), - ("who.int", "primary"), - ("www.nice.org.uk", "primary"), - ("www.escardio.org", "primary"), + ("guide.medlive.cn", False, True), + ("www.dxy.cn", False, True), + ("www.sinomed.ac.cn", False, False), + ("www.medsci.cn", False, False), + ("www.guidelines-registry.cn", False, False), + ("kns.cnki.net", False, False), + ("who.int", True, False), + ("www.nice.org.uk", True, False), + ("www.escardio.org", True, False), + ("professional.diabetes.org", True, False), + ("kdigo.org", True, False), + ("ginasthma.org", True, False), ], ) -def test_source_policy_assigns_document_carrier_roles(domain: str, role: str) -> None: - module_name = f"role_{role}_{domain.replace('.', '_')}" +def test_source_policy_separates_primary_and_secondary_domains( + domain: str, primary: bool, secondary: bool +) -> None: + module_name = f"role_{domain.replace('.', '_')}" validator = _load_module(_ROOT / "scripts" / "validate_output.py", module_name) policy = validator._load_list_yaml(_ROOT / "references" / "source-policy.yaml") - assert validator._source_role(domain, policy) == role + assert validator._is_primary_domain(domain, policy) is primary + assert validator._is_secondary_domain(domain, policy) is secondary + assert validator._is_allowed_domain(domain, policy) is (primary or secondary) @pytest.mark.parametrize( - ("url", "grade"), + "url", [ - ("https://guide.medlive.cn/guideline/example", "B+"), - ("https://www.dxy.cn/bbs/newweb/pc/post/example", "B+"), - ("https://kns.cnki.net/kcms2/article/abstract/example", "B"), - ("https://d.wanfangdata.com.cn/periodical/example", "B"), - ("https://www.cqvip.com/QK/example", "B"), + "https://guide.medlive.cn/guideline/example", + "https://www.dxy.cn/bbs/newweb/pc/post/example", ], ) -def test_verified_secondary_fulltext_carrier_is_allowed(url: str, grade: str) -> None: +def test_secondary_fulltext_requires_primary_metadata_pair(url: str) -> None: domain = url.split("/", 3)[2].replace(".", "_") - validator = _load_module( - _ROOT / "scripts" / "validate_output.py", f"carrier_allowed_{grade}_{domain}" - ) - result = validator.validate( - _carrier_learning_text(title="中国基层随访管理指南(2025)", url=url, carrier_grade=grade), + validator = _load_module(_ROOT / "scripts" / "validate_output.py", f"carrier_{domain}") + + paired = validator.validate( + _carrier_learning_text(carrier_url=url), module="guideline_section_expansion", policy_path=_ROOT / "references" / "source-policy.yaml", allow_no_source=False, ) - assert result["ok"] is True - + assert paired["ok"] is True -def test_secondary_carrier_requires_all_document_identity_fields() -> None: - validator = _load_module( - _ROOT / "scripts" / "validate_output.py", "carrier_missing_identity_test" - ) - text = _carrier_learning_text( - title="中国基层随访管理指南(2025)", - url="https://guide.medlive.cn/guideline/example", - ).replace(";完整全文核验:已核验", "") - result = validator.validate( - text, + unpaired = validator.validate( + _carrier_learning_text(carrier_url=url, include_primary=False), module="guideline_section_expansion", policy_path=_ROOT / "references" / "source-policy.yaml", allow_no_source=False, ) - assert result["ok"] is False - assert "B+/B正文承载来源缺少文档核验字段:完整全文核验" in result["errors"] + assert unpaired["ok"] is False + assert "B+正文承载链接必须同时提供S/A原始元数据链接" in unpaired["errors"] + assert "B+受控降级必须标明:原始元数据" in unpaired["errors"] def test_secondary_carrier_rejects_guideline_interpretation() -> None: @@ -385,9 +382,8 @@ def test_secondary_carrier_rejects_guideline_interpretation() -> None: _ROOT / "scripts" / "validate_output.py", "carrier_interpretation_test" ) result = validator.validate( - _carrier_learning_text( - title="中国基层随访管理指南解读", - url="https://www.dxy.cn/bbs/newweb/pc/post/example", + _carrier_learning_text(carrier_url="https://www.dxy.cn/bbs/newweb/pc/post/example").replace( + "中国基层随访管理指南(2025)", "中国基层随访管理指南解读" ), module="guideline_section_expansion", policy_path=_ROOT / "references" / "source-policy.yaml", @@ -401,37 +397,41 @@ def test_secondary_carrier_rejects_guideline_interpretation() -> None: @pytest.mark.parametrize( - ("url", "expected_error"), + "url", [ - ( - "https://www.sinomed.ac.cn/article/example", - "B-题录核验源不得作为最终来源:www.sinomed.ac.cn", - ), - ( - "https://www.medsci.cn/guideline/example", - "C级发现源不得作为最终来源:www.medsci.cn", - ), + "https://www.sinomed.ac.cn/article/example", + "https://www.medsci.cn/guideline/example", + "https://kns.cnki.net/kcms2/article/abstract/example", + "https://d.wanfangdata.com.cn/periodical/example", + "https://www.cqvip.com/QK/example", ], ) -def test_metadata_and_discovery_sources_cannot_be_final(url: str, expected_error: str) -> None: +def test_discovery_and_legacy_academic_domains_cannot_be_final(url: str) -> None: domain = url.split("/", 3)[2].replace(".", "_") validator = _load_module(_ROOT / "scripts" / "validate_output.py", f"non_final_source_{domain}") result = validator.validate( - _carrier_learning_text(title="中国基层随访管理指南(2025)", url=url), + _carrier_learning_text(carrier_url=url, include_primary=False), module="guideline_section_expansion", policy_path=_ROOT / "references" / "source-policy.yaml", allow_no_source=False, ) assert result["ok"] is False - assert expected_error in result["errors"] + assert f"来源域名不在白名单:{url.split('/', 3)[2]}" in result["errors"] -def test_authorized_full_reprint_is_not_treated_as_unverified_repost() -> None: - validator = _load_module(_ROOT / "scripts" / "validate_output.py", "authorized_reprint_test") - text = _carrier_learning_text( - title="中国基层随访管理指南(2025)授权转载正式全文", - url="https://guide.medlive.cn/guideline/example", - ) +def test_fully_attributed_c_tier_relay_is_background_only() -> None: + validator = _load_module(_ROOT / "scripts" / "validate_output.py", "attributed_relay_test") + text = """【指南章节展开|随访管理】 +依据:中国基层随访管理指南(2025) +章节:随访管理章节 +定位状态:未取得原文 +原文要点:仅说明该页面的背景转述,不提取精确推荐。 +学习提示:等待取得规范性原文后再核验。 +边界:本内容不替代原文,不提供个体诊疗、处方剂量或急诊处置建议。 +来源:转述页面(C级,仅作背景):[链接](https://example.org/clinical-report) +原始出处:中华医学杂志|中国基层随访管理指南|2025|DOI未提供 +核验状态:未取得可核验原文,以上仅为背景转述,不作为权威依据。 +""" result = validator.validate( text, module="guideline_section_expansion", @@ -439,6 +439,33 @@ def test_authorized_full_reprint_is_not_treated_as_unverified_repost() -> None: allow_no_source=False, ) assert result["ok"] is True + assert "包含C级全网转述页面:只能作为背景,不是最终证据" in result["warnings"] + + +def test_clinical_fast_path_and_route_catalogs_are_registered() -> None: + policy = _load_module( + _ROOT / "scripts" / "validate_output.py", "fast_path_policy_test" + )._load_list_yaml(_ROOT / "references" / "source-policy.yaml") + assert "clinical_q_and_a" in policy["clinical_safety_modules"] + assert policy["retrieval_budget_hard_limits"] == [ + "searchfree_search_max_3", + "web_fetch_max_3", + "international_sites_normally_1", + "international_sites_absolute_max_2", + "final_normative_documents_normally_1", + ] + + professional_routes = ( + _ROOT / "references" / "professional-society-source-routes.yaml" + ).read_text(encoding="utf-8") + international_routes = ( + _ROOT / "references" / "international-guideline-source-routes.yaml" + ).read_text(encoding="utf-8") + assert "呼吸病学分会" in professional_routes + assert "中国药学会" in professional_routes + assert "official_discovery_pending_fulltext_acceptance" in professional_routes + assert "request_budget: 正常只访问 1 个国际网站;必要时最多 2 个" in international_routes + assert "id: gina" in international_routes def test_internal_learning_team_members_have_no_tools() -> None: