diff --git a/agent_system/inquirer/__init__.py b/agent_system/inquirer/__init__.py new file mode 100644 index 0000000..2f286f9 --- /dev/null +++ b/agent_system/inquirer/__init__.py @@ -0,0 +1,21 @@ +""" +Inquirer智能体模块 + +该模块实现询问者智能体,用于基于患者的现病史和既往史生成医生需要询问的具体问题。 +智能体的特殊之处在于其描述和指令主体内容由Prompter智能体动态生成。 + +主要组件: +- InquirerResponseModel: 询问者智能体的响应数据模型 +- InquirerPrompt: 询问者智能体的动态提示词模板 +- Inquirer: 询问者智能体的主要实现类 +""" + +from .response_model import InquirerResponseModel +from .prompt import InquirerPrompt +from .agent import Inquirer + +__all__ = [ + 'InquirerResponseModel', + 'InquirerPrompt', + 'Inquirer' +] \ No newline at end of file diff --git a/agent_system/inquirer/agent.py b/agent_system/inquirer/agent.py new file mode 100644 index 0000000..ce4bfd9 --- /dev/null +++ b/agent_system/inquirer/agent.py @@ -0,0 +1,105 @@ +from agent_system.base import BaseAgent +from agent_system.inquirer.prompt import InquirerPrompt +from agent_system.inquirer.response_model import InquirerResponseModel + + +class Inquirer(BaseAgent): + """ + 询问者智能体 + + 基于患者的现病史和既往史,生成医生需要询问的具体问题。 + 该智能体的特殊之处在于其描述和指令主体内容由Prompter智能体动态生成, + 然后结合固定的输入输出格式构成完整的提示词。 + + 核心功能: + 1. 接收患者的现病史和既往史信息 + 2. 基于Prompter生成的询问策略产生具体的问诊问题 + 3. 输出符合医患交流习惯的问题内容 + + Attributes: + model_type (str): 使用的大语言模型类型,默认为 gpt-oss:latest + llm_config (dict): LLM模型配置参数 + """ + + def __init__(self, description: str, instructions: list, model_type: str = "gpt-oss:latest", llm_config: dict = None): + """ + 初始化Inquirer智能体 + + Args: + description (str): 由Prompter生成的智能体描述 + instructions (list): 由Prompter生成的指令列表 + model_type (str): 大语言模型类型,默认使用 gpt-oss:latest + llm_config (dict): LLM模型的配置参数,如果为None则使用默认配置 + """ + # 将Prompter生成的指令与固定格式指令拼接 + complete_instructions = instructions.copy() + complete_instructions.extend(InquirerPrompt.get_fixed_format_instructions()) + + super().__init__( + model_type=model_type, + description=description, + instructions=complete_instructions, + response_model=InquirerResponseModel, + llm_config=llm_config or {}, + structured_outputs=True, + markdown=False, + use_cache=False + ) + + def run(self, hpi_content: str, ph_content: str, chief_complaint: str) -> InquirerResponseModel: + """ + 执行询问者智能体的问题生成 + + 基于患者病史信息生成具体的问诊问题。 + + Args: + hpi_content (str): 现病史内容,患者的主要症状描述 + ph_content (str): 既往史内容,患者的历史疾病信息 + chief_complaint (str): 患者主述,患者的主要不适描述 + + Returns: + InquirerResponseModel: 包含生成的问诊问题的结构化数据: + - current_chat: 生成的具体问诊问题内容 + """ + # 构建询问提示词 + prompt = self._build_prompt(hpi_content, ph_content, chief_complaint) + + # 调用基类的run方法执行LLM推理 + result = super().run(prompt) + + return result + + def _build_prompt(self, hpi_content: str, ph_content: str, chief_complaint: str) -> str: + """ + 构建Inquirer的提示词模板 + + 将患者的病史信息构建完整的提示词。 + + Args: + hpi_content (str): 现病史内容 + ph_content (str): 既往史内容 + chief_complaint (str): 患者主述 + + Returns: + str: 构建的提示词 + """ + # 确保既往史内容的合理显示 + past_history_display = ph_content.strip() if ph_content.strip() else "暂无既往史信息" + + # 获取示例输出格式 + example_output = InquirerPrompt.get_example_output() + + prompt = f"""患者基本信息: +患者主述: {chief_complaint} +现病史: {hpi_content} +既往史: {past_history_display} + +基于以上患者信息,请生成一个针对性的问诊问题,帮助医生获取更多诊断相关信息。 + +输出格式示例: +{example_output} + +请严格按照上述JSON格式输出。 +输出内容为:""" + + return prompt \ No newline at end of file diff --git a/agent_system/inquirer/prompt.py b/agent_system/inquirer/prompt.py new file mode 100644 index 0000000..36530b9 --- /dev/null +++ b/agent_system/inquirer/prompt.py @@ -0,0 +1,53 @@ +from agent_system.base import BasePrompt + + +class InquirerPrompt(BasePrompt): + """ + 询问者智能体的提示词模板 + + 该提示词模板的description和instructions主体内容由Prompter智能体动态生成, + 只在末尾添加固定的输入信息和输出格式要求。 + """ + + # 基础描述,将被prompter结果动态替换 + description = "" + + # 基础指令,将被prompter结果动态替换 + instructions = [] + + @staticmethod + def get_example_output() -> str: + """ + 获取示例输出格式,用于指导 LLM 生成符合要求的结构化输出 + + Returns: + str: JSON 格式的示例输出 + """ + return """{ + "current_chat": "根据您描述的头痛情况,我想进一步了解一些细节。请问您的头痛是什么时候开始的?是突然出现还是逐渐加重的?另外,头痛主要集中在头部的哪个位置?" +}""" + + @staticmethod + def get_fixed_format_instructions() -> list: + """ + 获取固定的输入输出格式指令 + + Returns: + list: 固定的格式指令列表 + """ + return [ + "", + "## 患者信息输入格式", + "- 现病史: 患者当前疾病的详细描述", + "- 既往史: 患者过往的疾病史和治疗史", + "", + "## 输出要求", + "生成的问诊问题应该:", + "1. 针对患者的具体病情背景", + "2. 使用通俗易懂的语言表达", + "3. 有助于获取更多诊断相关信息", + "4. 符合医患交流的实际情况", + "", + "## 示例输出格式(JSON)", + InquirerPrompt.get_example_output() + ] \ No newline at end of file diff --git a/agent_system/inquirer/response_model.py b/agent_system/inquirer/response_model.py new file mode 100644 index 0000000..e498354 --- /dev/null +++ b/agent_system/inquirer/response_model.py @@ -0,0 +1,22 @@ +from pydantic import Field +from agent_system.base.response_model import BaseResponseModel + + +class InquirerResponseModel(BaseResponseModel): + """ + 询问者智能体响应模型 + + 该模型用于封装询问者智能体生成的问诊问题, + 基于患者的现病史和既往史生成医生需要询问的具体问题。 + + Attributes: + current_chat (str): 当前生成的问诊问题内容 + """ + current_chat: str = Field( + ..., + description=( + "基于患者现病史和既往史生成的医生问诊问题。" + "问题应该针对性强、专业准确,有助于获取更多诊断相关信息。" + "语言通俗易懂,符合医患交流的实际情况。" + ) + ) \ No newline at end of file diff --git a/test_prompter.py b/test_prompter.py deleted file mode 100644 index 6ad5826..0000000 --- a/test_prompter.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -""" -测试Prompter智能体功能 -""" - -from agent_system.prompter import Prompter - -def test_prompter(): - """测试Prompter智能体的基本功能""" - - # 创建Prompter实例 - prompter = Prompter() - - # 测试数据 - hpi_content = "患者反复头痛3个月,以前额和颞部为主,呈搏动性疼痛,每周发作2-3次,每次持续4-6小时" - ph_content = "既往体健,无高血压、糖尿病等慢性疾病史,无头部外伤史" - chief_complaint = "反复头痛3个月" - current_task = "起病情况和患病时间" - - print("=== 测试Prompter智能体 ===") - print(f"患者主述: {chief_complaint}") - print(f"现病史: {hpi_content}") - print(f"既往史: {ph_content}") - print(f"当前任务: {current_task}") - print() - - try: - # 执行Prompter分析 - result = prompter.run( - hpi_content=hpi_content, - ph_content=ph_content, - chief_complaint=chief_complaint, - current_task=current_task - ) - - print("=== Prompter分析结果 ===") - print(f"子智能体描述:") - print(f"{result.description}") - print() - print(f"子智能体指令:") - for i, instruction in enumerate(result.instructions, 1): - print(f"{i}. {instruction}") - print() - - except Exception as e: - print(f"测试失败: {e}") - -if __name__ == "__main__": - test_prompter() \ No newline at end of file