当前位置: 首页 > news >正文

Rasa 模拟实现超简易医生助手(适合初学练手)

下面是一个纯 Rasa 实现的医生助手第一版项目文件内容,具备基本的“多轮问诊”流程逻辑,通过 slot 存储用户的多个症状,在最后阶段给出“模拟的诊断建议”。

PS:完成这个之后,下一步我还想在Rasa工作过程中引入大模型辅助完成对话流程。


📁 项目结构与文件内容

actions/actions.py

from typing import Any, Text, Dict, List
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.events import SlotSet

class ActionAskMoreSymptoms(Action):
    def name(self) -> Text:
        return "action_ask_more_symptoms"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        # 获取本轮对话中所有识别到的 symptom 实体
        new_symptoms = tracker.get_slot("new_symptom") or []

        # 获取历史症状
        collected_symptoms = tracker.get_slot("collected_symptoms") or []

        if new_symptoms:
            # 将当前轮症状添加到历史症状列表中
            collected_symptoms.extend(new_symptoms)
            dispatcher.utter_message(text=f"已记录你的症状:{', '.join(new_symptoms)}。")
        else:
            dispatcher.utter_message(text="我没有识别到具体症状,请再描述一下。")
        dispatcher.utter_message(text=f"目前已记录症状:{', '.join(collected_symptoms)}。还有其他不适吗?")
        # 更新槽位
        return [
            
            SlotSet("collected_symptoms", collected_symptoms)
        ]


class ActionSimulateDiagnosis(Action):
    def name(self) -> Text:
        return "action_simulate_diagnosis"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

        symptoms = tracker.get_slot("collected_symptoms") or []
        if not symptoms:
            dispatcher.utter_message(text="我目前没有记录到任何症状。")
        else:
            symptom_list = ", ".join(symptoms)
            dispatcher.utter_message(text=f"根据你提供的症状:{symptom_list},建议进一步检查。可能为常见疾病,请就医确认。")

        return []


data/nlu.yml

version: "3.1"

nlu:

- intent: greet
  examples: |
    - 你好
    - 嗨

- intent: report_symptom
  examples: |
    - 我有点[头疼](symptom)
    - [胸闷](symptom)
    - 最近[恶心](symptom)
    - [口干](symptom)
    - [胸口发闷](symptom)
    - [头疼](symptom)
    - [喉咙痛](symptom)
    - [发烧](symptom)
    - [肚子疼](symptom)
    - [胸口闷](symptom)
    - [咳嗽](symptom)
    - 感觉[恶心](symptom)
    - 有点[鼻塞](symptom)

- intent: deny
  examples: |
    - 没有了
    - 没有其他不适
    - 没事了
    - 没有



data/rules.yml

version: "3.1"

rules:
- rule: 启动问诊
  steps:
  - intent: greet
  - action: utter_greet

- rule: 用户说出症状后继续追问
  steps:
    - intent: report_symptom
    - action: utter_ack_symptom
    - action: action_ask_more_symptoms

- rule: 用户否认后进入诊断
  steps:
    - intent: deny
    - action: action_simulate_diagnosis

data/stories.yml

version: "3.1"

stories:
- story: 多轮问诊并诊断
  steps:
    - intent: report_symptom
    - action: utter_ack_symptom
    - action: action_ask_more_symptoms
    - intent: report_symptom
    - action: utter_ack_symptom
    - action: action_ask_more_symptoms
    - intent: deny
    - action: action_simulate_diagnosis

tests/test_stories.yml

version: "3.1"

stories:
- story: 测试完整问诊流程
  steps:
    - user: |
        我头疼
      intent: report_symptom
    - action: utter_ack_symptom
    - action: action_ask_more_symptoms
    - user: |
        还有点咳嗽
      intent: report_symptom
    - action: utter_ack_symptom
    - action: action_ask_more_symptoms
    - user: |
        没有了
      intent: deny
    - action: action_simulate_diagnosis

config.yml


recipe: default.v1


assistant_id: 20250412-010713-concrete-weapon

language: zh

