使用 Tool Call 扩展你的应用能力
大模型虽然掌握了丰富的知识,但在特定领域,例如时效性较高的资讯类和天气预报,或者需要严密科学计算,以及特定行业的知识,当它们匮乏这部分知识时,它们可能会编造看似真实但实则虚假的信息。
为解决这一问题。阶跃大模型提供了 Tool call 工具,Tool call 可以扩展语言模型的功能,使其能够执行额外的操作,如搜索信息、科学计算、访问数据库等。这样模型可以为用户提供更精准的信息,帮助开发者更好地处理业务需求。
除了获取信息以外, Tool Call 还可以帮助开发者生成函数调用签名,开发者通过对调用签名的处理,实现扩展应用能力,让你的应用除了对话,还可以完成各项不同的能力。
实现原理 & 参考
在使用 Tool Call 时,我们可以选择两个方向来思考 Tool Call 帮助我们扩展应用能力:
- 使用 Tool Call 获取大模型自身训练不包含的信息,丰富上下文,精确回答内容;
- 使用 Tool Call 操作本地应用程序,执行特定业务操作。
前者主要通过 Tool Call 调用预定义好的函数,以获得更加精确的信息,帮助大模型补全上下文,从而生成更加精确的回答。 后者则是通过 Tool Call 调用本地应用程序,执行特定的业务操作,以实现更加丰富的功能。
使用 Tool Call 获取信息
这里我们以助手类应用的常见技能 —— 查询天气为例,我们需要构建一个可以通过自然语言,查询天气的能力。
你需要做以下四步:
- 第一步,需要准备好查询天气接口的地址和密钥,构造查询天气的 Function;
- 第二步,构建 get_weather 工具定义查询天气 Function 的功能;
- 第三步,阶跃大模型识别用户查询天气的意图时,根据提示语给出查询参数;
- 第四步,使用大模型返回的参数调用查天气接口,获取准确的天气信息。
参考代码:以 Python 为例
from openai import OpenAI
import requests
import json
# 初始化 查询天气的接口参数,这里我使用的是高德查询天气接口,各位开发者可以按需自行选择供应商进行实现
get_weather_url = "https://restapi.amap.com/v3/weather/weatherInfo?parameters"
get_weather_key = "YourGaoDeAPIkey"
COMPLETION_MODEL= "step-1-8k"
# 初始化 阶跃星辰 Client
STEPFUN_KEY = "YourAPIkey"
client = OpenAI(base_url="https://api.stepfun.com/v1", api_key=STEPFUN_KEY)
# 初始化查询天气的函数
def get_weather(city):
params = {
"city": city,
"key": get_weather_key,
"extensions": "base", # 获取实时天气
}
response = requests.get(url=get_weather_url, params=params) # 实时天气
if response.status_code == 200:
data = response.json()
print(data)
# weather = data.get ('lives')[0].get ('weather') # 当前天气现象
# temperature = data ['lives'][0].get ('temperature') # 当前温度
# print ( f"{city} 现在的天气是 {weather} 温度是 {temperature}°C.")
else:
print("对不起,我无法获取这个地点的天气。")
# 构建 get_weather 函数说明
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称(必须为汉字)"}
},
"required": ["city"],
},
},
}
]
# 调用补全接口进行补全
def query_weather(prompt):
completion = client.chat.completions.create(
model=COMPLETION_MODEL,
messages=[{"role": "user", "content": prompt}],
## 自动选择是否调用外部函数
tool_choice="auto",
tools=tools,
)
# print (completion.choices [0].message.content.strip ())
print(completion)
# 判断是否命中查询天气 Function
if completion.choices[0].message.content.strip() == "":
if completion.choices[0].message.tool_calls[0].function.name == "get_weather":
# 获取参数
city_name = json.loads(
completion.choices[0].message.tool_calls[0].function.arguments
)
# 调用 Function
get_weather(city_name["city"])
else:
print("未命中查询天气 Tool")
else:
print("抱歉出错了")
# print (completion.choices [0].message.content.strip ())
# 查询天气
query_weather("上海现在的天气怎么样?")
返回结果
# 返回值结果
# 首先大模型通过意图识别到需要调用 Tool Call,所以在 tool_calls 里给出了需要调用的函数名称,以及参数
{
"id": "291c59ebf4017a937a2a42a8ed52581f.c2669ebc05a491c70f821b4e568b6433",
"object": "chat.completion",
"created": 1722505763,
"model": "step-1-8k",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_brg23SRcTgmpm_V0jfP-iA",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \" 上海 \"}"
}
}
]
},
"finish_reason": "stop"
}
],
"usage": {
"cached_tokens": 48,
"prompt_tokens": 94,
"completion_tokens": 16,
"total_tokens": 110
}
}
# 接着使用大模型给出的参数调用查询天气接口,获得准确的天气
{
"status": "1",
"count": "1",
"info": "OK",
"infocode": "10000",
"lives": [
{
"province": "上海",
"city": "上海市",
"adcode": "310000",
"weather": "晴",
"temperature": "37",
"winddirection": "西北",
"windpower": "≤3",
"humidity": "42",
"reporttime": "2024-08-02 10:01:14",
"temperature_float": "37.0",
"humidity_float": "42.0"
}
]
}
# 继续拼接作为上下文信息放入 Messages,让大模型进行补全。
使用 Tool Call 执行任务
当应用需要扩展其能力,不仅仅是获取数据时,则可以通过 Tool Call 能力,为你的应用增加一些神奇的能力,从而帮助用户更进一步展示不同的能力。
这里我们同样以助手类应用为例,我们可以实现一个通过自然语言发送电子邮件的能力。你需要做以下几步:
- 第一步,在本地构建出一个发送邮件的 Function ,并实现发送邮件相关功能;
- 第二步,构建 send_email 工具定义发送邮件的功能;
- 第三步,阶跃大模型识别用户发送邮件的意图时,根据提示语给出查询参数;
- 第四步,使用大模型返回的参数调用发送电子邮件。
参考代码:以 Python & Swift 为例
本地的发送邮件的 Function
func sendEmail (subject:String, body: String, recipient: String) {
// 调用 MFMailComposeViewController 来发送邮件
}
服务端调用阶跃星辰大模型的参考代码
from openai import OpenAI
# 初始化 阶跃星辰 Client
STEPFUN_KEY = "YourAPIkey"
client = OpenAI(base_url="https://api.stepfun.com/v1", api_key=STEPFUN_KEY)
# 构建 sendEmail 函数说明
tools = [
{
"type": "function",
"function": {
"name": "senEmail",
"description": "这个函数可以用于向特定的用户发送包含特定内容的电子邮件",
"parameters": {
"type": "object",
"properties": {
"subject": {
"type": "string",
"description": "邮件的标题,不可以超过 255 个字",
},
"body": {
"type": "string",
"description": "邮件内容,不可以超过 4096 个子",
},
"recipient": {"type": "string", "description": "收件人"},
},
"required": ["subject", "body", "recipient"],
},
},
}
]
# 调用阶跃星辰 API 生成接口调用方法
def get_call_sign(user_input):
completion = client.chat.completions.create(
model=COMPLETION_MODEL,
messages=[{"role": "user", "content": user_input}],
## 自动选择是否调用外部函数
tool_choice="auto",
tools=tools,
)
if completion.choices[0].message.content.strip() == "":
if completion.choices[0].message.tool_calls[0].function.name == "senEmail":
# 获取参数
arguments = json.loads(
completion.choices[0].message.tool_calls[0].function.arguments
)
# 触发本地调用函数
send_to_client("sendEmail", arguments)
注意事项
- 构造 Tool 的时候请注意将 Function 的 description 描述清楚,以便于大模型清晰的知道 Function 的功能,这样能提高命中率;
- Function 入参的 description 也需要备注清楚(建议说明入参是中文还是英文),以便于大模型生成有效的参数供使用。