function-calling初体验

课程地址:https://learn.deeplearning.ai/courses/function-calling-and-data-extraction-with-llms/lesson/1/introduction
github notebook地址:https://github.com/kingglory/LLMs-function-calling/tree/main


Function-Calling 介绍

函数调用(Function-Calling)允许使用自定义功能扩展LLM,使它们能够根据自然语言指令形成对外部函数的调用。结构化数据提取使LLM能够从非结构化文本中提取可用信息。
在这里插入图片描述
Function-calling is the capability of an LLM to take in a natural language query, along with a description of the function,and output a string that can be used to call that function.
Function-calling是LLM接收自然语言查询以及函数描述,并输出可用于调用该函数的字符串的能力。
在这里插入图片描述
在这里插入图片描述

先使用NexusRavenV2-13B 大模型,一个针对函数调用(function-calling)和数据提取进行了微调的开源模型。该模型可在Hugging Face上使用,在一些函数调用任务中表现优于GPT-4,并且具有130亿个参数,因此可以在本地托管。

写一个python tool

from matplotlib import pyplot as plt

def plot_some_points(x : list, y : list):
  """
  Plots some points!
  """
  plt.plot(x, y)
  plt.show()
USER_QUERY = "Hey can you plot y=10x where x=1, 2, 3 for me?"

plot_some_points(x=[1, 2, 3], y=[10, 20, 30])

在这里插入图片描述

想让大模型帮我们做上面的事,首先要给出一个tool 描述(description)和user query 给LLM。

  • 你首先要提供前面使用的函数的原型。
  • 你将要使用的LLM使用python格式的函数。
  • 你还将添加一些关于工具功能的描述。LLM会根据描述来判断是否应该使用该工具来回答用户查询的推理。
  • 你还需要提供LLM 用户的输入(user query)
prompt = \
f'''
Function:
def plot_some_points(x : list, y : list):
  """
  Plots some points!
  """
  plt.plot(x, y)
  plt.show()

User Query: {USER_QUERY}<human_end>
'''
# 这个大模型是训练过的,专门针对function-calling ,这里是接口调用,返回function-calling字符串
# def raven_post(payload):
#     """
#     Sends a payload to a TGI endpoint.
#     """
#     # Now, let's prompt Raven!
#     API_URL = "http://nexusraven.nexusflow.ai"
#     headers = {
#             "Content-Type": "application/json"
#     }
#     import requests
#     response = requests.post(API_URL, headers=headers, json=payload)
#     return response.json()

# def query_raven(prompt):
# 	"""
# 	This function sends a request to the TGI endpoint to get Raven's function call.
# 	This will not generate Raven's justification and reasoning for the call, to save on latency.
# 	"""
# 	import requests
# 	output = raven_post({
# 		"inputs": prompt,
# 		"parameters" : {"temperature" : 0.001, "stop" : ["<bot_end>"], "return_full_text" : False, "do_sample" : False, "max_new_tokens" : 2048}})
# 	call = output[0]["generated_text"].replace("Call:", "").strip()
# 	return call
from utils import query_raven
function_call = query_raven(prompt)

LLM function-calling 的结果是一个字符串: 函数名被调用的状态,并包含输入参数,然后exec 执行一下就会执行这个函数(tool)

print (function_call)
plot_some_points(x=[1, 2, 3], y=[10, 20, 30])

exec 执行储存在字符串或文件中的 Python 语句,相比于 eval,exec 可以执行更复杂的 Python 代码。https://www.runoob.com/python3/python3-func-exec.html

exec 的语法: exec(object[, globals[, locals]])

  • object:必选参数,表示需要被指定的 Python 代码。它必须是字符串或 code 对象。如果 object 是一个字符串,该字符串会先被解析为一组 Python 语句,然后再执行(除非发生语法错误)。如果 object 是一个 code 对象,那么它只是被简单的执行。
  • globals:可选参数,表示全局命名空间(存放全局变量),如果被提供,则必须是一个字典对象。
  • locals:可选参数,表示当前局部命名空间(存放局部变量),如果被提供,可以是任何映射对象。如果该参数被忽略,那么它将会取与 globals 相同的值。

exec 返回值永远为 None。

