【LLM】Agent &MCP & Function call的理解
step1:定义一个tool,这是一个list,定义可以看opanai官网的文档,各个模型厂商大差不差这里的description非常重要,描述的越具体越详细最好,这跟LLM去理解这个工具非常重要step2:获取function call的结果,返回的是一个json文件step3:执行function call,本质就是一个写好的工具函数,这个函数名就是function call输出的tool n
Agent
step1:定义一个tool,这是一个list,定义可以看opanai官网的文档,各个模型厂商大差不差

这里的description非常重要,描述的越具体越详细最好,这跟LLM去理解这个工具非常重要
step2:获取function call的结果
,返回的是一个json文件
step3:执行function call,本质就是一个写好的工具函数,这个函数名就是function call输出的tool name,函数参数是funciton call输出的tool args
step4:将function call的结果返回给LLM
step5:再次调用LLM
训练一个function call模型
SFT的数据怎么准备
用户输入<im_start>human 调用工具的结果<tool_call>{tool call}
用的xml格式,包括你做think思考也是一样
MCP只是一个协议,调用什么工具还是模型决定的

mcp就是一个协议,与模型无关




给不同软件写不同的插件
同时mcp不止是工具调用这么个功能,还可以封装可复用的提示词、暴露一些数据资源,看文档
MCP
MCP Server(Model Context Protocol Server)是一种基于标准化协议的服务端程序,主要为大语言模型(LLM)提供外部数据和能力支持。例如,Fetch MCP Server可以抓取网页内容,Google Drive MCP Server可以读取文件。它的核心定位是“被动服务”,仅响应调用请求,不参与决策或推理。 MCP Server就像一个工具箱,里面装满了各种工具(如爬虫、数据库查询),但它不会主动使用这些工具,而是等待别人来挑选。

Function Call:直接扩展模型的瑞士军刀
Function Call是指大模型直接调用预定义函数的能力,允许模型生成请求参数并整合结果。例如,模型可以通过Function Call查询天气或执行简单的数学计算。它的本质是“代码级工具”,通常与模型绑定部署。
Agent是一种具备自主决策能力的AI实体,能够感知环境、规划任务并调用工具(包括MCP Server和Function Call)完成目标。例如,一个Agent可以接到“撰写AI趋势报告”的任务后,自动抓取数据、分析内容并生成报告。
在实际系统中,Function Call、MCP Server和Agent常常协同工作。例如:
- 用户提问:“帮我总结知乎上关于AI的最新讨论。”
- LLM解析需求,调用Function Call检测平台类型。
- Function Call返回“知乎”,LLM通过MCP协议请求爬虫服务。
- MCP Server抓取网页数据后返回给LLM。
- LLM生成摘要报告并返回给用户。
MCP Server、Function Call和Agent在AI生态中扮演着不同角色,分别对应“工具箱”、“瑞士军刀”和“智能工人”。
学习
MCP
- MCP 不就是普通的 function call 换了个名字吗?
视频中有提到,普通的 function call 会有语言或者开发框架的限制,而MCP借由client-server的结构,不再有这个限制。建造起了 tool 和不同语言不同框架的巴别塔,意义很大。
另一方面,function call 对模型的能力也有要求,目前只有一些模型有着良好的 function call 能力。而 MCP 因为有 client 的存在,对模型的要求不高,使用的是 deepseek-v3,可以看到效果不错。 - 怎么代码中没有和 llm 交互的部分?
和 llm 交互是 mcp client 的工作,由 vscode 的插件 cline 完成。视频中建造的是 mcp server,负责工具的调用。 - 简单的讲,agent(llm)有一个能力叫工具调用,通过提供工具的具体描述,从而实现让agent(llm)调用自定义工具。mcp协议出现之前,这种工具的实现方式很自由,完全看个人理解。mcp协议出现后,它定义了工具实现的标准,还解决了工具复用的问题。这让llm应用开发大范围推广有了基础,以后现有的业务程序,只要再实现一个mcp服务器,就可以接入llm中,而不用自己再开发一个llm应用接入自己的业务程序。
- 模型肯定是需要微调才能具备工具调用的能力的,只不过现在模型已经不再宣传这个能力了。即使没有也可以用开源的数据集自己微调 huggingface.co/search/full-text?q=function+call&type=dataset 现在的工具调用并不能保证一定触发成功,影响的因素很多,微调数据集的质量,问题的相关程度,可调用工具的数量,工具的描述准确度等等都会有影响。mcp协议也只是解决了部分问题。这种不确定的问题在其他模型能力上都有。只能尽量使用更先进的模型来减小这种不确定性。
- MCP的本地通信与远程通信

