OpenAI Function calling

news/2024/5/20 6:04:35 标签: chatgpt, AI, OpenAI, FunctionCalling

开篇

原文出处

最近 OpenAI 在 6 月 13 号发布了新 feature,主要针对模型进行了优化,提供了 function calling 的功能,该 feature 对于很多集成 OpenAI 的应用来说绝对是一个“神器”。

Prompt 的演进

如果初看 OpenAI 官网对function calling的介绍,似乎不足以体现它的重要性。为了更进一步理解它的作用,我们先来简单回顾一下在使用 OPenAI 时 Prompt 是如何演进的。

Prompt 1.0

prompt 1.0

还记得 chatGPT 在最一开始大火时,除了 AI 强大的能力作为一个吸引点之外,“低门槛的要求使得所有人都可以使用”也扮演着至关重要的角色。也正是如此,大家不再对 AI 感到陌生,借助和 AI 对话,随便一个 Prompt 就可以让使用者直接或间接的获得帮助。

但是随着使用深度的增加,大家慢慢发现chatGPT有时会思维发散,往往不能聚焦关键问题,甚至会“无言乱语”。

在此之上,1.0 版本的 Prompt 出现,它要求对话开始前需要设定上下文。在这样的提示下,AI 能够有较好的表现,并且不再发散,可以解决较为简单的问题。

Prompt 2.0

prompt 2.0

随着使用场景的复杂化,单纯的设置一个上下文给chatGPT已经远远不够。你必须给“足”上下文,最简单的方式就是提供exmaple,这种做法的背后逻辑和 COT(Chain of Thought)是一样的。

2.0 版本的 Prompt 是使用最广泛的也是最可靠的。

Prompt 3.0

prompt 3.0

3.0 版本的 Prompt 并非比 2.0 要高级,只是在需求上不一样。因为随着大量 AI 工具和 OpenAI 集成,想要充分利用 AI 的能力,让更多的系统和模块和你结合,就必须得提取参数或者返回特定的输出。

因此,3.0 聚焦更多的是集成。

Function calling

Prompt 在迭代到 3.0 版本后,AI 的缺点已经一览无遗。虽然chatGPT有大量的知识储备,但它的数据都是预训练的,由于不能联网,所以它并不是“无所不知”的。

因此,集成第三方系统对模型的赋能就成为了当下众多 AI 应用的首要方案。可赋能就代表得知道用户到底要知道什么,这就是 3.0 版本的努力方向。但是 3.0 的版本其实并不能非常稳定的输出特定格式,或者即便格式可以固定,json 数据的类型也不能很好的控制。比如上面的 3.0 例子里,不是所有的 AI 模型都能稳定输出price: 1500,也有可能是$1500(Bard)。
也许你会觉得1500$1500的差异并不大,大不了可以处理一下前缀之类的问题,那就大错特错了。因为这是作为 不同模块(或系统)链接的桥梁,就如同 API 之间集成的契约一般,必须有严格的定义。

一个典型的例子就是前段时间大火的Auto-GPT, 在 3.5 turbo 的模型下,它很难完成一个任务,往往会陷入无限的循环,主要的原因就是它需要非常严格的上下文衔接来集成各种 command,但凡有一丁儿点的差异都会导致“连接”失败。

在此背景下,function calling出现了。

它允许用户定义一个或多个 function 描述,该描述满足 API doc 的规范,定义了参数的类型和含义。AI 在经过 function calling 的调教后,可以准确的理解这种规范并按照上下文去决定是否可以“命中”该方法,如果“命中”,则会返回该方法的参数。

到此它已经解决了参数提取的问题,但并没有结束。此时开发者可以利用这个参数去集成第三方系统,获取特定的信息然后把结果反馈给模型,这样模型就有了这个方法的输入和输出,看起来像是模型“执行”了该方法,而实际是模型被动的获取了它没有的知识。

最后,AI 根据新获得的知识和信息,给用户输出最后的结果。

Example: DB 搜索

假设我们想利用 AI 在 DB 层建立搜索接口,我们可以按照以下步骤:

    1. 将 DB 的 meta 数据作为上下文,定义 ask_database 的方法规范
{
  "functions": [
    {
      "name": "ask_database",
      "description": "Use this function to answer user questions about music. Output should be a fully formed SQL query.",
      "parameters": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "SQL query extracting info to answer the user\\'s question.SQL should be written using this database schema:\"Table name: album_tb; Columns: album(string), published_at(string), likes(string)\".The query should be returned in plain text, not in JSON."
          }
        },
        "required": ["query"]
      }
    }
  ]
}
    1. 设定 system 上下文,提示模型如果 user 的 prompt 无法命中 function 的话就不要强行“脑补”

这很有用,说明不是所有的 Prompt 都需要被 function 来解析,有点类似 if else,这样可以回归到正常的对话中。

{
  "role": "system",
  "content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous."
}
    1. 提问
{
  "role": "user",
  "content": "What are the top 2 the albums"
}
    1. 模型命中 function 并且返回解析的参数
{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "ask_database",
    "arguments": "{\n  \"query\": \"SELECT * FROM album_tb ORDER BY likes DESC LIMIT 5\"\n}"
  }
}
    1. 查询 DB,将数据返回给我模型(赋能)
{
  "role": "function",
  "name": "ask_database",
  "content": "[{\"album\":\"Tanya\",\"published_at\":\"2000-01-01\",\"likes\":\"10000\"},{\"artist\":\"Im OK\",\"published_at\":\"1999-01-01\",\"likes\":\"20000\"}]"
}
    1. 模型根据新的知识储备响应用户的 Prompt
{
  "role": "assistant",
  "content": "The top 2 albums are \"Im OK\" with 20,000 likes and \"Tanya\" with 10,000 likes."
}
    1. 再次提问,测试新的知识储备是否被模型深刻理解
{
  "role": "user",
  "content": "What are the most popular one"
}
    1. 模型可以准确的在新的知识储备进行搜索
{
  "role": "assistant",
  "content": "The most popular album is \"Im OK\" with 20000 likes."
}

