InternLM/lmdeploy 工具调用功能详解
工具调用功能概述
InternLM/lmdeploy 项目提供了强大的工具调用功能,支持多种主流大语言模型(InternLM2、InternLM2.5、llama3.1 和 Qwen2.5)的工具调用能力。这一功能使得大语言模型能够与外部工具和服务进行交互,极大地扩展了模型的应用场景和能力边界。
工具调用解析器配置
在使用 api_server 启动服务时,需要通过 --tool-call-parser
参数指定要使用的解析器类型。目前支持以下解析器:
- internlm - 适用于 InternLM 系列模型
- qwen - 适用于 Qwen 系列模型
- llama3 - 适用于 Llama3 系列模型
单轮工具调用示例
以下是一个获取天气信息的单轮工具调用示例:
from openai import OpenAI
# 定义工具描述
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定位置的当前天气情况",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和州,例如:北京, 中国",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
}
}
]
# 用户消息
messages = [{"role": "user", "content": "今天北京的天气怎么样?"}]
# 创建客户端连接
client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
# 发起请求
response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False,
tools=tools)
print(response)
多轮工具调用详解
InternLM 模型示例
InternLM 模型支持完整的工具链调用流程。以下是一个计算 (3+5)*2 的完整示例:
from openai import OpenAI
# 定义工具函数
def add(a: int, b: int):
return a + b
def mul(a: int, b: int):
return a * b
# 工具描述
tools = [
{
'type': 'function',
'function': {
'name': 'add',
'description': '计算两个数的和',
'parameters': {
'type': 'object',
'properties': {
'a': {'type': 'int', 'description': '数字'},
'b': {'type': 'int', 'description': '数字'},
},
'required': ['a', 'b'],
},
}
},
{
'type': 'function',
'function': {
'name': 'mul',
'description': '计算两个数的乘积',
'parameters': {
'type': 'object',
'properties': {
'a': {'type': 'int', 'description': '数字'},
'b': {'type': 'int', 'description': '数字'},
},
'required': ['a', 'b'],
},
}
}
]
# 用户请求
messages = [{'role': 'user', 'content': '计算 (3+5)*2'}]
# 初始化客户端
client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
# 第一轮请求 - 加法
response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False,
tools=tools)
# 执行加法
add_result = eval(f"add(**{response.choices[0].message.tool_calls[0].function.arguments})")
# 更新对话历史
messages.extend([
response.choices[0].message,
{
'role': 'tool',
'content': f'3+5={add_result}',
'tool_call_id': response.choices[0].message.tool_calls[0].id
}
])
# 第二轮请求 - 乘法
response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False,
tools=tools)
# 执行乘法
mul_result = eval(f"mul(**{response.choices[0].message.tool_calls[0].function.arguments})")
print(f"最终结果: {mul_result}")
Llama3.1 模型工具调用
Llama3.1 模型内置了三种工具:
- Brave Search - 执行网页搜索
- Wolfram Alpha - 执行复杂数学计算
- Code Interpreter - 输出 Python 代码
以下是一个使用 Wolfram Alpha 工具求解方程的示例:
from openai import OpenAI
import requests
# 系统提示必须包含工具描述
messages = [
{
"role": "system",
"content": "Environment: ipython\nTools: wolfram_alpha\n\nToday Date: 23 Jul 2024\n\nYou are a helpful Assistant."
},
{
"role": "user",
"content": "帮我解这个方程: x^3 - 4x^2 + 6x - 24 = 0"
}
]
# 初始化客户端
client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
# 获取模型生成的查询
response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False)
wolfram_query = response.choices[0].message.content
# 调用 Wolfram Alpha API
app_id = 'YOUR-Wolfram-Alpha-API-KEY'
params = {
"input": wolfram_query,
"appid": app_id,
"format": "plaintext",
"output": "json",
}
wolfram_response = requests.get(
"https://api.wolframalpha.com/v2/query",
params=params
).json()
# 将结果返回给模型
messages.extend([
{"role": "assistant", "content": wolfram_query},
{"role": "ipython", "content": wolfram_response}
])
final_response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False)
print(final_response.choices[0].message.content)
Qwen2.5 模型的多工具调用
Qwen2.5 模型支持在一次请求中同时调用多个工具,以下是一个同时查询当前和未来天气的示例:
from openai import OpenAI
import json
# 天气查询工具函数
def get_current_temperature(location: str, unit: str = "celsius"):
return {"temperature": 26.1, "location": location, "unit": unit}
def get_temperature_date(location: str, date: str, unit: str = "celsius"):
return {"temperature": 25.9, "location": location, "date": date, "unit": unit}
# 工具描述
tools = [
{
'type': 'function',
'function': {
'name': 'get_current_temperature',
'description': '获取指定位置的当前温度',
'parameters': {
'type': 'object',
'properties': {
'location': {'type': 'string', 'description': '位置,格式为"城市, 州, 国家"'},
'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit'], 'description': '温度单位'}
},
'required': ['location']
}
}
},
{
'type': 'function',
'function': {
'name': 'get_temperature_date',
'description': '获取指定位置和日期的温度',
'parameters': {
'type': 'object',
'properties': {
'location': {'type': 'string', 'description': '位置,格式为"城市, 州, 国家"'},
'date': {'type': 'string', 'description': '日期,格式为"年-月-日"'},
'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit'], 'description': '温度单位'}
},
'required': ['location', 'date']
}
}
}
]
# 用户请求
messages = [{'role': 'user', 'content': '今天是2024-11-14,旧金山现在的温度是多少?明天的呢?'}]
# 初始化客户端
client = OpenAI(api_key='YOUR_API_KEY', base_url='http://0.0.0.0:23333/v1')
model_name = client.models.list().data[0].id
# 获取工具调用请求
response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False,
tools=tools)
# 执行工具调用
for tool_call in response.choices[0].message.tool_calls:
args = json.loads(tool_call.function.arguments)
if tool_call.function.name == "get_current_temperature":
result = get_current_temperature(**args)
else:
result = get_temperature_date(**args)
messages.append({
'role': 'tool',
'name': tool_call.function.name,
'content': json.dumps(result),
'tool_call_id': tool_call.id
})
# 获取最终回答
final_response = client.chat.completions.create(
model=model_name,
messages=messages,
temperature=0.8,
top_p=0.8,
stream=False)
print(final_response.choices[0].message.content)
最佳实践建议
-
模型选择:对于复杂工具调用场景,建议使用70B或更大参数的模型,小模型可能无法可靠地维持工具调用对话
-
错误处理:在实际应用中,应添加适当的错误处理逻辑,特别是对于外部API调用
-
工具描述:确保工具的描述清晰准确,这将直接影响模型选择和使用工具的能力
-
对话历史管理:在多轮交互中,正确维护对话历史对于模型理解上下文至关重要
-
性能考虑:工具调用会增加响应时间,对于实时性要求高的应用需要考虑优化策略
通过合理利用 InternLM/lmdeploy 的工具调用功能,开发者可以构建出功能更加强大、交互更加智能的应用系统。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考