361 lines
18 KiB
Python
Raw Permalink Normal View History

from typing import Dict
from agent_system.base import BaseAgent
from agent_system.monitor.prompt import MonitorPrompt
from agent_system.monitor.response_model import MonitorResult
class Monitor(BaseAgent):
"""
Monitor智能体
根据具体任务提供专门的评分标准实现分诊阶段和病史收集阶段的精准评估
"""
def __init__(self, model_type: str = "gpt-oss:latest", llm_config: dict = {}):
super().__init__(
model_type=model_type,
description=MonitorPrompt.description,
instructions=MonitorPrompt.instructions,
response_model=MonitorResult,
llm_config=llm_config,
structured_outputs=True,
markdown=False,
use_cache=False
)
def run(self, hpi_content: str, ph_content: str, chief_complaint: str,
task_name: str = None, task_description: str = None,
triage_result: dict = None) -> MonitorResult:
"""
监控病史质量
Args:
hpi_content: 现病史内容
ph_content: 既往史内容
chief_complaint: 主诉
task_name: 任务名称可选用于针对性评估
task_description: 任务描述可选用于针对性评估
triage_result: 分诊结果可选仅在分诊阶段使用
Returns:
MonitorResult: 包含完成度评分和评分理由
"""
if task_name and task_description:
prompt = self._build_task_specific_prompt(task_name, task_description,
hpi_content, ph_content, chief_complaint,
triage_result)
else:
prompt = self.build_prompt(hpi_content, ph_content, chief_complaint, triage_result)
# 调用LLM进行评估
result = super().run(prompt)
# 确保返回正确的类型
if isinstance(result, MonitorResult):
return result
elif isinstance(result, dict):
return MonitorResult(**result)
else:
return MonitorResult(
completion_score=0.0,
reason="监控评估失败无法解析LLM响应"
)
def build_prompt(self, hpi_content: str, ph_content: str, chief_complaint: str,
triage_result: dict = None) -> str:
"""
构建整体病史质量评估的提示语
Args:
hpi_content: 现病史内容
ph_content: 既往史内容
chief_complaint: 主诉
triage_result: 分诊结果可选
Returns:
str: 构建好的提示语
"""
task_name = "整体病史质量评估"
task_description = "综合评估现病史、既往史和主诉的信息完整性"
return self._build_task_specific_prompt(
task_name, task_description, hpi_content, ph_content, chief_complaint, triage_result
)
def _build_task_specific_prompt(self, task_name: str, task_description: str,
hpi_content: str, ph_content: str, chief_complaint: str,
triage_result: dict = None) -> str:
"""
构建针对特定任务的评估提示语每个子任务有专门的评分标准
Args:
task_name: 任务名称
task_description: 任务描述
hpi_content: 现病史内容
ph_content: 既往史内容
chief_complaint: 主诉
triage_result: 分诊结果可选
Returns:
str: 构建好的任务特定评估提示语
"""
# 获取任务特定的评分标准
scoring_criteria = self._get_task_scoring_criteria(task_name, triage_result)
# 构建分诊信息(仅在分诊阶段使用)
triage_info = ""
if task_name in ["一级科室判定", "二级科室判定"] and triage_result:
primary_dept = triage_result.get("primary_department", "")
secondary_dept = triage_result.get("secondary_department", "")
triage_info = f"""
**分诊结果参考**
一级科室{primary_dept}
二级科室{secondary_dept}
**评估重点**
基于上述分诊结果评估当前病史信息对科室选择的支持程度"""
prompt = f"""请对以下病史信息进行质量监控和评估:
**评估目标任务**
任务名称{task_name}
任务描述{task_description}
{triage_info}
**当前病史信息**
主诉{chief_complaint}
**现病史**
{hpi_content}
**既往史**
{ph_content}
**评估要求**
1. **专门针对任务"{task_name}"进行评估**
2. 根据任务描述"{task_description}"判断当前病史信息在这个方面的完整性
3. 重点关注与该任务相关的信息是否充分收集
4. 基于临床实际价值进行评估否定性回答"""未发生""不记得"具有同等重要的临床意义
5. 考虑记忆限制的合理性对时间久远或非关键细节接受模糊回答
6. 避免过度询问当患者明确表示无相关情况时不应继续追问
7. 给出该任务的完成度评分0.0-1.0范围
8. 详细说明评分理由解释信息缺失是否影响诊疗决策
{scoring_criteria}
**临床考量要点**
- 否定性回答"无既往病史""无过敏史"是重要的临床信息
- 对于时间久远的事件记不清属正常现象
- 非关键性细节如具体药物商品名的模糊回答不影响评分
- 重点关注与当前病情密切相关的信息
**输出格式**
严格按照以下JSON格式输出
{{
"completion_score": 浮点数0.0-1.0
"reason": "详细评分理由需具体说明1)哪些信息具有临床价值包括否定性回答2)哪些缺失或模糊是可接受的3)哪些缺陷可能影响诊疗决策"
}}
请基于上述要求进行客观评估"""
return prompt
def _get_task_scoring_criteria(self, task_name: str, triage_result: dict = None) -> str:
"""
获取每个子任务专门的评分标准
Args:
task_name: 任务名称
triage_result: 分诊结果用于分诊阶段
Returns:
str: 该任务的专门评分标准
"""
# 分诊阶段评分标准
if task_name == "一级科室判定":
return """**一级科室分类评分标准**
- 0.9-1.0症状明确指向某一级科室病史信息充分支持科室选择
- 0.8-0.9症状与科室匹配度较高病史信息基本完整接受"可能属于某科室"等模糊判断
- 0.65-0.79科室选择基本合理但信息支持度一般询问不够全面
- 0.5-0.65科室选择勉强合理病史信息明显不足缺少关键信息
- 0.0-0.5科室选择不合理或与症状描述不符未进行基本分诊判断"""
elif task_name == "二级科室判定":
return """**二级科室分类评分标准**
- 0.9-1.0在一级科室基础上症状明确指向具体二级科室信息充分
- 0.8-0.9二级科室选择合理症状支持度高信息较完整接受"可能属于某二级科室"等模糊判断
- 0.65-0.79二级科室选择基本合理但信息支持度有限询问不够全面
- 0.5-0.65二级科室选择存疑信息支持不足缺少关键分诊信息
- 0.0-0.5二级科室选择不合理或与症状不符未进行基本二级分诊判断"""
# 现病史阶段评分标准
elif task_name == "发病情况":
return """**发病情况评估标准**(重要:否定性诱因回答同样有效):
- 0.85-1.0发病时间和方式已询问接受"突然起病""逐渐加重""无明确诱因"等回答包括"无明显诱因""记不清具体时间"等回答视为完整
- 0.7-0.85发病时间或方式已询问但部分细节询问不够明确
- 0.6-0.69发病基本情况已获取但询问不够全面
- 0.5-0.59缺少发病时间和方式的询问
- 0.0-0.49发病情况询问严重缺失未进行基本询问
**重要原则**
- "无明显诱因""记不清具体发病时间"等回答视为有效临床信息
- 对久远事件的时间模糊回答不影响高分评价
- 重点关注发病模式是否符合当前疾病特征"""
elif task_name == "主要症状特征":
return """**主要症状特征评估标准**(重要:否定性症状描述同样有效):
- 0.85-1.0主要症状特征已询问接受"疼痛程度记不清""无特殊缓解方法"等回答包括"记不清具体部位""无明显缓解因素"等回答视为完整
- 0.7-0.85症状基本特征已获取但部分特征询问不够明确
- 0.6-0.69症状特征询问已进行但不够全面
- 0.5-0.59缺少症状关键特征的询问
- 0.0-0.49症状特征询问严重缺失未进行基本询问
**重要原则**
- "记不清具体部位""无法描述疼痛性质""无明显缓解因素"等回答视为有效临床信息
- 对症状细节记忆模糊的回答给予理解不影响高分评价
- 重点关注症状是否符合当前疾病特征而非描述的精确程度"""
elif task_name == "病情发展与演变":
return """**病情发展与演变评估标准**(重要:时间模糊但趋势清晰同样有效):
- 0.9-1.0病情演变过程按时间顺序描述变化趋势清晰"逐渐加重""时好时坏"等描述视为完整
- 0.8-0.89病情发展趋势明确接受"记不清具体时间""大概几周前开始加重"等模糊时间描述
- 0.7-0.79病情变化基本脉络清晰但部分时间点或变化细节略有缺失
- 0.6-0.69病情发展大致过程可辨时间顺序不够精确但趋势明确
- 0.5-0.59病情变化描述不够系统缺乏清晰的时间概念
- 0.0-0.49病情发展信息严重缺失无法了解疾病演变过程
**重要原则**
- "记不清具体时间""大概几个月前"等时间模糊回答视为有效临床信息
- "逐渐加重""突然恶化""时轻时重"等趋势描述具有重要临床价值
- 对久远事件具体时间记不清属正常现象不影响高分评价
- 重点关注病情变化趋势和规律而非时间节点的精确性
- 慢性病程中的波动情况"反复发作""间歇性加重"视为重要信息"""
elif task_name == "伴随症状":
return """**伴随症状评估标准**(重要:"无伴随症状"同样具有临床价值):
- 0.9-1.0伴随症状已询问包括"无其他不适""无相关症状"等否定性回答视为完整
- 0.8-0.89主要伴随症状已询问接受"记不清是否有其他症状""好像没有其他不适"等回答
- 0.7-0.79伴随症状基本询问已进行但部分相关症状询问不够明确
- 0.6-0.69伴随症状询问已进行但不够全面
- 0.5-0.59缺少伴随症状的询问
- 0.0-0.49伴随症状询问严重缺失未进行基本询问
**重要原则**
- "无其他症状""无伴随不适""未发现其他异常"等否定性回答视为有效完整信息
- "记不清是否有其他症状""不太确定"等模糊回答给予理解不影响高分评价
- 重点关注与主要疾病相关的典型伴随症状而非所有可能的症状
- 系统性疾病相关的全身症状如发热乏力等询问视为重要内容"""
elif task_name == "诊疗经过":
return """**诊疗经过评估标准**(重要:"未就诊""未治疗"同样具有临床价值):
- 0.9-1.0诊疗过程已询问包括"未就诊""未治疗""自行缓解"等否定性回答视为完整
- 0.8-0.89诊疗经过已询问接受"记不清具体药物""治疗效果一般"等模糊描述
- 0.7-0.79诊疗基本信息已获取但部分检查或治疗细节略有缺失
- 0.6-0.69诊疗经过基本具备但效果描述或具体措施不够详细
- 0.5-0.59诊疗经过信息不完整缺乏关键诊疗信息
- 0.0-0.49诊疗经过严重缺失未进行基本询问
**重要原则**
- "未就诊""未治疗""未用药"等否定性回答视为有效完整信息
- "记不清药名""记不清检查项目"等记忆模糊回答给予理解
- 重点关注诊疗措施与当前病情的相关性而非详细的治疗记录
- 自行用药民间疗法等信息的收集视为有价值的临床信息"""
elif task_name == "一般情况":
return """**一般情况评估标准**(重要:否定性回答具有同等临床价值):
- 0.85-1.0精神状态睡眠食欲大小便体重已询问无论肯定或否定回答均视为完整
- 0.7-0.85已询问主要生活状况接受"无异常""正常""记不清"等回答基本满足诊疗需求
- 0.6-0.69基本生活状况信息已获取但询问不够全面
- 0.5-0.59缺少部分重要生活状况的询问
- 0.0-0.49关键生活状况信息严重缺失未进行基本询问
**重要原则**
- "精神状态正常""睡眠尚可""食欲正常""大小便正常""体重无明显变化"等否定性回答视为有效信息
- 对记不清具体时间或细节的回答给予理解不影响高分评价
- 重点关注是否存在影响诊疗的异常情况而非描述的详细程度"""
# 既往史阶段评分标准
elif task_name == "疾病史":
return """**疾病史评估标准**
- 0.9-1.0既往疾病史已询问包括"无慢性疾病史""否认高血压糖尿病"等否定性回答视为完整有效
- 0.8-0.89主要疾病史已询问接受"既往体健""无重大疾病"等回答满足诊疗需求
- 0.7-0.79基本疾病史信息已获取但部分重要疾病询问不够明确
- 0.6-0.69疾病史基本询问已进行但不够全面
- 0.5-0.59缺少部分重要疾病史的询问
- 0.0-0.49疾病史询问严重缺失未进行基本询问
**重要原则**
- "既往体健""无慢性疾病史""否认传染病史"等否定性回答视为有效完整信息
- 对记不清具体疾病名称或时间的回答给予理解
- 重点关注是否存在影响当前诊疗的重要既往疾病而非病史的详细程度"""
elif task_name == "预防接种史":
return """**预防接种史评估标准**
- 0.9-1.0疫苗接种史已询问包括"疫苗接种随当地""无特殊疫苗接种史"等否定性回答视为完整
- 0.8-0.89疫苗接种史已询问接受"按常规接种""无特殊要求"等回答满足诊疗需求
- 0.7-0.79疫苗接种史基本询问已进行但部分重要疫苗询问不够明确
- 0.6-0.69疫苗接种史询问已进行但不够全面
- 0.5-0.59缺少疫苗接种史的询问
- 0.0-0.49疫苗接种史询问严重缺失未进行基本询问
**重要原则**
- "预防接种随当地""按常规接种""无特殊疫苗接种史"等回答视为有效完整信息
- 对记不清具体疫苗名称或接种时间的回答给予理解
- 重点关注是否存在影响当前诊疗的特殊疫苗接种情况"""
elif task_name == "手术外伤史":
return """**手术外伤史评估标准**
- 0.9-1.0手术外伤史已询问包括"无手术史""无重大外伤史""否认手术外伤史"等否定性回答视为完整
- 0.8-0.89手术外伤史已询问接受"无相关手术""无重大外伤"等回答满足诊疗需求
- 0.7-0.79手术外伤史已询问但回答不够明确
- 0.6-0.69手术外伤史询问已进行但不够全面
- 0.5-0.59缺少手术外伤史的询问
- 0.0-0.49手术外伤史询问严重缺失未进行基本询问
**重要原则**
- "无手术史""无外伤史""否认手术外伤史"等否定性回答视为有效完整信息
- 对记不清具体手术时间或细节的回答给予理解
- 重点关注是否存在影响当前诊疗的手术外伤史"""
elif task_name == "输血史":
return """**输血史评估标准**
- 0.9-1.0输血史已询问包括"无输血史""否认输血史""无相关输血"等否定性回答视为完整
- 0.8-0.89输血史已询问接受"无输血需求""未接受过输血"等回答满足诊疗需求
- 0.7-0.79输血史已询问但回答不够明确
- 0.6-0.69输血史询问已进行但不够全面
- 0.5-0.59缺少输血史的询问
- 0.0-0.49输血史询问严重缺失未进行基本询问
**重要原则**
- "无输血史""否认输血史""未接受过输血"等否定性回答视为有效完整信息
- 对记不清具体输血时间或细节的回答给予理解
- 重点关注是否存在影响当前诊疗的输血史"""
elif task_name == "过敏史":
return """**过敏史评估标准**
- 0.9-1.0过敏史已询问包括"无过敏史""否认过敏史""无药物食物过敏"等否定性回答视为完整
- 0.8-0.89过敏史已询问接受"无过敏""未发现过敏"等回答满足诊疗需求
- 0.7-0.79过敏史基本询问已进行但不够明确
- 0.6-0.69过敏史询问已进行但不够全面
- 0.5-0.59缺少过敏史的询问
- 0.0-0.49过敏史询问严重缺失未进行基本询问
**重要原则**
- "无过敏史""否认过敏史""无药物过敏"等否定性回答视为有效完整信息
- 对记不清具体过敏源或反应的回答给予理解
- 重点关注是否存在影响当前诊疗的过敏史"""
else:
# 默认评分标准
return """**通用评分标准**(病史阶段专用,强调否定性回答价值):
- 0.9-1.0相关病史信息已询问包括"无异常""未发生""记不清"等否定性回答视为完整有效
- 0.8-0.89重要病史信息已询问接受"无相关""正常""无特殊"等回答满足诊疗需求
- 0.7-0.79关键病史信息已询问但部分询问不够明确
- 0.6-0.69基本病史信息已获取但询问不够全面
- 0.5-0.59缺少重要病史信息的询问
- 0.0-0.49病史询问严重缺失未进行基本询问
**重要原则**
- 所有否定性回答"""未发生""否认""正常"均视为有效完整的临床信息
- 对时间久远或非关键细节的记忆模糊回答给予充分理解
- 重点关注是否存在影响诊疗的异常情况而非信息描述的详细程度""",