Skip to content

面试官:你说你参与了“AI症状检查”功能的开发,能系统地讲讲这个模块的整体设计吗?

面试者: 当然可以。

“AI症状检查”是我们医疗平台中一个面向用户的智能健康导诊功能。它的核心目标是: 帮助用户在未就医前,通过输入自身症状,获得初步的疾病可能性分析、就医建议和健康指导,从而减少盲目挂号、提升就医效率。

但我们也非常清楚:

AI不能替代医生,只能作为辅助工具。 所以整个设计从一开始,就围绕“智能、安全、可控、可解释”四个原则展开。


一、整体业务流程设计

整个功能的用户旅程如下:

  1. 用户输入症状 支持三种方式:

    • 自由文字输入(如“我头疼三天了,还发烧”)
    • 语音输入(调用讯飞语音识别转文字)
    • 预设症状选择(点击“头痛”、“咳嗽”等常见症状)
  2. 系统初步分析 后端接收输入后,进行文本清洗、关键词提取,结合用户的年龄、性别、既往病史等基础信息,生成一个“初步症状画像”。

  3. AI交互式问诊 系统不会一次性给出结论,而是像医生一样,主动追问关键问题,比如:

    • “头痛是持续性的还是阵发性的?”
    • “有没有恶心、呕吐或视力模糊?”
    • “最近有没有受过外伤?”

    通过2~3轮交互,逐步缩小可能的疾病范围。

  4. 生成最终建议 在信息相对完整后,系统输出:

    • 可能的疾病方向(如“偏头痛可能性较大”、“上呼吸道感染待排查”)
    • 建议就诊科室(如“神经内科”、“呼吸内科”)
    • 紧急程度提示(普通 / 建议尽快就诊 / 立即就医)
    • 健康指导(如“多休息、避免劳累”)
    • 明确免责声明:“本建议仅供参考,不能替代专业医疗诊断”
  5. 引导下一步动作 用户可选择:

    • 查看详细解释
    • 直接跳转“在线挂号”
    • 分享结果给家人

二、后端核心架构设计(Java视角)

作为Java开发工程师,我主要负责整个后端的流程编排、AI集成、状态管理、安全控制和系统稳定性保障

1. 多模态输入统一处理

前端传来的无论是文字、语音转文字,还是预设症状,后端都会统一归一化为“症状关键词集合”。 例如:“头好晕” → 标准化为“头晕”;“发烧”和“发热”视为同义词。 这个过程依赖一个可配置的医疗同义词词典,由产品和医学团队维护,后端通过配置中心动态加载。

2. AI分析流程的结构化控制

我们没有让AI“自由发挥”,而是设计了一个结构化推理流程

  • 第一步:角色定制(Role Prompting) 我们给大模型设定明确身份:“你是一名三甲医院全科医生,擅长初步筛查和分诊”。 并严格规定输出格式,确保返回的是结构化数据,而不是一段自由文本。
  • 第二步:检索增强(RAG) AI的“知识”不是靠记忆,而是靠实时检索。 我们接入了一个医学知识库,包含《常见病诊疗指南》《症状鉴别诊断手册》等权威资料。 当用户输入“头痛+恶心”时,系统会先从知识库中检索“偏头痛”“颅内压增高”等条目,作为AI推理的依据,避免“幻觉”。
  • 第三步:函数调用(Function Calling) AI不仅能“说”,还能“做”。 例如,当AI判断需要查看用户过往的血压记录时,它可以“调用”一个内部接口,获取历史数据,再结合新症状做判断。 这种能力让AI从“聊天机器人”升级为“智能协作者”。
  • 第四步:多轮交互控制(MCP) 我们设计了一个会话状态机,管理用户的问诊进度:
    • 初始状态:收集主诉
    • 第一轮追问:症状特征(持续时间、加重因素)
    • 第二轮追问:伴随症状
    • 最终状态:生成建议 每一步都可中断、可回退,确保流程可控。
  • 第五步:Agent式整合 最终,我们将以上能力整合为一个“AI诊疗代理(Agent)”,它能自主决策: “先查知识 → 再问用户 → 调历史数据 → 更新判断 → 输出建议”,实现端到端的智能服务。

三、关键非功能性设计

1. 性能优化:异步 + 缓存

AI分析耗时较长,不能阻塞用户。 我们采用异步处理 + WebSocket推送: 用户提交后,系统立即返回“AI分析中…”,后台通过消息队列(RabbitMQ)异步处理,完成后主动推送结果。

同时,对高频症状组合(如“感冒”“拉肚子”)的AI结果做Redis缓存,命中率超60%,显著降低响应延迟和AI调用成本。

2. 安全与合规:四重防护

医疗场景容不得半点马虎,我们做了四层保障:

  • 内容安全:输出结果过滤“推荐药物”“自行用药”等敏感词,禁止AI越界;
  • 紧急拦截:一旦用户输入“胸痛”“意识模糊”“呼吸困难”,系统直接跳过AI,弹出“建议立即就医”;
  • 免责声明:所有AI建议页面顶部有红色提示,明确告知“仅供参考”;
  • 审计留痕:所有AI调用、用户交互、结果生成均记录日志,支持追溯与复核。