>>>exec('print("Hello World")')
Hello World
# 单行语句字符串
>>> exec("print ('runoob.com')")
runoob.com
 
#  多行语句字符串
>>> exec ("""for i in range(5):
...     print ("iter time: %d" % i)
... """)
iter time: 0
iter time: 1
iter time: 2
iter time: 3
iter time: 4
exec(function_call)

在这里插入图片描述

再试一个
USER_QUERY = "帮我画个y=x**3, 其中 x = 1,2,3, 4, 5"
prompt = \
f'''
Function:
def plot_some_points(x : list, y : list):
  """
  Plots some points!
  """
  plt.plot(x, y)
  plt.show()

User Query: {USER_QUERY}<human_end>
'''
from utils import query_raven
function_call = query_raven(prompt)
exec(function_call)

在这里插入图片描述
在这里插入图片描述

试一个复杂的例子

定义一个函数
#  提供 脸的颜色, 眼睛的颜色, 鼻子的颜色 画一个笑脸
import matplotlib.pyplot as plt
import matplotlib.patches as patches

def draw_clown_face(face_color='yellow', eye_color='black', 
                    nose_color='red'):
    """
    Draws a customizable, simplified clown face using matplotlib.

    Parameters:
    - face_color (str): Color of the clown's face. Default is 'yellow'.
    - eye_color (str): Color of the clown's eyes. Default is 'black'.
    - nose_color (str): Color of the clown's nose. Default is 'red'.

    This function creates a plot displaying a simplified clown face, where essential facial features' size, position, and color can be customized. 
    """
    # Constants
    face_radius = 0.4
    nose_radius = 0.1
    nose_x, nose_y = 0.5, 0.5
    mouth_x, mouth_y = 0.5, 0.3
    mouth_color = 'black'
    eye_size = 0.05
    mouth_size = (0.3, 0.1)
    eye_offset=(0.15, 0.15)
    mouth_theta = (200, 340)

    fig, ax = plt.subplots()
    # Face
    face = patches.Circle((0.5, 0.5), face_radius, color=face_color, fill=True)
    ax.add_patch(face)
    # Eyes
    eye_left = patches.Circle((0.5-eye_offset[0], 0.5+eye_offset[1]), eye_size, color=eye_color, fill=True)
    eye_right = patches.Circle((0.5+eye_offset[0], 0.5+eye_offset[1]), eye_size, color=eye_color, fill=True)
    ax.add_patch(eye_left)
    ax.add_patch(eye_right)
    # Nose
    nose = patches.Circle((nose_x, nose_y), nose_radius, color=nose_color, fill=True)
    ax.add_patch(nose)
    # Mouth
    mouth = patches.Arc((mouth_x, mouth_y), mouth_size[0], mouth_size[1], angle=0, 
                        theta1=mouth_theta[0], theta2=mouth_theta[1], color=mouth_color, linewidth=2)
    ax.add_patch(mouth)
    # Setting aspect ratio to 'equal' to ensure the face is circular
    ax.set_aspect('equal')
    # Remove axes
    ax.axis('off')
    plt.show()
定义一个Prompt
USER_QUERY = \
"画一个白色的小丑脸和红色的鼻子吗" 

raven_prompt = \
'''
Function:
def draw_clown_face(face_color='yellow', 
                    eye_color='black',
                    nose_color='red'):
    """
    Draws a customizable, simplified clown face using matplotlib.

    Parameters:
    - face_color (str): Color of the clown's face.
    - eye_color (str): Color of the clown's eyes.
    - nose_color (str): Color of the clown's nose.
    """

User Query: {query}<human_end>
'''
raven_prompt_with_query = raven_prompt.format(query=USER_QUERY)

print (raven_prompt_with_query)
Function:
def draw_clown_face(face_color='yellow', 
                    eye_color='black',
                    nose_color='red'):
    """
    Draws a customizable, simplified clown face using matplotlib.

    Parameters:
    - face_color (str): Color of the clown's face.
    - eye_color (str): Color of the clown's eyes.
    - nose_color (str): Color of the clown's nose.
    """

