这是大模型编程系列的第三篇,也是我学习 某云大模型工程师ACA认证免费课程 的笔记,这课真不错,太香了必须强烈推荐👍🏻。对课程有兴趣请点击底部的查看原文。
上一篇里面我们实现了大模型API的循环调用调用,来完成我们实际的业务需求。
老板的需求
作为一个牛马,随时要接受老板的安排,今天老板早上说等会晚点帮我订一张机票,时间和地点我还没确定,等会确定了我和你说。
嘴上答应没问题,内心一万个不愿意,什么时候给我发消息啊,我那会一定在电脑前面吗,想到这点就烦,要是 AI 能做这事就好了。
AI 的实现 function call
订机票有点复杂了,换个简单的,参考 某云大模型工程师ACA认证免费课程 查天气吧。
我们知道大语言模型的本质概括来说是根据给定的文本预测下一个token
。对我们来说,看似像在对大模型提问,但实际上是给了大模型一串提示文本,让它可以对后续的文本进行推理。(图看不懂可以先忽略)
具体可以学习这篇课程认识大模型
所以当我们问大模型今天会议室的空闲状态,今天的天气的时候,他是不知道的,但是我们是可以调用接口查询到的(先不考虑后面 RAG 的方案,假设要查天气只能通过接口查询,不能通过搜索网页查询)。
捋捋这个思路就是 最难的点就在于,如果大模型能主动调用接口,再把接口调用的结果整理之后返回给我们就好了。 如下:
还别说 openai 早给我们设计好了这样的插件机制,参考 function call 示例
程序设计的话,流程如下:
- 用户输入:用户向你的应用发送一条消息,比如 "北京今天天气怎样"。
- 处理用户请求:你的应用程序接收到这条消息后,可以使用 OpenAI 的 API 来解析用户的意图,并识别出他们想查询的是伦敦当天的天气情况。
- 函数调用 (Function Call):基于 OpenAI API 的响应,如果你的应用程序需要查询具体的天气数据,它可以调用预先定义好的函数,例如 get_weather(city: str),这个函数会使用第三方天气 API 来获取最新的天气信息。
- 获取天气信息:get_weather() 函数将向第三方天气 API 发送请求,传入城市名作为参数,并接收包含天气信息的响应。
- 整合信息并回应用户:一旦获得了天气信息,你的应用程序就可以格式化这些信息,并使用 OpenAI 的 API 生成一个自然语言的回答给用户,比如 "今天北京市的天气是雨天。请带好雨具,出行注意安全。"
from openai import OpenAI
import os
import json
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
# 定义工具列表,模型在选择使用哪个工具时会参考工具的name和description
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "当你想查询指定城市的天气时非常有用。",
"parameters": {
"type": "object",
"properties": {
# 查询天气时需要提供位置,因此参数设置为location
"location": {
"type": "string",
"description": "城市或县区,比如北京市、杭州市、余杭区等。"
}
}
},
"required": [
"location"
]
}
}
]
# 模拟天气查询工具。返回结果示例:“北京今天是雨天。”
def get_current_weather(location):
return f"{location}今天是雨天。 "
# 封装模型响应函数
def get_response(messages):
completion = client.chat.completions.create(
model="qwen-plus",
messages=messages,
tools=tools
)
return completion.model_dump()
def call_with_messages():
print('\n')
messages = [
{
"content": input('请输入:'), # 提问示例: "北京天气如何?"
"role": "user"
}
]
print("-"*60)
# 模型的第一轮调用
i = 1
first_response = get_response(messages)
assistant_output = first_response['choices'][0]['message']
print(f"\n第{i}轮大模型输出信息:{first_response}\n")
# 如果不需要调用工具,则直接返回最终答案
if assistant_output['tool_calls'] == None: # 如果模型判断无需调用工具,则将assistant的回复直接打印出来,无需进行模型的第二轮调用
print(f"无需调用工具,我可以直接回复:{assistant_output['content']}")
return
messages.append(assistant_output)
# 如果判断需要调用查询天气工具,则运行查询天气工具
if assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather':
tool_info = {
"name": "get_current_weather", "role":"tool"}
# 提取位置参数信息
location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['location']
tool_info['content'] = get_current_weather(location)
print(f"工具输出信息:{tool_info['content']}\n")
print("-"*60)
messages.append(tool_info)
assistant_output = get_response(messages)['choices'][0]['message']
if assistant_output['content'] is None:
assistant_output['content'] = ""
messages.append(assistant_output)
i += 1
print(f"第{i}轮大模型输出信息:{assistant_output}\n")
print(f"最终答案:{assistant_output['content']}")
if __name__ == '__main__':
call_with_messages()
里面有很多调试的信息,方便我们学习,比如第一轮对话会返回的数据如下
{
"id": "chatcmpl-233f4cc2-3e69-9b97-b348-27ec1867d694",
"choices": [
{
"finish_reason": "tool_calls",
"index": 0,
"logprobs": "None",
"message": {
"content": "",
"refusal": "None",
"role": "assistant",
"audio": "None",
"function_call": "None",
"tool_calls": [
{
"id": "call_a53c36f740d14e1fb6fd80",
"function": {
"arguments": "{\"location\":\"北京市\"}",
"name": "get_current_weather"
},
"type": "function",
"index": 0
}
]
}
}
],
"created": 1735797998,
"model": "qwen-plus",
"object": "chat.completion",
"service_tier": "None",
"system_fingerprint": "None",
"usage": {
"completion_tokens": 18,
"prompt_tokens": 184,
"total_tokens": 202,
"completion_tokens_details": "None",
"prompt_tokens_details": {
"audio_tokens": "None",
"cached_tokens": 0
}
}
}
也就是说告诉我们需要调用工具方法,并且已经帮我们把工具的参数已经组装好了,这也太神奇了‼️
我这里只是一些笔记,完整课程请点击底部的查看原文,完全免费的。
这个思路有了,AI 订机票不就依葫芦画瓢了吗?那也太简单了,你们评论区实现下吧。