3. 高可用保障:熔断 + 降级

AI服务可能因网络、负载等原因不可用。 我们引入熔断机制(Sentinel): 当AI调用失败率超过阈值,自动切换到“规则引擎兜底”。 例如:“头痛 + 发热” → 默认建议“呼吸内科”;“腹痛 + 腹泻” → 建议“消化内科”。 虽然智能程度降低,但基本功能不中断。


四、可拓展场景与未来方向

这个模块不仅仅是一个“症状自查工具”,它还可以延伸出多个高价值场景:

1. 与医生端系统打通

当用户完成AI症状检查后,生成的“主诉摘要”可直接同步到医生端电子病历系统,减少医生重复问诊时间,提升门诊效率。

2. 个性化健康档案

长期使用AI症状检查的用户,系统可自动构建“个人健康画像”,记录常见症状模式,未来可提供慢性病管理、健康预警等服务。

3. 家庭健康共享

支持用户将AI检查结果分享给家人或家庭医生,便于远程问诊或照护决策。

4. 与可穿戴设备联动

未来可接入智能手表的实时数据(如心率、血氧),让AI分析更全面,例如:“您当前心率偏高,结合胸闷症状,建议尽快就医”。

面试官:你们的AI医生对话功能依赖网络调用大模型,如果用户网络很差,页面卡住或者请求失败,这种情况你们是怎么处理的?

面试者: 这是一个非常实际的问题。在移动端或弱网环境下,网络不稳定是常态。我们从用户体验、系统稳定性和降级策略三个层面做了系统性设计。


面试官:具体是怎么保障用户体验的?

面试者: 首先,在前端交互上,我们做了友好的加载反馈机制

当用户发送问题后,即使网络慢,我们也立即给出响应:

  • 立刻显示“AI正在思考中…”的动画;
  • 如果2秒内没返回,提示“网络较慢,正在努力加载”;
  • 支持用户手动“重新生成”或“切换到文字建议”。

这样避免用户觉得“卡死了”,提升等待耐心。


面试官:那后端是怎么应对网络不稳定的?

面试者: 后端我们做了三件事:

  1. 超时控制: 调用大模型API时,设置严格的超时时间,比如连接1秒,读取3秒。 避免线程长时间阻塞,防止服务雪崩。
  2. 异步处理 + 消息队列: 用户请求进来后,我们不直接同步调AI,而是放入消息队列(如RabbitMQ),后台异步处理。 即使网络波动,请求也不会丢失,处理完后通过WebSocket推送给用户。
  3. 本地缓存兜底: 对常见症状(如“感冒”“头痛”),我们将高频AI回答缓存在Redis中。 当检测到用户网络较差时,优先尝试返回缓存结果,保证“有内容可看”。

面试官:如果AI服务本身也响应慢或不可用呢?

面试者: 这就是我们要做的熔断与降级

我们使用了Sentinel做流量控制和熔断管理:

  • 当AI服务连续调用失败超过阈值,自动触发熔断;
  • 熔断后,不再调用大模型,而是切换到“规则引擎兜底”;
  • 规则引擎基于预设逻辑返回基础建议,比如:
    • “头痛 + 发热” → 建议“呼吸内科”
    • “腹痛 + 腹泻” → 建议“消化内科”
    • 所有结果都带免责声明

虽然不如AI智能,但保证了核心功能可用,用户体验不中断。


面试官:用户已经发了消息,但中途断网了怎么办?

面试者: 我们做了对话状态持久化

每次用户发起对话,系统都会创建一个“会话ID”,所有提问和追问都绑定这个ID。

  • 如果中途断网,用户重新进入时,系统通过会话ID恢复上下文;
  • 用户可以看到“之前的对话记录”;
  • 可选择“继续等待”或“重新开始”。

这样避免用户重复描述症状,提升弱网下的使用体验。


面试官:有没有考虑离线方案?

面试者: 目前大模型还无法完全跑在手机端,但我们做了轻量级预加载

  • 在用户打开AI对话页时,预先加载一些常见问题的静态答案(如“发烧怎么处理”);
  • 这些内容打包在前端资源中,不依赖网络;
  • 当检测到离线或极慢网络时,展示这些预置内容,引导用户先看基础知识。

未来如果端侧大模型成熟,我们会探索“本地小模型+云端大模型”的混合架构。


面试官:总结一下,你是怎么看待这个问题的?

面试者: 我认为,网络差不是异常,而是常态。 特别是在医疗场景下,用户可能在地铁、山区、医院地下室使用,网络条件复杂。

所以我们不能假设“网络永远通畅”,而要设计一个弹性、可靠、有退路的系统

  • 快的时候,用AI提供智能服务;
  • 慢的时候,用缓存和异步保体验;
  • 断的时候,用降级和持久化保功能。