MCP-Agent的简单实用
https://blog.csdn.net/fufan_LLM/article/details/146397283 很不错 手把手教了属于是
step1:在虚拟环境中安装uv
pip install uv
step2:初始化uv
到指定路径下,如agent_mcp_project,init uv 需要指定自己的python版本,不然容易报错出问题
uv init agent_mcp_project --python 3.11
step3:依赖安装
uv add mcp httpx
step4:OpenWeather API申请
在这个网站https://api.openweathermap.org上注册即可
step5:服务器代码编写
import json
import httpx
from typing import Any
from mcp.server.fastmcp import FastMCP
# 初始化 MCP 服务器
mcp = FastMCP("WeatherServer")
# OpenWeather API 配置
OPENWEATHER_API_BASE = "https://api.openweathermap.org/data/2.5/weather"
API_KEY = "请替换为你自己的 OpenWeather API Key"
USER_AGENT = "weather-app/1.0"
async def fetch_weather(city: str) -> dict[str, Any] | None:
"""
从 OpenWeather API 获取天气信息。
:param city: 城市名称(需使用英文,如 Beijing)
:return: 天气数据字典;若出错返回包含 error 信息的字典
"""
params = {
"q": city,
"appid": API_KEY,
"units": "metric",
"lang": "zh_cn"
}
headers = {"User-Agent": USER_AGENT}
async with httpx.AsyncClient() as client:
try:
response = await client.get(OPENWEATHER_API_BASE, params=params, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json() # 返回字典类型
except httpx.HTTPStatusError as e:
return {"error": f"HTTP 错误: {e.response.status_code}"}
except Exception as e:
return {"error": f"请求失败: {str(e)}"}
def format_weather(data: dict[str, Any] | str) -> str:
"""
将天气数据格式化为易读文本。
:param data: 天气数据(可以是字典或 JSON 字符串)
:return: 格式化后的天气信息字符串
"""
# 如果传入的是字符串,则先转换为字典
if isinstance(data, str):
try:
data = json.loads(data)
except Exception as e:
return f"无法解析天气数据: {e}"
# 如果数据中包含错误信息,直接返回错误提示
if"error"in data:
return f"⚠️ {data['error']}"
# 提取数据时做容错处理
city = data.get("name", "未知")
country = data.get("sys", {}).get("country", "未知")
temp = data.get("main", {}).get("temp", "N/A")
humidity = data.get("main", {}).get("humidity", "N/A")
wind_speed = data.get("wind", {}).get("speed", "N/A")
# weather 可能为空列表,因此用 [0] 前先提供默认字典
weather_list = data.get("weather", [{}])
description = weather_list[0].get("description", "未知")
return (
f"🌍 {city}, {country}\n"
f"🌡 温度: {temp}°C\n"
f"💧 湿度: {humidity}%\n"
f"🌬 风速: {wind_speed} m/s\n"
f"🌤 天气: {description}\n"
)
@mcp.tool()
async def query_weather(city: str) -> str:
"""
输入指定城市的英文名称,返回今日天气查询结果。
:param city: 城市名称(需使用英文)
:return: 格式化后的天气信息
"""
data = await fetch_weather(city)
return format_weather(data)
if __name__ == "__main__":
# 以标准 I/O 方式运行 MCP 服务器
mcp.run(transport='stdio')
step6:申请LLM 的api key
平台:https://cloud.siliconflow.cn/
填写邀请码: Di8srcWc 可白嫖一些额度
到平台申请api key即可使用
- 制作.env
API_KEY='sk-xxxxxxxxxxxxxxxxxxx' # 自己的api key
BASE_URL='https://api.siliconflow.cn/v1'
MODEL='Qwen/Qwen2.5-14B-Instruct'
step7:客户端代码编写
- 客户端代码
import asyncio
import os
import json
from typing import Optional
from contextlib import AsyncExitStack
from openai import OpenAI
from dotenv import load_dotenv
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# 加载 .env 文件,确保 API Key 受到保护
load_dotenv()
class MCPClient:
def __init__(self):
"""初始化 MCP 客户端"""
self.exit_stack = AsyncExitStack()
self.openai_api_key = os.getenv("API_KEY") # 读取 OpenAI API Key
self.base_url = os.getenv("BASE_URL") # 读取 BASE YRL
self.model = os.getenv("MODEL") # 读取 model
if not self.openai_api_key:
raise ValueError("❌ 未找到 OpenAI API Key,请在 .env 文件中设置 OPENAI_API_KEY")
self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url) # 创建OpenAI client
self.session: Optional[ClientSession] = None
self.exit_stack = AsyncExitStack()
async def connect_to_server(self, server_script_path: str):
"""连接到 MCP 服务器并列出可用工具"""
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
)
# 启动 MCP 服务器并建立通信
stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params))
self.stdio, self.write = stdio_transport
self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write))
await self.session.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:
"""
使用大模型处理查询并调用可用的 MCP 工具 (Function Calling)
"""
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]
# print(available_tools)
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
tools=available_tools
)
# 处理返回的内容
content = response.choices[0]
if content.finish_reason == "tool_calls":
# 如何是需要使用工具,就解析工具
tool_call = content.message.tool_calls[0]
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")
# 将模型返回的调用哪个工具数据和工具执行完成后的数据都存入messages中
messages.append(content.message.model_dump())
messages.append({
"role": "tool",
"content": result.content[0].text,
"tool_call_id": tool_call.id,
})
# 将上面的结果再返回给大模型用于生产最终的结果
response = self.client.chat.completions.create(
model=self.model,
messages=messages,
)
return response.choices[0].message.content
return content.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) # 发送用户输入到 OpenAI API
print(f"\n🤖 OpenAI: {response}")
except Exception as e:
print(f"\n⚠️ 发生错误: {str(e)}")
async def cleanup(self):
"""清理资源"""
await self.exit_stack.aclose()
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()
finally:
await client.cleanup()
if __name__ == "__main__":
import sys
asyncio.run(main())
Open-Manus
ReAct Agent基本原理
● 本质:由reason和action组成,此处的action通常是function call或者是tool call
● 流程:Query ->模型 think->action ->执行 Action ->结果
通过得到的action信息如参数之类的,在得到这样的action之后,我们会去通过jason的解析,然后去调用function call,执行了这个action。然后把结果放到observation里面,之后ai通过前面的思考think,以及obsevation完成final anwer输出给用户
两种不同的方法,下图是说,有一个planing agent帮助生成一个步骤列表,然后manus去捕捉列表的内容,然后进行action
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)