AI Agent辅助门诊分诊症状采集、初步分流和边界控制怎么设计门诊分诊类 Agent 的核心难点不是“让模型多回答几句”而是如何把症状采集、示例规则判断、人工转接和边界控制串成可审计的工程链路。本文只讨论技术架构和工程流程示例不提供诊断、治疗、分诊或用药建议文中所有阈值、风险分层和升级规则均为示例真实项目必须由医疗专业人员和机构规范确认。问题背景分诊 Agent 最容易踩的三个坑在门诊前置服务里用户通常输入的是自然语言例如“胸口不舒服”“孩子发热”“头晕两天”。如果直接把这类描述交给 LLM 生成结论系统很容易越界到诊断建议甚至给出不应由系统自动输出的处理方案。工程上常见问题有三个症状采集不完整缺少持续时间、严重程度、伴随表现、特殊人群信息。规则链路不可审计模型说了什么、为什么升级人工、命中了哪些规则没有记录。输出边界失控从“建议联系人工服务”滑向“判断为某疾病”。因此比较稳妥的设计是LLM 负责结构化采集和表达整理示例决策树负责风险标签服务端策略层负责拦截越界内容和触发人工转接。技术目标与约束本文示例技术栈FastAPI提供问答和状态推进接口Python实现规则引擎与 Agent 编排PostgreSQL保存会话、结构化症状、规则命中记录LLM API用于意图识别、追问生成和用户话术改写decision tree实现可配置的示例风险分层需要明确几个边界Agent 不输出诊断结论。Agent 不推荐药物、剂量和治疗方案。Agent 只做信息采集、示例风险提示、人工转接建议。所有风险规则必须可配置、可回溯、可由机构审核。总体架构把 LLM 放在“采集层”不要放在“裁决层”一个可控的流程可以拆成 5 个节点是否用户输入症状描述LLM结构化抽取缺失字段追问示例规则引擎评估是否触发升级人工转接/提示联系线下服务给出非诊断性下一步引导保存审计日志这里的关键设计是LLM 不直接决定“去哪一科”或“是否紧急”它只将用户输入整理成结构化字段。真正的风险分层由规则层完成并且每条规则都能在数据库里留下命中记录。数据模型先把“症状事实”和“系统判断”分开建议把用户原始输入、结构化症状、规则命中、最终回复分表保存。这样做便于回放、质检和追责。CREATETABLEtriage_session(id UUIDPRIMARYKEY,user_idTEXT,statusTEXTNOTNULL,created_atTIMESTAMPDEFAULTnow());CREATETABLEsymptom_record(id UUIDPRIMARYKEY,session_id UUIDREFERENCEStriage_session(id),chief_complaintTEXT,durationTEXT,severityTEXT,associated_symptoms JSONB,special_population JSONB,raw_textTEXT,created_atTIMESTAMPDEFAULTnow());CREATETABLErule_hit_log(id UUIDPRIMARYKEY,session_id UUIDREFERENCEStriage_session(id),rule_codeTEXT,risk_levelTEXT,reasonTEXT,created_atTIMESTAMPDEFAULTnow());注意不要把“模型猜测”混入症状事实字段。比如用户没有说“持续时间”就应该标记为 unknown而不是让模型补一个看似合理的时间。核心实现示例规则引擎和边界过滤下面代码是一个最小可运行的规则层示例。规则内容仅用于说明工程结构不代表真实医疗分诊标准。fromenumimportEnumfromtypingimportDict,ListfrompydanticimportBaseModelclassRiskLevel(str,Enum):LOWlowMEDIUMmediumHIGHhighHANDOFFhandoffclassSymptomInput(BaseModel):chief_complaint:strduration:str|NoneNoneseverity:int|NoneNoneassociated_symptoms:List[str][]age_group:str|NoneNoneis_pregnant:bool|NoneNoneclassRuleHit(BaseModel):rule_code:strrisk_level:RiskLevel reason:strdefevaluate_rules(symptom:SymptomInput)-List[RuleHit]:hits:List[RuleHit][]# 示例规则严重程度较高时进入人工复核ifsymptom.severityisnotNoneandsymptom.severity8:hits.append(RuleHit(rule_codeEXAMPLE_SEVERITY_HIGH,risk_levelRiskLevel.HANDOFF,reason用户自述严重程度较高示例规则要求人工复核))# 示例规则特殊人群触发人工复核ifsymptom.age_groupin[infant,elderly]orsymptom.is_pregnantisTrue:hits.append(RuleHit(rule_codeEXAMPLE_SPECIAL_POPULATION,risk_levelRiskLevel.HANDOFF,reason特殊人群信息命中示例升级规则))# 示例规则存在未采集关键字段继续追问ifnotsymptom.duration:hits.append(RuleHit(rule_codeEXAMPLE_MISSING_DURATION,risk_levelRiskLevel.MEDIUM,reason缺少持续时间字段需要继续采集))ifnothits:hits.append(RuleHit(rule_codeEXAMPLE_DEFAULT_LOW,risk_levelRiskLevel.LOW,reason未命中示例升级规则仅提供非诊断性引导))returnhits FORBIDDEN_PATTERNS[确诊,诊断为,建议服用,用药剂量,治疗方案]defguardrail_response(text:str)-str:ifany(pintextforpinFORBIDDEN_PATTERNS):return我无法提供诊断、治疗或用药建议。可以继续帮你整理症状信息并为你转接人工服务或提示联系正规医疗机构。returntext这段代码体现两个原则风险升级由显式规则触发而不是由 LLM 自由判断。输出前必须经过边界过滤避免出现诊断、治疗、用药类表述。FastAPI 编排会话状态要可恢复接口层不要只做一次性问答而要维护会话状态。一次分诊采集可能包含多轮追问主诉、持续时间、严重程度、伴随表现、特殊人群信息等。fromfastapiimportFastAPIfrompydanticimportBaseModel appFastAPI()classChatRequest(BaseModel):session_id:strmessage:strclassChatResponse(BaseModel):reply:straction:strrisk_level:strapp.post(/triage/chat,response_modelChatResponse)deftriage_chat(req:ChatRequest):# 示例真实项目中应从LLM抽取结构化字段并与历史会话合并symptomSymptomInput(chief_complaintreq.message,durationNone,severity5,associated_symptoms[],age_groupNone,is_pregnantNone)hitsevaluate_rules(symptom)max_hitsorted(hits,keylambdax:[low,medium,high,handoff].index(x.risk_level))[0]ifany(h.risk_levelRiskLevel.HANDOFFforhinhits):reply根据当前采集到的信息系统将为你转接人工服务。此处不提供诊断或治疗建议。actionhandofflevelhandoffelifany(h.rule_codeEXAMPLE_MISSING_DURATIONforhinhits):reply为了更准确地整理信息请补充这个不适大约持续了多久actionask_morelevelmediumelse:reply已记录你的症状信息。你可以继续补充变化情况或选择联系人工服务。actioncontinuelevellowreturnChatResponse(replyguardrail_response(reply),actionaction,risk_levellevel)这里的action比自然语言回复更重要。前端应根据handoff、ask_more、continue等动作切换界面而不是解析回复文本来决定流程。调试重点如何发现 Agent 越界上线前建议准备一组红队测试用例覆盖以下输入用户直接要求“帮我诊断是什么病”用户要求“推荐药和剂量”用户只输入一个模糊症状用户反复追问是否严重用户输入特殊人群信息用户描述强烈不适但字段不完整每条测试用例至少检查 4 件事是否拒绝诊断、治疗、用药建议是否继续采集缺失字段是否命中预期示例规则是否留下完整审计日志如果发现 LLM 经常输出越界内容可以把提示词拆成两段一段只做结构化抽取一段只做礼貌话术改写。不要让同一个 Prompt 同时承担抽取、判断和建议。规则配置与人工转接真实项目中规则不应写死在代码里。更推荐把规则配置化例如字段条件severity、duration、age_group、special_population动作ask_more、handoff、continue文案模板只允许使用经过审核的非诊断性表达版本号支持按机构、科室、时间回滚人工转接也要设计失败兜底。如果当前没有在线人员系统应提示用户联系机构规定渠道而不是继续让模型“补位”。结论AI Agent 辅助门诊分诊的工程重点是把自然语言输入变成可审计、可配置、可人工接管的流程。LLM 适合做症状整理和追问生成示例风险分层应放在规则引擎中输出层必须设置诊断、治疗、用药边界。下一步可以继续完善 PostgreSQL 审计表、规则后台、红队测试集和人工坐席系统对接让整个链路从 Demo 走向可治理的生产形态。本文文献检索、文献挖掘以及文献翻译采用的是【超能文献| AI文献检索|AI文档翻译】。