这才是一个真正可用的AI医疗产品。

面试官:你们的AI医生对话最后能直接预约医生,这个“预约”功能是怎么实现的?涉及哪些系统?

面试者: 是的,这是我们设计的关键转化路径

用户输入症状 → AI分析 → 推荐医生 → 一键预约 → 完成挂号

“预约”不是简单的跳转链接,而是一个安全、可靠、可追溯的业务闭环。 我在后端负责整个预约流程的接口对接、状态管理、并发控制和异常处理


面试官:那用户在AI对话里点“预约”,系统是怎么处理的?

面试者

这里AI肯定不能做这些事情,这里就使用到了Function Calling

整个流程分为五步,我来一步步说明:

  1. 预约前校验 用户点击“预约”时,系统立即检查:

    • 医生号源是否可用(调用排班系统API)
    • 用户是否已实名认证(医疗合规要求)
    • 是否存在未完成的预约(防重复提交)

    任一校验失败,立即提示用户,避免后续失败。

  2. 锁定号源(预占) 如果校验通过,系统会向医院的预约挂号系统发起“号源预占”请求:

    • 锁定该时段的号源,防止被他人抢走;
    • 设置预占有效期(如10分钟),超时自动释放。
  3. 生成预约订单 在我们平台创建一条“预约订单”,状态为“待支付”或“待确认”,包含:

    • 用户信息
    • 医生ID、科室、就诊时间
    • 来源标记:“来自AI对话推荐”
  4. 引导完成支付/确认 跳转到支付页或医院官方确认页,用户完成支付或确认后,状态更新为“已预约”。

  5. 通知与提醒 预约成功后:

    • 发送站内信、短信、微信模板消息;
    • 自动加入用户“我的就诊”列表;
    • 支持添加日历提醒。

面试官:如果多个用户同时抢一个号,会不会超卖?

面试者: 这是个非常关键的问题,我们通过分布式锁 + 数据库乐观锁双重机制防止超卖。

  1. 分布式锁(Redis) 每次预约请求进来,先尝试获取该“医生+时段”的Redis锁:

    SETNX appointment_lock:doctor_1001:2025-04-05-14-00 true EX 5

    只有拿到锁的请求才能继续,其他请求排队或返回“号源紧张”。

  2. 数据库乐观锁 在更新号源表时,使用版本号控制:

    UPDATE doctor_schedule 
    SET available_count = available_count - 1, version = version + 1
    WHERE id = ? AND available_count > 0 AND version = ?

    如果更新影响行数为0,说明已被他人占用,本次预约失败。

  3. 最终一致性 所有操作通过本地事务 + 消息队列保证最终一致:

    • 预约成功 → 发消息 → 同步到HIS系统(医院管理信息系统)、发送通知;
    • 失败 → 记录日志 → 支持人工对账。

面试官:如果医院系统挂了,预约失败了怎么办?

面试者: 我们设计了熔断 + 降级 + 补偿机制来应对依赖系统故障。

  1. 熔断机制 使用Sentinel监控医院挂号接口的失败率,超过阈值自动熔断,暂停预约功能,避免雪崩。
  2. 降级策略 熔断后,前端提示:“当前医院系统繁忙,建议稍后通过医院官方渠道挂号”,并提供医院官网或电话。
  3. 补偿任务 所有失败的预约请求进入“重试队列”,后台定时重试(最多3次),成功后通知用户。
  4. 人工对账 每天定时跑批,对比我们系统的预约记录和医院HIS系统的实际挂号数据,发现不一致时告警处理。

面试官:预约信息怎么和医院系统同步?会不会对不上?

面试者: 这是医疗系统的核心合规要求,我们采用双向同步 + 唯一标识 + 审计日志保障一致性。

  1. 唯一订单号 每次预约生成全局唯一ID(如Snowflake),同时作为我们系统的订单号和医院系统的外部订单号。

  2. 状态同步 医院HIS系统会通过回调接口,主动推送预约状态变更:

    • 已确认
    • 已取消
    • 就诊完成

    我们收到后更新本地状态,保证两端一致。

  3. 审计日志 所有预约操作(创建、取消、修改)都记录完整日志,包括:

    • 操作人(用户或系统)
    • 时间戳
    • 请求/响应报文(脱敏)
    • 用于后续对账和合规审查。

面试官:用户预约后想取消,怎么处理?

面试者: 我们支持用户自助取消,但要符合医院规则。

  1. 取消规则校验 根据医院政策,判断是否可取消:
    • 一般要求提前24小时;
    • 临近就诊时间不可取消;
    • 特需门诊可能不支持取消。
  2. 释放号源 取消成功后,调用医院接口释放号源,同时更新我们系统的号源库存。
  3. 退款处理 如果已支付,触发退款流程:
    • 原路退回
    • 异步处理,通过消息队列解耦
    • 退款状态可查
  4. 记录取消原因 引导用户选择取消原因(如“时间冲突”“症状缓解”),用于分析AI推荐的合理性。