AI问诊网站设计方案
要求写一个AI问诊网站的详细方案,包括UML建模、项目文件结构、以及完整源代码。并用Markdown和Mermaid来建立文档。需要前后端分离:前端用HTML/CSS/JS,后端用Python,调用“火山引擎”的DeepSeek。但火山引擎有提供DeepSeek模型的API吗?是的,火山引擎的方舟平台提供了DeepSeek模型的API。所以将使用火山引擎DeepSeek API。
需要实现的功能:用户在前端填写表单(问诊信息),提交给后端,后端调用AI进行多轮回答(可能意味着与AI进行多轮对话以收集信息,然后生成诊断报告?),最后给出固定格式的报告打印。
用户只需要简单进行项目选择填写。这意味着前端可能是简单的表单,包含一些病症描述、症状选择等。
要提供完整的项目搭建过程,包括云服务器部署。但源代码部分,需要提供前端的HTML、CSS、JavaScript文件,后端的Python文件(如Flask或FastAPI)。并说明如何部署。
需求中要求用UML建模,并用Mermaid画出。可以在文档中嵌入Mermaid图,如用例图、类图(如果是后端的话,但后端主要是API调用,可能没有复杂的类)、时序图(展示前后端交互以及调用AI的过程)、部署图等。
项目结构组织:建议如下:
ai_consultation/
├── backend/
│ ├── app.py # Flask/FastAPI主应用
│ ├── requirements.txt # Python依赖
│ ├── config.py # 配置(API密钥等)
│ └── ...
├── frontend/
│ ├── index.html # 主页面
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── ...
└── README.md # 项目说明
后端需要调用火山引擎DeepSeek API。需要注册火山引擎账号,获取API密钥和模型Endpoint。在config.py中配置。
前端表单需要包含什么?既然是问诊,需要年龄、性别、主诉、症状描述、持续时间、既往病史等。也可以提供一些选项让用户选择,比如症状列表(头痛、发烧等),用户要求“只需要简单进行项目选择填写”,所以可以用下拉框、单选框、复选框等简化输入。
后端接收到表单数据后,需要构造一个提示词给AI,模拟医生问诊的多轮对话。但真正的多轮对话需要维护状态。可以简化:后端根据用户提交的信息,构造一个初始消息给AI,然后AI可能会返回一些追问,后端再根据用户的回答(但用户只提交了一次表单,没有多轮交互)?这可能不符合“多轮回答”的要求。或许需要前端与AI进行多轮对话,但用户描述是“用户在前端应用程序中填写,填完之后发送给后端应用程序,后端调用AI进行多轮回答”。这可能意味着用户一次性填写所有信息,然后后端模拟AI进行多轮问答来生成诊断?或者后端调用AI进行多次交互,但用户已经提供了所有信息,所以后端可以模拟多轮对话(比如让AI扮演医生,根据用户提供的信息进行问诊,然后输出一段对话和诊断)。我们可以这样做:后端构造一个提示,让AI以医生的身份,根据用户提供的症状信息,进行多轮问诊(模拟问答),并最终给出诊断建议和报告。然后后端将AI生成的报告返回给前端。前端可以显示报告并提供打印功能。
或者更简单的:后端将用户信息发给AI,要求AI生成诊断报告,并返回固定格式的报告。这样就不需要多轮了。但题目明确要求“多轮回答”,所以尽量体现多轮。
可以这样设计:用户填写基本信息后,后端与AI进行多轮对话,模拟医生逐步提问和患者回答的过程。但患者的所有信息已经提供,所以需要设计一个对话生成方式:让AI基于已有信息,生成一系列问答对,最终生成诊断。但这样不是真正的交互,而是模拟多轮。用户期望的是真正的多轮对话,但那样需要前端与后端多次交互,比较复杂。考虑到“实现简单”和“用户只需要简单进行项目选择填写”,倾向于一次性填写,后端模拟多轮对话生成报告。
为了满足“多轮回答”,可以让后端构造一个提示,要求AI模拟多轮问诊过程,并输出一个包含多轮对话和最终诊断的报告。这样在报告中会包含多个问答回合。
报告格式可以是文本,也可以是结构化的JSON,然后前端显示。打印功能可以通过浏览器的window.print实现。
所以整体流程:
-
用户在前端填写表单(姓名、年龄、性别、症状描述、持续时间、既往病史等)。
-
点击提交,前端通过AJAX POST请求将数据发送到后端API(如/consult)。
-
后端接收数据,调用火山引擎DeepSeek API,构造提示词,获取AI生成的报告。
-
后端解析AI返回的内容,返回给前端。
-
前端显示报告,并提供“打印报告”按钮,调用window.print。
需要确保AI返回的内容格式固定。可以通过提示词要求AI以特定格式输出,例如包含“【问诊过程】”和“【诊断建议】”等部分。
后端使用Flask或FastAPI。选择Flask因为简单。
现在开始写详细方案文档,包括UML图,然后提供源代码。
注意:要求“用UML建模并提供具体详尽深入的方案,用Markdown,mermind建立文档”。所以要在Markdown中嵌入Mermaid代码块,渲染UML图。
可以在文档中包括:
-
用例图:展示用户与系统的交互。
-
类图:后端可能用到的类(如Config、AIService等),但可以简单。
-
时序图:展示用户前端操作、后端、API之间的交互。
-
部署图:展示云服务器部署架构。
然后提供项目结构说明。
源代码部分:提供完整的文件内容。
最后,说明如何部署到云服务器。
需要确保使用火山引擎API的细节。因为这里没有实际的API密钥,所以代码中需要用户自行配置。在代码中会留出位置。
现在开始撰写回答。
AI问诊网站:详细设计方案与实现
1. 项目概述
本项目是一个基于Web的AI问诊系统,用户在前端填写基本信息(症状、病史等),后端调用火山引擎DeepSeek API进行多轮模拟问诊,生成结构化报告并支持打印。项目采用前后端分离架构,前端使用HTML/CSS/JavaScript,后端使用Python(Flask框架),部署于云服务器。
2. 功能需求
- 前端:提供表单供用户输入个人信息和症状描述,提交后显示AI生成的问诊报告,并支持报告打印。
- 后端:接收前端数据,构造提示词调用DeepSeek API,返回固定格式的报告。
- AI集成:利用火山引擎DeepSeek模型进行多轮问答模拟,生成诊断建议。
3. 技术选型
- 前端:HTML5、CSS3、JavaScript(原生,无框架)
- 后端:Python 3.8+、Flask、Requests库
- AI服务:火山引擎DeepSeek API(需注册获取Access Key和Endpoint)
- 部署:云服务器(如阿里云、腾讯云),Ubuntu 20.04,Nginx + Gunicorn
4. UML建模
4.1 用例图
4.2 类图(后端简化)
4.3 时序图
4.4 部署图
5. 项目文件结构
ai_consultation/
├── backend/
│ ├── app.py # Flask主程序
│ ├── config.py # 配置文件(API密钥等)
│ ├── ai_service.py # AI调用封装
│ ├── requirements.txt # 依赖列表
│ └── utils.py # 辅助函数(如报告解析)
├── frontend/
│ ├── index.html # 主页面
│ ├── css/
│ │ └── style.css # 样式表
│ ├── js/
│ │ └── script.js # 前端交互逻辑
│ └── assets/ # 静态资源(如图标)
├── README.md # 项目说明
└── deploy/ # 部署相关配置(可选)
└── nginx.conf
6. 详细实现
6.1 后端实现
6.1.1 config.py
import os
class Config:
# 火山引擎API配置(请替换为实际值)
API_KEY = "your-volcano-api-key"
API_URL = "https://ark.cn-beijing.volces.com/api/v3/chat/completions" # 示例地址
MODEL = "deepseek-r1" # 模型名称,根据火山引擎实际命名
TIMEOUT = 60
6.1.2 ai_service.py
import requests
import json
from config import Config
class AIService:
@staticmethod
def generate_report(user_data):
"""
调用DeepSeek API生成问诊报告
:param user_data: 前端提交的字典,包含姓名、年龄、性别、症状描述等
:return: 生成的报告文本
"""
prompt = AIService._build_prompt(user_data)
response_text = AIService._call_api(prompt)
return AIService._format_report(response_text)
@staticmethod
def _build_prompt(data):
"""
构造提示词,要求AI模拟多轮问诊并输出报告
"""
name = data.get('name', '患者')
age = data.get('age', '未知')
gender = data.get('gender', '未知')
symptoms = data.get('symptoms', '未描述')
duration = data.get('duration', '未知')
history = data.get('history', '无')
additional = data.get('additional', '')
prompt = f"""你是一位经验丰富的全科医生,请根据以下患者信息进行多轮问诊模拟,并最终给出诊断建议和报告。
要求:
1. 模拟至少三轮问答(医生提问和患者回答),基于已有信息合理展开。
2. 最后输出【诊断建议】部分,包括可能的疾病、进一步检查建议和初步处理意见。
3. 输出格式清晰,包含【问诊过程】和【诊断建议】两个主要部分。
患者信息:
姓名:{name}
年龄:{age}
性别:{gender}
主诉症状:{symptoms}
症状持续时间:{duration}
既往病史:{history}
其他补充:{additional}
请开始模拟问诊:"""
return prompt
@staticmethod
def _call_api(prompt):
"""
发送请求到火山引擎DeepSeek API
"""
headers = {
"Authorization": f"Bearer {Config.API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": Config.MODEL,
"messages": [
{"role": "system", "content": "你是一位专业、耐心的医生。"},
{"role": "user", "content": prompt}
],
"temperature": 0.7,
"max_tokens": 2000
}
try:
response = requests.post(
Config.API_URL,
headers=headers,
json=payload,
timeout=Config.TIMEOUT
)
response.raise_for_status()
result = response.json()
# 假设返回格式为 { "choices": [ { "message": { "content": "..." } } ] }
return result['choices'][0]['message']['content']
except Exception as e:
return f"AI调用失败: {str(e)}"
@staticmethod
def _format_report(raw_text):
"""
对AI返回文本进行后处理(如需结构化可在此扩展)
目前直接返回原始文本,但可确保包含必要的标题
"""
# 确保报告包含预期格式
if "【问诊过程】" not in raw_text and "【诊断建议】" not in raw_text:
raw_text = "【问诊过程】\n" + raw_text + "\n\n【诊断建议】\n(AI未能按格式生成)"
return raw_text
6.1.3 app.py
from flask import Flask, request, jsonify
from flask_cors import CORS # 处理跨域
from ai_service import AIService
app = Flask(__name__)
CORS(app) # 允许所有跨域请求,生产环境应限制
@app.route('/consult', methods=['POST'])
def consult():
"""
接收前端表单数据,调用AI生成报告,返回JSON
"""
try:
data = request.get_json()
if not data:
return jsonify({'error': '无效的请求数据'}), 400
# 调用AI服务
report = AIService.generate_report(data)
return jsonify({'success': True, 'report': report})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'ok'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True) # debug模式仅开发使用
6.1.4 requirements.txt
Flask==2.3.3
flask-cors==4.0.0
requests==2.31.0
gunicorn==21.2.0 # 生产环境用
6.2 前端实现
6.2.1 index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI问诊助手</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<header>
<h1>智能问诊系统</h1>
<p>请填写以下信息,AI将为您模拟多轮问诊并生成报告</p>
</header>
<main>
<form id="consultForm">
<div class="form-group">
<label for="name">姓名:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-row">
<div class="form-group half">
<label for="age">年龄:</label>
<input type="number" id="age" name="age" required>
</div>
<div class="form-group half">
<label for="gender">性别:</label>
<select id="gender" name="gender" required>
<option value="">请选择</option>
<option value="男">男</option>
<option value="女">女</option>
</select>
</div>
</div>
<div class="form-group">
<label for="symptoms">主要症状:</label>
<textarea id="symptoms" name="symptoms" rows="3" placeholder="请详细描述您的不适" required></textarea>
</div>
<div class="form-group">
<label for="duration">症状持续时间:</label>
<input type="text" id="duration" name="duration" placeholder="例如:3天、一周" required>
</div>
<div class="form-group">
<label for="history">既往病史(如有):</label>
<textarea id="history" name="history" rows="2" placeholder="例如:高血压、糖尿病等"></textarea>
</div>
<div class="form-group">
<label for="additional">补充信息(可选):</label>
<textarea id="additional" name="additional" rows="2" placeholder="其他您想说明的情况"></textarea>
</div>
<button type="submit" id="submitBtn">提交问诊</button>
</form>
<div id="reportSection" class="hidden">
<h2>问诊报告</h2>
<div id="reportContent" class="report-content"></div>
<button id="printBtn" onclick="window.print()">打印报告</button>
</div>
<div id="loading" class="hidden">正在生成报告,请稍候...</div>
</main>
</div>
<script src="js/script.js"></script>
</body>
</html>
6.2.2 css/style.css
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
padding: 30px;
}
header {
text-align: center;
margin-bottom: 30px;
}
header h1 {
color: #2c3e50;
margin-bottom: 10px;
}
header p {
color: #7f8c8d;
}
.form-group {
margin-bottom: 20px;
}
.form-row {
display: flex;
gap: 20px;
}
.form-group.half {
flex: 1;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #34495e;
}
input, select, textarea {
width: 100%;
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 16px;
transition: border 0.3s;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #3498db;
}
button {
background-color: #3498db;
color: white;
border: none;
padding: 14px 25px;
font-size: 16px;
border-radius: 8px;
cursor: pointer;
transition: background 0.3s;
width: 100%;
font-weight: 600;
}
button:hover {
background-color: #2980b9;
}
#reportSection {
margin-top: 40px;
border-top: 2px solid #ecf0f1;
padding-top: 20px;
}
.report-content {
background: #f8f9fa;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
white-space: pre-wrap;
line-height: 1.6;
font-family: 'Georgia', serif;
max-height: 500px;
overflow-y: auto;
}
.hidden {
display: none;
}
#loading {
text-align: center;
padding: 30px;
font-size: 18px;
color: #3498db;
}
/* 打印样式 */
@media print {
body * {
visibility: hidden;
}
#reportSection, #reportSection * {
visibility: visible;
}
#reportSection {
position: absolute;
left: 0;
top: 0;
width: 100%;
border: none;
}
button, form, header p, #submitBtn, #printBtn {
display: none;
}
}
6.2.3 js/script.js
document.getElementById('consultForm').addEventListener('submit', async (e) => {
e.preventDefault();
// 收集表单数据
const formData = {
name: document.getElementById('name').value.trim(),
age: document.getElementById('age').value.trim(),
gender: document.getElementById('gender').value,
symptoms: document.getElementById('symptoms').value.trim(),
duration: document.getElementById('duration').value.trim(),
history: document.getElementById('history').value.trim() || '无',
additional: document.getElementById('additional').value.trim() || '无'
};
// 显示加载中
document.getElementById('loading').classList.remove('hidden');
document.getElementById('reportSection').classList.add('hidden');
document.getElementById('submitBtn').disabled = true;
try {
// 发送请求到后端
const response = await fetch('http://localhost:5000/consult', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
const result = await response.json();
if (result.success) {
// 显示报告
document.getElementById('reportContent').innerText = result.report;
document.getElementById('reportSection').classList.remove('hidden');
} else {
alert('生成报告失败:' + (result.error || '未知错误'));
}
} catch (error) {
alert('网络错误,请检查后端服务是否运行。' + error.message);
} finally {
document.getElementById('loading').classList.add('hidden');
document.getElementById('submitBtn').disabled = false;
}
});
7. 部署说明
7.1 云服务器准备
- 购买一台云服务器(如Ubuntu 20.04 LTS),开放端口80(HTTP)和5000(可选,但生产环境用Nginx反向代理)。
- SSH登录服务器,更新系统:
sudo apt update && sudo apt upgrade -y
7.2 安装Python环境
sudo apt install python3-pip python3-venv nginx -y
7.3 上传项目代码
可以使用scp或git clone。假设代码放在/var/www/ai_consultation。
7.4 配置后端
cd /var/www/ai_consultation/backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
测试运行:python app.py,确保能正常启动。
7.5 使用Gunicorn运行
gunicorn -w 4 -b 127.0.0.1:5000 app:app &
(最好使用systemd管理进程,此处简化)
7.6 配置Nginx反向代理
创建配置文件 /etc/nginx/sites-available/ai_consultation:
server {
listen 80;
server_name your_domain_or_ip;
location / {
root /var/www/ai_consultation/frontend;
index index.html;
try_files $uri $uri/ /index.html;
}
location /consult {
proxy_pass http://127.0.0.1:5000/consult;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /health {
proxy_pass http://127.0.0.1:5000/health;
}
}
启用配置:
sudo ln -s /etc/nginx/sites-available/ai_consultation /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
7.7 修改前端请求地址
前端script.js中的fetch应改为服务器域名或IP(例如/consult),使用相对路径(通过Nginx代理)。
7.8 配置API密钥
在config.py中填写正确的火山引擎API密钥和URL。
7.9 防火墙设置
确保云服务器安全组允许80端口访问。
8. 盈利模式建议
- 广告收入:在页面中嵌入医疗相关广告。
- 付费报告:基础报告免费,详细定制报告收费。
- 会员订阅:提供无限次问诊、历史记录保存等高级功能。
- 医生对接:将AI生成的报告转给真实医生审核,收取咨询费。
9. 总结
本项目实现了一个简单的AI问诊网站,通过火山引擎DeepSeek模型模拟多轮问诊并生成报告。前后端分离,易于扩展和维护。部署到云服务器后,可对外提供服务。注意合规性,医疗信息需遵循相关法律法规,建议添加免责声明。
更多推荐


所有评论(0)