User Query: 画一个白色的小丑脸和红色的鼻子吗<human_end>
from utils import query_raven
raven_call = query_raven(raven_prompt_with_query)
print (raven_call)
draw_clown_face(face_color='white', nose_color='red')
Run The Call
exec(raven_call)

在这里插入图片描述

再画一个笑脸
USER_QUERY = "画一个小丑的笑脸,眼睛是白色的,脸是黑色的,嘴巴是粉色的,鼻子是大红色,耳朵就跟米老鼠一样的"
raven_prompt_with_query = raven_prompt.format(query=USER_QUERY)

from utils import query_raven
raven_call = query_raven(raven_prompt_with_query)
print (raven_call)
exec(raven_call)
draw_clown_face(face_color='black', eye_color='white', nose_color='red')

在这里插入图片描述

试一下 chatgpt的function-calling

import json
from openai import OpenAI
from dotenv import load_dotenv
import os

_ = load_dotenv()

def query_openai(msg, functions=None):
  load_dotenv()
  GPT_MODEL = "gpt-3.5-turbo"

  openai_client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
  openai_response = openai_client.chat.completions.create(
    model = GPT_MODEL,
    messages = [{'role': 'user', 'content': msg}],
    tools = functions)
  return openai_response

需要以json格式提供tool的描述(description)和参数(arguments)

openai_function = {
  "type": "function",
  "function": {
    "name": "draw_clown_face",
    "description": "Draws a customizable, simplified clown face using matplotlib.",
    "parameters": {
      "type": "object",
      "properties": {
        "face_color": {
          "type": "string",
          "description": "Color of the clown's face."
        },
        "eye_color": {
          "type": "string",
          "description": "Color of the clown's eyes."
        },
        "nose_color": {
          "type": "string",
          "description": "Color of the clown's nose."
        }
        }
      }
    }
  }

openai_msg = \
"Hey can you draw a pink clown face with a red nose"
result = query_openai(openai_msg, functions=[openai_function])

print (result.choices[0].message.tool_calls[0].function)
Function(arguments='{"face_color": "pink", "eye_color": "black", "nose_color": "red"}', name='draw_clown_face')

注意!返回的结果跟之前不一样,这样的字符串是不能直接用exec执行的,所以需要一个归一化处理

tool_name = result.choices[0].message.tool_calls[0].function.name
tool_args = result.choices[0].message.tool_calls[0].function.arguments

function_call = f"{tool_name}(**{tool_args})"

print (function_call)
draw_clown_face(**{"face_color": "pink", "eye_color": "black", "nose_color": "red"})
exec(function_call)

在这里插入图片描述

使用训练过的LLM在非结构化数据和高度结构化的code之间搭建了桥梁!!

在这里插入图片描述


辅助函数:utils.py

import inspect
def raven_post(payload):
    """
    Sends a payload to a TGI endpoint.
    """
    # Now, let's prompt Raven!
    API_URL = "http://nexusraven.nexusflow.ai"
    headers = {
            "Content-Type": "application/json"
    }
    import requests
    response = requests.post(API_URL, headers=headers, json=payload)
    return response.json()

def call_functioncalling_llm(prompt, api_to_call):
    """
    This function sends a request to the TGI endpoint to get Raven's function call.
    This will not generate Raven's justification and reasoning for the call, to save on latency.
    """
    signature = inspect.signature(api_to_call)
    docstring = api_to_call.__doc__
    prompt = f'''Function:\n{api_to_call.__name__}{signature}\n"""{clean_docstring(docstring)}"""\n\n\nUser Query:{prompt}<human_end>'''
    import requests
    output = raven_post({
        "inputs": prompt,
        "parameters" : {"temperature" : 0.001, "stop" : ["<bot_end>"], "do_sample" : False, "max_new_tokens" : 2048, "return_full_text": False}})
    call = output[0]["generated_text"].replace("Call:", "").strip()
    return call

def query_raven(prompt):
	"""
	This function sends a request to the TGI endpoint to get Raven's function call.
	This will not generate Raven's justification and reasoning for the call, to save on latency.
	"""
	import requests
	output = raven_post({
		"inputs": prompt,
		"parameters" : {"temperature" : 0.001, "stop" : ["<bot_end>"], "return_full_text" : False, "do_sample" : False, "max_new_tokens" : 2048}})
	call = output[0]["generated_text"].replace("Call:", "").strip()
	return call

