
文章目录
文章目录
为什么需要function calling函数调用
-
大模型的三个主要局限性
(1)事实可靠性缺陷:参数化记忆静态且更新滞后,常产生幻觉、张冠李戴或无法追溯来源,难以满足高精度场景需求。
(2)可解释性与可控性不足:决策过程呈黑箱,对输出逻辑、置信度与偏见缺乏直观解释,导致关键领域难以审计、纠错或合规。
(3)资源与情境局限:训练与推理算力、显存和能耗巨大,端侧部署受限;同时上下文长度有限,长程依赖、多模态融合及实时增量学习仍受硬约束。 -
Function Calling 如何解决这些问题
(1)事实可靠性:模型不再依赖静态参数记忆,而是实时调用搜索引擎、数据库或知识库 API,将动态结果直接注入上下文,显著降低幻觉率。
(2)可解释性与可控性:调用链以结构化 JSON 形式显式输出,每一步函数名、输入参数、返回结果均可审计、重放与单元测试;失败时可重试或降级,避免黑箱输出无法追踪。
(3)资源与上下文压力:复杂计算、大数据查询或长文档处理被离线下载到专用服务,模型仅负责轻量级调度与总结,可减少 50-80% 的上下文长度及 GPU 算力消耗,同时支持缓存、批量与异步并行,显著降低延迟与成本。
理解Function Calling的基本工作流程
Function Calling 把大模型从“生成答案”变成“调度工具”,核心流程只有四步:
(1)用户提问
用户给出自然语言请求(“查明天北京天气并总结穿衣建议”)。
(2)模型生成调用方案
大模型评估可用函数,输出结构化 JSON:
[{"name": "get_weather", "arguments": {"city": "北京", "date": "2025-06-25"}}]
(3)执行函数(模型之外)
外部系统(框架或客户端)解析 JSON,调用真实 API,得到返回:
{"temp": 32, "humidity": 65, "desc": "晴"}
(4)模型汇总回答
把函数返回拼回上下文,模型再生成自然语言结论:“明天北京晴,最高 32 ℃,建议短袖+防晒。”
流程可循环(多函数、多轮调用)。

快速理解Function Calling的基本调用
“天气查询 + 穿衣建议”的完整示例(依赖:openai ≥ 1.0 + requests)。
- 定义工具(真实天气 API)
import json, requests, openai
client = openai.OpenAI(base_url="http://localhost:1234/v1", api_key="lm-studio")
def get_weather(city: str, date: str) -> dict:
"""调用免费演示接口返回天气字典"""
# 此处用 wttr.in 免费接口,无需 key
url = f"https://wttr.in/{city}?format=j1"
try:
data = requests.get(url, timeout=5).json()
# 取指定日期的天气(简化:若 date==today 则取 current)
if date == "today":
w = data["current_condition"][0]
else:
w = data["weather"][0]["hourly"][6] # 随便取 06:00 数据
return {
"temp": int(w["tempC"]),
"humidity": int(w["humidity"]),
"desc": w["weatherDesc"][0]["value"]
}
except Exception as e:
return {"error": str(e)}
- 注册工具(让模型看懂)
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市、日期的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如 Beijing"},
"date": {"type": "string", "description": "日期,如 today、2025-06-26"}
},
"required": ["city", "date"]
}
}
}]
- 使用工具(两阶段循环)
def chat(user_q: str):
messages = [{"role": "user", "content": user_q}]
# ① 模型决定是否调用
response = client.chat.completions.create(
model="local", messages=messages, tools=tools, temperature=0
)
choice = response.choices[0]
# ② 若有调用 → 执行+回灌
if choice.message.tool_calls:
call = choice.message.tool_calls[0]
args = json.loads(call.function.arguments)
weather = get_weather(args["city"], args["date"])
# 回传结果
messages.append(choice.message) # 助手调用
messages.append({
"tool_call_id": call.id,
"role": "tool",
"name": "get_weather",
"content": json.dumps(weather)
})
# 再请求一次,让模型整合结果
final = client.chat.completions.create(
model="local", messages=messages, temperature=0.3
)
return final.choices[0].message.content
return choice.message.content # 无需调用时直接返回答案
# 4. 测试
if __name__ == "__main__":
print(chat("明天上海天气怎么样?请给出穿衣建议。"))
定义工具 → 注册 JSON 说明书 → 两阶段循环(模型写调用单→客户端执行→结果回灌)

示例脚本:
# main.py
import json
import random
from typing import List
try:
import openai
except ImportError:
raise SystemExit("请先 pip install openai")
# ---------------- 配置区 ----------------
# ① 本地 LM Studio 地址(默认端口 1234)
client = openai.OpenAI(base_url="http://localhost:1234/v1", api_key="lm-studio")
MODEL = "local" # LM Studio 加载的任意 GGUF 模型名
# ---------------------------------------
# ========== 1. 定义工具 ==========
def get_weather(city: str, date: str) -> dict:
"""模拟天气 API,返回 dict"""
# 伪随机,只要 city 相同结果就相同,方便复现
rng = random.Random(city + date)
temp = rng.randint(15, 35)
humidity = rng.randint(40, 90)
desc = rng.choice(["晴", "多云", "小雨"])
return {"temp": temp, "humidity": humidity, "desc": desc}
# ========== 2. 注册工具 ==========
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市和日期的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如 Shanghai"},
"date": {"type": "string", "description": "日期,如 today、2025-06-27"}
},
"required": ["city", "date"]
}
}
}]
# ========== 3. Function Calling 两阶段循环 ==========
def chat(user_query: str) -> str:
messages = [{"role": "user", "content": user_query}]
# ① 意图理解 & 函数选择
response = client.chat.completions.create(
model=MODEL,
messages=messages,
tools=tools,
temperature=0
)
choice = response.choices[0]
# 若无调用,直接返回答案
if not choice.message.tool_calls:
return choice.message.content or ""
# ② 执行函数 & 回灌结果
call = choice.message.tool_calls[0]
args = json.loads(call.function.arguments)
weather = get_weather(args["city"], args["date"])
# 把助手调用+函数返回追加进上下文
messages.append(choice.message)
messages.append({
"tool_call_id": call.id,
"role": "tool",
"name": "get_weather",
"content": json.dumps(weather)
})
# ③ 再次请求,让模型整合结果
final = client.chat.completions.create(
model=MODEL,
messages=messages,
temperature=0.3
)
return final.choices[0].message.content or ""
# ========== 4. 简单 CLI ==========
if __name__ == "__main__":
print("=== 本地 Function Calling 演示 ===")
print("输入 q 退出\n")
while True:
q = input("你:").strip()
if q.lower() == "q":
break
ans = chat(q)
print(f"AI:{ans}\n")
Function Calling 核心概念深度理解
Function Calling 的本质是把大模型从“生成下一个 token”的纯文本引擎,升级为“生成下一段调用”的符号化决策器;它借助语义-符号对齐、工具模式注册与可验证执行三层机制,实现对外部世界的可靠操作,同时保持生成式接口的易用性。
系列文章
【大语言模型】-- OpenAI定义的五个AGI发展阶段
【大语言模型】-- Fine-tuning 微调
【大语言模型】-- 私有化部署
【大语言模型】-- Prompt Engineering 提示工程
【大语言模型】-- Function Calling函数调用
【大语言模型】-- RAG
【大语言模型】-- Agent
【大语言模型】-- 一些概念

被折叠的 条评论
为什么被折叠?



