【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾

embedded/2024/11/17 10:04:21/

系列篇章💥

No.文章
1【GLM-4开发实战】Function Call进阶实战:外部函数调用回顾
2【GLM-4开发实战】Function Call进阶实战:常见挑战之意图识别处理
3【GLM-4开发实战】Function Call进阶实战:常见挑战之海量函数处理
4【GLM-4开发实战】Function Call进阶实战:常见挑战之并发调用处理

目录

  • 系列篇章💥
  • 引言
  • 一、概述
  • 二、Function Call调用详细流程
    • 1、定义模型客户端
    • 2、定义工具函数
    • 3、定义数据对象
    • 4、数据转换为String类型
    • 5、函数调用测试
    • 6、定义函数的说明
    • 7、大模型调用测试(不带工具函数)
    • 8、大模型调用测试(携带工具函数)
    • 9、查看结果中的tool_calls属性
    • 10、构建字段格式函数列表
    • 11、获取执行函数并执行
    • 12、第二次调用大模型
    • 13、查看最终执行结果
  • 三、Function Call函数调用封装
  • 结语


引言

人工智能领域,Function Call是大模型能力扩展的核心。它不仅在Retrieval-Augmented Generation(RAG)中扮演着重要角色,也是Agent智能体架构设计中不可或缺的一部分。本文将深入探讨GLM-4模型中Function Call的进阶应用,通过实战案例,回顾并总结外部函数调用的技巧与经验。

一、概述

Function Call作为模型与外部世界交互的桥梁,其重要性不言而喻。本章节旨在通过GLM-4模型的Function Call功能,为大家提供一个全面的使用回顾,帮助大家更高效地利用这一功能。

二、Function Call调用详细流程

1、定义模型客户端

首先,需要构建一个客户端,用于与GLM-4模型进行通信。

import os
import openai
from openai import OpenAI
import shutilimport numpy as np
import pandas as pdimport json
import io
import inspect
import requests
import re
import random
import string## 初始化客户端
api_key = os.getenv("ZHIPU_API_KEY")
## pip install zhipuaifrom zhipuai import ZhipuAI
client = ZhipuAI(api_key=api_key)

2、定义工具函数

定义了一个大模型里面肯定没有的算法工具函数

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 * 10return json.dumps(res.to_string())

3、定义数据对象

创建数据对象,为函数调用提供必要的数据支持。

df = pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]})
df

输出:
在这里插入图片描述

4、数据转换为String类型

与大模型进行配合调用的时候,尽可能的让调用的函数参数和返回值都用String表示。

df_str = df.to_string()
df_str

输出:
在这里插入图片描述

5、函数调用测试

进行初步的函数调用,测试其基本功能。

result_json=sunwukong_function(df_str)
result_json

输出:
在这里插入图片描述

6、定义函数的说明

方便大模型识别函数自动完成调用,注意格式为:JSON Schema的格式

sunwukong={"type": "function","function": {"name": "sunwukong_function","description": "用于执行孙悟空算法函数,定义了一种特殊的数据集计算过程","parameters": {"type": "object","properties": {"data": {"type": "string","description": "执行孙悟空算法的数据集"},},"required": ["data"],},}}

定义工具列表

tools = [sunwukong]

7、大模型调用测试(不带工具函数)

在没有外部函数工具的情况下测试大模型的第一次调用并执行孙悟空算法

