AI Agent辅助门诊分诊:症状采集、初步分流和边界控制怎么设计
门诊入口的常见工程问题不是“让 AI 替医生判断”,而是如何把用户主诉结构化、识别需要人工介入的风险信号,并把会话安全地交给导诊台或在线人工客服。本文只讨论技术架构和工程流程示例,不提供诊断、治疗、分诊或用药建议;文中的风险分层和阈值均为示例规则,真实项目必须由医疗专业人员和机构规范确认。
问题背景:AI Agent 容易在哪些地方越界
在门诊分诊辅助场景里,Agent 通常承担三个任务:采集症状、补充关键问题、生成前置分流建议。最容易出问题的是第三步:模型把“建议去哪个科室咨询”写成“你可能患有某病”,或者在缺少信息时继续追问不该由系统处理的细节。
工程上需要把 Agent 从“自由问答机器人”改造成“受控流程执行器”。LLM 负责自然语言理解和追问表达,规则引擎负责边界判断,审计模块负责留痕,人工转接负责兜底。
技术目标和约束
本文示例技术栈为 Python、FastAPI、decision tree、LLM API、PostgreSQL。目标不是构建自动分诊系统,而是实现一个辅助链路:
- 将用户输入转换为结构化字段,例如主诉、持续时间、严重程度、伴随情况。
- 使用可配置规则识别需要人工转接的场景。
- 输出“就医路径提示”而不是诊断结论。
- 保存会话、规则命中和模型输出,便于复核。
- 对高风险、低置信度、未成年人、表达不清等情况优先升级人工。
方案概览:LLM 只做抽取和表达,规则做决策
一个相对稳妥的架构是“LLM + 规则树 + 人工转接”三段式。
核心原则是:LLM 不直接决定风险等级,只把自然语言转成 JSON,并根据系统允许的模板生成回复。风险分层、转接条件、禁用话术应放在配置或数据库中,由业务和医疗专业人员共同维护。
数据模型:先定义 Agent 能看懂什么
症状采集不要一开始就追求复杂医学知识库,先把门诊导诊常用字段抽象出来。PostgreSQL 可以保存原始消息、结构化结果和规则命中记录。
CREATE TABLE triage_session (
id UUID PRIMARY KEY,
user_id TEXT,
status TEXT NOT NULL,
created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE triage_observation (
id UUID PRIMARY KEY,
session_id UUID REFERENCES triage_session(id),
chief_complaint TEXT,
duration_text TEXT,
severity_level INT,
age_group TEXT,
has_red_flag BOOLEAN,
extracted_json JSONB,
created_at TIMESTAMP DEFAULT now()
);
CREATE TABLE triage_audit_log (
id UUID PRIMARY KEY,
session_id UUID REFERENCES triage_session(id),
event_type TEXT,
event_payload JSONB,
created_at TIMESTAMP DEFAULT now()
);
这里的 severity_level 只是用户自述严重程度的结构化结果,不代表医学判断。has_red_flag 也只是“示例规则是否命中需人工处理的信号”,不能作为诊断依据。
FastAPI 实现:把每轮会话拆成可审计步骤
下面是一个最小可运行风格的接口示例。为了便于展示,LLM 调用用函数占位,真实项目应接入供应商 SDK,并增加超时、重试、限流和敏感信息处理。
from fastapi import FastAPI
from pydantic import BaseModel, Field
from typing import Optional, Literal
import uuid
app = FastAPI()
class UserMessage(BaseModel):
session_id: Optional[str] = None
text: str = Field(min_length=1, max_length=500)
class Observation(BaseModel):
chief_complaint: Optional[str] = None
duration_text: Optional[str] = None
severity_level: Optional[int] = None
age_group: Optional[Literal["child", "adult", "older_adult"]] = None
has_red_flag_text: Optional[bool] = None
def extract_observation_by_llm(text: str) -> Observation:
"""
示例:真实实现中应要求 LLM 只返回 JSON。
Prompt 中需要明确禁止输出诊断、治疗、用药建议。
"""
return Observation(
chief_complaint=text[:50],
duration_text=None,
severity_level=None,
age_group="adult",
has_red_flag_text=False
)
def evaluate_rules(obs: Observation) -> dict:
"""
示例规则:真实项目应由医疗专业人员和机构流程确认。
"""
missing = []
if not obs.duration_text:
missing.append("duration_text")
if obs.severity_level is None:
missing.append("severity_level")
if obs.has_red_flag_text:
return {
"action": "handoff",
"reason": "matched_configured_red_flag",
"message": "根据当前描述,建议转接人工服务进一步确认。"
}
if missing:
return {
"action": "ask_more",
"missing": missing,
"message": "为了更好地帮助登记,请补充症状持续时间和自感严重程度。"
}
return {
"action": "guidance",
"message": "已记录您的描述,可根据机构规则提示合适的咨询入口;本系统不提供诊断结论。"
}
@app.post("/triage/chat")
def triage_chat(msg: UserMessage):
session_id = msg.session_id or str(uuid.uuid4())
obs = extract_observation_by_llm(msg.text)
decision = evaluate_rules(obs)
return {
"session_id": session_id,
"observation": obs.model_dump(),
"decision": decision,
"safety_notice": "本功能仅为技术流程示例,不提供诊断、治疗、分诊或用药建议。"
}
这个接口的关键点不是代码复杂度,而是职责隔离:抽取、规则、回复、审计应可单独测试。不要让一个 Prompt 同时完成“理解、判断、安抚、推荐科室、生成结论”,否则很难定位错误来源。
症状问答设计:少问、问准、可退出
症状采集建议采用“必填字段 + 条件追问”的方式。第一轮只收集主诉和用户原文,第二轮再补持续时间、严重程度、年龄段等字段。每次追问最多 1 到 2 个问题,避免把门诊入口做成冗长问卷。
可配置字段示例:
chief_complaint:用户主要不适描述。duration_text:持续时间,保留原文,不强行标准化。severity_level:用户自评等级,展示为可选项。age_group:粗粒度年龄段,用于流程路由。red_flag_text:用户原文中命中的需人工确认信号。
界面上必须提供“跳过”“转人工”“重新描述”等入口。对无法理解、连续多轮缺失关键字段、用户表达明显焦虑或不确定的情况,应走人工兜底,而不是继续让模型猜测。
边界控制:用黑名单不够,要做输出契约
仅靠敏感词过滤很脆弱。更可靠的做法是定义输出契约:Agent 只能返回固定动作,例如 ask_more、handoff、guidance,不能返回疾病名称、处置方案或用药建议。
可以在系统 Prompt 中写清楚:
- 只抽取用户提供的信息,不补充事实。
- 不输出诊断结论。
- 不比较疾病可能性。
- 不给治疗、检查、用药建议。
- 遇到不确定、高风险、规则命中时转人工。
- 所有提示必须包含“以机构人工确认为准”。
同时要在服务端做二次校验。即使 LLM 返回了越界内容,也应该被模板化响应覆盖,而不是直接展示给用户。
常见故障和排查方法
第一类问题是“模型追问过多”。通常是 Prompt 给了模型过大自由度,建议把追问问题从模型生成改为模板生成,模型只负责判断缺哪个字段。
第二类问题是“规则命中不可解释”。解决方式是在每次决策中记录 rule_id、输入字段、规则版本和动作结果。上线后排查问题时,不能只看最终回复。
第三类问题是“人工转接过晚”。这通常不是模型问题,而是升级规则太激进地追求自动完成率。门诊入口更适合保守策略:信息不完整、用户描述不清、规则版本未覆盖时,都应进入人工确认。
性能和扩展建议
LLM 抽取可以异步化,但首轮响应不宜过慢。实践中可先返回“已收到,正在整理信息”,再通过流式或轮询返回下一步。对相同会话上下文要缓存结构化结果,避免每轮都把完整历史发送给模型。
规则树建议版本化,例如 triage_rule_version=2026-06-29-a。当医疗机构调整流程时,可以回放历史匿名样本,检查新旧规则对转人工比例、缺字段比例、越界输出拦截次数的影响。
总结
AI Agent 辅助门诊分诊的工程重点不是让模型“更像医生”,而是让它在受控边界内完成信息采集和流程路由。推荐把 LLM 限定在结构化抽取和自然语言表达,把风险分层交给可审计、可配置、可回滚的规则系统。真实项目中,所有示例规则、阈值和升级策略都应由医疗专业人员与机构规范确认,并持续通过日志审计和人工复核迭代。
本文文献检索、文献挖掘以及文献翻译采用的是【超能文献| AI文献检索|AI文档翻译】。
更多推荐

所有评论(0)