对话AI队列服务

一个基于MCP协议和OpenRouter API的对话AI队列服务,通过Redis实现异步请求处理,适用于高并发的AI文本生成场景。

  • by waifuai
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 waifuai/mcp-waifu-queue

使用说明

MCP外富队列

该项目为对话AI“waifu”角色实现了一个MCP(模型上下文协议)服务器,通过Redis队列利用OpenRouter API进行异步处理。它利用了 FastMCP 用于简化服务器设置和管理的库。

目录

特性

  • 使用模型通过OpenRouter生成文本 ~/.model-openrouter 或 openrouter/free.
  • 使用Redis异步处理并发请求的请求队列。
  • 符合MCP的API,使用 FastMCP.
  • 通过MCP资源跟踪作业状态。
  • 通过环境变量进行配置(.env 文件)。
  • API密钥加载:
    • OpenRouter: OPENROUTER_API_KEY 或 ~/.api-openrouter
  • 主目录中的型号选择文件:
    • ~/.model-openrouter OpenRouter型号名称

建筑

该项目由几个关键组成部分组成:

  • main.py:主入口点,初始化 FastMCP 应用程序和定义MCP工具/资源。
  • respond.py:包含使用OpenRouter API的核心文本生成逻辑。
  • task_queue.py:处理与Redis队列的交互(使用 python-rq),查询生成请求。
  • utils.py:包含实用程序功能,特别是 call_predict_response 该程序由工作人员执行,以调用生成逻辑 respond.py.
  • worker.py:Redis工作者(python-rq)处理队列中的作业,调用 call_predict_response.
  • config.py:使用管理配置 pydantic-settings.
  • models.py:定义MCP请求和响应验证的Pydantic模型。

请求流程如下:

  1. 客户端向 generate_text MCP工具(定义见 main.py).
  2. 该工具将请求(提示)排队到Redis队列(由处理 task_queue.py).
  3. A. worker.py 进程从队列中拾取作业。
  4. 工人执行 call_predict_response 功能(从 utils.py).
  5. call_predict_response 呼叫 predict_response 功能(in respond.py),与OpenRouter API交互。
  6. 生成的文本(或错误消息)由返回 predict_response 并由RQ存储为作业结果。
  7. 客户端可以使用以下命令检索作业状态和结果 job://{job_id} MCP资源(定义见 main.py).
graph LR
    subgraph Client
        A[User/Client] -->|1. Send Prompt via MCP Tool| B(mcp-waifu-queue: main.py)
    end
    subgraph mcp-waifu-queue Server
        B -->|2. Enqueue Job (prompt)| C[Redis Queue]
        B -->|7. Return Job ID| A
        D[RQ Worker (worker.py)] --|>| C
        D -->|3. Dequeue Job & Execute| E(utils.call_predict_response)
        E -->|4. Call Generation Logic| F(respond.predict_response)
        F -->|5. Call OpenRouter API| G[OpenRouter API]
        G -->|6. Return Response| F
        F --> E
        E -->|Update Job Result in Redis| C
        A -->|8. Check Status via MCP Resource| B
        B -->|9. Fetch Job Status/Result| C
        B -->|10. Return Status/Result| A
    end

先决条件

  • Python 3.7+
  • pip 或 uv (Python包安装程序)
  • Redis服务器(已安装并正在运行)
  • 一个OpenRouter API密钥

您可以在Redis官方网站上找到在您的系统上安装Redis的说明: https://redis.io/docs/getting-started/ 您可以从以下位置获取OpenRouter API密钥: https://openrouter.ai/

安装

  1. 克隆存储库:

    git clone <YOUR_REPOSITORY_URL>
    cd mcp-waifu-queue
    
  2. 使用创建和激活虚拟环境 uv:

    python -m uv venv .venv
    .venv/Scripts/python.exe -m ensurepip
    .venv/Scripts/python.exe -m pip install uv
    
  3. 安装依赖项:

    .venv/Scripts/python.exe -m uv pip install -r requirements.txt
    .venv/Scripts/python.exe -m uv pip install -r requirements-dev.txt
    