messages=[{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]response =  client.chat.completions.create(model="glm-4",messages=messages
)
response.choices[0].message

输出:

CompletionMessage(content='抱歉,但似乎有一些混淆。"孙悟空算法"并不是一个公认的数据处理或机器学习算法。孙悟空是中国古典文学作品《西游记》中的虚构人物,以其变化无常和神通广大著称。\n\n然而,根据您提供的数据集(以字符串形式表示),如果您是想要进行某种形式的数据处理或分析,下面是一个用Python实现的对给定字符串形式的数据集进行解析的简单示例:\n\n```python\n# 这是您提供的数据集字符串\ndata_str = """\nx1  x2\n0   1   3\n1   2   4\n"""\n\n# 将字符串分割成行\nlines = data_str.strip().split("\\n")\n\n# 解析标题和值\nheader = lines[0].split()\nvalues = [line.split() for line in lines[1:]]\n\n# 转换数据为字典形式\ndata_dict = {h: [] for h in header}\nfor row in values:\n    for i, value in enumerate(row):\n        data_dict[header[i]].append(int(value))\n\n# 输出字典形式的数据集\nprint(data_dict)\n\n# 如果需要转换为Pandas DataFrame(如果适用的话)\nimport pandas as pd\n\ndf = pd.DataFrame(data_dict)\nprint(df)\n```\n\n当运行这段代码时,它将输出以下字典形式的数据集:\n\n```\n{\'x1\': [0, 1], \'x2\': [1, 2]}\n```\n\n然后,它将创建一个Pandas DataFrame,如下所示:\n\n```\n   x1  x2\n0   0   1\n1   1   2\n```\n\n请注意,这段代码假设每行数据的列数是相同的,并且所有值都可以转换为整数。\n\n如果您有一个具体的任务或算法想要应用到这个数据集上,请详细描述,我将尽力提供帮助。', role='assistant', tool_calls=None)

8、大模型调用测试(携带工具函数)

第一次调用大模型,测试Funcation call流程,本次调用时,设置工具函数tools和tool_choice(由大模型自己判断选择是否需要调用外部工具函数)

messages=[{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": "请在数据集data上执行孙悟空算法"}
]
response = client.chat.completions.create(model="glm-4",messages=messages,tools=tools,tool_choice="auto",  )response.choices[0].message

输出:

CompletionMessage(content='', role='assistant', tool_calls=[CompletionMessageToolCall(id='call_8822099358575188366', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)])

输出结果可以看到,模型识别正确识别出来需要调用的函数,并且正确解析了参数 将第一次调用结果放入变量first_response中

first_response = response.choices[0].message
first_response

输出:

CompletionMessage(content=None, role='assistant', tool_calls=[CompletionMessageToolCall(id='call_8730210251242354639', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)])

9、查看结果中的tool_calls属性

分析函数调用的结果,特别是tool_calls属性,了解函数调用的细节。

response.choices[0].message.tool_calls

输出:

[CompletionMessageToolCall(id='call_8730210251242354639', function=Function(arguments='{"data":"x1  x2\\n0   1   3\\n1   2   4"}', name='sunwukong_function'), type='function', index=0)]

10、构建字段格式函数列表

构建字典形式的函数调用列表,key为函数名,value为函数体

available_tools =  {"sunwukong_function": sunwukong_function,
}

11、获取执行函数并执行

根据大模型的返回值中获取到函数调用需要到的:函数名,参数,函数体,并且执行函数。

tool_calls = response.choices[0].message.tool_callsfor tool_call in tool_calls:## 函数名function_name = tool_call.function.name## 根据函数名获取到函数体function_to_call = available_tools[function_name]function_args = json.loads(tool_call.function.arguments)## 执行函数function_response = function_to_call(**function_args)print(function_name)
print(function_args)
print(function_response)

输出:
在这里插入图片描述

查询执行函数,执行效果

function_response = function_to_call(**function_args)
function_response

输出:
在这里插入图片描述

12、第二次调用大模型

把结果给到大模型,大模型进行增强生成
在第一次调用的基础上,进行第二次调用,观察是否有性能提升或结果优化。

messages.append(response.choices[0].message.model_dump())
for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_tools[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="glm-4",messages=messages,tools=tools) 
# 获取最终结果
final_response = second_response.choices[0].message.content

13、查看最终执行结果

分析第二次调用的结果,评估Function Call的整体表现和可能的改进空间。

final_response

输出:

'根据孙悟空算法执行结果,数据集data经过计算后的结果为:\n```\n   x1  x2\n0  10  30\n1  20  40\n```'

三、Function Call函数调用封装

Function Call相关业务逻辑整体封装调用;封装Function Call不仅可以提高代码的可读性和可维护性,还可以在不同场景下复用函数调用逻辑。本部分将对Function Call相关使用代码进行封装,将Function Call封装为可复用的模块,以及如何通过封装提高开发效率。

from openai import OpenAI
import json## 步骤1:构建函数
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 * 10return json.dumps(res.to_string())available_tools =  {"sunwukong_function": sunwukong_function,
}df_str=pd.DataFrame({'x1':[1, 2], 'x2':[3, 4]}).to_stringdef run_conversation():# Step 1: send the conversation and available functions to the modelmessages=[{"role": "system", "content": "数据集data:%s,数据集以字符串形式呈现" % df_str},{"role": "user", "content": "请在数据集data上执行孙悟空算法"}  ]## 步骤2:函数说明  JSON Schema格式tools = [{"type": "function","function": {"name": "sunwukong_function","description": "用于执行孙悟空算法函数,定义了一种特殊的数据集计算过程","parameters": {"type": "object","properties": {"data": {"type": "string","description": "执行孙悟空算法的数据集"},},"required": ["data"],},}}]## 步骤3:第一次调大模型response = client.chat.completions.create(model="glm-4",messages=messages,tools=tools,tool_choice="auto",  # auto is default, but we'll be explicit)response_message = response.choices[0].messagetool_calls = response_message.tool_calls# Step 2: check if the model wanted to call a functionif tool_calls:messages.append(response.choices[0].message.model_dump())for tool_call in tool_calls:function_name = tool_call.function.namefunction_to_call = available_tools[function_name]function_args = json.loads(tool_call.function.arguments)function_response = function_to_call(**function_args)messages.append({"role": "tool","content": f"{json.dumps(function_response)}","tool_call_id":tool_call.id})## 步骤四:第二次调用大模型second_response = client.chat.completions.create(model="glm-4",  # 填写需要调用的模型名称messages=messages,tools=tools,)return second_responseresult=run_conversation()

查看调用结果

result.choices[0].message.content

输出:

'根据您的请求,我已经在数据集data上执行了孙悟空算法。执行结果如下:\n\n"   x1  x2\n0  10  30\n1  20  40"\n\n这是数据集经过孙悟空算法处理后的结果。如果您还有其他问题或需要进一步的帮助,请随时告诉我。'

结语

Function Call作为连接人工智能模型与外部世界的纽带,其应用广泛且深入。通过本文的深入分析与实战回顾,我们希望能够为读者提供Function Call使用的宝贵经验和策略,助力开发者们在AI领域的进一步探索和实践。随着技术的不断进步,Function Call的应用也将更加多样化和高效,期待与大家共同见证这一领域的未来发展。

在这里插入图片描述

🎯🔖更多专栏系列文章:AI大模型提示工程完全指南AI大模型探索之路(零基础入门)AI大模型预训练微调进阶AI大模型开源精选实践AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑

😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,加入技术交流群,开启编程探索之旅。
💘精心准备📚500本编程经典书籍、💎AI专业教程,以及高效AI工具。等你加入,与我们一同成长,共铸辉煌未来。
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!


http://www.ppmy.cn/embedded/90809.html

相关文章

【问题】C++:有哪些类型的智能指针,区别?

智能指针是一种在 C 中管理动态分配内存的工具,可以帮助避免内存泄漏和提高程序的安全性。在 C11 标准引入之后,C 提供了三种主要类型的智能指针,它们分别是 std::unique_ptr、std::shared_ptr 和 std::weak_ptr。这些智能指针有不同的所有权…

java 高级面试系列 (三)----JUC (java 并发编程)

1,面试官: 什么是线程,什么进程 ? 小菜弱弱的回答: 大学操作系统书上说: 进程是操作系统的基本单位, 多个线程组成进程,即一个进程包含多个线程;比如 播放网易云这个进程…

TortoiseSVN迁移到本地git

TortoiseSVN迁移到本地git 文章目录 TortoiseSVN迁移到本地git0 背景1 环境准备2 SVN库迁移到VisualSVN2.1 导出dump2.2 将dump文件灌入VisualSVN2.3 获取SVN仓最新URL 3 迁移到Git库中4 迁移分支到Git库5 创建本地远端库创建空仓关联空仓推送代码 0 背景 之前在前东家工作都是…

AI在招聘市场趋势分析中的应用

一、引言 在数字化、智能化的时代背景下,人工智能(AI)技术正逐步渗透到各行各业,其中招聘市场也不例外。AI技术的运用不仅极大地提高了招聘的效率和精准度,还在招聘市场趋势分析方面展现出巨大的潜力。本文旨在探讨AI在…

周末总结(2024/08/04)

工作 人际关系核心实践: 要学会随时回应别人的善意,执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己,抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内,职场社交不要放在5min以内 职场的人际关系在面对利…

DNS及主从同步方案详解

DNS及主从同步方案详解 一.环境部署二.主从配置(以centos为主)三.配置详解及检查工具四.windows辅助区域同步 一.环境部署 centos: yum install bind bind-utils ubuntu: apt-get install bind9 bind9utils bind9-doc检查配置: named-checkconf 检查区域&#xff…

用户认证与授权:在 Symfony 中实现安全控制

用户认证与授权:在 Symfony 中实现安全控制 Symfony 是一个功能强大且高度可扩展的 PHP 框架,广泛用于开发复杂的 Web 应用程序。在现代 Web 应用程序中,用户认证和授权是不可或缺的功能,用于确保应用程序的安全性和数据的隐私性…

新版本matlab将模糊PID规则表导出离线查询表

前言 为了将仿真的模糊PID规则应用到硬件现实中去,需要把模糊PID规则表导出为离线查询表的模式,对于这个问题在很久之前就有人尝试解决过. 🚪:李会先.如何在MATLAB下把模糊推理系统转化为查询表(原创) 🚪:李会先.在SIMULINK里把模糊控制逻辑生成查询表(原创) 最先提…