本仓库为远程超声诊断平台的统一代码仓库,包含前端、后端、AI质控模块以及专网实时通信中间件。 采用 Monorepo 结构管理,方便统一版本控制,支持针对不同医院/客户进行定制化开发。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

233 lines
9.6 KiB

from flask import Flask, request,jsonify
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True)
import time
import jieba
import re
import dashscope
from http import HTTPStatus
# 配置 Qwen API
dashscope.api_key = 'sk-c7d5687a4d044489974b65bde467e93e'
dashscope.base_url = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
def USReport_LLM(report):
query = """
请列出报告中的常见错误,特别关注错别字、拼写错误、单位使用问题。请确保单位用数字形式表达,并指出需要修改的地方。
"""
custom_prompt = f"""
你是一个医学报告专家,擅长阅读和撰写医学报告。在分析报告时,请特别注意以下几点:
**错别字和拼写错误**:指出任何拼写错误或术语使用不当的情况。
**语法错误**:指出任何语法错误。
**单位使用**:所有尺寸单位必须以数字形式表达,避免文字形式,并保持一致性。
**信息不一致**:检查报告中是否存在信息不一致的情况。
**术语使用**:确保所有术语符合医学标准。
**格式错误**:检查报告格式是否一致,有无错误。
**漏项**:检查报告是否缺少必要信息。
**上下文错误**:检查上下文是否存在逻辑错误或内容不符的情况。
**性别与检查部位不符**:确保报告中涉及性别特定的器官信息明确且一致。
请根据以下报告进行分析,并保持简洁明了的回应:
、、、
{report}
、、、
你是一个医学报告专家,请仔细阅读以下报告,列出发现的所有错误和问题。**不要**将缺少图像和患者隐私信息视为信息完整性或格式规范性问题。只需检查报告是否包含所有必要信息,如检查日期、患者姓名、检查部位等。
**评分与范例生成**:
**评分报告**:
- 信息完整性:检查报告是否包含所有必要信息,如检查日期、患者姓名、检查项目等。请给出具体评分。(满分20分)
- 表达清晰性:检查报告语言是否清晰易懂。请给出具体评分。(满分20分)
- 描述专业性:报告中使用的医学术语是否正确,描述是否准确。请给出具体评分。(满分20分)
- 临床相关性:检查报告是否提供了与患者临床状况相关的有用信息。请给出具体评分。(满分20分)
- 格式规范性:报告是否遵循医学报告的标准格式,包括检查所见和结论的标题区分。请给出具体评分。(满分20分)
请逐项列出评分细节,并给出总分并用**粗体**标注,格式如:**总计得分:80/100**。
**范例报告**:
- 请在开始处注明“此处为范例报告”。
- 使用原医生的报告内容,避免增加未提及的症状或信息。
- 关注检查所见和检查结论部分的语法、拼写、报告格式等问题,进行改进。
、、、
{report}
、、、
用户问题:
、、、
{query}
、、、
"""
messages = [
{'role': 'system', 'content': '你是医学报告专家'},
{'role': 'user', 'content': custom_prompt} # 添加 user 角色消息
]
response = dashscope.Generation.call(
model="qwen-max",
messages=messages,
# 将输出设置为"message"格式
result_format='message'
)
# 检查响应并输出结果
if response.status_code == HTTPStatus.OK:
return response.output.choices[0]['message']['content']
else:
print(f"请求错误: {response.status_code}, 错误消息: {response.message}")
return None
def USReport_VLLM(report_text, query, image_urls):
# 定义生成prompt的函数
def generate_prompt(report, query):
prompt = f"""
你是一个医学报告专家,擅长阅读和撰写医学报告。擅长分析和解读超声影像,并根据影像生成相应的医学报告。请按照以下步骤进行分析:
**影像质量评估**:
- 评估输入的超声图像是否清晰,是否存在伪影或模糊区域。无需说出具体哪些部位。
- 判断图像是否能准确显示关键解剖结构。无需说出具体哪些部位。
- 评估图像截取的质量是否合格。无需说出具体哪些部位。
请根据以下报告进行分析,并保持简洁明了的回应:
、、、
{report}
、、、
**超声报告总评分**:
- 信息完整性:检查报告是否包含所有必要信息,如检查日期、患者姓名、检查项目等。请给出具体评分。(满分20分)
- 表达清晰性:检查报告语言是否清晰易懂。请给出具体评分。(满分20分)
- 描述专业性:报告中使用的医学术语是否正确,描述是否准确。请给出具体评分。(满分20分)
- 临床相关性:报告是否提供了与患者临床状况相关的有用信息。请给出具体评分。(满分20分)
- 格式规范性:报告是否遵循医学报告的标准格式。请给出具体评分。(满分10分)
- 影像清晰度:评估影像的清晰度和细节展示程度。请给出具体评分。(满分10分)
请逐项列出评分细节,并给出总分并用**粗体**标注,格式如:**总计得分:80/100**。
、、、
{report}
、、、
用户问题:
、、、
{query}
、、、
"""
return prompt
prompt = generate_prompt(report_text, query)
# 构造消息,确保超声图像和文本都传递正确
messages = [
{
"role": "user",
"content": [
*[{"image": url} for url in image_urls], # 添加所有图片链接
{"text": prompt} # 添加文本提示
]
}
]
# 调用 Qwen-VL-Max 模型
response = dashscope.MultiModalConversation.call(
model='qwen-vl-max',
messages=messages
)
# 检查响应并输出结果
if response.status_code == HTTPStatus.OK:
return response.output.choices[0]['message']['content']
else:
print(f"请求错误: {response.status_code}, 错误消息: {response.message}")
return None
def format_vllm_output(vllm_output):
"""
格式化第二段代码的输出结果。
"""
# 提取文本内容,确保提取的是字符串
text = vllm_output[0].get('text', '')
# 检查是否成功提取字符串并非空
if isinstance(text, str) and text:
# 分割文本内容,按段落分割
sections = text.split('\n\n')
# 定义一个函数来解析每个部分
def parse_section(section):
lines = section.split('\n')
parsed_section = {}
for line in lines:
if ':' in line:
key, value = line.split(':', 1)
parsed_section[key.strip()] = value.strip()
else:
parsed_section[line] = None
return parsed_section
# 解析每个部分
parsed_output = {}
for section in sections:
parsed_section = parse_section(section)
parsed_output.update(parsed_section)
# 格式化解析后的内容
formatted_output = ""
for key, value in parsed_output.items():
if value is not None:
formatted_output += f"{key}: {value}\n"#
else:
formatted_output += f"{key}\n"
return formatted_output
else:
return "未能正确提取文本内容或文本为空"
def US_Report_CompleteAnalysis(report,image_urls):
# 调用第一段代码
llm_output = USReport_LLM(report)
# 提取从开头到 **评分报告**: 这部分内容
if llm_output:
report_text = llm_output.split('**评分报告**:')[0]
example_report_text = llm_output.split('**范例报告**:')[1] if '**范例报告**:' in llm_output else ""
# 定义用户查询
query = """
请根据输入的超声报告文字的问题总结和超声图像来评估整体超声报告的质量,需要按照严格标准给超声报告打分。
"""
# 定义超声图像 URL 列表
""" image_urls = [
"https://ultrasound-imgs.oss-eu-central-1.aliyuncs.com/Ulstrasound_IMG1.jpg",
"https://ultrasound-imgs.oss-eu-central-1.aliyuncs.com/Ulstrasound_IMG2.jpg",
"https://ultrasound-imgs.oss-eu-central-1.aliyuncs.com/Ulstrasound_IMG3.jpg",
"https://ultrasound-imgs.oss-eu-central-1.aliyuncs.com/Ulstrasound_IMG4.jpg",
"https://ultrasound-imgs.oss-eu-central-1.aliyuncs.com/Ulstrasound_IMG5.jpg"
] """
# 调用第二段代码
vllm_output = USReport_VLLM(report_text, query, image_urls)
# 格式化第二段代码的输出结果
formatted_vllm_output = format_vllm_output(vllm_output)
# 拼接完整的分析报告
complete_analysis = f"{report_text}\n\n{formatted_vllm_output}\n\n{example_report_text}"
return complete_analysis
else:
print("第一段代码输出为空")
return None
@app.route('/imgapi', methods=['POST'])
def analyze_report_img():
user_info = request.get_json()
report= user_info.get("report")
image_urls= user_info.get("image_urls")
result=US_Report_CompleteAnalysis(report,image_urls)
#print(result)
return jsonify({"result":result})
app.run(host='0.0.0.0', port=5000)