导读

如果你曾经尝试过让大模型(LLM)帮你查天气、订机票或操作数据库,你多半已经接触过"Function Call"技术。但你是否真正理解它的底层逻辑?当听到 MCP 和 A2A 这些新概念时,你是否感到困惑?

本文将带你深入理解 AI Agent 工具调用的核心技术,从最基础的 Function Call 原理讲起,逐步演进到 LangChain 框架的封装,最后解析 MCP 和 A2A 这两项前沿协议。读完本文,你将不仅理解“如何调用”,更能看清“调用什么”和“谁来调用”的全貌。

AI Agent 工具调用技术演进总览

一、Function Call: 最容易被误解的技术

1.1 一个常见的认知误区

很多人认为 Function Call 就是"大模型自己去调用工具"。这个说法只对了一半。

大模型本身并不执行任何代码,它只负责"决策"——输出一个结构化的指令。真正的"调用"动作,必须由你的应用程序 (宿主代码) 来完成。

这个认知偏差源于 OpenAI 等官方 SDK 封装得过于"丝滑",让开发者误以为一次 API 调用就完成了所有事情。实际上,在那些看似简单的 API 背后,隐藏着严格分离的职责边界。

1.2 Function Call 的完整四步流程

为了清晰理解,我们把一次完整的 Function Call 拆解为四个标准步骤:

第一步:注册工具

你将工具的名称、功能描述以及参数结构(JSON Schema)放入系统提示词或 API 的 tools 参数中。这相当于告诉大模型:“我有这些工具可用,它们各自做什么,需要什么参数。”

第二步:大模型决策

收到用户问题后,大模型不会直接回答。如果它判断需要借助工具,就会输出一个结构化的 JSON 对象,其中明确包含 tool_name(工具名) 和 parameters(参数值)。

第三步:宿主代码执行

这是最关键的一步。你的后端代码监听到大模型输出的 JSON 后,通过 if 判断或 switch 结构,由你的代码去真正执行对应的函数。大模型全程没有执行任何代码,它只是给出了指令。

第四步:结果回传与最终回复

你把执行获得的真实数据再次发给大模型,大模型基于这些数据生成最终的自然语言回复,呈现给用户。

Function Call 完整四步流程

1.3 代码示例:原生调用

下面是一段使用 OpenAI SDK 的原生调用代码,请注意"决策"与"执行"的分界线:

import json
from openai import OpenAI

client = OpenAI(api_key="你的 API_KEY")

# 真实的工具函数 (由你的代码执行)
def get_weather(city: str) -> str:
    weather_db = {"北京": "晴天 25°C", "上海": "小雨 22°C", "吉林市": "大雪 -20°C"}
    return weather_db.get(city, "未知城市天气")

# 注册工具
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "查询指定城市的实时天气状况",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名称"}
            },
            "required": ["city"]
        }
    }
}]

messages = [{"role": "user", "content": "吉林市现在天气怎么样?"}]

# 第一次调用:让大模型决策
response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools,
    tool_choice="auto"
)

response_message = response.choices[0].message

if response_message.tool_calls:
    tool_call = response_message.tool_calls[0]
    function_name = tool_call.function.name
    function_args = json.loads(tool_call.function.arguments)
    
    print(f"🤖 大模型决策:调用 '{function_name}',参数 {function_args}")
    
    # ⭐️ 关键分界线:此处由宿主代码真正执行
    real_result = get_weather(**function_args)
    print(f"💻 宿主代码执行结果:{real_result}")
    
    # 回传结果,生成最终回答
    messages.append(response_message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": real_result
    })
    
    final_response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    print("🗣️ 最终回答:", final_response.choices[0].message.content)

输出结果清晰地展示了决策与执行的分离:

🤖 大模型决策:调用 'get_weather',参数 {'city': '吉林市'}
💻 宿主代码执行结果:大雪 -20°C
🗣️ 最终回答:吉林市现在是大雪天气,气温低至零下 20°C,请注意保暖!

二、LangChain: 让事情变得更简单

2.1 封装了什么?

直接使用原生 API 时,你需要手动编写大量"胶水代码":解析 JSON、执行函数、判断是否再次调用、回传结果……这些重复劳动占据了大量开发时间。

LangChain 的 bind_tools()invoke() 方法将这些步骤全部封装起来,你只需关注核心业务逻辑 (工具函数本身),框架自动处理了"决策 - 执行 - 回传"的完整循环。

2.2 代码对比

使用 LangChain 实现同样的功能,代码大幅精简:

from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage

@tool
def get_weather(city: str) -> str:
    """查询指定城市的实时天气状况"""
    weather_db = {"北京": "晴天 25°C", "上海": "小雨 22°C", "吉林市": "大雪 -20°C"}
    return weather_db.get(city, "未知城市天气")

model = ChatOpenAI(model="gpt-4o").bind_tools([get_weather])
messages = [HumanMessage(content="吉林市现在天气怎么样?")]
response = model.invoke(messages)

print(response.content)  # 直接获得最终回答

2.3 便捷与控制的权衡

LangChain 的简化带来的好处显而易见:

  • 自动处理工具格式: @tool装饰器和 bind_tools() 自动完成 JSON Schema 转换
  • 自动执行循环: 无需手动编写 while 循环和 if 判断
  • 代码量大幅减少: 聚焦业务逻辑而非框架代码

