華為云計算 云知識 使用 FunctionGraph 快速構建自己的“ChatGPT”
使用 FunctionGraph 快速構建自己的“ChatGPT”

函數工作流 FunctionGraph >>

一、背景

ChatGPT是一個基于GPT-3模型的聊天機器人,可以與用戶進行自然、流暢和有趣的對話。ChatGPT可以理解和使用多種語言,如英語、中文、日語、西班牙語、法語或德語;還可以根據用戶的興趣和需求,提供相關建議和創(chuàng)意內容,如詩歌、故事、代碼、歌詞等。ChatGPT是一個強大而靈活的工具,可以用于娛樂、學習或工作。

但是在國內使用ChatGPT有些不便,是否可以基于OpenAI開放的API做一個給自己或者同事們使用的聊天機器人,甚至集成到更多的場景…. 效果如下:

二、方案選型

說干就干,我們先從做一個自己的機器人開始,首先我們從OpenAI獲取用于鑒權的秘鑰。

然后寫一個請求OpenAI接口的代碼,并寫一個web服務接口開放出去,再搭配一個交互用的前端即可??雌饋硎?小時的工作量,但是如何部署這個服務呢? 購買一個 云服務器 再安裝環(huán)境或者配置容器也太麻煩了,于是我問了ChatGPT:

可以看到, 使用FunctionGraph只需要聚焦完成請求OpenAI接口的功能函數,不需要購買和配置資源,甚至不需要寫Web接口的代碼。 于是一個簡單的方案如下:

其中,

  • 對象存儲服務 OBS:用于托管前端頁面
  • FunctionGraph : 用于響應前端請求,運行代碼向OpenAI發(fā)送問題
  • API網關: 對外開放調用函數的API

注:“函數” 是指客戶部署在FunctionGraph上的代碼,它可以是一個或多個文件組成的程序,甚至編譯好的二進制文件。 如Python 腳本文件,Java的jar 包。

三、開發(fā)并部署聊天應用

創(chuàng)建FunctionGraph函數處理用戶提問的請求

首先創(chuàng)建并開發(fā)FunctionGraph函數,打開華為云FunctionGraph 產品頁面,由于只有一個簡單的問題查詢接口,這里我們選用事件函數 使用Python 3.9 運行時。

注:事件函數,可以由某類事件觸發(fā)函數運行,如用戶對該函數發(fā)送了HTTP請求,關聯(lián)到該函數的消息隊列里產生了新消息,都會自動觸發(fā)函數運行。

對于事件函數,通常程序入口方法(這里是 handler)會有兩個參數:

  • event 參數包含觸發(fā)用戶函數的事件的相關信息。HTTP請求也是一種事件,event里會包含請求的body header 等;
  • context 參數:調用平臺的相關能力,如獲取在函數配置里設置的加密環(huán)境變量等

圖:FunctionGraph 函數源碼

