系列篇章💥
No. | 文章 |
---|---|
1 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎的构建与初步实践 |
2 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之GLM-4大模型技术的实践探索 |
3 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(初步实践) |
4 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(函数封装) |
5 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之知乎网站数据获取(流程优化) |
6 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之github网站在线搜索 |
7 | AI大模型探索之路-实战篇:智能化IT领域搜索引擎之HuggingFace网站在线搜索 |
目录
- 系列篇章💥
- 一、前言
- 二、总体概览
- 三、智谱AI开发平台
- 1、注册智谱AI
- 2、取出API key
- 四、GLM-4 函数调用说明
- 1、描述函数功能
- 2、编写函数参数列表的 JSON 描述
- 3、函数调用选择
- 五、GLM-4函数应用测试
- 1、提前安装依赖
- 2、创建智谱AI大模型客户端
- 3、定义测试的外部function calling函数
- 4、定义function calling函数信息生成器
- 5、封装AI大模型的两次调用
- 6、定义数据对象
- 7、定义消息列表
- 8、大模型调用测试
- 9、智能对话助手封装
- 10、智能对话助手测试
- 结语
一、前言
在先前的文章中,我们完成了智能化IT领域搜索引擎的基础架构设计以及Google Search API的申请等前期准备工作。本文将重点介绍如何利用GLM4的Function Calling能力进行实战体验,为我们的智能化IT领域搜索引擎的代码实现提供实践基础。
二、总体概览
本文主要通过实践体验GLM4的Function Calling能力,为我们的智能化IT领域搜索引擎的代码实现提供铺垫。我们将深入探讨智谱AI开放平台的功能特性,并在此基础上进行一系列的技术测试和应用实践。
三、智谱AI开发平台
智谱AI开放平台是一个专注于大模型技术的平台,提供多种AI应用场景的支持。该平台由智谱AI公司运营,该公司是由清华大学计算机系技术成果转化而来的,专注于做大模型的中国创新。智谱AI推出了包括中英双语千亿级对话模型、代码生成预训练模型、图片生成预训练模型等多种大模型产品,并提供大模型MaaS开放平台,实现SaaS、PaaS到MaaS的升级。
智谱AI开放平台的特点包括:
- 提供GLM-4模型开放API,支持多模态、多语言、多能力的智能体能力。
- 拥有高性能的大模型,例如GLM-4-9B,它在多项评分指标上超越了Llama-3-8B-InstructMeta,并在中文学科能力上提升了50%。
- 支持长文本处理,最高支持达1百万tokens的长文本。
- 支持多达26种语言。
- 提供一键微调功能,无需代码,以及AllTools智能体API,利用模型、工具和知识来执行复杂、多步骤的任务。
1、注册智谱AI
通过下面的地址注册一个开发者账号,注册成功后平台会送一部分免费的token额度。
地址:https://open.bigmodel.cn
2、取出API key
取出API key,配置到本地电脑的系统环境变量中
四、GLM-4 函数调用说明
ChatGLM 的函数调用功能可以增强模型推理效果或进行其他外部操作,包括信息检索、数据库操作、知识图谱搜索与推理、操作系统、触发外部操作等工具调用场景。
1、描述函数功能
为了向模型描述外部函数库,需要向 tools 字段传入可以调用的函数列表。参数如下表:
tools = [
{
"type": "function",
"function": {
"name": "get_flight_number",
"description": "根据始发地、目的地和日期,查询对应日期的航班号",
"parameters": {
......
},
}
},
{
"type": "function",
"function": {
"name": "get_ticket_price",
"description": "查询某航班在某日的票价",
"parameters": {
......
},
}
},
]
2、编写函数参数列表的 JSON 描述
为了准确定义函数的参数列表,在编写参数列表的 JSON Schema 时建议最少包含以下字段:
description :说明函数方法的用途。 type :定义 JSON 数据的数据类型约束。
properties:一个Object,其中的每个属性代表要定义的 JSON 数据中的一个键。
required:指定哪些属性在数据中必须被包含。 enum:如果一个属性是枚举类型,则此字段应当设置为枚举值的数组。
则完整的tools字段设置为:
tools = [
{
"type": "function",
"function": {
"name": "get_flight_number",
"description": "根据始发地、目的地和日期,查询对应日期的航班号",
"parameters": {
"type": "object",
"properties": {
"departure": {
"description": "出发地",
"type": "string"
},
"destination": {
"description": "目的地",
"type": "string"
},
"date": {
"description": "日期",
"type": "string",
}
},
"required": [ "departure", "destination", "date" ]
},
}
},
{
"type": "function",
"function": {
"name": "get_ticket_price",
"description": "查询某航班在某日的票价",
"parameters": {
"type": "object",
"properties": {
"flight_number": {
"description": "航班号",
"type": "string"
},
"date": {
"description": "日期",
"type": "string",
}
},
"required": [ "flight_number", "date"]
},
}
},
]
3、函数调用选择
在 tools 参数中,如果填写了 functions 参数,则默认情况下模型将决定何时适合使用其中一个函数。 如果要控制模型如何选择函数调用,需要设置 tool_choice 参数。参数默认值为auto,此时模型根据上下文信息自行选择是否返回函数调用。将其设置为 {“name”: “your_function_name”} 时,可以强制 API 返回特定函数的调用。还可以通过将 tool_choice 参数设置为 “none” 来强制 API 不返回任何函数的调用。目前函数调用仅支持 auto 模式。
通过设置tool_choice为{“type”: “function”, “function”: {“name”: “get_ticket_price”}}以强制模型生成调用get_ticket_price的参数。
messages = []
messages.append({"role": "system", "content": "不要假设或猜测传入函数的参数值。如果用户的描述不明确,请要求用户提供必要信息"})
messages.append({"role": "user", "content": "帮我查询1234航班的票价"})
response = client.chat.completions.create(
model="glm-4", # 填写需要调用的模型名称
messages=messages,
tools=tools,
tool_choice={"type": "function", "function": {"name": "get_ticket_price"}},
)
print(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
五、GLM-4函数应用测试
1、提前安装依赖
pip install zhipuai
2、创建智谱AI大模型客户端
import os
import openai
from openai import OpenAI
import shutil
import numpy as np
import pandas as pd
import json
import io
import inspect
import requests
import re
import random
import string
## 初始化客户端
api_key = os.getenv("ZHIPU_API_KEY")
## pip install zhipuai
from zhipuai import ZhipuAI
client = ZhipuAI(api_key=api_key)
3、定义测试的外部function calling函数
def sunwukong_function(data):
"""
孙悟空算法函数,该函数定义了数据集计算过程
:param data: 必要参数,表示带入计算的数据表,用字符串进行表示
:return:sunwukong_function函数计算后的结果,返回结果为表示为JSON格式的Dataframe类型对象
"""
data = io.StringIO(data)
df_new = pd.read_csv(data, sep='\s+', index_col=0)
res = df_new * 10
return json.dumps(res.to_string())
4、定义function calling函数信息生成器
def auto_functions(functions_list):
"""
Chat模型的functions参数编写函数
:param functions_list: 包含一个或者多个函数对象的列表;
:return:满足Chat模型functions参数要求的functions对象
"""
def functions_generate(functions_list):
# 创建空列表,用于保存每个函数的描述字典
functions = []
# 对每个外部函数进行循环
for function in functions_list:
# 读取函数对象的函数说明
function_description = inspect.getdoc(function)
# 读取函数的函数名字符串
function_name = function.__name__
system_prompt = '以下是某的函数说明:%s,输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_description
user_prompt = '根据这个函数的函数说明,请帮我创建一个JSON格式的字典,这个字典有如下5点要求:\
1.字典总共有三个键值对;\
2.第一个键值对的Key是字符串name,value是该函数的名字:%s,也是字符串;\
3.第二个键值对的Key是字符串description,value是该函数的函数的功能说明,也是字符串;\
4.第三个键值对的Key是字符串parameters,value是一个JSON Schema对象,用于说明该函数的参数输入规范。\
5.输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_name
response = client.chat.completions.create(
model="glm-4",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
)
json_str=response.choices[0].message.content.replace("```json","").replace("```","")
json_function_description=json.loads(json_str)
json_str={"type": "function","function":json_function_description}
functions.append(json_str)
return functions
## 最大可以尝试4次
max_attempts = 4
attempts = 0
while attempts < max_attempts:
try:
functions = functions_generate(functions_list)
break # 如果代码成功执行,跳出循环
except Exception as e:
attempts += 1 # 增加尝试次数
print("发生错误:", e)
if attempts == max_attempts:
print("已达到最大尝试次数,程序终止。")
raise # 重新引发最后一个异常
else:
print("正在重新运行...")
return functions
5、封装AI大模型的两次调用
def run_conversation(messages, functions_list=None, model="glm-4"):
"""
能够自动执行外部函数调用的对话模型
:param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象
:param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象
:param model: Chat模型,可选参数,默认模型为glm-4
:return:Chat模型输出结果
"""
# 如果没有外部函数库,则执行普通的对话任务
if functions_list == None:
response = client.chat.completions.create(
model=model,
messages=messages,
)
response_message = response.choices[0].message
final_response = response_message.content
# 若存在外部函数库,则需要灵活选取外部函数并进行回答
else:
# 创建functions对象
tools = auto_functions(functions_list)
# 创建外部函数库字典
available_functions = {func.__name__: func for func in functions_list}
# 第一次调用大模型
response = client.chat.completions.create(
model=model,
messages=messages,
tools=tools,
tool_choice="auto", )
response_message = response.choices[0].message
tool_calls = response_message.tool_calls
if tool_calls:
#messages.append(response.choices[0].message)
messages.append(response.choices[0].message.model_dump())
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(**function_args)
messages.append(
{
"role": "tool",
"content": function_response,
"tool_call_id": tool_call.id,
}
)
## 第二次调用模型
second_response = client.chat.completions.create(
model=model,
messages=messages,
tools=tools
)
# 获取最终结果
print(second_response.choices[0].message)
final_response = second_response.choices[0].message.content
else:
final_response = response_message.content
return final_response
6、定义数据对象
创建一个DataFrame对象,用于测试
# 创建一个DataFrame
df = pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]})
df_str = df.to_string()
7、定义消息列表
messages=[
{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},
{"role": "user", "content": "请在数据集data上执行孙悟空算法函数"}
]
8、大模型调用测试
functions_list=[sunwukong_function]
result = run_conversation(messages, functions_list=functions_list, model="glm-4")
print(result)
输出
CompletionMessage(content='根据孙悟空算法函数处理后的数据集data,我们可以看到每一行的x1和x2值都乘以了10。具体来说,第一行的x1从1变成了10,x2从3变成了30;第二行的x1从2变成了20,x2从4变成了40。这是孙悟空算法函数对输入数据集进行的计算处理。', role='assistant', tool_calls=None)
根据孙悟空算法函数处理后的数据集data,我们可以看到每一行的x1和x2值都乘以了10。具体来说,第一行的x1从1变成了10,x2从3变成了30;第二行的x1从2变成了20,x2从4变成了40。这是孙悟空算法函数对输入数据集进行的计算处理。
9、智能对话助手封装
def chat_with_model(functions_list=None,
prompt="你好",
model="glm-4",
system_message=[{"role": "system", "content": "你是小智助手。"}]):
messages = system_message
messages.append({"role": "user", "content": prompt})
while True:
answer = run_conversation(messages=messages,
functions_list=functions_list,
model=model)
print(f"智能助手回答: {answer}")
# 询问用户是否还有其他问题
user_input = input("您还有其他问题吗?(输入退出以结束对话): ")
if user_input == "退出":
break
# 记录用户回答
messages.append({"role": "user", "content": user_input})
10、智能对话助手测试
functions_list=[sunwukong_function]
chat_with_model(functions_list,prompt="你好")
对话测试如下
智能助手回答: 有什么可以帮助你的吗?
智能助手回答: 有什么我可以帮助你的吗?如果你有任何问题或需要帮助,随时告诉我。
智能助手回答: 当前年份是2023年。有什么我可以帮助你的吗?
智能助手回答: 今天是2023年11月4日。
智能助手回答: AIGC(AI-Generated Content)是指由人工智能生成的 content,可以理解为利用人工智能技术来生成文本、图片、音频、视频等各种各样的内容。AIGC 在很多领域都有广泛的应用,例如:新闻写作、视频制作、音乐创作、艺术创作等等。
结语
本篇章我们深入探索并体验了GLM-4大模型的Function Calling函数能力,通过一系列严谨的测试和实践;为后续的智能在线搜索功能奠定了坚实的技术基础,也为我们打造更智能、更高效的搜索体验提供了强有力的支持。
🎯🔖更多专栏系列文章:AIGC-AI大模型探索之路
😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:建立有技术交流群,可以扫码👇 加入社群,500本各类编程书籍、AI教程、AI工具等你领取!
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!