【实战项目 21-25】第 22/25 课

🤖 第22课:医院导诊

📌 医院导诊项目概述

医院导诊机器人帮助患者快速找到科室,减轻导诊台压力,提高就医效率:

🏥 医院导诊流程

患者到达 → 语音问诊 → 症状分诊 → 推荐科室 →
引导到科室 → 途中问答 → 到达确认 → 返回待命

📌 症状分诊系统

import json, random

class HospitalGuideRobot:
    """医院导诊机器人"""
    def __init__(self, name="MediBot-01"):
        self.name = name
        self.departments = {
            "内科": {"floor": 2, "location": "2F-A区", "doctors": ["张医生","李医生"],
                     "symptoms": ["发热","咳嗽","头痛","腹痛","胸闷"]},
            "外科": {"floor": 3, "location": "3F-B区", "doctors": ["王医生","赵医生"],
                     "symptoms": ["骨折","外伤","腰痛","关节痛"]},
            "儿科": {"floor": 2, "location": "2F-C区", "doctors": ["刘医生"],
                     "symptoms": ["儿童发热","儿童咳嗽","儿童腹泻"]},
            "妇产科": {"floor": 4, "location": "4F-A区", "doctors": ["陈医生"],
                       "symptoms": ["产检","月经不调","孕期不适"]},
            "眼科": {"floor": 3, "location": "3F-A区", "doctors": ["杨医生"],
                     "symptoms": ["视力下降","眼睛红肿","眼睛干涩"]},
            "口腔科": {"floor": 3, "location": "3F-C区", "doctors": ["吴医生"],
                       "symptoms": ["牙痛","牙龈出血","口腔溃疡"]},
            "皮肤科": {"floor": 4, "location": "4F-B区", "doctors": ["周医生"],
                       "symptoms": ["皮疹","瘙痒","过敏"]},
            "急诊科": {"floor": 1, "location": "1F-急诊", "doctors": ["值班医生"],
                       "symptoms": ["胸痛","呼吸困难","严重外伤","高烧"]},
        }
        self.state = "idle"
        self.current_patient = None

    def triage(self, symptoms):
        """症状分诊"""
        matches = {}
        for dept, info in self.departments.items():
            score = sum(1 for s in info["symptoms"] if any(s in sym for sym in symptoms))
            if score > 0:
                matches[dept] = {"score": score, "floor": info["floor"],
                                  "location": info["location"], "doctors": info["doctors"]}

        sorted_matches = sorted(matches.items(), key=lambda x: -x[1]["score"])
        
        # 检查是否需要急诊
        emergency_keywords = ["胸痛","呼吸困难","严重外伤","昏迷","大出血"]
        is_emergency = any(kw in " ".join(symptoms) for kw in emergency_keywords)
        
        return {
            "recommended": sorted_matches[0] if sorted_matches else None,
            "alternatives": sorted_matches[1:3] if len(sorted_matches) > 1 else [],
            "is_emergency": is_emergency,
        }

    def guide_patient(self, symptoms):
        """引导患者"""
        triage_result = self.triage(symptoms)
        
        if triage_result["is_emergency"]:
            return {
                "action": "紧急引导",
                "message": "您的情况需要紧急处理,请跟我前往急诊科!",
                "department": "急诊科",
                "location": "1F-急诊",
            }

        if not triage_result["recommended"]:
            return {
                "action": "人工咨询",
                "message": "抱歉,我无法确定您的科室,请到导诊台咨询。",
                "department": None,
                "location": "1F导诊台",
            }

        dept, info = triage_result["recommended"]
        return {
            "action": "引导就诊",
            "message": f"根据您的症状,建议您挂{dept},在{info['location']},请跟我来。",
            "department": dept,
            "floor": info["floor"],
            "location": info["location"],
            "doctors": info["doctors"],
        }

robot = HospitalGuideRobot()
print("医院导诊机器人模拟")
print("=" * 55)

patients = [
    ["发热","咳嗽","头痛"],
    ["牙痛","牙龈出血"],
    ["胸痛","呼吸困难"],
    ["皮疹","瘙痒"],
    ["儿童发热","咳嗽"],
    ["视力下降"],
]

for symptoms in patients:
    result = robot.guide_patient(symptoms)
    print(f"\n🏥 症状: {', '.join(symptoms)}")
    print(f"   {result['message']}")
    if result.get("doctors"):
        print(f"   可选医生: {', '.join(result['doctors'])}")

