ChatGPT 的 Function Call 如同 C3PO 和 R2-D2 聯(lián)手
ChatGPT 6 月 13 日的發(fā)布里面的 Function Call 的功能,把自然語言的世界和現(xiàn)在已經(jīng)有的編程語言的世界打通了。雖然最終我認(rèn)為整個(gè)世界將會(huì)是自然語言的世界,但是畢竟現(xiàn)在所有的計(jì)算機(jī)系統(tǒng)都還是代碼和 API 的世界。從存量的角度來說,這是和現(xiàn)有系統(tǒng)兼容的最好的辦法。
這件事情讓我想起了《星球大戰(zhàn)》里面的一對(duì)可愛的機(jī)器人。金黃色人型的有點(diǎn)傻的 C3PO,精通禮儀和協(xié)議,會(huì)各種語言;還有一個(gè) R2-D2,就是那個(gè)矮矮的圓圓的,是宇航技工機(jī)器人(Astromesh Droid),精通計(jì)算和與計(jì)算機(jī)系統(tǒng)用“嘀嘟嘟嘟”的聲音通信。他們兩個(gè)搭配在一起工作,倒是完美:R2-D2 負(fù)責(zé)干活,獲取信息,C3PO 負(fù)責(zé)翻譯成人的語言。這個(gè)合作關(guān)系,就如同現(xiàn)在的 ChatGPT 和 API 的關(guān)系一樣。
Function call 簡單的說,就是把原來 ChatGPT 的 API 中 completetions 的調(diào)用,從原來只支持 messages(messages里面又可以指定 system,user,assistant 三個(gè)角色),擴(kuò)展到還可以提供 functions。ChatGPT 會(huì)根據(jù) functions 里面每個(gè) function 描述里面「字面」的意思,通過簡單的邏輯判斷用戶的問題用這個(gè)函數(shù)是否可以回答。如果可以的話,把用戶的問題中間可以作為參數(shù)的部分提取出來,并且返回一個(gè)結(jié)構(gòu)化的函數(shù)調(diào)用數(shù)據(jù)結(jié)構(gòu)。
代碼的世界再通過嚴(yán)格的 JSON 格式定義的函數(shù)調(diào)用方法調(diào)用函數(shù),然后再把結(jié)果返還給 ChatGPT。ChatGPT 根據(jù)函數(shù)的結(jié)果,再繼續(xù)回答用戶的問題。
比如我自己的機(jī)器人的 functions 是這么寫的:
functions = [
{
"name": "get_articles",
"description": "Get List of articles",
"parameters": {
"type": "object",
"properties": {
"start": {
"type": "integer",
"description": "The starting point of index of articles",
},
"end": {
"type": "integer",
"description": "The ending point of index of articles",
},
},
"required": [],
},
},
{
"name": "read",
"description": "Get value from database",
"parameters": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "The key to store the value ",
},
},
"required": ["key"],
},
},
{
"name": "save",
"description": "Save value to the database",
"parameters": {
"type": "object",
"properties": {
"key": {
"type": "string",
"description": "The key to store the value ",
},
"value": {
"type": "string",
"description": "The value to store the value ",
},
},
"required": ["key", "value"],
},
},
{
"name": "run_node",
"description": "Run node.js code",
"parameters": {
"type": "object",
"properties": {
"code": {
"type": "string",
"description": "The node.js code I want to use to evaluate",
},
},
"required": ["code"],
},
}
]
其中包括獲取以前的文章的函數(shù),通用的保存和讀取的函數(shù),以及執(zhí)行 Node.js 代碼的函數(shù)。
如果我問:
User: 最近的5篇文章是什么?
ChatGPT 會(huì)回答:
Function: {'name': 'get_articles', 'arguments': '{\n "start": 0,\n "end": 5\n}'}fda
它把參數(shù)都準(zhǔn)備好了。這個(gè)是在 GPT-3 里面就很成熟的功能,只不過這樣子更加穩(wěn)定可控了。
如果問:
User: 現(xiàn)在幾點(diǎn)了
ChatGPT 會(huì)把凡是用 Node.js 的代碼可以回答的問題都轉(zhuǎn)變成 Node.js 的調(diào)用:
Function: {'name': 'run_node', 'arguments': '{\n "code": "new Date().toLocaleTimeString()"\n}'}
這些問題包括時(shí)間,算數(shù)等等。我們就可以把 Node.js 系統(tǒng)的世界和 ChatGPT 的自然語言的世界聯(lián)系在了一起。(不過一定要注意,這個(gè)例子的安全隱患和太平洋那么大。如果讓他返回系統(tǒng)的信息,以及刪除一些文件,它也會(huì)開心的照做,并且真的能做到。)
接下來基于這個(gè)連接器應(yīng)該有非常多有趣的應(yīng)用。雖然這件事情以前用 LangChain 或者自己直接寫代碼也可以實(shí)現(xiàn)。但很多事情都是,如果在最簡單的地方再簡單一點(diǎn)的效果比在很復(fù)雜的地方簡化很多還大。
隨著 Function Call 的支持,ChatGPT API 里面的角色(role)參數(shù),也從三種擴(kuò)充到了四種:
- system
- assistant
- user
- function
這四種,恰恰對(duì)應(yīng)于自然世界的四樣?xùn)|西:system 相當(dāng)于上帝或者大自然(機(jī)器人就是那樣被創(chuàng)造的,所擁有的角色就如同是被上帝設(shè)定的);assistant 就是服務(wù)用戶的機(jī)器人;user 就是和機(jī)器人交互的人類;而function 則代表著這個(gè)世界,是用戶和機(jī)器人之外的第三方。機(jī)器通過函數(shù)從中獲取信息,也通過函數(shù)改變它的狀態(tài)。
這個(gè) C3PO 和 R2-D2 的合作,我們既可以看作 ChatGPT 有了調(diào)用物理世界的能力,也可以看成是所有的計(jì)算機(jī)函數(shù)接口都有了人類語言的能力。