pipeline: 
  - name: JiebaTokenizer
  - name: RegexFeaturizer
  - name: LexicalSyntacticFeaturizer
  - name: CountVectorsFeaturizer
  - name: DIETClassifier
    epochs: 100
  - name: EntitySynonymMapper
  - name: FallbackClassifier
    threshold: 0.4
    ambiguity_threshold: 0.1

policies: 
  - name: RulePolicy
  - name: UnexpecTEDIntentPolicy    # 辅助检测用户意图偏差
    max_history: 5
    epochs: 100


credentials.yml

rest:

domain.yml

version: "3.1"

intents:
  - greet
  - report_symptom
  - deny

slots:

  new_symptom:
    type: list
    initial_value: []
    influence_conversation: false
    mappings:
      - type: from_entity
        entity: symptom

  collected_symptoms:
    type: any
    initial_value: []
    influence_conversation: false
    mappings: []  # 添加一个空的 mappings 配置



entities:
  - symptom

actions:
  - utter_greet
  - action_ask_more_symptoms
  - action_simulate_diagnosis

responses:
  utter_greet:
    - text: "你好,我是医生助手,请描述你的症状。"
  utter_ack_symptom:
    - text: 已记录你的症状。

endpoints.yml

action_endpoint:
  #url: "http://localhost:5055/webhook"
  #action_server是之后运行action的docker容器名字
  url: "http://action_server:5055/webhook"

✅ 启动流程简要说明

1. 训练模型:
docker run -u $(id -u):$(id -g) -v $(pwd):/app rasa/rasa:3.6.21-full train
2. 创建一个 bridge 网络
docker network create rasa-net

然后用这个网络跑两个容器:

3.启动 action server 服务器(一个终端)
docker run --rm -u $(id -u):$(id -g) --network rasa-net -v $(pwd):/app -p 5055:5055 --name action_server rasa/rasa:3.6.21-full run actions
#--name action_server注意这里设置的容器名需要和action_endpoint里的设置匹配
4.启动对话测试 rasa shell(另一个终端)
docker run --rm -it -u $(id -u):$(id -g) --network rasa-net -v $(pwd):/app rasa/rasa:3.6.21-full shell

这样两个容器在同一个网络里,localhost:5055 就能通了。


博主私人备注:

用于检测nul

docker run --rm -it -u $(id -u):$(id -g) --network rasa-net -v $(pwd):/app rasa/rasa:3.6.21-full shell nlu

相关文章:

  • Tkinter表格与列表框应用
  • 制作像素风《饥荒》类游戏的整体蓝图和流程
  • ubuntu 2404 安装 vcs 2018
  • Doris 安装部署、实际应用及优化实践:对比 ClickHouse 的深度解析
  • 从零搭建高可用Kafka集群与EFAK监控平台:全流程实战总结
  • Foxmail邮件客户端跨站脚本攻击漏洞(CNVD-2025-06036)技术分析
  • Go:基本数据
  • leetcode 139. Word Break
  • < 自用文 Project-30.6 Crawl4AI > 为AI模型优化的网络爬虫工具 帮助收集和处理网络数据的工具
  • Java中的数组
  • 苍穹外卖Day-5
  • c# 新建不重名的唯一文件夹
  • STM32 HAL库时钟系统详解
  • AndroidTV 当贝播放器-v1.5.2-官方简洁无广告版
  • SAP-ABAP:BAPI_ACC_DOCUMENT_POST 详解(总账、应收账款、应付账款等业务场景的自动化集成)
  • Android 存储路径
  • 大模型学习八:‌Sealos 私有化部署之VMware 安装ubuntu22.04 虚拟机安装(实操)
  • 【产品】ToB产品需求分析
  • 【Java SE】泛型详解
  • GAT-GRAPH ATTENTION NETWORKS(论文笔记)
  • 《求是》杂志发表习近平总书记重要文章《激励新时代青年在中国式现代化建设中挺膺担当》
  • 2025年“投资新余•上海行”钢铁产业“双招双引”推介会成功举行
  • 顺利撤离空间站,神十九乘组踏上回家之旅
  • 浙商银行外部监事高强无法履职:已被查,曾任建行浙江省分行行长
  • 人社部:一季度全国城镇新增就业308万人,同比增加5万人
  • 黄晓丹:用“诗心”找到生存的意义