# 医疗问诊语音转结构化数据 + 自动填表单 Demo ## 项目简介 这是一个完整的医疗问诊场景Demo,实现了以下功能流程: **语音转文字(ASR)** → **大模型提取结构化信息(LangChain4j + 通义千问)** → **浏览器自动填表单(Playwright)** ## 技术栈 - **后端框架**:Spring Boot 3.2.0 - **大模型集成**:LangChain4j 0.32.0 + 通义千问(qwen-plus) - **浏览器自动化**:Playwright 1.40.0 - **前端模板**:Thymeleaf - **工具库**:Hutool、Lombok ## 项目结构 ``` playwright_demo/ ├── pom.xml # Maven配置文件 ├── README.md # 项目说明文档 └── src/main/ ├── java/com/emoon/medical/ │ ├── MedicalFormApplication.java # Spring Boot启动类 │ ├── config/ │ │ └── LangChainConfig.java # LangChain4j配置 │ ├── entity/ │ │ └── PatientMedicalInfo.java # 医疗信息实体类 │ ├── controller/ │ │ ├── MedicalInfoController.java # 医疗信息接口 │ │ └── FormAutoFillController.java # 自动填表单接口 │ └── service/ │ ├── MedicalInfoExtractService.java # 大模型提取服务 │ └── PlaywrightFormFiller.java # Playwright自动填写服务 └── resources/ ├── application.yml # 主配置文件 ├── application-dev.yml # 开发环境配置示例 └── templates/ └── medical-form.html # 医疗问诊表单页面 ``` ## 快速开始 ### 前置要求 1. **JDK 17 或更高版本** 2. **Maven 3.6+** 3. **通义千问API Key**(需要在阿里云百炼平台申请) ### 步骤1:配置通义千问API Key 编辑 `src/main/resources/application.yml` 文件,将你的API Key填入: ```yaml dashscope: api-key: sk-your-real-api-key-here # 替换为你的真实API Key model: qwen-plus ``` 或者复制 `application-dev.yml` 为 `application-local.yml` 并在其中配置: ```bash cp src/main/resources/application-dev.yml src/main/resources/application-local.yml ``` 然后修改启动参数使用本地配置: ```bash java -jar medical-form-demo.jar --spring.profiles.active=local ``` ### 步骤2:安装依赖并启动项目 ```bash # 安装Maven依赖(首次运行需要下载Playwright浏览器驱动) mvn clean install # 启动项目 mvn spring-boot:run ``` 或者打包后运行: ```bash mvn clean package java -jar target/medical-form-demo-1.0.0.jar ``` ### 步骤3:访问应用 启动成功后,在浏览器中访问: ``` http://localhost:8080/ ``` ## 功能演示 ### 1. 查看医疗问诊表单 访问首页,可以看到完整的医疗问诊表单,包括: - 患者基本信息(姓名、年龄、性别、电话) - 医疗核心信息(主诉、现病史、既往史、过敏史) - 伴随症状(多选框) - 就诊类型(下拉菜单) ### 2. 前端自动填写演示 点击表单中的 **"演示自动填写"** 按钮,会调用后端示例数据接口,展示自动填写效果。 ### 3. 大模型提取医疗信息 使用以下API调用大模型从对话中提取结构化信息: **POST方式:** ```bash curl -X POST http://localhost:8080/api/extract \ -H "Content-Type: application/json" \ -d '医生:您好,请先报一下您的姓名、年龄和联系电话。 患者:我叫张三,今年35岁,电话是13800138000,男性。 医生:您今天来是因为什么不舒服呀? 患者:我咳嗽、发烧已经3天了。' ``` **GET方式(便于测试):** ```bash curl "http://localhost:8080/api/extract?dialogue=医生您好患者我叫张三今年35岁" ``` ### 4. 完整自动填表单流程(核心功能) **方式1:使用示例对话** 在浏览器中访问: ``` http://localhost:8080/api/auto-fill/demo ``` 此时会: 1. 调用大模型提取示例对话中的医疗信息 2. 自动打开浏览器窗口 3. 逐步填写表单(每个字段间隔1秒,便于观察) 4. 停留5秒后自动关闭 **方式2:使用自定义对话** ```bash curl -X POST http://localhost:8080/api/auto-fill \ -H "Content-Type: application/json" \ -d '{ "dialogue": "医生:您好... 患者:...", "formUrl": "http://localhost:8080/" }' ``` ## 测试对话示例 ### 示例1:完整问诊对话 ``` 医生:您好,请先报一下您的姓名、年龄和联系电话。 患者:我叫张三,今年35岁,电话是13800138000,男性。 医生:您今天来是因为什么不舒服呀? 患者:我咳嗽、发烧已经3天了,还伴有咽痛,这几天一直没好转。 医生:您详细说一下发病过程。 患者:3天前受凉后开始发烧,体温最高38.9℃,随后出现干咳,第二天开始有少量白痰,咽痛明显,吞咽时加重,昨天在家吃了布洛芬,体温暂时下降,但反复升高,没有去医院看过。 医生:您以前有没有什么基础疾病? 患者:我有高血压病史5年了,一直在吃硝苯地平,没有手术史,对青霉素过敏。 医生:好的,您这次是来门诊就诊对吧? 患者:是的,门诊。 ``` ### 预期输出JSON ```json { "patientName": "张三", "patientAge": 35, "patientGender": "男", "patientPhone": "13800138000", "chiefComplaint": "咳嗽、发烧伴咽痛3天,症状无好转", "presentIllness": "3天前受凉后出现发烧(最高38.9℃),随后干咳,次日出现少量白痰,咽痛明显、吞咽时加重;自行服用布洛芬后体温暂时下降但反复升高,未到医院诊疗", "pastHistory": "高血压病史5年,长期服用硝苯地平,无手术史", "allergyHistory": "对青霉素过敏", "symptoms": ["咳嗽", "发烧", "咽痛"], "visitType": "门诊" } ``` ## 配置说明 ### application.yml 核心配置 ```yaml # 服务端口 server: port: 8080 # 通义千问配置 dashscope: api-key: your-dashscope-api-key # 必填 model: qwen-plus # 可选:qwen-turbo、qwen-max、qwen-medical # Playwright配置 playwright: headless: false # 是否无头模式(false=显示浏览器,true=后台运行) slow-mo: 1000 # 操作间隔(毫秒),便于观察自动填写过程 ``` ## 常见问题 ### 1. 大模型调用失败 **错误提示**:`提取失败:...` **解决方法**: - 检查API Key是否正确配置 - 确认API Key有足够的额度 - 查看网络是否能够访问通义千问API ### 2. Playwright浏览器驱动下载失败 **错误提示**:`Executables not found` **解决方法**: ```bash # 手动安装Playwright浏览器 mvn exec:java -e -D exec.mainClass="com.microsoft.playwright.CLI" -D exec.args="install" ``` ### 3. 表单元素定位失败 **错误提示**:`TimeoutError: locator.click: Timeout` **解决方法**: - 确认表单页面已正确加载 - 检查CSS选择器是否正确 - 增加等待时间(修改 `slow-mo` 配置) ## 技术要点说明 ### 1. 大模型提示词设计 在 `MedicalInfoExtractService.java` 中,使用了结构化提示词: - 明确指定JSON格式模板 - 要求字段类型(字符串/整数/数组) - 说明字段的可选值(如性别、就诊类型) - 要求不输出额外说明文字 ### 2. 浏览器自动化策略 在 `PlaywrightFormFiller.java` 中: - 使用 `setSlowMo()` 设置操作间隔,便于观察 - 使用 `waitForLoadState()` 等待页面加载完成 - 每个表单元素都有独立的定位逻辑 - 添加了详细的日志输出,便于调试 ### 3. 数据流转流程 ``` 对话文本 → 大模型提取 → JSON对象 → Playwright → 浏览器DOM → 表单填写 ``` ## 生产环境优化建议 1. **安全性** - 添加API密钥加密存储 - 增加接口鉴权机制 - 添加访问频率限制 2. **性能优化** - 大模型调用结果缓存 - 并发处理多个表单 - 使用连接池管理浏览器实例 3. **可靠性** - 增加重试机制(大模型调用、表单定位) - 添加数据格式校验 - 完善异常处理和日志记录 4. **功能扩展** - 支持更复杂的表单类型(日期选择、文件上传等) - 支持多种表单系统(不限于Web) - 集成真实的语音识别服务 ## 许可证 MIT License ## 联系方式 如有问题,请提交Issue或联系开发团队。