Skip to main content

stcc-mcp — 电话分诊分级:规则确定性算,0.6B 只核对判据

一段问诊记录进去,出 L1–L5 档位 + 处置措辞 + 逐条引文 + 还缺哪几条判据。 分级由确定性规则引擎算出(225 份 STCC 协议 / 849 分支 / 4,168 条判据,随包分发), Qwen3-0.6B 只回答一件事:给定记录和一条判据,yes / no / unknown

模型不选分支、不定档位、不生成处置措辞、不做 tool call

⚠️ 不是急诊分诊系统,不做诊断,不能替代医生。L1–L5 是处置阶梯 (叫救护车 / 立即急诊 / 今天就医 / 近两日门诊 / 居家观察)。紧急情况直接拨 120。

三步跑起来

pip install stcc-mcp                                       # 或 uvx stcc-mcp …
ollama pull hf.co/chenhaodev/stcc-checker-0.6b-GGUF:Q8_0   # 640MB 核对器
stcc-mcp doctor                                            # 自检:索引 / Ollama / 模型
stcc-mcp triage --protocol Chest_Pain.md "$(cat 记录.txt)"

零常驻进程、零 Docker、不联网。引擎是纯标准库,无第三方依赖。

第一次运行大概率会看到 tier: L1 + certain: false —— 这是对的

拿一段普通问诊记录进去,很可能得到最紧急档加一串 unresolved不是判错: 引擎只有在某支全部条件都为 no 时才敢排除它,而一次真实问诊不会把一支的判据问完。 例如轻症发热的记录里护士问了意识/呼吸/颈硬/皮疹,却从没问过脱水体征 (排尿减少、眼窝凹陷、皮肤张力差、口渴),于是该支排除不掉,输出停在它的档位上界。

unresolved 就是"再问这几条就能收紧"的清单。 把答案补进记录重跑, unresolved 会单调变短;但档位只有在某支被完全排除时才会降—— 实测同一份发热记录补齐脱水体征后 unresolved 8→2,档位仍停在 L1, 因为剩下的主干(老年人或免疫低下者…脱水表现: 这种半截话)核对器给的是 unknown。 这时候该动的是下面那个阈值旋钮,不是继续问。详见边界 ①②。

接进 agent(Claude Code / 任何 MCP client):

pip install "stcc-mcp[mcp]" && stcc-mcp serve               # stdio MCP

Ollama 不支持 MCP,而这对本形态不是问题:小模型从不 tool call, 编排层分别去调 Ollama(HTTP)和规则引擎(进程内),两者互不相识。 0.6B 自主 tool-calling 是已知重灾区,这个架构从设计上绕开了它。

输出

字段 含义
tier L1L5安全上界:永不比真实答案更轻
disposition 该分支的处置措辞(来自规则表,不是模型生成)
certain true = 证据已足以定档;false = 这是 worst_case 上界
citations 判定依据的判据 + 行号,可审计
unresolved 还缺哪几条判据 —— 补问它们就能收紧档位

档位到行动的映射由你的编排层定;本包只给档位与处置措辞。

no 的门槛是一个旋钮

--no-threshold(默认 0.63):P(no) ≥ τ ⇒ no,否则在 yes/unknown 里取大者。 同一个模型在发布分布(n=3225)上的整条取舍曲线:

τ acc false_no🔴 no_recall
0.63(默认) 0.9426 0.0000 0.9027
0.50 0.9457 0.0000 0.9189
0.40 0.9495 0.0024 0.9378
0.30 0.9498 0.0084 0.9432
0.10 0.9516 0.0120 0.9635

同一段发热问诊记录,只改 τ:

$ stcc-mcp triage --protocol Fever_Adult.md --no-threshold 0.63 "$(cat 记录.txt)"
  tier L1 · 拨打救护车        · unresolved 2
$ stcc-mcp triage --protocol Fever_Adult.md --no-threshold 0.40 "$(cat 记录.txt)"
  tier L3 · 2小时内接受医疗护理 · unresolved 5

τ 调低 ⇒ 核对器更敢把"问过且被否认"的判据判成 no ⇒ 分支被排除 ⇒ 档位下降。 这不是让模型更准,是在同一条取舍曲线上换工作点——换来的是漏诊风险上升。

false_no(该成立却判成 no)是硬门——假 no 会把真值分支从安全收敛里排除掉。 少判 no 只造成过分诊,是成本旋钮。 默认值在 dev 上按 false_no ≤ 0.0036 选出(该 dev 仅 495 条正例、分辨率 0.0020, 系统性偏保守)。所以没有硬钉"最优值",曲线一起给出,按自己的代价矩阵挑点。 复现:python -m scripts.threshold_sweep --model <m> --split <s> --collect --report

