Skip to main content

函数调用

检查模型是否支持函数调用

使用 litellm.supports_function_calling(model="") -> 如果模型支持函数调用则返回 True,否则返回 False

assert litellm.supports_function_calling(model="gpt-3.5-turbo") == True
assert litellm.supports_function_calling(model="azure/gpt-4-1106-preview") == True
assert litellm.supports_function_calling(model="palm/chat-bison") == False
assert litellm.supports_function_calling(model="ollama/llama2") == False

检查模型是否支持并行函数调用

使用 litellm.supports_parallel_function_calling(model="") -> 如果模型支持并行函数调用则返回 True,否则返回 False

assert litellm.supports_parallel_function_calling(model="gpt-4-turbo-preview") == True
assert litellm.supports_parallel_function_calling(model="gpt-4") == False

并行函数调用

并行函数调用是指模型能够同时执行多个函数调用,允许这些函数调用的效果和结果并行解析。

快速开始 - gpt-3.5-turbo-1106

Open In Colab

在这个例子中,我们定义了一个单一的函数 get_current_weather

  • 步骤1:将用户问题与 get_current_weather 一起发送给模型
  • 步骤2:解析模型响应的输出 - 使用模型提供的参数执行 get_current_weather
  • 步骤3:将运行 get_current_weather 函数的输出发送给模型

完整代码 - 使用 gpt-3.5-turbo-1106 进行并行函数调用

import litellm
import json
# 设置 openai api key
import os
os.environ['OPENAI_API_KEY'] = "" # litellm 从 .env 读取 OPENAI_API_KEY 并发送请求

# 示例硬编码的虚拟函数,返回相同的天气信息
# 在生产环境中,这可以是你的后端 API 或外部 API
def get_current_weather(location, unit="fahrenheit"):
"""获取指定位置的当前天气"""
if "tokyo" in location.lower():
return json.dumps({"location": "Tokyo", "temperature": "10", "unit": "celsius"})
elif "san francisco" in location.lower():
return json.dumps({"location": "San Francisco", "temperature": "72", "unit": "fahrenheit"})
elif "paris" in location.lower():
return json.dumps({"location": "Paris", "temperature": "22", "unit": "celsius"})
else:
return json.dumps({"location": location, "temperature": "unknown"})


def test_parallel_function_call():
try:
# 第一步:将对话和可用函数发送给模型
messages = [{"role": "user", "content": "旧金山、东京和巴黎的天气如何?"}]
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定位置的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如:San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
},
}
]
response = litellm.completion(
model="gpt-3.5-turbo-1106",
messages=messages,
tools=tools,
tool_choice="auto", # auto 是默认值,但我们明确指定
)
print("\n第一个 LLM 响应:\n", response)
response_message = response.choices[0].message
tool_calls = response_message.tool_calls

print("\n工具调用数量:", len(tool_calls))

# 第二步:检查模型是否想要调用函数
if tool_calls:
# 第三步:调用函数
# 注意:JSON 响应可能并不总是有效;务必处理错误
available_functions = {
"get_current_weather": get_current_weather,
} # 此示例中只有一个函数,但你可以有多个
messages.append(response_message) # 用助手的回复扩展对话

# 第四步:将每个函数调用的信息和函数响应发送给模型
for tool_call in tool_calls:
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
function_response = function_to_call(
location=function_args.get("location"),
unit=function_args.get("unit"),
)
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
) # 用函数响应扩展对话
second_response = litellm.completion(
model="gpt-3.5-turbo-1106",
messages=messages,
) # 获取一个新的响应,模型可以看到函数响应
print("\n第二个 LLM 响应:\n", second_response)
return second_response
except Exception as e:
print(f"发生错误: {e}")

test_parallel_function_call()

解释 - 并行函数调用

以下是对上述代码片段中使用 gpt-3.5-turbo-1106 进行并行函数调用的解释

第一步:设置 toolsget_current_weather 的 litellm.completion()

import litellm
import json
# 设置 openai api key
import os
os.environ['OPENAI_API_KEY'] = "" # litellm 从 .env 中读取 OPENAI_API_KEY 并发送请求
# 示例硬编码的假函数,返回相同的天气
# 在生产环境中,这可以是你的后端 API 或外部 API
def get_current_weather(location, unit="fahrenheit"):
"""获取指定位置的当前天气"""
if "tokyo" in location.lower():
return json.dumps({"location": "Tokyo", "temperature": "10", "unit": "celsius"})
elif "san francisco" in location.lower():
return json.dumps({"location": "San Francisco", "temperature": "72", "unit": "fahrenheit"})
elif "paris" in location.lower():
return json.dumps({"location": "Paris", "temperature": "22", "unit": "celsius"})
else:
return json.dumps({"location": location, "temperature": "unknown"})