print("\n✅ 医院导诊验证通过")
✅ 验证通过 医院导诊机器人模拟 ======================================================= 🏥 症状: 发热, 咳嗽, 头痛 根据您的症状,建议您挂内科,在2F-A区,请跟我来。 可选医生: 张医生, 李医生 🏥 症状: 牙痛, 牙龈出血 根据您的症状,建议您挂口腔科,在3F-C区,请跟我来。 可选医生: 吴医生 🏥 症状: 胸痛, 呼吸困难 您的情况需要紧急处理,请跟我前往急诊科! 🏥 症状: 皮疹, 瘙痒 根据您的症状,建议您挂皮肤科,在4F-B区,请跟我来。 可选医生: 周医生 🏥 症状: 儿童发热, 咳嗽 根据您的症状,建议您挂内科,在2F-A区,请跟我来。 可选医生: 张医生, 李医生 🏥 症状: 视力下降 根据您的症状,建议您挂眼科,在3F-A区,请跟我来。 可选医生: 杨医生 ✅ 医院导诊验证通过

📌 医学知识问答

class MedicalKnowledgeQA:
    """医学知识问答(简化版)"""
    def __init__(self):
        self.qa_pairs = {
            "挂号": {
                "keywords": ["挂号","怎么挂号","在哪里挂号","挂什么科"],
                "answer": "挂号请前往1楼大厅挂号窗口,或使用自助挂号机。您也可以通过手机APP预约挂号。",
                "follow_up": "需要我带您去挂号窗口吗?"
            },
            "取药": {
                "keywords": ["取药","药房","拿药","药在哪里"],
                "answer": "取药请前往1楼药房,请携带好您的处方单和就诊卡。",
                "follow_up": "需要我带您去药房吗?"
            },
            "检查": {
                "keywords": ["检查","化验","抽血","B超","CT","拍片"],
                "answer": "检查地点:抽血在2F检验科,B超在3F影像科,CT在3F放射科。请先到对应科室前台登记。",
                "follow_up": "您需要做哪项检查?"
            },
            "缴费": {
                "keywords": ["缴费","收费","交费","付款"],
                "answer": "缴费可在各楼层自助缴费机完成,也可到1楼收费窗口。支持医保卡和移动支付。",
                "follow_up": "需要我带您去最近的缴费机吗?"
            },
            "住院": {
                "keywords": ["住院","办住院","住院部"],
                "answer": "住院办理请到1楼住院处,需携带身份证、医保卡和入院通知单。住院部在5-8楼。",
                "follow_up": "需要我带您去住院处吗?"
            },
            "wifi": {
                "keywords": ["wifi","网络","上网","密码"],
                "answer": "医院免费WiFi: Hospital-Guest,密码: 12345678。连接后需在浏览器确认。",
                "follow_up": None
            },
        }

    def answer(self, question):
        """回答问题"""
        for topic, qa in self.qa_pairs.items():
            if any(kw in question for kw in qa["keywords"]):
                return {"topic": topic, "answer": qa["answer"], "follow_up": qa["follow_up"]}
        return {"topic": "unknown", "answer": "抱歉,我无法回答这个问题,请到导诊台咨询。", "follow_up": None}

qa = MedicalKnowledgeQA()
print("医学知识问答")
print("=" * 55)

questions = ["怎么挂号?","药房在哪里?","抽血在几楼?","怎么缴费?","WiFi密码是什么?","停车场在哪里?"]
for q in questions:
    result = qa.answer(q)
    print(f"\n❓ {q}")
    print(f"   💡 {result['answer']}")
    if result["follow_up"]:
        print(f"   🤔 {result['follow_up']}")

print("\n✅ 知识问答验证通过")
✅ 验证通过 医学知识问答 ======================================================= ❓ 怎么挂号? 💡 挂号请前往1楼大厅挂号窗口,或使用自助挂号机。您也可以通过手机APP预约挂号。 🤔 需要我带您去挂号窗口吗? ❓ 药房在哪里? 💡 取药请前往1楼药房,请携带好您的处方单和就诊卡。 🤔 需要我带您去药房吗? ❓ 抽血在几楼? 💡 检查地点:抽血在2F检验科,B超在3F影像科,CT在3F放射科。请先到对应科室前台登记。 🤔 您需要做哪项检查? ❓ 怎么缴费? 💡 缴费可在各楼层自助缴费机完成,也可到1楼收费窗口。支持医保卡和移动支付。 🤔 需要我带您去最近的缴费机吗? ❓ WiFi密码是什么? 💡 医院免费WiFi: Hospital-Guest,密码: 12345678。连接后需在浏览器确认。 ❓ 停车场在哪里? 💡 抱歉,我无法回答这个问题,请到导诊台咨询。 ✅ 知识问答验证通过

