MCP和Function Calling:基础知识与实践

在人工智能领域,MCP(Managed Context Protocol)和Function Calling是两个重要的概念,它们在AI应用中发挥着不同的作用。下面我们将以简单易懂的方式介绍它们的基础知识,并提供实例和代码示例,以帮助读者更好地理解。

1. 目的和范围

  • MCP:MCP是一个通用协议标准,类似于USB-C接口,允许AI模型与不同平台、不同数据源之间进行标准化的通信。这使得AI系统更加开放和互操作
  • Function Calling:Function Calling是特定模型或平台的功能扩展,允许LLM调用预定义函数以执行特定操作。它通常局限于特定的模型或平台

2. 执行方式

  • MCP:MCP协议是异步的,发送请求后程序不会等待结果,而是继续执行其他代码,等结果出来再处理。这适合处理时间较长的任务
  • Function Calling:Function Calling是同步的,调用函数后程序会一直等待函数执行完并返回结果,才继续执行后续代码。这适合需要立即得到结果的场景

3. 应用场景

  • MCP:适合处理复杂、多步骤的任务,如网络请求、文件读写等。例如,使用MCP可以让AI模型与数据库进行交互,获取数据并处理
  • Function Calling:适合需要立即得到结果,并且后续代码依赖这个结果的场景。例如,查询天气信息或执行简单的数学计算

4. 灵活性和开放性

  • MCP:更开放和灵活,可用于各种服务和AI Agent的集成。这意味着开发者可以轻松地将不同的服务接入到AI系统中
  • Function Calling:相对受限,取决于平台提供的功能定义。这意味着开发者需要依赖特定平台的API和功能

代码示例

Function Calling示例(Python)

python 复制代码
def get_weather(location):
    # 查询天气信息的函数
    return f"{location} 的天气是晴天"

# 调用函数
weather = get_weather("北京")
print(weather)

MCP协议示例(Python)

python 复制代码
import json
import requests

def fetch_data(url):
    # 使用MCP协议发送请求获取数据
    headers = {"Content-Type": "application/json"}
    payload = {"url": url}
    response = requests.post("http://mcp-server.com/fetch", headers=headers, data=json.dumps(payload))
    return response.json()

# 获取数据
data = fetch_data("https://example.com")
print(data)

总结

  • MCP:是一个通用标准协议,旨在构建开放的AI生态系统,适合处理复杂任务。
  • Function Calling:是特定模型的功能扩展,适用于特定的应用场景,需要立即得到结果。

要基于 OpenAI 使用 Model Context Protocol (MCP),你需要了解 MCP 的基本架构和功能。MCP 是一种标准化协议,允许 AI 模型与外部工具和数据源进行交互,而无需为每个工具编写自定义代码。以下是一个使用 MCP 的基本示例,展示如何连接到一个 MCP 服务器并调用工具。

MCP 基本概念

  • MCP 主机:请求数据或操作的 AI 模型(例如 Azure OpenAI GPT)。
  • MCP 客户端:AI 模型内部的组件,负责与 MCP 服务器通信。
  • MCP 服务器:连接 AI 模型与外部系统(如数据库或 API)的中间件。

示例代码

这个示例使用 Python 和 MCP 库来连接到一个 MCP 服务器,并调用一个名为 get_forecast 的工具。我们假设你已经安装了必要的库,并且有一个 MCP 服务器脚本(例如 server.py)。

依赖库

你需要安装以下库:

bash 复制代码
pip install mcp openai

MCP 客户端代码

python 复制代码
import asyncio
import os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from openai import OpenAI

# 加载环境变量
load_dotenv()

