多步工具编排系统

一个使用模型上下文协议(MCP)、LangChain和自定义LLM集成(ChatMMC)的多步骤工具编排系统,能够自动规划和执行多步骤工作流程。

  • by ANKIT9263
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 ANKIT9263/mcp_demo_owg

使用说明

MCP代理演示

一个使用模型上下文协议(MCP)、LangChain和自定义LLM集成(ChatMMC)的多步骤工具编排系统。该系统使用可用工具自动规划和执行多步骤工作流。

🌟 特性

  • 自动规划:LLM支持的多步骤执行计划
  • 工具编排:具有依赖关系管理的顺序工具执行
  • 流式API:实时服务器发送事件(SSE)流
  • 聊天界面:使用Streamlit构建的类似ChatGPT的UI
  • 可扩展:易于添加新工具

📋 先决条件

  • Python 3
  • MMC API密钥(内部使用)或兼容的LLM API端点

🚀 安装

  1. 克隆仓库

    cd /Users/ankit/Desktop/varsha_projects/mcp_demo_owg
    
  2. 安装依赖项

    pip install fastmcp langchain-openai python-dotenv uvicorn fastapi streamlit requests
    
  3. 设置环境变量

    复制示例环境文件并使用您的凭据进行更新:

    cp .env.example .env
    

    编辑 .env 使用您的API证书:

    # Organization LLM Configuration
    ORG_LLM_ENDPOINT=https://your-api-endpoint/chat/completions
    ORG_LLM_API_KEY=your-api-key-here
    ORG_LLM_MODEL=your-model-name
    ORG_LLM_BASE_URL=https://your-api-base-url
    
    # OpenAI Compatible Keys (used by ChatMMC)
    OPENAI_API_KEY=your-api-key-here
    OPENAI_MODEL=your-model-name
    

🎯 快速开始

选项1:使用Streamlit UI(推荐)

  1. 启动MCP服务器 (1号航站楼)

    python server.py
    

    服务器运行时间: http://localhost:8080/mcp

  2. 启动API服务器 (2号航站楼)

    python api.py
    

    API运行于: http://localhost:8000

  3. 启动Streamlit应用程序 (3号航站楼)

    streamlit run streamlit_app.py
    

    UI在以下位置打开: http://localhost:8501

选项2:直接使用Python客户端

python client.py

选项3:使用带卷曲的API

curl -X POST http://localhost:8000/run_agent \
  -H "Content-Type: application/json" \
  -d '{"query": "add 5 and 8 then multiply by 6"}'

📁 项目结构

mcp_demo_owg/
├── server.py              # MCP server (loads and registers tools)
├── api.py                 # FastAPI server with SSE streaming
├── client.py              # MCPAgentOrchestrator class
├── streamlit_app.py       # Streamlit chat interface
├── llm.py                 # ChatMMC class (custom LLM integration)
├── tools/
│   ├── generic_tools.py   # Conversational tools
│   └── math_tools.py      # Math operation tools
├── .env                   # Environment variables (create from .env.example)
├── .env.example           # Example environment configuration
└── README.md              # This file

🤖 自定义LLM集成(ChatMMC)

该项目使用自定义 ChatMMC 上课中 llm.py 与您的组织的LLM API端点集成。本课程旨在作为以下课程的直接替代 ChatOpenAI 来自LangChain。

特征:

  • 与LangChain链和管道兼容
  • 支持环境变量配置
  • 处理dict和LangChain消息格式
  • 自动从以下位置加载凭据 .env 文件

使用示例:

from llm import ChatMMC

# Initialize with defaults from .env
llm = ChatMMC()

# Or explicitly provide configuration
llm = ChatMMC(
    api_key="your-api-key",
    model="your-model-name",
    temperature=0.7
)

# Use it like ChatOpenAI
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello!"}
]

response = llm.invoke(messages)
print(response)

环境变量:

这 ChatMMC 类按照优先顺序从这些环境变量中读取:

  1. OPENAI_API_KEY 或 ORG_LLM_API_KEY -您的API密钥
  2. OPENAI_MODEL 或 ORG_LLM_MODEL -型号名称
  3. ORG_LLM_BASE_URL -API终结点的基本URL

🛠️ 添加新工具

步骤1:创建工具文件

在中创建新文件 tools/ 目录(例如。, tools/my_custom_tools.py):

"""
My Custom Tools for MCP
-----------------------
"""

from fastmcp import FastMCP

def register_tools(mcp: FastMCP):
    """Register custom tools with the MCP server"""

    @mcp.tool()
    async def greet_user(name: str) -> str:
        """Greet a user by name"""
        return f"Hello, {name}! Welcome to MCP Agent."

    @mcp.tool()
    async def calculate_square(number: float) -> float:
        """Calculate the square of a number"""
        return number ** 2

    @mcp.tool()
    async def reverse_text(text: str) -> str:
        """Reverse a given text"""
        return text[::-1]

    print("✅ Custom tools registered")

步骤2:注册工具模块

更新 server.py 加载新工具:

def create_mcp_server() -> FastMCP:
    """Create a single MCP server and load all tool modules."""
    mcp = FastMCP("IntegratedTools")

    # Add your new module to this list
    tool_modules = [
        "generic_tools",
        "my_custom_tools"  # Add this line
    ]

    for module_name in tool_modules:
        # ... rest of the code

步骤3:重新启动服务器

重新启动MCP服务器以加载新工具:

python server.py

工具功能要求

  • 必须 async 函数
  • 对参数使用类型提示
  • 包含文档字符串(由规划者使用)
  • 用…装饰 @mcp.tool()
  • 返回可序列化数据(str、int、float、dict、list)

示例:带有API集成的工具

@mcp.tool()
async def fetch_weather(city: str, api_key: str) -> dict:
    """Fetch current weather for a city"""
    import httpx

    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"https://api.weather.com/v1/current",
            params={"city": city, "key": api_key}
        )
        return response.json()

🧪 测试

卷曲测试(SSE流)

curl -N -X POST http://localhost:8000/run_agent \
  -H "Content-Type: application/json" \
  -d '{
    "query": "first add 5 and 8 then multiply by 6"
  }'

预期产量:

event: plan
data: {"plan": [{"tool": "add", "args": [5, 8]}, {"tool": "multiply", "args": ["PREVIOUS_RESULT", 6]}]}

event: step
data: {"step": 1, "tool": "add", "args": {"a": 5, "b": 8}}

event: step_result
data: {"step": 1, "result": 13}

event: step
data: {"step": 2, "tool": "multiply", "args": {"a": 13, "b": 6}}

event: step_result
data: {"step": 2, "result": 78}

event: final
data: {"result": 78}

event: done
data: {}

与邮递员一起测试

  1. 创建新的POST请求

    • 网址: http://localhost:8000/run_agent
    • 标题: Content-Type: application/json
  2. 请求正文:

    {
      "query": "calculate (10 + 5) * 3"
    }
    
  3. 查看流媒体响应 在Postman控制台中

查询示例

# Math operations
curl -X POST http://localhost:8000/run_agent \
  -H "Content-Type: application/json" \
  -d '{"query": "what is 100 divided by 4?"}'

# Multi-step calculation
curl -X POST http://localhost:8000/run_agent \
  -H "Content-Type: application/json" \
  -d '{"query": "subtract 10 from 50, then multiply the result by 2"}'

# Using conversational tools
curl -X POST http://localhost:8000/run_agent \
  -H "Content-Type: application/json" \
  -d '{"query": "say hello to me"}'

🔧 API 参考

POST/run_agent

执行多步骤代理工作流。

请求:

{
  "query": "your natural language query here"
}

答复: 服务器发送事件(SSE)流

事件类型:

  • plan -已生成执行计划
  • step -工具执行已开始
  • step_result -工具执行已完成
  • final -最终结果
  • error -发生错误
  • done -流已完成

🏗️ 建筑

┌─────────────────┐
│  Streamlit UI   │
│  (Port 8501)    │
└────────┬────────┘
         │ HTTP POST
         ▼
┌─────────────────┐
│   FastAPI       │
│   (Port 8000)   │ ◄─── SSE Stream
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ MCPAgent        │
│ Orchestrator    │
└────────┬────────┘
         │ HTTP
         ▼
┌─────────────────┐
│   MCP Server    │
│   (Port 8080)   │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  Tool Modules   │
│  (generic, etc) │
└─────────────────┘

🔒 安全

  • API键在UI中自动屏蔽(显示为 sk-...)
  • 从流式响应中过滤敏感参数
  • 凭证管理的环境变量

🐛 故障排除

问题:“计划输出无效”

解决方案: LLM未生成有效的JSON。在中检查您的API密钥和型号名称 .env 文件。确保 OPENAI_API_KEY 和 OPENAI_MODEL 设置正确。

问题:端口8080上的“连接被拒绝”

解决方案: 确保MCP服务器正在运行(python server.py).

问题:LLM API连接错误

解决方案:

  • 验证API端点是否可访问:检查 ORG_LLM_BASE_URL 在 .env
  • 确认您的API密钥有效:检查 OPENAI_API_KEY 在 .env
  • 使用curl手动测试端点以验证连接

问题:“找不到模块”错误

解决方案: 安装缺少的依赖项:

pip install fastmcp langchain-openai python-dotenv uvicorn fastapi streamlit

📝 可用工具(默认)

数学工具

  • add(a, b) -加两个数字
  • subtract(a, b) -从a中减去b
  • multiply(a, b) -将两个数字相乘
  • divide(a, b) -将a除以b

会话工具

  • handle_greeting(text, openai_api_key) -回应问候

🤝 贡献

要添加新的工具类别,请执行以下操作:

  1. 在中创建新文件 tools/ 目录
  2. 实施 register_tools(mcp) 功能
  3. 将模块名称添加到 tool_modules 列入 server.py
  4. 重新启动MCP服务器

📄 许可证

MIT许可证

🙏 致谢