
掌握API建模:基本概念和實踐
Atty Eleti:我想帶大家回到 1973 年,也就是 50 年前。1973 年,《科學美國人》(Scientific American)發表了一篇非常有趣的文章,他們在文章中比較了各種動物的運動。他們著手比較運動的效率。換句話說,一只動物從 A 點到 B 點燃燒了多少卡路里,與它們的體重等是否有關?他們比較了各種動物,鳥類、昆蟲,當然還有我們人類,并將它們根據效率從高到低進行了排名。他們發現,就運動的效率而言,禿鷲的最高。
禿鷲是一種美麗的鳥類,原產于加利福尼亞州和南美洲的一些地區,有時它可以飛數百英里而無需扇動翅膀。它具有非常好的滑翔能力。另一方面,人類行走,在榜單中的排名相當平庸,大約排在榜單三分之一的位置。《科學美國人》這篇文章的精妙之處在于,除了所有物種之外,他們還增加了一個項目,那就是騎自行車的人。騎自行車的人在競爭中大獲全勝,擊敗了所有競爭對手,其運動效率幾乎是禿鷲的兩倍。
我很喜歡這個故事,因為它有一個很簡單的認識,只要用一點工具,有一點機械幫助,我們就能極大地增強我們的能力。你們中的一些人可能以前聽過這個故事。你可能會想,我是在哪里看到的?這個故事是蘋果公司創立之初史蒂夫·喬布斯(Steve Jobs)經常講的。他和蘋果團隊利用這個故事作為早期 Macintosh 的靈感來源。史蒂夫比較了這個故事,并說到:“人類是工具的制造者。”
我們制造了像自行車這樣的工具來增強我們完成任務的能力。就像自行車是運動的工具一樣,計算機也是我們思維的工具。它增強了我們的能力、創造力、想象力和生產力。事實上,史蒂夫曾經用這個神奇的短語來形容個人計算機。他說:“計算機是思維的自行車”。這篇文章發表十年后的 1983 年,蘋果公司發布了 Macintosh,并掀起了個人計算的革命。當然,多年后的今天,我們仍然每天都在使用 mac 電腦。
那是 1973 年。現在是 2023 年,50 年后,計算已經發生了很大的變化。如果《科學美國人》的工作人員再次進行這項研究,我敢打賭他們會在名單上再增加一個“物種”。對我們大多數人來說,這個“物種”在公眾的想象中只存在了大約六個月的時間。我談論當然是人工智能,或者具體來說是語言模型。
自去年 11 月 ChatGPT 推出以來,人工智能和語言模型已經在全球范圍內引起了公眾的廣泛關注。更令人興奮的是,它們吸引了世界各地開發者的想象力。我們已經看到很多人將人工智能集成到他們的應用程序中,使用語言模型來構建全新的產品,并提出與計算機交互的全新方式。自然語言交互終于成為了可能,并且質量很高。但這存在局限性,也存在問題。對于任何使用過 ChatGPT 的人來說,我們都知道它的訓練數據是 2021 年 9 月之前的,所以它不知道當前的事件。
在大多數情況下,像 ChatGPT 這樣的語言模型是根據訓練中的記憶進行操作的,因此它們與當前事件或所有 API、我們每天使用的自己的應用程序和網站無關。或者,如果你在一家公司工作,它不會連接到你公司的數據庫和你公司的內部知識庫等等。這使得語言模型的使用受到了限制。你可以寫一首詩,可以寫一篇文章,可以從中得到一個很棒的笑話,可以搜索一些東西。但如何將語言模型與外部世界聯系起來呢?如何增強人工智能的能力,讓它來代表你執行行動,讓它做比它固有能力更多的事情呢??
如果計算機是思維的自行車,那么人工智能思維的自行車是什么?這就是我們要探討的問題:一輛人工智能思維的自行車。我們將討論 GPT,這是 OpenAI 開發的一組旗艦語言模型,以及如何將它們與工具或外部 API 和函數集成,以支持全新的應用程序。我叫 Atty。是 OpenAI 的一名工程師。Sherwin 是我的搭檔,我們是 OpenAI 的 API 團隊的成員,共同構建了 OpenAI API 和其他各種開發者產品。
我們將討論三件事。首先,我們將討論語言模型及其局限性。我們將快速介紹它們是什么以及它們是如何工作的。先培養下對它們的直觀認識。然后還要了解它們的不足之處。其次,我們將討論我們發布的一個全新特性,即使用 GPT 進行函數調用。函數調用是將 OpenAI 的 GPT 模型插入外部世界并讓它執行操作的方式。最后,我們將通過三個快速演示樣例來演示如何使用 OpenAI 模型和 GPT 函數調用功能,并將其集成到公司產品和輔助項目中。?
Sherwin Wu:首先,我想對 LLM 做一個非常高層級的概述:它們做什么,它們是什么,它們如何工作。然后再談談它們開箱即用的一些限制。對于那些已經關注這個領域一段時間的人來說,這可能是你們都知道的信息,但我只是想在深入討論細節之前確保我們都能達成共識。
非常高層級的 GPT 模型,包括 ChatGPT、GPT-4、GPT-3.5-turbo,它們都是我們所說的自回歸語言模型。這意味著它們是巨大的人工智能模型,它們接受過龐大的數據集的訓練,包括互聯網、維基百科、公共 GitHub 代碼和其他授權材料。它們被稱為自回歸,因為它們所做的只是綜合所有這些信息。它們接受一個 prompt,或者我們可以稱之為上下文。它們查看 prompt。然后它們基本上只是決定,給定這個 prompt,給定這個輸入,下一個單詞應該是什么?它實際上只是在預測下一個單詞。
例如,如果給定 GPT 的輸入是,“the largest city in the United States is“(美國最大的城市是),那么答案就是 New York City(紐約市)。它會一個字一個字地思考,它會說“New”、“York”,然后是“City”。同樣,在更具對話性的環境中,如果你問它地球和太陽之間的距離是多少。GPT 已經從互聯網上學過這個,它將輸出 9400 萬英里。它是根據輸入逐個單詞逐個單詞思考的。
在底層,它真正做的是每次輸出單詞時,都會查看一堆候選單詞并為它們分配概率。例如,在最初的例子中,“美國最大的城市是”,它可能有很多候選城市,New 代表“紐約”(New York),或者“新澤西”(New Jersey),或者其他什么,Los 代表“洛杉磯”(Los Angeles),然后還有其他一些可能的例子。你可以看到,它確實認為“New York City”(紐約市)可能是正確的答案,因為 New 的概率為 95%。在這種情況下,它通常會選擇最有可能的結果,所以它會選擇 New,然后繼續前進。這個單詞出現后,我們現在就知道 New 是第一個單詞,所以它對下一個單詞是什么就有了更多的限制。
我們可以看到,現在它認為 New York(紐約)的可能性要高得多,但它也在考慮 New Brunswick(新不倫瑞克)、New Mexico(新墨西哥)和 New Delhi(新德里)等。直到完成第二個單詞,這基本上是模型的疊加。它基本上知道答案是 New York City,概率幾乎是 100%。但它仍在考慮其他一些剩余概率很低的選項,比如 County(縣)、New York Metro(紐約地鐵)、New York Times(紐約時報),但最終它選擇了 City 并給出答案。
對于更機敏的 LLM 人士來說,這在技術上過于簡單化了。我們并不是真正在預測單詞,而是在預測 token,比如單詞片段,這實際上是一種更有效的表達英語的方式,主要是因為單詞片段會在一堆不同的單詞中重復,而不是單詞本身會重復。但概念仍然是一樣的。LLM 在這種上下文中,很可能會連續輸出一堆不同的 token。就是這樣,這就是這些語言模型的真正含義。了解了這一點,我認為讓我們很多人感到驚訝的瘋狂之處在于,我們只需預測下一個單詞就可以走得很遠。
這張圖表來自我們今年 3 月發布的 GPT-4 博客文章,它顯示了我們最有能力的模型 GPT-4 在各種專業考試中的表現。這實際上只是 GPT-4 根據問題預測下一個單詞。你可以看到,在很多不同的考試中,它的表現實際上和人類一樣,甚至超過了人類的表現。y 軸是考生的百分位數。在 AP 考試、GRE 考試、LSAT 考試、美國生物奧林匹克競賽等一系列不同的考試中,它基本上處于第 80 個百分位,有時甚至是第 90 個百分位,甚至是第 100 個百分位。
在這一點上,很多這樣的測試我甚至都做不到,所以 GPT-4 遠遠超出了我自己的能力,而這只是來自對下一個單詞的預測。這真的太酷了。你可以用它構建很多很酷的東西。任何一個已經學習了 LLM 一段時間的人都會意識到,我們很快就會遇到一些限制。當然,最大的一個是開箱即用的 LLM 或 GPT 實際上是一個裝在盒子里的人工智能。它無法進入外部世界。它不知道任何其他信息。它就在那里,有它自己的記憶。感覺就像你在學校里參加考試時,只有你和考試,你只能根據記憶來回憶一些東西。
想象一下,如果考試是開放的,你可以使用手機或類似的東西,你會做得更好。GPT 今天真的只是在它自己的盒子里。正因為如此,作為工程師,我們希望使用 GPT 并將其集成到我們的系統中。限制 GPT,不允許它與我們的內部系統對話,這對于你可能想做的事情來說是非常有限的。此外,即使它確實可以訪問某些工具,因為語言模型是概率性的,有時也很難保證模型與外部工具交互的方式。如果你有一個 API 或其他你想要使用的東西,當前模型不能保證總是能與你 API 可能想要的輸入相匹配時,這最終也會成為一個問題。
例如,如果我正在構建一個應用程序,并將此輸入提供給 GPT,基本上就是說,下面是一個劇本的文本,從中提取一些信息,并以這種 JSON 格式對其進行結構化。我真的只是給它一個劇本,讓它推斷出一種類型和一個子類型,以及其中的一些角色和年齡范圍。我真正想要的是,我希望它能輸出像這樣的東西。就像 JSON 輸出一樣。
也許這是一個關于哈利波特的浪漫故事之類的劇本。它知道這是浪漫的,青少年的浪漫,它看到羅恩(Ron)和赫敏(Hermione),并以這種 JSON 格式準確輸出。這太棒了,因為我可以獲取這個輸出,現在我可以使用它并將其放入 API 中。然后我就像在我的代碼中一樣,一切都正常。問題是,它大概只有 80%、70% 的概率是這樣的。
在剩下的時間里,它會嘗試并提供額外的幫助,做一些像這樣的事情,它會說:“當然,我可以為你做。下面是你要求的 JSON 格式的信息。”這是非常有用的,但如果你試圖將其插入到 API 中,它實際上室不起作用的,因為前面所有這些隨機文本,你的 API 并不知道如何解析它。這顯然是非常令人失望的。這不是你真正想要的。我們真正想做的是,幫助 GPT 打破常規,或者給 GPT 一輛自行車或另一套工具來真正增強它的能力,并讓它無縫地工作。?
這就把我們帶到了下一部分,那就是我們所說的 GPT 函數調用,這是我們發布的 API 的一個新變化,它使函數調用能夠以一種非常一流的方式更好地使用我們的 GPT 模型。舉個例子,如果你問 GPT 這樣的問題,what’s the weather like in Brooklyn today? (今天布魯克林的天氣怎么樣?)如果你問一個普通的 GPT 這個問題,它基本上會說,“作為一個由 OpenAI 訓練的人工智能模型,我無法提供實時信息。”這是真的,因為它實際上無法訪問任何東西。它在一個盒子里。它怎么會知道今天天氣怎么樣呢?
這顯然確實限制了它的能力,這是不可取的。我們所做的是更新了 GPT-4 和 gpt-3.5-turbo 模型或旗艦模型。我們收集了大量的工具使用和函數調用數據,根據這些數據對我們的模型進行了微調,使其真正擅長選擇是否使用工具。最終的結果是我們發布了一組新的模型,這些模型現在可以為你智能地使用工具和調用函數。在這個特殊的例子中,當我們詢問模型“今天布魯克林的天氣怎么樣?”時,我現在能做的就是解析這個輸入,同時告訴它一組函數,或者在本例中,告訴它它可以訪問的一個函數,如果需要幫助,它應該嘗試并調用這個函數。在本例中,我們將為它提供一個名為get_current_filther
的函數。
它接收一個帶有 location(位置)的字符串,然后它就知道它可以使用這個。在本例中,在這個新的世界里,當你解析此輸入時,GPT 將表達它打算調用get_current_filther
函數的意圖。然后,你可以根據需要在自己的系統中自行調用該函數。假設你得到的輸出是 “22 Celsius and Sunny”(22 攝氏度和陽光明媚)。你可以將其解析回 GPT,它會綜合這些信息,并返回給用戶說:the weather in Brooklyn is currently sunny, with a temperature of 22 degrees Celsius(目前布魯克林天氣晴朗,溫度為 22 攝氏度。)
稍微解釋一下,真正發生的事情是 GPT 知道一組函數,并且它會智能地自行表達調用其中某個函數的意圖。然后執行調用,并將其解析回 GPT。這就是我們最終將它與外界聯系起來的方式。為了進一步了解它在高層級上到底發生了什么,其實它仍然就像是一個來回,你的用戶問了一個問題,發生了很多事情后,你對你的用戶做出了回應。你的應用程序在底層實際做的事情將經歷一個三步的過程,首先調用 OpenAI,然后使用你自己的函數,最后再次調用 OpenAI 或 GPT。
第一步,顯然是用戶問了一個問題,在本例中,問題是 what’s the weather like in Brooklyn today?(“今天布魯克林的天氣怎么樣?”)然后下一步是,在應用程序中,調用模型,調用 OpenAPI,并非常具體地告訴它它可以訪問的函數集以及用戶輸入。這是一個 API 請求的例子,目前它實際有效且可正常工作,任何具有 API 訪問權限的人都可以嘗試該操作。這是一個使用函數調用能力的 curl 示例。我們可以看到,這只是我們聊天完成端點的正常 curl,這是我們發布的一個新的 API 端點,為我們的 GPT-4 和 GPT-3.5 模型提供支持。你 curl 該 API。它會在模型中進行解析。
在本例中,我們將在 gpt-3.5-turbo-0613 中進行解析,它代表 6 月 13 日,一個我們發布的模型。這是一個能夠進行函數調用的模型。我們還在解析一組消息。對于那些可能不熟悉我們聊天完成格式的人,你可以將其解析到我們的模型中,基本上是一個消息列表,也就是對話記錄。
在本例中,實際上只有一條消息,沒有歷史記錄。它只是用戶詢問“今天布魯克林的天氣怎么樣”。你可以想象,隨著對話的變長,它可能是一個包含 5 到 10 條消息的列表。我們正在解析消息,模型將能夠看到歷史記錄并對此做出回應。那么,這里的新事物就是函數。
這是一個我們現在可以解析的新參數,我們在這里解析的是,我們列出了這個模型應該知道的一組函數,它應該可以訪問的函數集。在本例中,我們只有一個函數,它就是get_current_tweather
函數。我們在這里還放了一個自然語言描述。我們說這個函數可以獲取特定位置的當前天氣。我們還需要輸入函數簽名。并且我們告訴它有兩個參數。一個參數是 location(位置),這是一個字符串,包含城市和州,格式是這樣的:舊金山,加州(San Francisco, California.)。另一個參數時 unit(單位),即攝氏度(Celsius)或華氏度(Fahrenheit)。
在這里首屏的下面,還有另一個參數,該參數表示唯一必須的屬性是位置。從技術上講,你只需要解析位置,這里不需要單位。我們將該請求解析到 GPT,然后 GPT 將作出響應。在過去中,GPT 可能只會以文本形式進行響應。它會說:“我不能這樣做,因為我沒有訪問權限。”在本例中,我們的 API 響應的是調用天氣函數的意圖。
這里真正發生的事情是 GPT 憑自己的直覺,為了弄清楚今天的天氣,我自己做不到,但我可以訪問get_current_weither
這個函數,所以我會選擇調用它,所以我要表達要調用它的意圖。此外,如果你還沒有真正注意到的話,GPT 在這里所做的是,它在這里構造參數。我們可以看到它在告訴我們,它想調用get_current_tweather
,它想用參數位置(Brooklyn, New York;紐約布魯克林)來調用該函數。
它所做的就是看到函數簽名,并為其創建請求。然后還算出布魯克林在紐約,然后用這種方式構造字符串。它把這一切都弄清楚了。至此,GPT 就表達了現在要調用函數的意圖。下一步是,我們要弄清楚我們到底想要如何調用這個函數。我們可以根據特定參數從get_current_tweather
的函數調用中獲取相應的返回值。然后我們可以自己執行。它可以是本地的,在我們自己的 Web 服務器上運行。它也可以是系統中的另一個 API,還可能是一個外部 API,我們可以調用 weather.com API。
那么在這個例子中,我們調用了一些東西,可能是一個內部 API,它返回的輸出是我們看到的是 22 degrees Celsius and Sunny(22 攝氏度和晴天)。給定了模型的輸出,就可以開始這個過程中的第三步,即調用模型,用函數的輸出調用 GPT,然后查看 GPT 想要做什么。在本例中,我談論的是消息。這次,我們在向 OpenAI API 發送的第二個請求中添加了幾條消息。最初,只有一條信息,那就是“今天布魯克林的天氣怎么樣?”,現在再添加兩條新消息來表示函數調用時所發生的情況。
第一個基本上是對意圖的重申,所以基本上是說助理或 GPT 想要用紐約布魯克林的這個參數來調用get_current_tweather
函數。然后,我們還添加了第三條消息,它基本上說明了我們所進行的函數調用的結果,因此這是get_current_filther
的結果。然后,內聯這里輸出的數據,即溫度“22”、單位“攝氏度”和描述“晴天”,然后將所有數據解析給 GPT。在此時,GPT 接收了它,并決定它想要做什么。
此時,模型已經足夠智能了,它能夠意識到“我將調用這個函數。這是輸出。我實際上已經掌握了實際完成請求所需的所有信息。”它現在最終會通過文本方式來做出回應,并顯示“今天布魯克林天氣晴朗,溫度為 22 攝氏度”。這時,我們終于得到了 GPT 的最終輸出。然后我們就可以回應我們的用戶了。
將所有這些放在一起,我們最終會得到我們理想中的體驗,即用戶詢問“今天布魯克林的天氣怎么樣?”我們的服務器會思考一下,GPT 表達意圖,我們完成完整的三步過程,調用了我們的函數。最終,用戶看到的是“今天布魯克林天氣晴朗,氣溫為 22 攝氏度。成功”?
Eleti:我們剛剛介紹了幾個入門性的主題。首先,我們了解了語言模型是如何工作的,以及它們的一些局限性,因為它們沒有所有的訓練數據,它們沒有連接到外部世界,它們的結構化輸出并不總是可解析的。Sherwin 還向我們介紹了新特性、函數調用和 API 的工作原理,以及如何將函數解析為 API 并獲取輸出,以及如何讓 GPT 以面向用戶的方式來總結響應。讓我們通過幾個演示來了解如何將所有這些組合起來,并將其應用到我們的產品和應用程序中。
讓我們從小事做起。我們將介紹的第一個示例是將自然語言轉換為查詢的內容。我們的示例是,假設你正在構建一個數據分析應用程序或商業智能工具,比如 Tableau 或 Looker。你們中的一些人可能很擅長 SQL,但我肯定不擅長了。大多數情況下,我只想問數據庫,誰是頂級用戶,然后得到響應。今天終于有可能了。我們將使用 GPT,將給它一個稱為 SQL 查詢的函數,它只需要一個參數,即一個字符串“query”。
它應該是針對我們數據庫的一個有效 SQL 字符串。讓我們看看它是如何工作的。首先,我們將為模型提供一條系統消息,描述它應該做什么。我們稱之為 SQL GPT,可以將自然語言查詢轉換為 SQL。當然,模型需要訪問數據庫模式。在本例中,我們有兩個表,用戶表(users)和訂單表(orders)。用戶表有姓名、電子郵件和生日。訂單表有用戶 ID、購買金額和購買日期。現在我們可以開始使用一些自然語言來查詢數據庫了。
我們來問這樣一個問題“根據上周的消費金額,找出排名前 10 的用戶姓名”(get me the names of the top 10 users by amount spent over the last week.)。這是一個相當正常的業務問題,當然不是我可以立即編寫 SQL 就能解決的問題,但 GPT 可以。讓我們運行一下。我們可以看到它正在調用 SQL 查詢函數。它有一個參數“query”,它創建了一個漂亮的 SQL 查詢。它是選擇了名稱和金額的總和;它連接到訂單表;并獲取最后一周的訂單,按總花費進行排序,并將其限制為 10 個。這看起來是正確且恰當的。讓我們在數據庫中運行一下它。我們得到了一些結果。
當然,這是 JSON 格式的,因此用戶無法渲染它。讓我們把它發送回 GPT 看看它說了什么。GPT 總結了這些信息,并表示“這些是按消費金額排名前十的用戶。這是他們上周的花費,包括 Global Enterprises, Vantage Partners。”這是一個了不起的用戶可讀的答案。
我們要對 GPT 給予的幫助表示感謝。我們說“謝謝”,GPT 說“不客氣”。這是一種快速的方法,它可以了解完全的自然語言、完全的自然語言查詢是如何將結構化輸出轉換為有效的 SQL 語句的,我們在數據庫中運行該語句,獲取數據,并將其匯總回自然語言。我們當然可以在此基礎上構建數據分析應用程序。
你還可以構建其他的內部工具。Honeycomb 最近為 Honeycomb 查詢語言構建了一個非常相似的工具。這是使用 GPT 和函數將自然語言轉換為查詢的一個示例。?
讓我們來做第二個演示。這是關于將外部 API 和多個函數一起調用的。我們提高了復雜度。假設我們正在紐約參加一個會議,我們想預訂今晚的晚餐。我們將使用兩個函數來調用 GPT。第一個是get_current_location
。它在設備上本地運行,比如在你的手機或瀏覽器上,并獲取你所在位置的緯度(Lat
)和經度(Long
)。第二個函數是 Yelp 搜索,它使用 Yelp 的 API,也就是流行餐廳評價應用程序,我們可以對緯度、經度和查詢進行解析。
我們來運行一下這個演示。本例中的系統消息相當簡單。它所說的就是我們的私人助理,來幫助用戶完成任務,把 GPT 變成了一個有用的助手。我說“我正在參加一個會議,想在附近吃晚飯,有什么選擇嗎?我的公司會支付這筆費用,這樣我們就可以盡情享受了”。讓我們用 GPT 來運行一下它,看看它是如何做的。
當然,GPT 不知道我們在哪里,所以它說get_current_location
,我們將調用本地 API 來獲取我們的緯度和經度。我們已經獲取到了。是紐約的布魯克林(Brooklyn, New York)的某個地方。我們會將其返回給 GPT,看它怎么說。它已經有了所需的信息,現在它想調用 Yelp,它說“緯度、經度和查詢”,并且會說“美食”。這很好。這就是我想要的。讓我們調用 Yelp 并獲取一些數據。
我們從 Yelp API 中獲取了一堆餐館。當然,我希望它能給出一個漂亮的總結,所以讓我們再次運行它。它回復說“你附近有一些高檔餐飲可選擇,La Vara、Henry’s End、Colonie、Estuary”。上面還寫著“請檢查營業時間,盡情用餐。”這聽起來很美味。再次感謝 GPT 幫助我們組織今晚的晚宴。
這是一個使用 GPT 和函數調用外部 API(在本例中為 Yelp API)以及協調多個函數的示例。它能夠憑借推理能力解析用戶意圖,并依次執行多個步驟的操作,以實現最終目標。
第三個演示,讓我們來進一步加強。我們討論了 GPT-4 是如何通過 SAT 和 GRE 的。如果可以的話,它一定比僅僅調用 Yelp API 或編寫一些 SQL 更聰明。讓我們來測試一下。我們都是工程師,我們每天都有很多事情要做。我們必須要做的任務之一是拉取請求審查。我們必須審查同事的代碼。如果 GPT 能幫助我,減輕我的工作量,那就太棒了。我們將做一個 GPT 的演示,它可以進行拉取請求審查,有點像構建自己的工程師。
我們只需要一個函數submit_comments
。它接受一些代碼并返回一個要審查的評論列表,包括行、數字和評論。你可以想象,我們可以將其發送到 GitHub API 或 GitLab API,并發布一堆評論。當然,你還可以添加更多的功能以使其更強大。讓我們看看它是如何做的。
在本例中,prompt 有點長。我們向上滾動著看下。我們說:“GPT,你記錄、審查 rot,查看其差異并生成有關更改代碼的審查評論,保留所有代碼審查評論和相應的行號。”我們在這里也賣弄下個性。我們說 toxicity 為 10 分之 0,其實我們不希望這樣。
為了好玩,讓我們在 snark 上嘗試 10 分之 8。我們都認識一些表現出這些個性的工程師。然后嘗試 10 分之 2。讓我們從這里開始吧。下面是一些我們要審查的代碼。它是 SaaS 應用程序中的一個 API 方法,用于更改用戶的權限。讓我們運行一下它。我們看看 GPT 對這些代碼有何看法。它給出了三條審查意見。我們可以看到它調用了submit_comments
函數,并且它輸出了完全有效的 JSON。讓我們看看上面寫著什么。它說,“我們現在是在捉迷藏嗎?”,“當角色不在身體里時會發生什么?”,“你在那里添加一個了小轉折,你就直接訪問了第一項。”
我們只是隨意地加入了數據庫會話,是嗎?這有點粗魯。我們也不想那樣。讓我們來解決一下這個問題。我現在要退出并稍微修改一下 prompt。要執行該操作,請退出。在幕后,我所做的就是返回 prompt 并更改這些的數字:toxicity
,然后下一個,snark
,我們將其恢復到 0。我們并不希望這樣。讓我們禮貌一點。
我們要把禮貌做到十分之十。好吧,再給我三條審查意見。它再次使用完全有效的 JSON 調用該函數。它說,“很高興看到你檢索角色值。”;“你的錯誤信息簡潔明了。”;“我很感激你對數據庫的更改,做得很好。”。我希望有人能這樣審查我的代碼。感謝 GPT,我將退出了。這是第三個快速演示。
從本質上講,它仍然在做同樣的事情。它調用一個函數,給出一些 prompt,并對其做出響應。我們看到的是 GPT 的推理能力。GPT 認識代碼。它已經看到了成千上萬行代碼,可以給出很好的評價。如果你拋開一些個性的東西,它會指出錯別字,指出潛在的錯誤案例和邊緣案例。我們在這里將高級推理與日常任務相結合。它確實非常擅長編碼。它在考試方面也確實非常出色,它的智力應用范圍也很廣。這實際上取決于開發人員的創造力,將其應用于盡可能困難的任務,并在此基礎上循環運行。?
這是本次內容的快速總結。我們討論了三件事。首先,我們討論了 LLM 及其局限性。我們了解了 LLM 是如何工作的,它是 token 預測機。我們了解了它的局限性。它被時間限制住了。它并不總是輸出結構化的輸出等等。其次,我們了解了這個新特性,即使用 GPT 進行函數調用,這是對我們 API 和模型的更新。它允許模型表達何時調用函數的意圖,并為我們構建有效的參數,然后在我們的終端上調用該函數。最后,我們瀏覽了一些演示。在某個時候,我會把公關的東西產品化。
讓我們回到開始的地方。我們談到了史蒂夫·喬布斯的名言,他說“計算機是思維的自行車”。這對我來說確實如此,對你們所有人來說也都是如此。我們身處計算機行業,計算機改變了我們的生活。計算機增強了我們與生俱來的能力,給了我們更多的生產力、想象力和創造力。ChatGPT 中的人工智能和語言模型還是個嬰兒。它才出生幾個月。我們有責任增強人工智能的思維,賦予它超越其內在推理能力的新能力,將其與工具連接,與 API 連接,并利用這一特性開發出真正令人興奮的應用程序。
原話對我來說非常有啟發。我們永遠無法公正地對待史蒂夫·喬布斯的名言。“我記得在我大約 12 歲的時候讀過一篇文章,我想可能是在《科學美國人》上,他們在文章中測量了地球上所有這些物種的運動效率,它們從 A 點到 B 點需要消耗多少千卡熱量。禿鷲贏了,位居榜首,超過了其他所有物種。人類排在榜單大約三分之一的位置,這對創造之冠來說并不是一個很好的表現。在那里有人有足夠的想象力來測試人類騎自行車的效率。一個騎自行車的人把禿鷲吹走了,一直高居榜首。這給我留下了非常深刻的印象,我們人類是工具的制造者,我們可以制造出將這些固有能力放大到驚人程度的工具。對我來說,計算機一直是思維的自行車,它讓我們遠遠超越了固有的能力。我認為我們只是處于這個工具的早期階段,非常早期的階段。我們只走了很短的一段距離,它仍處于形成階段,但我們已經看到了巨大的變化。我認為,與未來 100 年發生的事情相比,這算不了什么。”
就像 50 年前的計算機一樣,我認為今天的人工智能也是如此。技術還處于起步階段,所以我們很高興看到它的發展。
參會者 1:我們應該如何應對錯誤和失敗,你有什么建議的策略?以你的演示為例,在你構建 SQL 查詢時,如果我提出的問題導致 ChatGPT 給出了一個在語法上完成正確,但在語義上完全不正確的 SQL 查詢時,該怎么辦?然后我向我的用戶報告一些不正確的內容。很難告訴用戶,這是錯誤的,但你有什么建議的策略來應對這個問題嗎?
Eleti:我認為首先,作為一個社會和這些語言模型的用戶,我們必須了解它的局限性,幾乎要圍繞它的局限性來建立抗體。要知道輸出可能是不準確的。我認為第二部分就像打開了盒子。我們已經將生產中的函數調用與 ChatGPT 集成在了一起。我們推出了一款名為插件的產品,它基本上可以做到這一點,它允許 ChatGPT 與互聯網對話。我們要做的一件事是,如果最終用戶愿意的話,那么所有的請求和響應都是可見的。這有助于信息部分。我個人認為 SQL 也是一個非常廣闊的開放領域。我認為將其限制在僅在后端執行安全操作的知名 API 是一個好方法。你總是可以得到好的錯誤信息之類的。這些就是我即興的建議。?
參會者 2:有人嘗試過做一些 LangChain 嗎,它可以與 LangChain 一起使用嗎?
Eleti:是的,事實上,LangChain、Harrison 團隊在我們推出一個小時后就發布了一個集成,所以它是有效的。?
參會者 2:這還暴露了一個泄漏問題。SQL 示例就是一個很好的例子。如果有人讀到這篇文章,他們對金融數據庫進行 SQL 查詢,并將其輸入到 gpt-3.5-turbo,我們基本上就泄露了數據。
如果你使用的是 text-davinci-003 或不同的模型,就會出現這樣的問題,一些來自查詢的數據會變成模型本身。在我看來,這個例子是極其危險的。
Wu:實際上這存在一個誤解,我認為我們最近沒有作出很好地澄清,直到今年 3 月或 2 月,在我們為 API 提供的服務條款中,我們就說過“我們保留自己對 API 輸入數據進行培訓的權利”。我想這可能就是你所說的,就像你對一些 SQL 查詢進行解析一樣,它會在返回時以某種方式回到模型中。事實上,到目前為止,我們已經不再這樣做了。根據我們的服務條款,我們實際上不會在 API 中對你的數據進行訓練。我認為我們還沒有把這一點說得非常清楚,所以人們對此非常偏執。到目前為止,還沒有。你應該查閱我們的服務條款。我們不訓練它。也就是說,解析的東西并不像企業級的那樣。我們不會針對你的用戶進行隔離。我們只是沒有在自己的數據上訓練它。這種圍繞企業級數據隔離的特性顯然很快就會出現。這一特定的安全層還沒有出現。
Eleti:我們不使用 API 數據進行訓練。?
參會者 3:你展示的演示運行有點慢。我想知道,你們支持函數調用的并行化嗎?就像現在你是串行的嗎,你得到了這個函數簽名,然后調用它,但假設 ChatGPT 說,三個函數應該同時被調用,這可行嗎?
Eleti:API 實際上不支持多個函數調用。沒有輸出顯示“調用這三個函數”。但你可以破解它。你只需要定義一個函數,讓它調用多個函數,然后你提供一個簽名,讓模型調用它,即可實現調用多個函數,這完全是可行的。歸根結底,我們仍然是使用模型的推理能力來輸出一些文本。?
參會者 4:在你給出的 SQL 示例中,你為其提供了一些可以訪問的表。我們有沒有辦法可以讓任何人的后續調用預加載所有上下文呢?
Wu:有幾個潛在的解決方案。我們有一個稱為系統消息的功能,你可以在那里進行解析,它基本上設置了模型的整體對話上下文。但在當時的語境中它是完全顛倒的。目前,我們已經將上下文窗口增加到大約 16000 個 token。你可以逐漸將更多內容壓縮到系統消息中。該模型經過訓練,會格外關注系統消息,以指導其做出回應。在本例中,Atty 在系統消息中有兩個表的模式。可以預見的是,你可以添加更多的內容來填充整個上下文。
參會者 4:這就是我們的預加載方式嗎?
Wu:是的,這是最簡單的。還有一些其他的方法。你可以將它連接到外部數據源、數據庫之類的。微調也是另一種選擇。還有其他一些。?
參會者 5:關于將 GPT 集成到不同的軟件中。我在使用枚舉時遇到了一些問題,當我要求它用英語、法語或德語做一些工作時,我使用的枚舉有時會出現德語或法語。API 函數也會發生這種情況嗎?
Eleti:是的,很不幸。模型在正常情況下以及在這種情況下都很容易產生幻覺。我們所做的基本上是對模型進行了微調,因此我們可以看到大約 100000 個關于如何可靠地調用函數的示例。它比你自己做的任何其他提示都要好得多。它仍然會生成參數,可能會輸出無效的 JSON,也可能會輸出其他語言。為了防止這種情況,我們將進行更多的微調。我們也在探索一些低級推理技術來改進這一點。然后在你這邊,你可以做 prompt 工程,只要提醒模型,不要輸出德語,它會盡力的。
Wu:看看它在這方面是否能做得更好,這會很有趣,尤其是如果你有一個函數簽名,并且你明確列出了 5 個不同的英文枚舉。較新的模型可能會更好,但也不完美。我不能百分百確定,不幸的是,我們沒有跨英語、法語枚舉那樣的評估。這可能是一個值得思考的好問題,但我們很好奇,想看看它是否會變得更好。?
參會者 6:我有一個關于 API 理解意圖能力的問題。函數調用是否有相似的溫度(temperature)參數;如果我解析兩個具有相似意圖的函數,那么 GPT 對每個要調用的函數是否具有確定性;或者如果我多次詢問,選擇要調用哪個函數是否具有隨機性?
Eleti:隨機性依然是存在的。歸根結底,在底層,它仍然是一個 token 一個 token 地輸出,選擇要調用的函數。降低溫度增加了確定性,但這并不能保證確定性。也就是說,API 中有一個名為函數調用的參數,如果你知道你想讓它調用哪個函數,實際上可以直接指定它,它肯定會調用該函數的。?
參會者 7:如果我們想限制某些用戶進行某些函數調用,或者像你這樣在這些 SQL 查詢中訪問某些表,你們有函數調用的權限嗎,人們還需要實現他們自己的嗎?
Eleti:所有這些都會發生在你的服務器上,因為你擁有誰可以訪問什么內容的完整上下文。這個 API 提供的只是 GPT 選擇要調用哪個函數以及要使用哪些參數的能力。然后,我們希望你像對待任何其他客戶端一樣對待 GPT 的輸出,因此對于不受信任的客戶端輸出,你可以在你的終端上驗證其權限和內容。?
參會者 8:我只是想知道你是否可以詳細說明一下這在底層發生了什么。這是底層的思維鏈嗎?這是這些技術之上的一個有效的 API 層嗎?
Eleti:思維鏈提示是一種在給模型任務時的詢問方式,首先,告訴我你要做什么,然后去做。如果你問“布魯克林的天氣怎么樣?”它可能會說“我收到了一個天氣請求,我將調用天氣 API”。然后它就這樣做了。這是一種快速的工程技術。這是一個微調。隨著插件的推出,我們收集了大約 100000 個用戶問題和函數調用示例的內部和外部數據。這一切都在模型中進行了微調。這就是它的來源。
我們還可以使用第三種技術,叫做約束采樣,其中在 token 采樣層,你可以確保預測的下一個 token 是值集中的一個。在 JSON 示例中,逗號之后必須是新行或類似的內容。我們可能會弄錯,但是我們明白了,我們有語法要分配。這是我們正在探索的領域。這是從提示到微調再到更低層的東西的漫長旅程。這是讓 GPT 輸出可靠結構化數據的過程。?
參會者 9:這可以與矢量數據庫一起使用嗎?我的想法是,我想根據我輸入到向量數據庫中的信息來約束信息,但它仍然能適用于函數邏輯?
Eleti:是的,和以前一樣好用。?
參會者 10:我們今天就能使用它了嗎?它現在對公眾開放了嗎?
Wu:它是今天公開的,但有一個警告。它在 gpt-3.5-turbo 模型上可用。這里的任何人實際上都可以使用 gpt-3.5-turbo 訪問函數調用,因為這是普遍可用的。它也可以在 GPT-4 API 上使用,但不幸的是,它仍然處于等待名單中。如果你不在該等待名單中,并且你可以訪問 GPT-4 API,那么你實際上可以使用 GPT-4 進行此操作。它在這方面做得更好。進度有點慢。如果你仍在等待名單上,或者你無法訪問 GPT-4 API,你今天可以在 GPT-3.5-turbo 上試用。
文章轉自微信公眾號@InfoQ