完整的 API 请求如下:

{
	"model": "gpt-3.5-turbo-0613",
	"messages": [
		{
			"role": "system",
			"content": "Don't make assumptions about what values to plug into functions. Ask for clarification if a user request is ambiguous."
		},
		{
			"role": "user",
			"content": "What are the top 2 the albums"
		},
		{
			"role": "assistant",
			"content": null,
			"function_call": {
					"name": "ask_database",
					"arguments": "{\n  \"query\": \"SELECT * FROM album_tb ORDER BY likes DESC LIMIT 5\"\n}"
				}
		},
		{
			"role": "function",
			"name": "ask_database",
			"content": "[{\"album\":\"Tanya\",\"published_at\":\"2000-01-01\",\"likes\":\"10000\"},{\"artist\":\"Im OK\",\"published_at\":\"19999-01-01\",\"likes\":\"20000\"}]"

		},
		{
			"role": "user",
			"content": "What are the most popular one"
		}
	],
	"functions": [
		{
			"name": "ask_database",
			"description": "Use this function to answer user questions about music. Output should be a fully formed SQL query.",
			"parameters": {
				"type": "object",
				"properties": {
					"query": {
						"type": "string",
						"description": "SQL query extracting info to answer the user\\'s question.SQL should be written using this database schema:\"Table name: album_tb; Columns: album(string), published_at(string), likes(string)\".The query should be returned in plain text, not in JSON."
					}
				},
				"required": [
					"query"
				]
			}
		}
	]
}

模型

OpenAI 在 6 月 13 号的 release 中,专门针对 function calling 发布了新的模型,无论是价格还是上下文的长度都有比较大的变化,以下为 3.5(免费)的模型列表:

release

最后

function calling 对与模型精准的理解 Prompt 和集成外部知识储备系统绝对是一个强大的工具,未来 Prompt 的趋势肯定也会朝着个方向去设计,拭目以待吧。


http://www.niftyadmin.cn/n/4953198.html

相关文章

前端面试的计算机网络部分(2)每天10个小知识点

目录 系列文章目录前端面试的计算机网络部分(1)每天10个小知识点 知识点11. DNS 完整的查询过程递归查询过程:迭代查询过程: 12. OSI 七层模型13. TCP 的三次握手和四次挥手三次握手(Three-Way Handshake)&…

CSS加载失败的6个原因

有很多刚刚接触 CSS 的新手有时会遇到 CSS 加载失败这个问题,但测试时,网页上没有显示该样式的问题,这就说明 CSS 加载失败了。出现这种状况一般是因为的 CSS 路径书写错,或者是在浏览器中禁止掉了 CSS 的加载,可以重新…

面试官:JVM是如何判定对象已死的?学JVM必会的知识!

本文已收录至GitHub,推荐阅读 👉 Java随想录 文章目录 引用计数算法可达性分析算法引用类型Dead Or Alive永久代真的"永久"吗?垃圾收集算法标记-清除算法标记-复制算法标记-整理算法标记-清除 VS 标记-整理 作为一名Java程序员&…

网盘传文件限速严重,来试试ssh内网穿透创建的公网到本地http服务器吧

title: 网盘传文件限速严重,来试试ssh内网穿透创建的公网到本地http服务器吧 如果你被国内某度网盘的火星传输速度折磨,可以搞一个固定IP的服务器,传输文件会变得简单,通过ssh转发,我们可以让接受者通过浏览器直接下载…

电脑技巧:电脑关机、休眠、睡眠之间如何选择,看完你就懂了

目录 一、关机、休眠、睡眠的区别? 1.关机 2.休眠 休眠的优点 休眠的缺点 3.睡眠 睡眠的优点 睡眠的缺点 二、什么时候关机/休眠/睡眠? 什么时候需要关机? 什么情况下使用休眠模式? 什么情况下使用睡眠模式&…

最强自动化测试框架Playwright(35)-API测试

playwright可以进行API测试 APIRequestContext可以通过网络发送各种HTTP(S)请求。 以下示例演示如何使用 Playwright 通过 GitHub API 测试问题创建。测试套件将执行以下操作: 在运行测试之前创建新存储库。创建一些问题并验证服务器状态。…

leetcode359周赛

第四题:找出最长等值数组 滑动窗口 总长度 - 众数 > k就需要收缩窗口了。 所以需要一个数据结构统计众数:multiset维护每一个数字的个数。 这里有一个坑ms.erase(x):会把所有的等于x的数字都删除。所以需要使用auto it ms.find(x); m…

关于内存融合cache fusion中锁模式的一些思考

集群中不可能即存在写锁,又存在读锁。这个从读写锁的语义上已经定义。集群中只能存在一个人持有写锁,其他人再申请写锁时必须要释放当前写锁。集群中可能存在多个读锁。集群中存在脏块时,可能存在(一个或多个)读锁&…