def clean_docstring(docstring):
    if docstring is not None:
        # Remove leading and trailing whitespace
        docstring = docstring.strip()
    return docstring

def build_raven_prompt(function_list, user_query):
    import inspect
    raven_prompt = ""
    for function in function_list:
        signature = inspect.signature(function)
        docstring = function.__doc__
        prompt = \
f'''
Function:
def {function.__name__}{signature}
    """
    {clean_docstring(docstring)}
    """
    
'''
        raven_prompt += prompt
        
    raven_prompt += f"User Query: {user_query}<human_end>"
    return raven_prompt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/767061.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux Centos7部署Zookeeper

目录 一、下载zookeeper 二、单机部署 1、创建目录 2、解压 3、修改配置文件名 ​4、创建保存数据的文件夹 ​5、修改配置文件保存数据的地址 ​6、启动服务 7、api创建节点 一、下载zookeeper 地址&#xff1a;Index of /dist/zookeeper/zookeeper-3.5.7 (apache.org…

Python23 使用Tensorflow实现线性回归

TensorFlow 是一个开源的软件库&#xff0c;用于数值计算&#xff0c;特别适用于大规模的机器学习。它由 Google 的研究人员和工程师在 Google Brain 团队内部开发&#xff0c;并在 2015 年首次发布。TensorFlow 的核心是使用数据流图来组织计算&#xff0c;使得它可以轻松地利…

【Python画图-驯化seaborn】一文搞懂seaborn中的箱线图实践技巧

【Python画图-驯化seaborn】一文搞懂seaborn中的箱线图实践技巧 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注&a…

05 docker 镜像

目录 1. 镜像 2. 联合文件系统 3. docker镜像加载原理 4. 镜像分层 镜像分层的优势 5. 容器层 1. 镜像 镜像是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖打包好行程一个可交付的运行环境&#xf…

每日一题 7月1日

1 设数组data[m]作为循环队列的存储空间,front为队头指针,rear为队尾指针,则执行出队操作后其头指针front值为____ 2 采用滑动窗口机制对两个相邻结点A(发送方)和B(接收方)的通信过程进行流量控制。假定帧的序号长度为3比特,发送窗口与接收窗口的大小均为7,当A发送了…

昇思25天学习打卡营第9天|MindSpore-Vision Transformer图像分类

Vision Transformer图像分类 Vision Transformer(ViT)简介 近些年,随着基于自注意(Self-Attention)结构的模型的发展,特别是Transformer模型的提出,极大地促进了自然语言处理模型的发展。由于Transformers的计算效率和可扩展性,它已经能够训练具有超过100B参数的空前…

传输线在阻抗匹配时串联端接电阻为什么要靠近发送端

传输线在阻抗匹配时串联端接电阻为什么要靠近发送端 在进行阻抗匹配的时候我们可以在电阻源端放置一个串联端接电阻&#xff0c;但是有时候受到空间的限制可能会把电阻摆的稍微远一点&#xff0c;那么这个时候大家可能会有疑问&#xff0c;电阻离发送端远一点或者电阻放置在接…

java+mysql教师管理系统

完整源码地址 教师信息管理系统使用命令行交互的方式及数据库连接实现教师信息管理系统&#xff0c;该系统旨在实现教师信息的管理&#xff0c;并根据需要进行教师信息展示。该软件的功能有如下功能 (1)基本信息管理(教师号、姓名、性别、出生年月、职称、学历、学位、教师类型…

【Git 学习笔记】1.3 Git 的三个阶段

1.3 Git 的三个阶段 由于远程代码库后续存在新的提交&#xff0c;因此实操过程中的结果与书中并不完全一致。根据书中 HEAD 指向的 SHA-1&#xff1a;34acc370b4d6ae53f051255680feaefaf7f7850d&#xff0c;可通过以下命令切换到对应版本&#xff0c;并新建一个 newdemo 分支来…

【STM32 RTC实时时钟如何配置!超详细的解析和超简单的配置,附上寄存器操作】

