1Function Calling(函数调用)

Function Calling由OpenAI等公司推动,允许大语言模型与外部工具连接,将自然语言转换为API调用。这解决了大模型在训练结束,就知识更新停滞的问题。

通过调用外部工具和服务,Function Calling帮助大模型解决了比如今天温度多少度,今天的大盘收盘点数是多少之类的实时性问题。

Function Calling的工作原理可以通过以下几个简单步骤来理解:

以天气查询为例,Function Calling的工作流程大致如下:

第一步,识别需求 :这是一个关于实时天气的问题,需要调用外部天气API。

第二步,选择函数 :从可用函数中选择get_current_weather函数。

第三步,准备参数

Plain Text
{
  "location": "北京",
  "unit": "celsius"
}

第四步,调用函数 :系统使用这些参数调用实际的天气API,获取北京的实时天气数据。

第五步,整合回答 : "根据最新数据,北京今天的天气晴朗,当前温度23°C,湿度45%,微风。今天的最高温度预计为26°C,最低温度为18°C。"

对开发者来说,使用LLM的Function Calling起步相对容易,只需按照API要求定义函数规格(通常JSON模式)并将其随请求发送,模型就可能按照需要调用这些函数,逻辑较直观。

因此,对于**单一模型、少量功能**的简单应用,Function Calling 实现起来非常直接,几乎“一键”将模型输出对接到代码逻辑中。

然而,它的**局限**在于缺乏跨模型的一致性:每个LLM供应商的接口格式略有差异,开发者若想支持多个模型,需要为不同API做适配或使用额外框架处理。而且,**无状态性** :模型仅生成调用规范,实际执行由外部系统完成。

2MCP协议和开发

1、定义

MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口。

Function CallingAI模型调用函数的机制,MCP是一个标准协议,使AI模型与API无缝交互,而AI Agent是一个自主运行的智能系统,利用Function CallingMCP来分析和执行任务,实现特定目标。

 

即使是最强大模型也会受到数据隔离的限制,形成信息孤岛,要做出更强大的模型,每个新数据源都需要自己重新定制实现,使真正互联的系统难以扩展,存在很多的局限性。

现在,MCP 可以直接在 AI 与数据(包括本地数据和互联网数据)之间架起一座桥梁,通过 MCP 服务器和 MCP 客户端,大家只要都遵循这套协议,就能实现“万物互联”。

有了MCP,可以和数据和文件系统、开发工具、Web 和浏览器自动化、生产力和通信、各种社区生态能力全部集成,实现强大的协作工作能力,它的价值远不可估量。

2MCP Function Calling 的区别

  • MCP(Model Context Protocol),模型上下文协议
  • Function Calling,函数调用

这两种技术都旨在增强 AI 模型与外部数据的交互能力,但 MCP 不止可以增强 AI 模型,还可以是其他的应用系统。

3、工作原理

MCP 协议采用了一种独特的架构设计,它将 LLM 与资源之间的通信划分为三个主要部分:客户端、服务器和资源。

客户端负责发送请求给 MCP 服务器,服务器则将这些请求转发给相应的资源。这种分层的设计使得 MCP 协议能够更好地控制访问权限,确保只有经过授权的用户才能访问特定的资源。

以下是 MCP 的基本工作流程:

  • 初始化连接:客户端向服务器发送连接请求,建立通信通道。
  • 发送请求:客户端根据需求构建请求消息,并发送给服务器。
  • 处理请求:服务器接收到请求后,解析请求内容,执行相应的操作(如查询数据库、读取文件等)。
  • 返回结果:服务器将处理结果封装成响应消息,发送回客户端。
  • 断开连接:任务完成后,客户端可以主动关闭连接或等待服务器超时关闭。

4、通信机制

MCP 协议支持三种主要的通信机制:

  • 1、基于标准输入输出的本地通信(stdio);
  • 2、基于SSE(Server-Sent Events)的远程通信。是一种基于HTTP协议的单向通信协议,允许服务器以事件流的形式实时向客户端推送数据,而无需客户端明确请求。MCP中的SSE Transport结合了SSE技术和HTTP POST

  • 3、Streamable-http

streamable HTTP是MCP协议在2025年3月引入的一种新传输机制,旨在取代之前的HTTP+SSE传输模式。它的设计理念是在保留SSE优点的同时克服其限制,特别是提供更好的可扩展性和企业环境兼容性。

Streamable HTTP的核心思想是提供一个统一的HTTP端点,同时支持POST和GET方法:

  1. POST方法:用于客户端向服务器发送请求和接收响应
  1. GET方法(可选):用于建立SSE流,接收服务器实时推送的消息

