快速入门 - Spring AI Alibaba 医疗信息系统集成实战教程
·
Spring AI Alibaba 医疗信息系统集成实战教程
项目地址:https://github.com/crablduck/springbootAI-alibaba-learn
技术栈:Spring Boot 3.2.0 + Spring AI 1.0.0-M1 + 通义千问
项目名称:spring-ai-his-demo
第一章:快速入门
1.1 项目结构
spring-ai-his-demo/
├── src/main/java/com/etong/ai/his/
│ ├── HisAiApplication.java # 启动类
│ ├── config/
│ │ └── ChatConfig.java # ChatClient配置
│ ├── controller/
│ │ └── HisAiController.java # REST控制器
│ ├── service/
│ │ └── AiService.java # 业务逻辑
│ └── model/
│ ├── DiagnosisRequest.java # 请求模型
│ └── AiResponse.java # 响应模型
├── src/main/resources/
│ ├── application.yml # 配置文件
│ └── prompts/
│ └── his_qa_prompt.yaml # 提示词模板
└── pom.xml # Maven配置
1.2 Maven 依赖配置
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<groupId>com.etong.ai</groupId>
<artifactId>spring-ai-his-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<spring-ai.version>1.0.0-M1</spring-ai.version>
</properties>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI Core -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- Spring AI OpenAI (通义千问兼容) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Actuator 监控 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<!-- Spring Milestone仓库 -->
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.3 配置文件
src/main/resources/application.yml
server:
port: 8080
spring:
application:
name: spring-ai-his-demo
ai:
openai:
api-key: ${DASHSCOPE_API_KEY} # 通义千问API Key
base-url: https://dashscope.aliyuncs.com/compatible-mode
chat:
options:
model: qwen-turbo
temperature: 0.7
max-tokens: 1000
# 日志配置
logging:
level:
com.etong.ai.his: DEBUG
org.springframework.ai: DEBUG
file:
name: logs/spring-ai-his-demo.log
# 监控配置
management:
endpoints:
web:
exposure:
include: health,info,metrics
1.4 核心代码
启动类
HisAiApplication.java
package com.etong.ai.his;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@SpringBootApplication
public class HisAiApplication {
public static void main(String[] args) {
log.info("正在启动Spring AI HIS系统...");
SpringApplication.run(HisAiApplication.class, args);
log.info("系统启动完成");
}
}
配置类
ChatConfig.java
package com.etong.ai.his.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatConfig {
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder.build();
}
}
数据模型
DiagnosisRequest.java
package com.etong.ai.his.model;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
@Data
public class DiagnosisRequest {
@Length(min = 1, message = "症状描述不能为空")
private String symptom;
private String patientId;
private String age;
private String gender;
private String medicalHistory;
}
AiResponse.java
package com.etong.ai.his.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AiResponse {
private String result;
private boolean success;
private String message;
private long timestamp;
public AiResponse(String result, boolean success, String message) {
this.result = result;
this.success = success;
this.message = message;
this.timestamp = System.currentTimeMillis();
}
}
控制器层
HisAiController.java
package com.etong.ai.his.controller;
import com.etong.ai.his.service.AiService;
import com.etong.ai.his.model.DiagnosisRequest;
import com.etong.ai.his.model.AiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
@Slf4j
public class HisAiController {
@Autowired
private AiService aiService;
/**
* 诊断建议
*/
@PostMapping("/diagnosis")
public ResponseEntity<AiResponse> askDiagnosis(@RequestBody DiagnosisRequest request) {
log.info("收到诊断请求: {}", request.getSymptom());
try {
String result = aiService.askDiagnosis(request.getSymptom());
return ResponseEntity.ok(new AiResponse(result, true, "诊断成功"));
} catch (Exception e) {
log.error("诊断失败", e);
return ResponseEntity.internalServerError()
.body(new AiResponse(null, false, "诊断失败: " + e.getMessage()));
}
}
/**
* 病历摘要
*/
@PostMapping("/summarize")
public ResponseEntity<AiResponse> summarizeMedicalRecord(@RequestBody DiagnosisRequest request) {
log.info("收到病历摘要请求");
try {
String result = aiService.summarizeMedicalRecord(request.getSymptom());
return ResponseEntity.ok(new AiResponse(result, true, "摘要生成成功"));
} catch (Exception e) {
log.error("摘要生成失败", e);
return ResponseEntity.internalServerError()
.body(new AiResponse(null, false, "摘要失败: " + e.getMessage()));
}
}
/**
* 健康咨询
*/
@PostMapping("/consultation")
public ResponseEntity<AiResponse> healthConsultation(@RequestBody DiagnosisRequest request) {
log.info("收到健康咨询: {}", request.getSymptom());
try {
String result = aiService.healthConsultation(request.getSymptom());
return ResponseEntity.ok(new AiResponse(result, true, "咨询完成"));
} catch (Exception e) {
log.error("咨询失败", e);
return ResponseEntity.internalServerError()
.body(new AiResponse(null, false, "咨询失败: " + e.getMessage()));
}
}
/**
* 健康检查
*/
@GetMapping("/health")
public ResponseEntity<String> health() {
return ResponseEntity.ok("系统运行正常");
}
}
业务逻辑层
AiService.java
package com.etong.ai.his.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class AiService {
@Autowired
private ChatClient chatClient;
/**
* 诊断建议
*/
public String askDiagnosis(String symptom) {
log.info("开始诊断,症状: {}", symptom);
try {
String prompt = buildDiagnosisPrompt(symptom);
log.debug("提示词: {}", prompt);
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
log.info("诊断完成");
return response;
} catch (Exception e) {
log.error("AI调用失败", e);
throw new RuntimeException("AI服务暂时不可用", e);
}
}
/**
* 病历摘要
*/
public String summarizeMedicalRecord(String medicalRecord) {
log.info("开始生成病历摘要");
try {
String prompt = buildSummaryPrompt(medicalRecord);
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
log.info("摘要生成完成");
return response;
} catch (Exception e) {
log.error("AI调用失败", e);
throw new RuntimeException("摘要服务暂时不可用", e);
}
}
/**
* 健康咨询
*/
public String healthConsultation(String question) {
log.info("健康咨询: {}", question);
try {
String prompt = buildHealthPrompt(question);
String response = chatClient.prompt()
.user(prompt)
.call()
.content();
log.info("咨询完成");
return response;
} catch (Exception e) {
log.error("AI调用失败", e);
throw new RuntimeException("咨询服务暂时不可用", e);
}
}
/**
* 构建诊断提示词
*/
private String buildDiagnosisPrompt(String symptom) {
return String.format("""
你是医院问诊助手,根据症状给出初步诊断建议。
患者症状:%s
请分析:
1. 可能的疾病
2. 建议检查项目
3. 临时缓解措施
4. 何时需立即就医
注意:
- 这是初步建议,不能替代医生诊断
- 症状严重请及时就医
- 回答要专业、清晰、易懂
用中文回答。
""", symptom);
}
/**
* 构建病历摘要提示词
*/
private String buildSummaryPrompt(String medicalRecord) {
return String.format("""
你是医疗信息专家,请生成结构化病历摘要。
病历内容:%s
按以下格式整理:
## 患者基本信息
## 主诉
## 现病史
## 既往史
## 检查结果
## 诊断
## 治疗方案
## 注意事项
要求简洁、准确、重点突出。
""", medicalRecord);
}
/**
* 构建健康咨询提示词
*/
private String buildHealthPrompt(String question) {
return String.format("""
你是健康顾问,请回答健康咨询问题。
问题:%s
回答原则:
1. 基于医学知识
2. 语言通俗易懂
3. 强调重要建议
4. 必要时建议就医
5. 不提供药物剂量
用中文回答。
""", question);
}
}
1.5 运行测试
启动应用
# 设置API Key环境变量
export DASHSCOPE_API_KEY=sk-your-api-key
# 启动应用
mvn spring-boot:run
测试接口
1. 诊断建议
curl -X POST http://localhost:8080/api/ai/diagnosis \
-H "Content-Type: application/json" \
-d '{
"symptom": "头痛伴发热,体温38.5度,已持续2天"
}'
响应示例:
{
"result": "根据您描述的症状...",
"success": true,
"message": "诊断成功",
"timestamp": 1704067200000
}
2. 病历摘要
curl -X POST http://localhost:8080/api/ai/summarize \
-H "Content-Type: application/json" \
-d '{
"symptom": "患者张三,男,45岁。主诉:胸痛3小时..."
}'
3. 健康咨询
curl -X POST http://localhost:8080/api/ai/consultation \
-H "Content-Type: application/json" \
-d '{
"symptom": "如何预防感冒?"
}'
4. 健康检查
curl http://localhost:8080/api/ai/health
1.6 提示词模板(可选)
src/main/resources/prompts/his_qa_prompt.yaml
template: |
你是医院问诊助手,根据症状给出初步诊断建议。
患者症状:{symptom}
请分析:
1. 可能的疾病
2. 建议检查项目
3. 临时缓解措施
4. 何时需立即就医
注意事项:
- 这是初步建议,不能替代医生诊断
- 症状严重请及时就医
- 回答要专业、清晰、易懂
input-variables:
- symptom
metadata:
version: "1.0"
department: "general"
1.7 关键要点
框架核心
- Spring AI 提供统一的 AI 模型接入抽象
- 通义千问通过 OpenAI 兼容层接入
- ChatClient 封装所有模型交互细节
项目特点
- 清晰的分层架构:Controller → Service → AI Model
- 统一的异常处理和响应格式
- 完整的日志记录便于调试
提示词工程
- 明确 AI 角色定位(医院助手)
- 结构化输出要求(分点分析)
- 责任声明(初步建议,非医生诊断)
1.8 练习任务
- 添加多轮对话:实现会话记忆,支持上下文对话
- 专科诊断:为不同科室设计专门的提示词模板
- 监控指标:统计 API 调用次数、响应时间、成功率
作者:在路上的蟹老板
项目地址:spring-ai-his-demo
版本:v1.0.0
更多推荐


所有评论(0)