医疗搜索多LLM代理

一个基于多LLM代理的医疗问答系统,通过检索增强生成(RAG)方法整合网络搜索和PubMed数据,提供医学问题解答。

  • by Kush614
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 kush614/multi-llm-medical-agent-using-mcp-server

使用说明

CliniSearch-用于医学搜索的多LLM代理

该项目在Python中实现了一个旨在回答医学问题的Multi-LLM Agent系统。它利用自定义模型上下文协议(MCP)与不同的工具服务器进行交互,以进行信息检索(Web搜索和PubMed搜索)。核心代理使用Retrieval-AugedGeneration(RAG)方法,从拥抱面部推理API编排多个免费的大型语言模型(LLM),以执行查询细化、上下文片段摘要和最终答案合成等任务。该系统旨在根据从网络搜索和PubMed检索到的上下文提供单独的综合答案,包括原始源材料的链接。

视频演示链接

https://youtu.be/JvFvCYFYpzU?si=Vho8MM5Dy7YQk53E

系统架构

两个llm模型使用免费层拥抱面部api中的distillabart和mistral指令

核心方法与设计

该系统遵循一个多步骤的代理RAG流程:

  1. 用户输入: 代理人回答用户的医疗问题。
  2. (可选)查询优化(LLM1): 用户的问题可以传递给第一LLM(例如。, mistralai/Mistral-7B-Instruct-v0.3)生成更简洁有效的搜索查询,重点关注关键的医学术语。
  3. 信息检索(MCP工具):
    • (可能经过优化的)搜索查询被发送到一个或两个MCP工具服务器:
      • Web搜索MCP服务器: 使用以下命令查询通用web duckduckgo-search.
      • PubMed MCP服务器: 使用以下命令查询PubMed数据库 BioPython输入实用程序。
    • 这些服务器返回结构化搜索结果(标题、代码段、URL/ID)。
  4. 上下文处理:
    • (可选)代码段摘要(LLM2): 对于每个搜索结果,如果片段很长,则可以将其传递给专门的摘要LLM(例如。, sshleifer/distilbart-cnn-6-6)以创建更简洁的版本。
    • 上下文格式: 来自每个来源(Web搜索、PubMed)的(摘要或原始)片段被单独格式化为结构化上下文字符串。上下文中的每个项目都有标签(例如,“项目1”、“项目2”),并包括其标题、内容和参考(URL或PubMed ID)。
  5. 答案综合(LLM3-RAG):
    • 对于每个信息源(网络搜索、PubMed),代理单独调用功能强大的指令调优LLM(例如。, mistralai/Mistral-7B-Instruct-v0.3).
    • 此LLM的提示包括:
      • 原始用户问题。
      • 格式化的上下文 来自该特定来源.
      • 基于答案的指令 仅 根据提供的上下文,并在可能的情况下引用项目编号。
    • 该LLM为该来源生成一个综合答案。
  6. 输出: 该系统首先呈现原始问题,然后是从网络搜索(带源链接)中得出的合成答案,然后是来自PubMed(带源连接)的合成答案。

关键技术:

  • Python 3.9+ 随着 asyncio 为了实现并发性。
  • FastAPI和Uvicorn: 用于构建异步MCP工具服务器。
  • httpx: 用于从代理到MCP服务器和Hugging Face API的异步HTTP请求。
  • 拥抱面部推理API: 访问免费的LLM以进行改进、总结和综合。
  • duckduckgo-search: 用于无API密钥的网络搜索。
  • BioPython: 用于查询NCBI的PubMed数据库。
  • python-dotenv: 用于管理API密钥和环境变量。

模型上下文协议(MCP)定义

本项目中使用的MCP是一个简单的基于HTTP的JSON协议,用于主代理和工具服务器之间的通信:

  • 向MCP服务器发出请求:
    • 端点: POST /execute
    • JSON正文: {"query": "user's search query string"}
  • MCP服务器的响应:
    • JSON正文(成功):
      {
        "source": "server_name_string (e.g., WebSearchServer, PubMedServer)",
        "status": "success",
        "results": [
          {
            "title": "string",
            "snippet": "string",
            "url": "string_url_if_web_search", // or missing
            "id": "string_pubmed_id_if_pubmed" // or missing
          }
          // ... more results
        ]
      }
      
    • JSON正文(错误):
      {
        "source": "server_name_string",
        "status": "error",
        "error_message": "string_describing_the_error"
      }
      