配置

  1. 通过$HOME中的文件显示型号名称:

    • OpenRouter模型文件:
      echo "openrouter/free" > ~/.model-openrouter
      
  2. API密钥: 首选通过带有文件回退的环境变量:

    • OpenRouter: OPENROUTER_API_KEY 或 ~/.api-openrouter
    echo "YOUR_API_KEY_HERE" > ~/.api-openrouter
    

    (替换 YOUR_API_KEY_HERE 使用您的实际密钥)

  3. 其他设置: 复制 .env.example 文件到 .env:

    cp .env.example .env
    
  4. 修改 .env 文件以设置其余配置值:

    • MAX_NEW_TOKENS:响应的最大令牌数(默认值: 2048).
    • REDIS_URL:Redis服务器的URL(默认值: redis://localhost:6379).
    • FLASK_ENV, FLASK_APP:可选,如果在其他地方使用,则与Flask相关,而不是MCP服务器/工作程序操作的核心。

运行服务

  1. 确保Redis正在运行。 如果你在本地安装了它,你可能需要启动Redis服务器进程(例如。, redis-server 命令或通过服务管理器)。

  2. 启动RQ Worker: 打开终端,激活您的虚拟环境(source .venv/bin/activate 或类似),并运行:

    python -m mcp_waifu_queue.worker
    

    此命令启动worker进程,该进程将侦听Redis队列中定义的作业 .env 文件。保持此终端运行。

  3. 启动MCP服务器: 打开 另一个 终端,激活虚拟环境,并使用以下工具运行MCP服务器 uvicorn (您可能需要安装它: pip install uvicorn 或 uv pip install uvicorn):

    uvicorn mcp_waifu_queue.main:app --reload --port 8000 # Example port
    

    替换 8000 您想要的港口 --reload 国旗对发展很有用。

    或者,您可以使用 start-services.sh 脚本(主要为Linux/macOS环境设计),尝试在后台启动Redis(如果未运行)和worker:

    # Ensure the script is executable: chmod +x ./scripts/start-services.sh
    ./scripts/start-services.sh
    # Then start the MCP server manually as shown above.
    

MCP API

服务器提供以下符合MCP的端点:

工具

  • generate_text
    • 说明: 通过后台队列向OpenRouter API发送文本生成请求。
    • 输入: {"prompt": "Your text prompt here"} (类型: GenerateTextRequest)
    • 输出: {"job_id": "rq:job:..."} (排队作业的唯一ID)

资源

  • job://{job_id}
    • 说明: 检索以前提交的作业的状态和结果。
    • URI参数: job_id (返回的ID generate_text 工具)。
    • 输出: {"status": "...", "result": "..."} (类型: JobStatusResponse)
      • status:作业的当前状态(例如,“排队”、“已开始”、“完成”、“失败”)。RQ内部使用的术语略有不同(“开始”与“处理”、“完成”与“完成”)。资源映射了这些。
      • result:如果作业状态为“已完成”,则生成文本,否则 null。如果作业失败,结果可能是 null 或者根据RQ的处理包含错误信息。

测试

该项目包括测试。确保您已安装测试依赖项(pip install -e .[test] 或 uv pip install -e .[test]).

使用以下命令运行测试 pytest:

pytest tests

注: 测试可能需要模拟Redis(fakeredis)以及可能的OpenRouter API调用,这取决于它们的实现。

故障排除

  • 错误: OpenRouter API key not available:确保 OPENROUTER_API_KEY 已设置或 ~/.api-openrouter 与您的密钥一起存在于一行中(没有空格)。
  • 工作陷入“排队”状态:验证RQ工作人员(python -m mcp_waifu_queue.worker)在单独的终端中运行,并连接到中指定的同一Redis实例 .env。检查工作日志是否有错误。
  • ConnectionRefusedError(Redis):确保你的Redis服务器正在运行,并且可以在 REDIS_URL 在...中指定 .env.
  • MCP服务器连接问题:确保MCP服务器(uvicorn ...)正在运行,并且您正在连接到正确的主机/端口。

贡献

  1. 分叉存储库。
  2. 为您的功能或错误修复创建一个新分支(git checkout -b feature/your-feature-name).
  3. 进行更改并提交(git commit -am 'Add some feature').
  4. 将您的分支推送到分叉存储库(git push origin feature/your-feature-name).
  5. 在原始存储库上创建Pull Request。

请遵守项目的编码标准和linting规则(ruff).

许可证

此项目根据MIT-0许可证获得许可-请参阅 许可证 文件以获取详细信息。