函数调用
检查模型是否支持函数调用
使用 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
在这个例子中,我们定义了一个单一的函数 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
进行并行函数调用的解释
第一步:设置 tools
为 get_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
- 定义你的函数
get_current_weather
- 为你的函数
get_current_weather
添加文档字符串 - 将函数传递给
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)