但也要注意权衡:

  • 灵活性降低:精细控制每一步 (如自定义重试、超时、流式处理) 时较为受限
  • 调试难度增加:错误可能被多层封装隐藏,定位不如原生调用直观

选择 LangChain,本质上是选择用"便捷性"交换"控制权"。

三、MCP: 让工具调用标准化

3.1 为什么需要 MCP?

在 MCP 出现之前,每个 AI 框架都有自己定义工具的方式。如果你想在 LangChain 中调用一个工具,需要按 LangChain 的格式写;换到别的框架,又得重新适配一遍。这导致了大量的重复劳动和生态割裂。

MCP(Model Context Protocol) 由 Anthropic 提出,旨在解决这个问题。它定义了一个标准化的工具接入协议,让 AI 应用可以像使用 USB 设备一样,即插即用地接入任何遵循 MCP 标准的工具服务器。

如果说 Function Call 解决的是"如何调用"的问题,那么 MCP 解决的就是"调用什么"的问题——它为工具提供了统一的接口规范。

3.2 在 LangChain 中使用 MCP

LangChain 官方提供了 langchain-mcp-adapters 库来支持 MCP:

import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent

async def main():
    client = MultiServerMCPClient({
        "math": {  # 数学计算 MCP 服务器
            "transport": "stdio",
            "command": "python",
            "args": ["/path/to/math_server.py"],
        },
        "weather": {  # 天气查询 MCP 服务器
            "transport": "http",
            "url": "http://localhost:8000/mcp",
        },
    })
    
    tools = await client.get_tools()  # 统一加载所有工具
    agent = create_agent("claude-sonnet-4-6", tools)
    
    response = await agent.ainvoke(
        {"messages": [{"role": "user", "content": "计算 (3+5)x12"}]}
    )

Agent 可以无缝调用来自不同 MCP 服务器的工具,完全不需要关心它们背后的实现差异。

3.3 MCP 的核心价值

  • 生态互通: 同一个工具服务器可以被任何支持 MCP 的 AI 框架使用
  • 标准化接入: 工具开发者只需实现一次 MCP 接口,即可被所有 AI 应用调用
  • 去中心化: 任何人都可以发布 MCP 服务器,丰富 AI 工具生态

四、A2A: 让智能体相互协作

4.1 单 Agent 的局限与多 Agent 的挑战

单个 Agent 的能力终究有限。当任务复杂到一定程度 (如"规划一次跨国旅行并预订所有行程"),可能需要多个专业 Agent 分工协作:一个负责订机票,一个负责订酒店,一个负责制定行程路线。

但问题来了:不同框架开发的 Agent 如何相互通信?如何协调分工?

A2A(Agent-to-Agent Protocol) 由 Google 提出,正是为了解决这个问题。它定义了一套智能体之间标准化通信的协议,让不同来源、不同框架的 AI 代理能够像人类同事一样相互对话、协作完成任务。

4.2 LangChain 中的 A2A 支持

在 LangChain 生态中,A2A 的支持主要体现在LangSmith 的 Agent Server中。你可以将一个 LangGraph Agent 部署为 A2A 服务器,它就能通过标准化的 JSON-RPC 2.0 协议与其他 A2A 兼容的 Agent 对话。

一次典型的 A2A 调用请求如下:

curl --request POST \
  --url https://api.example.com/a2a/{assistant_id} \
  --header 'Content-Type: application/json' \
  --data '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{"kind": "text", "text": "请帮我查询明天的航班"}],
        "messageId": "msg-1"
      }
    }
  }'

4.3 A2A 的核心价值

  • 跨框架协作: 用 LangChain 开发的 Agent 可以与用其他框架开发的 Agent 协同工作
  • 任务分解: 复杂任务可以被自动分解给多个专业 Agent
  • 标准化生态: 为多智能体系统提供了统一的通信语言

五、完整图景:从调用到生态

回顾整个技术演进路径,我们可以清晰地看到一条主线:

层次 技术 解决的核心问题
调用层 Function Call 如何让大模型"调用"外部工具
封装层 LangChain 如何简化调用的工程复杂度
接入层 MCP 工具如何标准化接入 (调用什么)
协作层 A2A 智能体之间如何协作 (谁来调用)

AI Agent 工具调用四层技术栈

Function Call 是技术地基,解决的是"如何调用"的工程问题。

LangChain 是工程封装,让开发者从重复劳动中解放出来。

MCP 是协议延伸,让工具接入走向标准化、生态化。

A2A 是架构升级,让多智能体协作成为可能。

这四个层次共同构建了当今 AI Agent 技术栈的完整图景。理解它们之间的关系,不仅能帮助你更好地选择技术方案,也能让你更清晰地看到这个领域未来的演进方向。

结语

从最基础的 Function Call 到 LangChain 的便捷封装,再到 MCP 和 A2A 这两项前沿协议,AI Agent 工具调用技术正在经历从"能用"到"好用"再到"互联互通"的快速演进。

作为开发者,理解 Function Call 的底层原理能让你在调试时更从容;善用 LangChain 能让你在开发时更高效;关注 MCP 和 A2A 能让你在架构设计时更有前瞻性。