messages = [{"role": "user", "content": "旧金山、东京和巴黎的天气怎么样?"}]
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定位置的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如 San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
},
}
]

response = litellm.completion(
model="gpt-3.5-turbo-1106",
messages=messages,
tools=tools,
tool_choice="auto", # auto 是默认值,但我们明确指定
)
print("\nLLM 响应1:\n", response)
response_message = response.choices[0].message
tool_calls = response.choices[0].message.tool_calls
预期输出

在输出中可以看到模型多次调用函数 - 分别对旧金山、东京、巴黎进行调用

ModelResponse(
id='chatcmpl-8MHBKZ9t6bXuhBvUMzoKsfmmlv7xq',
choices=[
Choices(finish_reason='tool_calls',
index=0,
message=Message(content=None, role='assistant',
tool_calls=[
ChatCompletionMessageToolCall(id='call_DN6IiLULWZw7sobV6puCji1O', function=Function(arguments='{"location": "San Francisco", "unit": "celsius"}', name='get_current_weather'), type='function'),

ChatCompletionMessageToolCall(id='call_ERm1JfYO9AFo2oEWRmWUd40c', function=Function(arguments='{"location": "Tokyo", "unit": "celsius"}', name='get_current_weather'), type='function'),

ChatCompletionMessageToolCall(id='call_2lvUVB1y4wKunSxTenR0zClP', function=Function(arguments='{"location": "Paris", "unit": "celsius"}', name='get_current_weather'), type='function')
]))
],
created=1700319953,
model='gpt-3.5-turbo-1106',
object='chat.completion',
system_fingerprint='fp_eeff13170a',
usage={'completion_tokens': 77, 'prompt_tokens': 88, 'total_tokens': 165},
_response_ms=1177.372
)

第二步 - 解析模型响应并执行函数

发送初始请求后,解析模型响应以识别其想要进行的函数调用。在这个例子中,我们期望三个工具调用,每个对应一个位置(旧金山、东京和巴黎)。

# 检查模型是否想要调用一个函数
if tool_calls:
# 执行函数并准备响应
available_functions = {
"get_current_weather": get_current_weather,
}

messages.append(response_message) # 扩展对话内容,包含助手的回复

for tool_call in tool_calls:
print(f"\n执行工具调用\n{tool_call}")
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
# 调用 get_current_weather() 函数
function_response = function_to_call(
location=function_args.get("location"),
unit=function_args.get("unit"),
)
print(f"工具调用的结果\n{function_response}\n")

# 扩展对话内容,包含函数响应
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)

第三步 - 第二次 litellm.completion() 调用

执行完函数后,将每个函数调用的信息及其响应发送给模型。这使得模型能够根据函数调用的效果生成新的响应。

second_response = litellm.completion(
model="gpt-3.5-turbo-1106",
messages=messages,
)
print("第二次响应\n", second_response)

预期输出

ModelResponse(
id='chatcmpl-8MHBLh1ldADBP71OrifKap6YfAd4w',
choices=[
Choices(finish_reason='stop', index=0,
message=Message(content="当前旧金山的天气是72°F,东京是10°C,巴黎是22°C。", role='assistant'))
],
created=1700319955,
model='gpt-3.5-turbo-1106',
object='chat.completion',
system_fingerprint='fp_eeff13170a',
usage={'completion_tokens': 28, 'prompt_tokens': 169, 'total_tokens': 197},
_response_ms=1032.431
)

并行函数调用 - Azure OpenAI

# 设置Azure环境变量
import os
os.environ['AZURE_API_KEY'] = "" # litellm从.env读取AZURE_API_KEY并发送请求
os.environ['AZURE_API_BASE'] = "https://openai-gpt-4-test-v-1.openai.azure.com/"
os.environ['AZURE_API_VERSION'] = "2023-07-01-preview"

import litellm
import json
# 示例虚拟函数硬编码以返回相同的天气信息
# 在生产环境中,这可能是您的后端API或外部API
def get_current_weather(location, unit="fahrenheit"):
"""获取指定位置的当前天气"""
if "tokyo" in location.lower():
return json.dumps({"location": "Tokyo", "temperature": "10", "unit": "celsius"})
elif "san francisco" in location.lower():
return json.dumps({"location": "San Francisco", "temperature": "72", "unit": "fahrenheit"})
elif "paris" in location.lower():
return json.dumps({"location": "Paris", "temperature": "22", "unit": "celsius"})
else:
return json.dumps({"location": location, "temperature": "unknown"})

## 步骤1:将对话和可用函数发送给模型
messages = [{"role": "user", "content": "旧金山、东京和巴黎的天气如何?"}]
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定位置的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如:San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
},
}
]

