本文是程序员转行学习AI大模型的第13个核心知识点笔记,附清晰业务流程示例。
当前阶段:还在学习知识点,由点及面,从 0 到 1 搭建 AI 大模型知识体系中。
系列更新,关注我,后续会持续记录分享转行经历~
原理
Function Calling,可以让模型通过调用外部工具,来增强自身能力。
使用 Function Calling, 获取用户当前位置的天气信息示例:
from openai import OpenAI
def send_messages(messages):
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
tools=tools
)
return response.choices[0].message
client = OpenAI(
api_key="<your api key>",
base_url="https://api.deepseek.com",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather of a location, the user should supply a location first.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
}
},
"required": ["location"]
},
}
},
]
messages = [{"role": "user", "content": "How's the weather in Hangzhou, Zhejiang?"}]
message = send_messages(messages)
print(f"User>\t {messages[0]['content']}")
tool = message.tool_calls[0]
messages.append(message)
messages.append({"role": "tool", "tool_call_id": tool.id, "content": "24℃"})
message = send_messages(messages)
print(f"Model>\t {message.content}")
上述代码执行流程:
- 用户:查询现在的天气;
- 模型:返回 function get_weather({location:'Hangzhou'})
- 用户:调用 function get_weather({location:'Hangzhou'}),并传给模型
- 模型:返回自然语言,“The current temperature in Hangzhou is 24°C.”
注:上述代码中 get_weather 函数功能需由用户提供,模型本身不执行具体函数。
"""
Function Calling中的函数实现位置:
1. 函数定义(JSON Schema):传给LLM,告诉LLM有哪些函数
2. 函数实现(Python代码):在开发者代码中,由开发者手动调用
"""
import openai
import json
import requests
# ========================================
# 步骤1:定义函数(JSON Schema)
# ========================================
# 这个定义传给LLM,告诉LLM有哪些函数可用
functions = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
]
# ========================================
# 步骤2:实现具体函数(Python代码)
# ========================================
# 这个函数在开发者代码中实现,由开发者手动调用
def get_weather(city: str) -> dict:
"""
具体函数实现
注意:这个函数不在LLM中,而是在开发者代码中!
"""
# 函数内部调用外部API
api_url = f"https://api.weather.com/v1/current?city={city}"
try:
# 调用外部天气API
response = requests.get(api_url)
weather_data = response.json()
return {
"status": "success",
"temperature": weather_data["temp"],
"condition": weather_data["condition"]
}
except Exception as e:
return {
"status": "error",
"message": str(e)
}
# ========================================
# 步骤3:调用LLM
# ========================================
# 将函数定义传给LLM
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
functions=functions, # 传入函数定义(JSON Schema)
function_call="auto" # 让LLM自动决定是否调用函数
)
# ========================================
# 步骤4:检查LLM是否要调用函数
# ========================================
if response.choices[0].message.get("function_call"):
# LLM决定调用函数
function_call = response.choices[0].message.function_call
function_name = function_call.name
function_args = json.loads(function_call.arguments)
print(f"LLM决定调用函数: {function_name}")
print(f"LLM传递的参数: {function_args}")
# ========================================
# 步骤5:开发者手动调用函数
# ========================================
# 注意:这里不是LLM调用函数,而是开发者手动调用!
result = get_weather(function_args["city"])
print(f"函数执行结果: {result}")
# ========================================
# 步骤6:将结果返回给LLM
# ========================================
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"},
{"role": "assistant", "content": None, "function_call": function_call},
{"role": "function", "name": function_name, "content": str(result)}
]
)
print(f"LLM最终回答: {second_response.choices[0].message.content}")
"""
总结:
1. 函数定义(JSON Schema)→ 传给LLM,告诉LLM有哪些函数
2. 函数实现(Python代码)→ 在开发者代码中,由开发者手动调用
3. LLM的作用 → 分析是否需要调用函数,生成函数调用请求
4. 开发者的作用 → 手动调用函数,将结果返回给LLM
"""
LLM 的角色和职责
"""
LLM的角色:
1. 分析用户问题
2. 判断是否需要调用函数
3. 生成函数调用请求(JSON格式)
4. 接收函数执行结果
5. 基于结果生成最终回答
LLM不做的:
1. 不执行函数
2. 不调用外部API
3. 不处理函数逻辑
"""
# LLM做的事情:
# 1. 分析
user_input = "北京今天天气怎么样?"
llm_analysis = "用户想查询北京天气"
# 2. 判断
llm_decision = "需要调用get_weather函数"
# 3. 生成请求
llm_request = {
"function_call": {
"name": "get_weather",
"arguments": '{"city": "北京"}'
}
}
# 4. 接收结果
llm_input = {
"function_result": {
"status": "success",
"temperature": 25,
"condition": "晴"
}
}
# 5. 生成回答
llm_output = "根据天气API,北京今天天气晴,温度25°C"
"""
LLM只负责分析和生成,不负责执行!
"""
开发者的角色和职责
"""
开发者的角色:
1. 定义函数(JSON Schema)
2. 实现具体函数(Python代码)
3. 调用LLM
4. 解析LLM响应
5. 手动调用函数
6. 将结果返回给LLM
开发者做的:
1. 实现函数逻辑
2. 调用外部API
3. 处理错误和重试
4. 管理数据流
"""
# 开发者做的事情:
# 1. 定义函数
functions = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {...}
}
]
# 2. 实现函数
def get_weather(city: str) -> dict:
# 调用外部API
response = requests.get(f"https://api.weather.com/v1/current?city={city}")
return response.json()
# 3. 调用LLM
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[...],
functions=functions
)
# 4. 解析响应
if response.choices[0].message.get("function_call"):
function_call = response.choices[0].message.function_call
function_args = json.loads(function_call.arguments)
# 5. 手动调用函数
result = get_weather(function_args["city"])
# 6. 返回结果给LLM
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
...,
{"role": "function", "name": function_name, "content": str(result)}
]
)
"""
开发者负责实现和调用函数!
"""
完整天气查询示例
import openai
import json
import requests
# ========================================
# 1. 定义函数(JSON Schema)
# ========================================
# 这个定义传给LLM,告诉LLM有哪些函数可用
functions = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
]
# ========================================
# 2. 实现具体函数(Python代码)
# ========================================
# 这个函数在开发者代码中实现
def get_weather(city: str) -> dict:
"""
获取天气信息
注意:这个函数在开发者代码中实现!
"""
# 调用外部天气API
# 这里调用的是真实的天气API
api_url = f"https://api.weather.com/v1/current?city={city}"
try:
# 调用外部API
print(f"正在调用外部API: {api_url}")
response = requests.get(api_url)
weather_data = response.json()
return {
"status": "success",
"temperature": weather_data["temp"],
"condition": weather_data["condition"],
"humidity": weather_data["humidity"]
}
except Exception as e:
return {
"status": "error",
"message": f"API调用失败: {str(e)}"
}
# ========================================
# 3. 调用LLM
# ========================================
print("=== 步骤1:调用LLM ===")
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
functions=functions, # 传入函数定义
function_call="auto" # 让LLM自动决定
)
print(f"LLM响应: {response.choices[0].message}")
# ========================================
# 4. 检查LLM是否要调用函数
# ========================================
if response.choices[0].message.get("function_call"):
print("\n=== 步骤2:LLM决定调用函数 ===")
function_call = response.choices[0].message.function_call
function_name = function_call.name
function_args = json.loads(function_call.arguments)
print(f"函数名: {function_name}")
print(f"函数参数: {function_args}")
# ========================================
# 5. 开发者手动调用函数
# ========================================
print("\n=== 步骤3:开发者手动调用函数 ===")
result = get_weather(function_args["city"])
print(f"函数执行结果: {result}")
# ========================================
# 6. 将结果返回给LLM
# ========================================
print("\n=== 步骤4:将结果返回给LLM ===")
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"},
{"role": "assistant", "content": None, "function_call": function_call},
{"role": "function", "name": function_name, "content": str(result)}
]
)
print(f"LLM最终回答: {second_response.choices[0].message.content}")
"""
输出示例:
=== 步骤1:调用LLM ===
LLM响应: {
"function_call": {
"name": "get_weather",
"arguments": '{"city": "北京"}'
}
}
=== 步骤2:LLM决定调用函数 ===
函数名: get_weather
函数参数: {"city": "北京"}
=== 步骤3:开发者手动调用函数 ===
正在调用外部API: https://api.weather.com/v1/current?city=北京
函数执行结果: {
"status": "success",
"temperature": 25,
"condition": "晴",
"humidity": 45
}
=== 步骤4:将结果返回给LLM ===
LLM最终回答: 根据天气API,北京今天天气晴,温度25°C,湿度45%
"""
Function Calling 工作流程
开发者代码:
1. 定义函数(JSON Schema)→ 传给LLM
2. 实现函数(Python代码)→ 在开发者代码中
3. 调用LLM → 传入函数定义
4. 解析LLM响应 → 检查是否要调用函数
5. 手动调用函数 → 调用开发者实现的函数
6. 将结果返回给LLM → 生成最终回答
LLM:
1. 分析用户问题
2. 判断是否需要调用函数
3. 生成函数调用请求(JSON格式)
4. 接收函数执行结果
5. 基于结果生成最终回答
外部API:
1. 被开发者实现的函数调用
2. 返回数据给函数
3. 函数将数据返回给开发者
Function Calling = LLM 分析 + 开发者执行
- LLM:分析问题,生成调用请求
- 开发者:实现函数,手动调用
- 外部 API:被函数调用,返回数据