上圖為本次調用的入口方法handler(),在函數中,我們:

  1. 從event 里取得請求的參數 prompt
  2. 調用OpenAI 的接口Python SDK,向OpenAI 發(fā)送請求, (示例里我們使用text-davinci-003模型 [1] https://platform.openai.com/docs/model-index-for-researchers#footnote-2)
  3. handler 方法中我們使用了 context 獲取訪問OpenAI的key(上圖29行) ,獲取前需要在函數上配置對應環(huán)境變量,如下圖所示:

圖:函數配置環(huán)境變量

注:示例中我們使用了OpenAI的sdk ,也可以將sdk放在函數代碼里一起上傳,或利用函數的依賴管理能力,通過添加依賴的方式實現(xiàn):

圖:函數配置依賴

在編輯好代碼后,只需要點擊部署按鈕即可完成部署。

創(chuàng)建APIG觸發(fā)器來開放接口

通常對于使用函數開發(fā)WEB 后端的場景,我們使用API 網關服務,來將函數開放出去供前端訪問。為函數在API網關上注冊API非常簡單,只需要在函數頁面上創(chuàng)建APIG觸發(fā)器:

注意:這里將后端超時時間設定為一個較大的時間,如60s,因為OpenAi的接口響應較慢。在北京4局點中,APIG服務有共享版,支持按需計費,若有較大的流量可以考慮購買APIG獨享實例。

圖:為GPT函數綁定APIG觸發(fā)器

APIG觸發(fā)器上的調用URL,可以直接用于向后端發(fā)送請求,該URL 為測試URL,每日僅可訪問1000次,可以點擊觸發(fā)器跳轉到APIG頁面綁定自己的域名。

托管前端頁面到OBS

  • 我們準備了一個簡單的前端,只需改下前端頁面配置的后端地址即可。
  • 創(chuàng)建一個OBS 桶,上傳前端文件

  • 配置OBS 桶靜態(tài)文件托管,將桶訪問權限設置為公共讀,并在靜態(tài)網站托管選項里配置默認首頁,將自己的域名指向訪問地址。

最后,通過訪問配置的域名訪問頁面,開始體驗!

至此,我們其實已經完成了整個簡單聊天系統(tǒng)的搭建,案例中我們使用了一個簡單的前端頁面,開發(fā)者也可以考慮集成到如VSCode插件,語音聊天機器人,微信公眾號等等。

更進一步,若想使用Serverless技術,開發(fā)更為完整,適合生產環(huán)境的應用,需要添加鑒權, 數據庫 連接等功能。 

四、為后端服務增加接口鑒權

以上我們已經基于FunctionGraph 函數創(chuàng)建了一個簡易聊天系統(tǒng)的后端的服務,但是該接口沒有任何鑒權,如果開放接口,所有用戶都可以訪問。

如果需要用戶登錄后才可以使用,如何做?一個思路是在原有業(yè)務代碼里增加鑒權,這里我們也可以考慮使用APIG自定義鑒權即APIG組合FunctionGraph 鑒權的形式。 一個新的解決方案,如下。

創(chuàng)建并配置APIG自定義鑒權函數

使用APIG 自定義鑒權有以下優(yōu)勢:

  1. 提升開發(fā)效率:鑒權與業(yè)務解耦,新增邏輯只需關注業(yè)務,無需引入鑒權;鑒權代碼集中而非分散在多個業(yè)務模塊,更新鑒權邏輯只需要更新鑒權模塊而非所有業(yè)務模塊;
  2. 降低成本:對于使用大規(guī)格函數進行后端服務的代碼,無效請求可以直接由較小規(guī)格的鑒權函數攔截,降低大中規(guī)格資源服務的運行成本;
  • 創(chuàng)建鑒權函數

和普通函數的創(chuàng)建流程一樣,只需要注意響應的格式,一個使用JWT 鑒權的簡單案例如下。 

  • 編輯接口,配置自定義鑒權

編輯對應的API,選擇自定義鑒權,選擇到我們創(chuàng)建的函數:

一個鑒權拒絕的示例如下:

創(chuàng)建授權函數

基于以上自定義鑒權模式,開發(fā)者可以組合自己已有的鑒權邏輯放到自定義鑒權函數中。如果進一步想基于FunctionGraph 創(chuàng)建一個 “登錄” 或token授權函數,可以考慮以下方案。

我們首先需要創(chuàng)建一個函數,該函數用于接收用戶登錄請求,然后去數據庫請求,判斷用戶合法則返回鑒權token。

  • 創(chuàng)建授權函數

創(chuàng)建一個普通的事件函數即可,一個簡單的示例如下,隨后可以為其創(chuàng)建APIG 觸發(fā)器。 

注意,如果需要函數訪問VPC里的資源,如本例中的RDS,需要在函數頁面配置RDS所在的VPC。

五、“ChatGPT”的升級和“運維

日志與監(jiān)控

使用函數,系統(tǒng)會自動收集用戶打印在控制臺的日志,用戶無需處理日志落盤,收集或直接上報。對于每一條請求日志,F(xiàn)unctionGraph 還會顯示請求執(zhí)行耗時,使用內存及請求狀態(tài)。

用戶可以基于關鍵詞,請求狀態(tài)進行過濾和檢索。 

圖:函數用戶日志頁面

同時,平臺自動收集函數運行指標,如調用次數,運行時間,錯誤次數,被拒絕次數,并發(fā)數等。

圖:函數監(jiān)控

版本迭代

在用戶更新函數代碼時,為保障“ChatGPT”業(yè)務穩(wěn)定運行,可以配置APIG觸發(fā)器的后端服務指向函數別名:

圖:函數別名

圖:FunctionGraph別名灰度版本