class MCPClient:
    def __init__(self):
        self.openai_api_key = os.getenv("OPENAI_API_KEY")
        self.base_url = os.getenv("BASE_URL")
        self.model = os.getenv("MODEL")
        
        if not self.openai_api_key:
            raise ValueError("未找到 OpenAI API Key")
        
        self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)
        self.session = None

    async def connect_to_server(self, server_script_path: str):
        is_python = server_script_path.endswith('.py')
        is_js = server_script_path.endswith('.js')
        
        if not (is_python or is_js):
            raise ValueError("服务器脚本必须是 .py 或 .js 文件")
        
        command = "python" if is_python else "node"
        server_params = StdioServerParameters(command=command, args=[server_script_path], env=None)
        
        stdio_transport = await asyncio.create_task(stdio_client(server_params))
        self.stdio, self.write = stdio_transport
        self.session = await ClientSession(self.stdio, self.write).initialize()

        # 列出 MCP 服务器上的工具
        response = await self.session.list_tools()
        tools = response.tools
        print("\n已连接到服务器,支持以下工具:", [tool.name for tool in tools])

    async def process_query(self, query: str) -> str:
        messages = [{"role": "user", "content": query}]
        
        # 获取可用的工具
        response = await self.session.list_tools()
        available_tools = [{"type": "function", "function": {"name": tool.name, "description": tool.description, "input_schema": tool.inputSchema}} for tool in response.tools]
        
        # 调用 OpenAI API 并传递工具信息
        response = self.client.chat.completions.create(model=self.model, messages=messages, tools=available_tools)
        
        # 处理工具调用
        if response.choices[0].finish_reason == "tool_calls":
            tool_call = response.choices[0].message.tool_calls
            tool_name = tool_call.function.name
            tool_args = json.loads(tool_call.function.arguments)
            
            # 执行工具调用
            result = await self.session.call_tool(tool_name, tool_args)
            print(f"\n\n[Calling tool {tool_name} with args {tool_args}]\n\n")
            
            # 将结果返回给用户
            return result.content.text
        
        return response.choices[0].message.content

    async def chat_loop(self):
        print("\n🤖 MCP 客户端已启动!输入 'quit' 退出")
        
        while True:
            try:
                query = input("\n你: ").strip()
                if query.lower() == 'quit':
                    break
                
                response = await self.process_query(query)
                print(f"\n🤖 OpenAI: {response}")
            except Exception as e:
                print(f"\n⚠️ 发生错误: {str(e)}")

async def main():
    if len(sys.argv) < 2:
        print("Usage: python client.py <path_to_server_script>")
        sys.exit(1)
    
    client = MCPClient()
    try:
        await client.connect_to_server(sys.argv[1])
        await client.chat_loop()
    except Exception as e:
        print(f"\n⚠️ 发生错误: {str(e)}")

if __name__ == "__main__":
    import sys
    asyncio.run(main())

运行示例

  1. 启动 MCP 服务器 :确保你有一个 MCP 服务器脚本(例如 server.py),并且它已经配置好工具(如 get_forecast)。

  2. 运行客户端脚本:使用以下命令运行客户端脚本,传入服务器脚本路径作为参数。

    bash 复制代码
    python client.py server.py
  3. 与 AI 交互 :在客户端终端中输入查询,例如"北京今天天气如何?",如果配置了相应的工具(如 get_forecast),MCP 将自动调用该工具并返回结果。

注意事项

  • 确保 .env 文件中正确配置了 OpenAI API Key 和 Base URL。
  • MCP 服务器脚本需要正确配置并运行,以提供工具访问功能。
  • 本示例使用了简化的错误处理和日志记录,实际应用中应添加更全面的异常处理和日志记录。
相关推荐
CQ_07123 小时前
自学记录:力扣hot100第三题
算法·leetcode
Wilber的技术分享5 小时前
【机器学习实战笔记 12】集成学习:AdaBoost算法
人工智能·笔记·算法·决策树·机器学习·分类·集成学习
金融小师妹7 小时前
基于LSTM-GARCH混合模型的“获利了结”量化解析:黄金单日1.27%跌幅的技术性归因
大数据·人工智能·算法
不良手残8 小时前
Java实现10大经典排序算法
数据结构·算法·排序算法
是紫焅呢8 小时前
I排序算法.go
开发语言·后端·算法·golang·排序算法·学习方法·visual studio code
fangeqin8 小时前
CentOS 8解决ssh连接github时sign_and_send_pubkey失败问题
centos·ssh·github
lovebugs8 小时前
Java线上死锁问题实战:从定位到解决的全链路指南
java·后端·面试
辉辉还没睡8 小时前
Lora训练
人工智能·算法·机器学习
丘山子10 小时前
一些 Python 字典(dict)的常见使用误区
后端·python·面试
电院大学僧10 小时前
初学python的我开始Leetcode题10-2
python·算法·leetcode