与传统HTTP+SSE不同,Streamable HTTP不要求维护单独的初始化连接和消息端点,简化了协议设计并提高了可靠性。

  1. 连接:在streamable HTTP模式下,并没有和SSE模式类似的“连接”过程(在sse_client调用时),因为无需事先创建SSE连接;
  1.  客户端发起初始化请求(Initialize。如果是有状态模式,会在返回消息的HTTP头中携带session-id;
  1. 客户端发起初始化确认(Initialized。此时如果已有session-id(有状态),客户端会首先发起一次HTTP Get请求,以建立独立的SSE通道;
  1. 后续正常交互:普通的交互都是通过Post通道来进行,只有两种情况会使用SSE通道:服务端发起的通知与请求、以及会话恢复的事件发送。

Streamable HTTP相比SSE的五大优势

  1. 简化的通信模型

传统的HTTP+SSE方法需要两个不同的端点:一个用于建立连接,另一个用于发送消息。而Streamable HTTP提供了一个统一的端点,简化了客户端和服务器之间的交互。

  1. 支持无状态模式

Streamable HTTP的一个重要创新是支持完全无状态操作。通过设置sessionIdGenerator: () => undefined,服务器可以在不维护会话状态的情况下处理请求,非常适合无服务器环境。比如:部署在AWS LambdaAzure Functions等无服务器环境。短暂交互而非长期连接的场景。

  1. 更好的可伸缩性

由于Streamable HTTP可以在无状态模式下运行,它非常适合容器化和自动扩展场景。服务器不需要维护长期连接,可以根据请求动态分配资源,显著提高可伸缩性。

这解决了SSE的一个主要问题:当有大量客户端时,每个客户端都需要维持一个长连接,可能导致服务器资源耗尽。使用Streamable HTTP的无状态模式,服务器只在处理请求时分配资源,处理完成后即可释放。

  1. 提高的可靠性

Streamable HTTP的简化设计减少了出错机会:

  • 会话管理:在有状态模式下,会话ID通过HTTP头而非查询参数传递,减少安全风险
  • 重连处理:客户端可以在会话有效期内随时重连,无需复杂的重连逻辑
  • 错误恢复:简化的协议使错误处理和恢复更加直观
  1. 更好的企业环境兼容性

在企业环境中,代理服务器和防火墙常常会阻止非标准HTTP连接。Streamable HTTP使用标准HTTP通信,大大减少了这类问题:

  • 使用标准HTTP POST和GET,无需特殊配置
  • 不依赖长连接,减少代理超时问题
  • 会话ID通过HTTP头传递,更符合企业安全要求

5FastMCP:构建模型上下文协议(MCP)服务器的快速Python方案

Python
pip install langchain-mcp-adapters

Java开发MCP服务:把SpringBoot项目改造成MCP Server非常简单 - 知乎

Python开发MCP服务:FastMCP

开源的MCP服务项目:MCP servers | Glama

它提供了一种简单且高效的方法来构建MCP服务器,为开发者提供强大的工具和资源,从而帮助他们为LLMs提供上下文信息。

FastMCP的主要特性:

  • 快速:高层接口意味着更少的代码和更快的开发速度。
  • 简单:构建MCP服务器时,所需的样板代码最少。
  • Pythonic:符合Python开发者的直觉,使用起来更自然。
  • 完整:致力于提供MCP规格的全面实现(当前某些高级功能仍在开发中)。♂️
  • FastMCP正在积极开发中,而MCP规格本身也在不断完善。

6MCP的认证和安全

FastMCP 的 Bearer Token Authentication 认证机制基于 JWT (JSON Web Token) 标准实现,是一种无状态的、基于声明的安全验证体系。

认证验证流程

当请求到达服务端时,按以下顺序验证:

  • 存在性检查​:确认请求头包含 Authorization: Bearer <token>
  • 结构验证​:检查JWT格式是否符合规范
  • 签名验证​:使用配置的公钥验证签名有效性
  • 声明校验​:
  • iss 必须匹配 BearerAuthProvider 配置的签发方
  • aud 必须包含服务端指定的受众
  • exp 必须未过期
  • 权限检查​:Token中的 scopes 需满足工具要求的权限
  1. 生成 RSA 密钥对

作用​:生成用于 JWT 签名和验证的 RSA 密钥对

详细说明​:

  • 生成一对 RSA 密钥(公钥和私钥)
  • 公钥(public_key)用于验证 Token 签名
  • 私钥(private_key)用于签发 Token

Python
# 1. 生成 RSA 密钥对(生产环境应从安全存储读取)
key_pair = RSAKeyPair.generate()

  1. 配置 Bearer 认证提供方

Python
# 2. 配置认证提供方
auth = BearerAuthProvider(
    public_key=key_pair.public_key,  # 公钥用于校验签名
    issuer="http://localhost",  # 令牌签发方标识
    audience="my-dev-server",            # 目标服务标识
)

  1. 生成token

Python
# 服务器,模拟生成一个token
# Generate a token for testing
token = key_pair.create_token(
    subject="dev-user",
    issuer="http://localhost",
    audience="my-dev-server",
    scopes=["read", "write"]  # token中包含的数据
        expires_in_seconds=3600  # 1小时后过期
)

  1. 客户端Agent传入token
  2. 服务器验证和获取Token

get_access_token()

  • 作用​:从当前请求中提取并解码 JWT
  • 返回​:AccessToken 对象,包含以下主要属性:

Python
class AccessToken:
    client_id: str    # 对应JWT的'sub'(subject)声明
    scopes: List[str] # 对应JWT的'scopes'声明
    issuer: str       # 对应JWT的'iss'声明
    token: str      # 对应JWT的Token字符串
    expires_at: int    # 对应JWT的'exp'声明

 

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