response = litellm.completion(
model="azure/chatgpt-functioncalling", # model = azure/<your-azure-deployment-name>
messages=messages,
tools=tools,
tool_choice="auto", # auto是默认值,但我们会明确指定
)
print("\nLLM Response1:\n", response)
response_message = response.choices[0].message
tool_calls = response.choices[0].message.tool_calls
print("\nTool Choice:\n", tool_calls)

## 步骤2 - 解析模型响应并执行函数
# 检查模型是否想要调用函数
if tool_calls:
# 执行函数并准备响应
available_functions = {
"get_current_weather": get_current_weather,
}

messages.append(response_message) # 将助手的回复扩展到对话中

for tool_call in tool_calls:
print(f"\nExecuting tool call\n{tool_call}")
function_name = tool_call.function.name
function_to_call = available_functions[function_name]
function_args = json.loads(tool_call.function.arguments)
# 调用get_current_weather()函数
function_response = function_to_call(
location=function_args.get("location"),
unit=function_args.get("unit"),
)
print(f"Result from tool call\n{function_response}\n")

# 将函数响应扩展到对话中
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": function_response,
}
)

## 步骤3 - 第二次litellm.completion()调用
second_response = litellm.completion(
model="azure/chatgpt-functioncalling",
messages=messages,
)
print("Second Response\n", second_response)
print("Second Response Message\n", second_response.choices[0].message.content)

已弃用 - 使用completion(functions=functions)的函数调用

import os, litellm
from litellm import completion

os.environ['OPENAI_API_KEY'] = ""

messages = [
{"role": "user", "content": "What is the weather like in Boston?"}
]

# 将被执行的Python函数
def get_current_weather(location):
if location == "Boston, MA":
return "The weather is 12F"

# 传递给OpenAI的JSON Schema
functions = [
{
"name": "get_current_weather",
"description": "获取给定地点的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如:San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
]

response = completion(model="gpt-3.5-turbo-0613", messages=messages, functions=functions)
print(response)

litellm.function_to_dict - 将函数转换为字典以供 OpenAI 函数调用

function_to_dict 允许你传递一个函数的文档字符串,并生成一个可用于 OpenAI 函数调用的字典。

使用 function_to_dict

  1. 定义你的函数 get_current_weather
  2. 为你的函数 get_current_weather 添加文档字符串
  3. 将函数传递给 litellm.utils.function_to_dict 以获取用于 OpenAI 函数调用的字典
# 带有文档字符串的函数
def get_current_weather(location: str, unit: str):
"""获取给定位置的当前天气

参数
----------
location : str
城市和州,例如:San Francisco, CA
unit : {'celsius', 'fahrenheit'}
温度单位

返回
-------
str
指示天气的句子
"""
if location == "Boston, MA":
return "The weather is 12F"

# 使用 litellm.utils.function_to_dict 将函数转换为字典
function_json = litellm.utils.function_to_dict(get_current_weather)
print(function_json)

function_to_dict 的输出

{
'name': 'get_current_weather',
'description': '获取给定位置的当前天气',
'parameters': {
'type': 'object',
'properties': {
'location': {'type': 'string', 'description': '城市和州,例如:San Francisco, CA'},
'unit': {'type': 'string', 'description': '温度单位', 'enum': "['fahrenheit', 'celsius']"}
},
'required': ['location', 'unit']
}
}

使用 function_to_dict 进行函数调用

import os, litellm
from litellm import completion

os.environ['OPENAI_API_KEY'] = ""

messages = [
{"role": "user", "content": "波士顿的天气怎么样?"}
]

def get_current_weather(location: str, unit: str):
"""获取给定位置的当前天气

参数
----------
location : str
城市和州,例如:San Francisco, CA
unit : str {'celsius', 'fahrenheit'}
温度单位

返回
-------
str
指示天气的句子
"""
if location == "Boston, MA":
return "The weather is 12F"

functions = [litellm.utils.function_to_dict(get_current_weather)]

response = completion(model="gpt-3.5-turbo-0613", messages=messages, functions=functions)
print(response)

不支持函数调用的模型进行函数调用

将函数添加到提示中

对于不支持函数调用的模型/提供者,LiteLLM 允许你将函数添加到提示集中:litellm.add_function_to_prompt = True

用法

import os, litellm
from litellm import completion

# 重要 - 设置为 TRUE 以将函数添加到非 OpenAI LLMs 的提示中
litellm.add_function_to_prompt = True # 为非 OpenAI LLMs 设置 add_function_to_prompt

os.environ['ANTHROPIC_API_KEY'] = ""

messages = [
{"role": "user", "content": "波士顿的天气怎么样?"}
]

def get_current_weather(location):
if location == "Boston, MA":
return "The weather is 12F"

functions = [
{
"name": "get_current_weather",
"description": "获取给定位置的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如:San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
]

response = completion(model="claude-2", messages=messages, functions=functions)
print(response)
优云智算