安装说明

  1. 克隆/下载:

    • 获取项目文件并将其放置在名为的目录中 intra_intel_multi_llm_challenge.
  2. 创建并激活Python虚拟环境:

    • 导航到项目根目录(intra_intel_multi_llm_challenge).
    • 创造环境:
      python -m venv venv
      
    • 激活它:
      • 在macOS/Linux上: source venv/bin/activate
      • 在Windows上: venv\Scripts\activate
  3. 安装依赖关系:

    pip install -r requirements.txt
    
  4. 配置环境变量:

    • 在项目根目录中,复制文件 .env.example 到名为的新文件 .env.
    • 打开 .env 归档并填写您的详细信息:
      # .env
      HF_API_TOKEN="your_huggingface_api_token_here"
      NCBI_EMAIL="your_email_for_pubmed@example.com"
      
      • HF_API_TOKEN: 从您的Hugging Face帐户设置中获取此信息(https://huggingface.co/settings/tokens).一个令牌 read 权限就足够了。
      • NCBI_EMAIL: 请提供您的电子邮件地址,以便通过Entrez礼貌地编程访问NCBI的PubMed数据库。此项目不需要事先向NCBI注册此电子邮件。
  5. 接受门控模型的条款(对Mistral至关重要):

    • 使用的默认文本生成LLM是 mistralai/Mistral-7B-Instruct-v0.3这是一个门控模型。
    • 登录 在他们的网站上登录您的Hugging Face帐户。
    • 转到型号卡页面: https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.3
    • 阅读和 接受许可条款 以访问此模型。你的 HF_API_TOKEN 将被授权使用它。如果跳过此操作,则对此模型的API调用将失败。

运行系统

系统要求MCP服务器在主代理查询之前运行。

  1. 终端1:启动Web搜索MCP服务器:

    • 导航到项目根目录(intra_intel_multi_llm_challenge).
    • 确保您的虚拟环境已激活。
    • 运行:
      python -m uvicorn mcp_servers.web_search_server:app --reload --port 8001
      
    • 等待指示Uvicorn正在运行的消息(例如。, Uvicorn running on http://0.0.0.0:8001).
  2. 终端2:启动PubMed MCP服务器(用于奖励功能):

    • 导航到项目根目录。
    • 确保您的虚拟环境已激活。
    • 运行:
      python -m uvicorn mcp_servers.pubmed_search_server:app --reload --port 8002
      
    • 等待Uvicorn启动确认。
  3. 终端3:运行主代理:

    • 导航到项目根目录。
    • 确保您的虚拟环境已激活。
    • 运行:
      python agent/main_agent.py
      
    • 代理将处理一个预定义的5个医疗问题列表。对于每个问题,它将:
      • 可以选择使用LLM1细化查询。
      • 查询Web搜索MCP服务器。
      • 可选择使用LLM2总结网络搜索片段。
      • 使用LLM3根据网络搜索上下文合成答案。
      • 打印基于网络搜索的答案及其源链接。
      • 查询PubMed MCP服务器(如 use_pubmed_for_this_question 是 True 在示例中默认)。
      • 可选择使用LLM2总结PubMed片段。
      • 使用LLM3根据PubMed上下文合成答案。
      • 打印基于PubMed的答案及其源链接。
    • 在处理每个问题之间都会暂停,以考虑到拥抱脸API的费率限制。

    关于承压面API模型荷载的说明: 第一次通过推理API调用LLM时,可能需要通过拥抱面部加载,这可能需要20-90秒(对于Mistral-7B等较大型号,可能需要更长时间)。后续通话通常更快。该脚本包括超时和处理模型加载消息的尝试。

定制和调试

  • LLM选择: 你可以改变 VERIFIED_INSTRUCT_MODEL_ID 和 SUMMARIZATION_MODEL_ID 在……里面 agent/main_agent.py 如果您发现其他模型在Hugging Face free推理API上工作得更好或更可靠(请始终首先使用模型卡片页面上的小部件进行验证!)。
  • 切换功能: 在 if __name__ == "__main__": 块 agent/main_agent.py,您可以更改 refine_queries 和 summarize_snippets 传递给的布尔标志 main_agent_workflow 在启用或禁用这些步骤的情况下测试管道。您也可以更改 use_pubmed_for_this_question 对于个人通话。
  • 详细日志记录: 要查看详细的调试信息(API有效负载、完整上下文等):
    1. 打开 agent/main_agent.py.
    2. 改变 LOG_LEVEL = logging.INFO 向 LOG_LEVEL = logging.DEBUG.
    3. 保存并重新运行代理。

依赖项

主要依赖关系列在 requirements.txt:

  • fastapi:用于构建MCP服务器。
  • uvicorn[standard]:FastAPI的ASGI服务器。
  • httpx:用于发出异步HTTP请求。
  • duckduckgo-search:用于网络搜索功能。
  • biopython:通过NCBI Entrez查询PubMed。
  • python-dotenv:用于管理环境变量。

此自述文件应涵盖理解、设置和运行项目所需的详细信息。

示例医疗问题输出截图

网络搜索

Pubmed搜索