🔴 已知边界(先读这段再决定用不用)

① 「该用哪份协议」这一步本包不提供。 --protocol 是必填参数,需要调用方给——完整链路里这一环是空的:

一段问诊记录 ──[?? 谁来选协议 ??]──► protocol_id ──► 本包(引擎 + 核对器)──► L1–L5
                     ↑ 缺这一环

推荐形态:编排层用一个大模型看中文标题菜单来选stcc-mcp protocols 可打印,225 份)。 上一轮(run1,221 份协议的菜单,34 条真实自述)实测:大模型菜单选择 @1 = 0.85(原文直选)/ 0.94(先抽一句主诉再选)· @2 = 1.00; 而用判据文本做向量检索定协议只有 @1 = 0.18 —— 同一句判据(如"恶心或呕吐") 跨几十份协议出现,判据级索引天然定不了协议,这条路已证伪,别再走。 选错协议时引擎的 referral / indeterminate 状态是自纠网,但那是网,不是替代

② 输入必须是「已按协议问过一轮」的记录,不是原始自述。 短主诉 unknown 率 94%;真实富对话(IMCS-21,748 字 / 40 轮)仍有 88%。 原因是 STCC 前置分支筛的是急症红旗(噎着、发紫、无反应), 而自然产生的语料按定义不含这些情形、医生也不会去问——这是选择效应,换更富的语料无效。

③ 一次真实问诊不会把一支的判据全问完,于是档位停在该支上界。 这是 worst_case 在正确工作,但上界松紧完全由问诊完备性决定

worst_case 的安全性以「不产生假 no」为前提。 输出是在现有证据下排除不掉的最紧急一档(某支只有全部条件为 no 才算排除), 因此欠分诊恒为 0、证据每多一个 no 就单调收紧(两条不变量由 tests/ 守着)。 信息不足时它会退化成"人人叫救护车"——这是设计取向(欠分诊 10·d² vs 过分诊 d),不是 bug。

⑤ 分级本身是 silver:分支级参照由强模型定稿 + 人工复核,终局结论仍缺一个真人护士 gold

unknown 为什么是第一等状态

STCC 分支语义是「本支任一条件为 ⇒ 命中;全部为 ⇒ 转下一支」。 "没提到" ≠ "说了没有":前者必须触发追问,后者才能转分支。 把 unknown 压成 no 等于凭空伪造阴性,会让引擎走到错误的分支。

判据文本

索引里的判据是逐条独立改写版(5,214/5,214)。纯阈值与单个医学术语 (「咳嗽」「体温>100.4°F」)按事实保留。改写过三道闸: 数值/否定/长度/雷同的形式校验、oracle 回放与原版逐位一致、下游 checker 指标不掉。

开发

uv sync
uv run pytest -q                        # 27 条回归
uv run python -m scripts.mcp_selfcheck  # oracle 回放 4,168 条判据,<1 秒

scripts/mcp_selfcheck.py 是引擎的忠实度自检:逐条判据置 yes、其余置 no, 核对引擎走到的分支与处置。这不是模型评测——对不上就是编译或求值有洞。

模型

chenhaodev/stcc-checker-0.6b-GGUF (Q8_0 / Q4_K_M)。判据级 false_no 0.0024、延迟中位 ~250ms、端到端 1.25s/条。

Apache-2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stcc_mcp-0.1.2.tar.gz (155.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stcc_mcp-0.1.2-py3-none-any.whl (156.2 kB view details)

Uploaded Python 3

File details

Details for the file stcc_mcp-0.1.2.tar.gz.

File metadata

  • Download URL: stcc_mcp-0.1.2.tar.gz
  • Upload date:
  • Size: 155.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.8

File hashes

Hashes for stcc_mcp-0.1.2.tar.gz
Algorithm Hash digest
SHA256 da050f2682a36d5c5e9cd0bb412e92d4d5333decf633d59c46da8eebd7bde87f
MD5 7c14a09ed1c5f777b8fca2512b933e8c
BLAKE2b-256 ff783a5016841cf9f475a8b657fe57ff4c59d349fd370844bc246604b4817f25

See more details on using hashes here.

File details

Details for the file stcc_mcp-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: stcc_mcp-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 156.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.8

File hashes

Hashes for stcc_mcp-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 1c009d6fa380a023f0b6701229077ae11be72721179d0eb482564438847679c1
MD5 6d3677865dc88d6e86c9d173738bdd0e
BLAKE2b-256 a0675d9b5a509b8f266f406c431b4856c4e69c29f8fefb879125d98c9294368f

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page