STM32 里面RTC模块和时钟配置系统(RCC_BDCR寄存器)处于后备区域&#xff0c;即在系统复位或从待机模式唤醒后&#xff0c;RTC的设置和时间维持不变。因为系统对后备寄存器和RTC相关寄存器有写保护&#xff0c;所以如果想要对后备寄存器和RTC进行访问&#xff0c;则需要通过操作…

社交媒体优化的智能顾问:Kompas.ai如何提升品牌社交表现

在社交媒体盛行的数字时代&#xff0c;品牌必须在社交平台上保持活跃和互动&#xff0c;以增强品牌社交互动和提升在线可见性。社交媒体优化不仅能够扩大品牌的影响力&#xff0c;还能够加深与消费者的联系。Kompas.ai&#xff0c;作为一款智能社交媒体顾问工具&#xff0c;能够…

【前端项目笔记】7 商品管理

商品管理 效果展示&#xff1a; 在功能开发之前&#xff0c;创建商品列表的子分支 git branch 查看所有分支 git checkout -b goods_list 创建并切换到新分支goods_list git push -u origin goods_list 将新分支goods_list推送到云端仓库origin并命名为goods_list保存 通过…

LLM学习记录

概述 语言模型的发展 语言模型经历过四个阶段的发展&#xff0c;依次从统计语言模型到神经网络语言模型&#xff08;NLM&#xff09;&#xff0c;到出现以 BERT 和 Transformer 架构为代表的预训练语言模型&#xff08;PLM&#xff09;&#xff0c;最终到大型语言模型阶段&am…

竞赛选题 交通目标检测-行人车辆检测流量计数 - 竞赛选题

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

【Java环境配置过程详解(包括IDEA配置Java)】

目录 一、JDK下载安装 1. 官网下载JDK 2. 本地安装JDK 3. 配置环境变量 4. 验证是否安装成功 ​编辑二、IDEA进行安装下载 1. 官网下载 IDEA 2、IDEA进行Java开发 1. 创建Java项目 2. 程序测试 一、JDK下载安装 1. 官网下载JDK 1&#xff09;官网链接: https://www.o…

PTrade如何获取技术值班?如get_RSI - 相对强弱指标;PTrade量化软件如何获取?

get_RSI - 相对强弱指标 get_RSI(close, n6) 使用场景 该函数仅在回测、交易模块可用 接口说明 获取相对强弱指标RSI指标的计算结果 PTrade是恒生公司开发的一款专业量化软件&#xff0c;部分合作券商可提供&#xff0c;↑↑↑&#xff01; 参数 close&#xff1a;价格…

C语言的数据结构:图的基本概念

前言 之前学过了其它的数据结构&#xff0c;如&#xff1a; 集合 \color{#5ecffd}集合 集合 —— 数据元素属于一个集合。 线型结构 \color{#5ecffd}线型结构 线型结构 —— 一个对一个&#xff0c;如线性表、栈、队列&#xff0c;每一个节点和其它节点之间的关系 一个对一个…

rpm包下载

内网无法下载、选择外网的一台机器下载rpm包 下载后上传rpm包 1、创建下载目录 mkdir /data/asap/test 2、下载能留存包的工具 sudo yum install yum-utils -y 报错就是环境问题没下载成功&#xff0c;我换了个环境正常的机器就可以了 3、下载rpm包到指定目录/data/asa…

一文彻底搞懂Transformer - Input(输入)

一、输入嵌入&#xff08;Input Embedding&#xff09; 词嵌入&#xff08;Word Embedding&#xff09;&#xff1a;词嵌入是最基本的嵌入形式&#xff0c;它将词汇表中的每个单词映射到一个固定大小的向量上。这个向量通常是通过训练得到的&#xff0c;能够捕捉单词之间的语义…

GAMES104:04游戏引擎中的渲染系统1:游戏渲染基础-学习笔记

文章目录 概览&#xff1a;游戏引擎中的渲染系统四个课时概览 一&#xff0c;渲染管线流程二&#xff0c;了解GPUSIMD 和 SIMTGPU 架构CPU到GPU的数据传输GPU性能限制 三&#xff0c;可见性Renderable可渲染对象提高渲染效率Visibility Culling 可见性裁剪 四&#xff0c;纹理压…