
function call介绍和实现(以DeepSeek为例)
(如数据库、硬件设备、业务系统)交互,从而实现更复杂的任务。。当然大模型本身无法调用函数,还得通过程序实现。用户问:北京今天天气怎么样?这个问题是需要的,但是众所周知,大模型裸推的话是无法获取实时信息的。。大模型回答问题的时候发现需要调用函数,并提取参数。整理流程如下所示:name:函数的名字(具体的函数需要自己定义)。:函数的描述。parameters:函数的入参,该例子中只需要一个"locat
function call介绍和实现(以DeepSeek为例)
function call定义
Function Call 是一种机制,允许大语言模型在推理过程中动态调用外部函数或 API,以获取实时数据、执行特定任务或操作外部系统。通过 Function Call,模型能够直接与外部工具(如数据库、硬件设备、业务系统)交互,从而实现更复杂的任务。
简单来说就是:大模型调用外部函数完成用户的任务。当然大模型本身无法调用函数,还得通过程序实现。
举个例子:
用户问:北京今天天气怎么样?
这个问题是需要实时天气信息的,但是众所周知,大模型裸推的话是无法获取实时信息的。
因此我们可以写一个获得天气的函数:get_weather
函数,用于获得天气,函数的入参为:location:str
。大模型回答问题的时候发现需要调用get_weather
函数,并提取参数location:"北京"
。
整理流程如下所示:
那么还有一个关键点:大模型如何知道有哪些可调用的模型呢?
需要我们明确描述每个可用工具的输入输出规范,格式如下:
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "获得天气的函数,需要提供地点信息",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市或者地区,比如北京,上海",
}
},
"required": ["location"]
},
}
}
]
简单介绍下比较重要的参数:
name
:函数的名字(具体的函数需要自己定义)。
description
:函数的描述。
parameters
:函数的入参,该例子中只需要一个"location"
参数。
required
:大模型需要提供的入参。
至此我们定义了tools
,并且申明有哪些外部函数可以调用。
创建client
的时候传入tools
参数即可。
client.chat.completions.create(
model="deepseek-chat",
messages=messages,
tools=tools,
tool_choice="auto"
)
简单介绍完了Function Call,我们可以发现最重要的其实只有两点:
- 编写外部可调用函数。
- 将可调用的函数的信息以写入
tools
中交给大模型。
实战:以deepseek为例
下面以deepseek为基础模型简单实现一个function call的例子。
deepseek api请自行前往:https://platform.deepseek.com/申请。
首先我们需要编写外部可调用的函数。
mykey = "xxxxxx"
def weibohot():
url = f"https://apis.tianapi.com/weibohot/index?key={mykey}"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data and 'list' in data['result']:
data_lists = data['result']['list']
data_str = '\n'.join(f'{i+1}: {item["hotword"]}' for i, item in enumerate(data_lists))
return data_str
else:
return "Failed to retrieve data from Weibo trending topics."
except requests.RequestException as e:
return f"error: {e}"
def douyinhot():
url = f"https://apis.tianapi.com/douyinhot/index?key={mykey}"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data and 'list' in data['result']:
data_lists = data['result']['list']
data_str = '\n'.join(f'{i+1}: {item["word"]}' for i, item in enumerate(data_lists))
return data_str
else:
return "Failed to retrieve data from douyin trending topics."
except requests.RequestException as e:
return f"error: {e}"
def get_weather(location):
url = f"https://apis.tianapi.com/tianqi/index?key={mykey}&city={location}&type=1"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data:
weather_info = data['result']
return f"{location}的天气是{weather_info['weather']},温度{weather_info['real']}。Tips:{weather_info['tips']}"
else:
return "Failed to retrieve weather data."
except requests.RequestException as e:
return f"error: {e}"
我写了三个函数,分别用于获得天气,获取微博热搜,获得抖音热搜。
这里的api我是在
申请的。
申请功能接口和个人的KEY
密钥key:
微博热搜,抖音热搜每天都有免费的额度可以使用。
申请api后,我们可以测试下函数
print(weibohot())
'''
1: 一天官宣三部大剧
2: 缅甸7.9级地震地表位移画面首曝光
3: 中国坚定不移扩大高水平对外开放
4: 京东618买苹果领券叠国补更便宜
5: 折腰今日开播
6: 13岁女孩称以为是妈妈让女教官打自己
7: 女子被困自家别墅电梯1天1夜
....
'''
print(douyinhot())
'''
1: 金价
2: 中美最终加征多少关税
3: 数说中国民营经济新动能
4: 外交部:芬太尼是美国的问题
5: 苹果iOS 18.5正式版发布
6: 65款应用违法违规收集使用个人信息
7: 金饰克价跌破千元
8: A股港股行情
9: 董军同法国国防部长举行会谈
10: 杜特尔特狱中当选市长
11: 独行侠抽中状元签
12: 森林狼轻取勇士夺赛点
....
'''
print(get_weather("北京"))
'''
北京的天气是晴,温度30.5℃。
Tips:晴天紫外线等级较高,外出注意补水防晒。
该地区今日温差较大,建议根据实际情况适时调整衣着安排。
天气炎热,适宜着短衫、短裙、短裤、薄型T恤衫、敞领短袖棉衫等夏季服装。
空气质量较差,敏感人群建议减少体力消耗类户外活动。
'''
都能返回实时信息。勇士没库里还真不行。
下面将函数的信息写入tools
中。
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获得天气的函数,需要提供地点信息",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市或者地区,比如北京,上海",
}
},
"required": ["location"]
},
}
},
{
"type": "function",
"function": {
"name": "weibohot",
"description": "获得微博热搜,将返回现在的微博搜热结果",
"parameters": {
"type": "object"
},
"required": []
},
},
{
"type": "function",
"function": {
"name": "douyinhot",
"description": "获得抖音热搜,将返回现在的抖音搜热结果",
"parameters": {
"type": "object"
},
"required": []
},
}
]
下面我们定义函数chat_llm_tools
用于回答用户问题和调用外部函数。
def chat_llm_tools(query: str) -> str:
client = openai.Client(api_key=API_KEY, base_url=URL)
messages = [{"role": "user", "content": query}]
while True:
# 将tools传入大模型
response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
tools=tools,
tool_choice="auto"
)
reply = response.choices[0].message
messages.append(reply)
# 如果大模型判断是否需要执行tools
if not reply.tool_calls:
break
# 执行tools
for tool_call in reply.tool_calls:
function_args = json.loads(tool_call.function.arguments)
result = globals()[tool_call.function.name](**function_args)
print(f"use tool: {tool_call.function.name}")
tool_call_id = tool_call.id
# 将tools执行的结果加入messages中
messages.append({"role": "tool", "tool_call_id": tool_call_id, "content": str(result)})
final_response = response.choices[0].message.content
return final_response
query = "总结下现在的微博和抖音热搜"
print(chat_llm_tools(query=query))
'''
use tool: weibohot
use tool: douyinhot
### 微博热搜总结:
1. **社会热点**:缅甸7.9级地震地表位移画面首曝光、卫健委回应救护车在西藏拉警报旅游、女子被困自家别墅电梯1天1夜等。
2. **娱乐动态**:一天官宣三部大剧、折腰今日开播、迪士尼发了肖战剧照、肖战一键转场打开藏海传等。
3. **国际新闻**:莫迪对印巴空战公开讲话但只字不提美国、巴基斯坦举国感谢中国等。
4. **商业活动**:天猫618补贴真的大、抖音商城618超级补贴价更低等。
5. **争议话题**:代孕一旦合法穷人更将苦不堪言、曝司机骚扰未成年女乘客问是不是处女等。
### 抖音热搜总结:
1. **经济与政策**:金价、中美最终加征多少关税、外交部:芬太尼是美国的问题等。
2. **科技与产品**:苹果iOS 18.5正式版发布、国补版iPhone16Pro被抢空等。
3. **体育赛事**:森林狼轻取勇士夺赛点、独行侠抽中状元签、郑钦文晋级罗马站8强等。
4. **娱乐与生活**:夏天的味道在抖音、你家端午吃甜粽还是咸粽、藏海传定档0518等。
5. **国际动态**:印巴冲突后莫迪首次公开发言、智利总统博里奇抵京等。
### 共同点:
- **国际新闻**:莫迪对印巴冲突的发言在微博和抖音均有提及。
- **商业活动**:抖音商城618超级补贴在两大平台均有热度。
- **娱乐内容**:影视剧和明星动态在微博和抖音都占据重要位置。
### 差异:
- **微博**更侧重于社会热点和娱乐新闻。
- **抖音**更关注经济、科技和体育赛事。
'''
成功执行weibohot
和douyinhot
简单分析下对话的代码。
response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
tools=tools,
tool_choice="auto"
)
reply = response.choices[0].message
获得reply
后查看下里面的内容
ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None,
tool_calls=[
ChatCompletionMessageToolCall(id='call_0_32551392-1330-467b-82dc-d3db4391ac15', function=Function(arguments='{}', name='weibohot'), type='function', index=0),
ChatCompletionMessageToolCall(id='call_1_33c6a597-6a36-4ee0-ac5f-8d0724794132', function=Function(arguments='{}', name='douyinhot'), type='function', index=1)])
大模型返回需要调用的函数:调用'weibohot'
和'douyinhot'
for tool_call in reply.tool_calls:
function_args = json.loads(tool_call.function.arguments)
result = globals()[tool_call.function.name](**function_args)
print(f"use tool: {tool_call.function.name}")
tool_call_id = tool_call.id
messages.append({"role": "tool", "tool_call_id": tool_call_id, "content": str(result)})
循环执行需要调用的函数,function_args
为执行函数需要的入参,因为'weibohot'
和'douyinhot'
两个函数不需要入参,因此这里function_args
为空。
result = globals()[tool_call.function.name](**function_args)
通过globals()
执行外部函数,得到返回结果。
并且将返回结果加入到messages
中
messages.append({"role": "tool", "tool_call_id": tool_call_id, "content": str(result)})
完整代码如下:
import requests
import openai
import json
MODEL_NAME = "deepseek-chat"
API_KEY = "sk-xxxxxx"
URL = "https://api.deepseek.com"
mykey = "xxxxxxxx"
def weibohot():
url = f"https://apis.tianapi.com/weibohot/index?key={mykey}"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data and 'list' in data['result']:
data_lists = data['result']['list']
data_str = '\n'.join(f'{i+1}: {item["hotword"]}' for i, item in enumerate(data_lists))
return data_str
else:
return "Failed to retrieve data from Weibo trending topics."
except requests.RequestException as e:
return f"error: {e}"
def douyinhot():
url = f"https://apis.tianapi.com/douyinhot/index?key={mykey}"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data and 'list' in data['result']:
data_lists = data['result']['list']
data_str = '\n'.join(f'{i+1}: {item["word"]}' for i, item in enumerate(data_lists))
return data_str
else:
return "Failed to retrieve data from douyin trending topics."
except requests.RequestException as e:
return f"error: {e}"
def get_weather(location):
url = f"https://apis.tianapi.com/tianqi/index?key={mykey}&city={location}&type=1"
try:
response = requests.get(url)
response.raise_for_status() # Raise an error for bad responses
data = response.json()
if 'result' in data:
weather_info = data['result']
return f"{location}的天气是{weather_info['weather']},温度{weather_info['real']}。Tips:{weather_info['tips']}"
else:
return "Failed to retrieve weather data."
except requests.RequestException as e:
return f"error: {e}"
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获得天气的函数,需要提供地点信息",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市或者地区,比如北京,上海",
}
},
"required": ["location"]
},
}
},
{
"type": "function",
"function": {
"name": "weibohot",
"description": "获得微博热搜,将返回现在的微博搜热结果",
"parameters": {
"type": "object"
},
"required": []
},
},
{
"type": "function",
"function": {
"name": "douyinhot",
"description": "获得抖音热搜,将返回现在的抖音搜热结果",
"parameters": {
"type": "object"
},
"required": []
},
}
]
def chat_llm_tools(query: str) -> str:
client = openai.Client(api_key=API_KEY, base_url=URL)
messages = [{"role": "user", "content": query}]
while True:
response = client.chat.completions.create(
model=MODEL_NAME,
messages=messages,
tools=tools,
tool_choice="auto"
)
reply = response.choices[0].message
# print(f"大模型返回: {reply}")
messages.append(reply)
if not reply.tool_calls:
break
for tool_call in reply.tool_calls:
function_args = json.loads(tool_call.function.arguments)
result = globals()[tool_call.function.name](**function_args)
print(f"use tool: {tool_call.function.name}")
tool_call_id = tool_call.id
messages.append({"role": "tool", "tool_call_id": tool_call_id, "content": str(result)})
final_response = response.choices[0].message.content
return final_response
# query = "上海今天天气"
query = "总结下现在的微博和抖音热搜"
print(chat_llm_tools(query=query))
参考
八、基于OpenAI大模型开发——Function calling-CSDN博客
【DeepSeek开发入门】Function Calling 函数功能应用实战指南_deepseek function calling-CSDN博客
更多推荐
所有评论(0)