📌 医院感染控制

医院场景的特殊要求——感染控制是安全红线:

class HospitalInfectionControl:
    """医院感染控制"""
    def __init__(self):
        self.zones = {
            "普通区域": {"disinfection": "daily", "mask": False, "gloves": False},
            "门诊区域": {"disinfection": "every_4h", "mask": True, "gloves": False},
            "病房区域": {"disinfection": "every_2h", "mask": True, "gloves": True},
            "发热门诊": {"disinfection": "after_each", "mask": True, "gloves": True, "gown": True},
            "ICU": {"disinfection": "after_each", "mask": True, "gloves": True, "gown": True, "face_shield": True},
        }
        self.disinfection_log = []
        self.robot_zones = {}

    def enter_zone(self, robot_id, zone):
        """进入区域前检查"""
        rules = self.zones.get(zone, self.zones["普通区域"])
        self.robot_zones[robot_id] = zone
        
        requirements = []
        if rules.get("mask"): requirements.append("佩戴N95口罩")
        if rules.get("gloves"): requirements.append("佩戴手套")
        if rules.get("gown"): requirements.append("穿防护服")
        if rules.get("face_shield"): requirements.append("佩戴面罩")
        
        return {"zone": zone, "requirements": requirements, "disinfection": rules["disinfection"]}

    def leave_zone(self, robot_id):
        """离开区域后消毒"""
        zone = self.robot_zones.get(robot_id, "未知")
        self.disinfection_log.append({"robot": robot_id, "from_zone": zone, "action": "紫外线+酒精消毒"})
        return {"action": "消毒完成", "zone": zone}

    def check_disinfection_schedule(self):
        """检查消毒计划"""
        schedule = []
        for zone, rules in self.zones.items():
            schedule.append({"zone": zone, "frequency": rules["disinfection"]})
        return schedule

ic = HospitalInfectionControl()
print("医院感染控制")
print("=" * 55)

# 模拟机器人进入不同区域
movements = [("R01","门诊区域"), ("R01","病房区域"), ("R02","发热门诊"), ("R01","普通区域")]
for rid, zone in movements:
    result = ic.enter_zone(rid, zone)
    reqs = ", ".join(result["requirements"]) if result["requirements"] else "无特殊要求"
    print(f"\n  {rid}进入{zone}: {reqs}")

ic.leave_zone("R01")
ic.leave_zone("R02")

print(f"\n消毒记录: {len(ic.disinfection_log)}条")
for log in ic.disinfection_log:
    print(f"  {log['robot']}: 从{log['from_zone']}离开 → {log['action']}")

schedule = ic.check_disinfection_schedule()
print("\n消毒计划:")
for s in schedule:
    print(f"  {s['zone']}: {s['frequency']}")

print("\n✅ 感染控制验证通过")
✅ 验证通过 医院感染控制 ======================================================= R01进入门诊区域: 佩戴N95口罩 R01进入病房区域: 佩戴N95口罩, 佩戴手套 R02进入发热门诊: 佩戴N95口罩, 佩戴手套, 穿防护服 R01进入普通区域: 无特殊要求 消毒记录: 2条 R01: 从普通区域离开 → 紫外线+酒精消毒 R02: 从发热门诊离开 → 紫外线+酒精消毒 消毒计划: 普通区域: daily 门诊区域: every_4h 病房区域: every_2h 发热门诊: after_each ICU: after_each ✅ 感染控制验证通过

📌 医院场景特殊要求

⚠️ 医院特殊要求

要求描述实现
感染控制区域分级消毒紫外线+酒精自动消毒
隐私保护患者信息保密本地处理+脱敏
安静要求降低噪音低速+低音量模式
急诊优先急诊患者优先症状关键词检测
医患关系语气温和专业语音+耐心态度

📌 练习

📝 练习 1

实现多轮问诊:通过追问细化症状描述(如'腹痛是哪个位置?持续多久?'),提高分诊准确率。

📝 练习 2

设计特殊人群模式:老人模式(放大字体+慢语速)、儿童模式(卡通形象+趣味引导)。

📝 练习 3

实现就诊流程全引导:挂号→候诊→就诊→检查→取药→离院,全程陪伴引导。

📌 成就

🏆 本课成就

◀ 上一课 📚 目录 下一课 ▶