摘要:在國內使用ChatGPT有些不便,是否可以基於OpenAI開放的API做一個給自己或者同事們使用的聊天機器人,甚至整合到更多的場景….
本文分享自華為雲社群《使用 FunctionGraph 快速構建自己的“ChatGPT”》,作者:ChatGPT 、果寶、歷川。
一、背景
ChatGPT是一個基於GPT-3模型的聊天機器人,可以與使用者進行自然、流暢和有趣的對話。ChatGPT可以理解和使用多種語言,如英語、中文、日語、西班牙語、法語或德語;還可以根據使用者的興趣和需求,提供相關建議和創意內容,如詩歌、故事、程式碼、歌詞等。ChatGPT是一個強大而靈活的工具,可以用於娛樂、學習或工作。
但是在國內使用ChatGPT有些不便,是否可以基於OpenAI開放的API做一個給自己或者同事們使用的聊天機器人,甚至整合到更多的場景…. 效果如下:

二、方案選型
說幹就幹,我們先從做一個自己的機器人開始,首先我們從OpenAI獲取用於鑑權的秘鑰。

然後寫一個請求OpenAI介面的程式碼,並寫一個web服務介面開放出去,再搭配一個互動用的前端即可。看起來是1小時的工作量,但是如何部署這個服務呢? 購買一個雲伺服器再安裝環境或者配置容器也太麻煩了,於是我問了ChatGPT:

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

其中,
- 物件儲存服務OBS:用於託管前端頁面
- FunctionGraph : 用於響應前端請求,執行程式碼向OpenAI傳送問題
- API閘道器: 對外開放呼叫函式的API
注:“函式” 是指客戶部署在FunctionGraph上的程式碼,它可以是一個或多個檔案組成的程式,甚至編譯好的二進位制檔案。 如Python 指令碼檔案,Java的jar 包。
三、開發並部署聊天應用
3.1 建立FunctionGraph函式處理使用者提問的請求
首先建立並開發FunctionGraph函式,開啟華為雲FunctionGraph 產品頁面,由於只有一個簡單的問題查詢介面,這裡我們選用事件函式 使用Python 3.9 執行時。

注:事件函式,可以由某類事件觸發函式執行,如使用者對該函式傳送了HTTP請求,關聯到該函式的訊息佇列裡產生了新訊息,都會自動觸發函式執行。
對於事件函式,通常程式入口方法(這裡是 handler)會有兩個引數:
- event 引數: 包含觸發使用者函式的事件的相關資訊。HTTP請求也是一種事件,event裡會包含請求的body header 等;
- context 引數: 呼叫平臺的相關能力,如獲取在函式配置裡設定的加密環境變數等

圖:FunctionGraph 函式原始碼
上圖為本次呼叫的入口方法handler(),在函式中,我們:
- 從event 裡取得請求的引數 prompt
- 呼叫OpenAI 的介面Python SDK,向OpenAI 傳送請求, (示例裡我們使用text-davinci-003模型 [1] https://platform.openai.com/docs/model-index-for-researchers#footnote-2)
- handler 方法中我們使用了 context 獲取訪問OpenAI的key(上圖29行) ,獲取前需要在函式上配置對應環境變數,如下圖所示:

圖:函式配置環境變數
注:示例中我們使用了OpenAI的sdk ,也可以將sdk放在函式程式碼裡一起上傳,或利用函式的依賴管理能力,透過新增依賴的方式實現:

圖:函式配置依賴
在編輯好程式碼後,只需要點選部署按鈕即可完成部署。
3.2 建立APIG觸發器來開放介面
通常對於使用函式開發WEB 後端的場景,我們使用API 閘道器服務,來將函式開放出去供前端訪問。為函式在API閘道器上註冊API非常簡單,只需要在函式頁面上建立APIG觸發器:

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

圖:為GPT函式繫結APIG觸發器
APIG觸發器上的呼叫URL,可以直接用於向後端傳送請求,該URL 為測試URL,每日僅可訪問1000次,可以點選觸發器跳轉到APIG頁面繫結自己的域名。
3.3 託管前端頁面到OBS
- 我們準備了一個簡單的前端,只需改下前端頁面配置的後端地址即可。
- 建立一個OBS 桶,上傳前端檔案

- 配置OBS 桶靜態檔案託管,將桶訪問許可權設定為公共讀,並在靜態網站託管選項裡配置預設首頁,將自己的域名指向訪問地址。


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

至此,我們其實已經完成了整個簡單聊天系統的搭建,案例中我們使用了一個簡單的前端頁面,開發者也可以考慮整合到如VSCode外掛,語音聊天機器人,微信公眾號等等。
更進一步,若想使用Serverless技術,開發更為完整,適合生產環境的應用,需要新增鑑權,資料庫連線等功能。
四、為後端服務增加介面鑑權
以上我們已經基於FunctionGraph 函式建立了一個簡易聊天系統的後端的服務,但是該介面沒有任何鑑權,如果開放介面,所有使用者都可以訪問。
如果需要使用者登入後才可以使用,如何做?一個思路是在原有業務程式碼裡增加鑑權,這裡我們也可以考慮使用APIG自定義鑑權即APIG組合FunctionGraph 鑑權的形式。 一個新的解決方案,如下。

4.1 建立並配置APIG自定義鑑權函式
使用APIG 自定義鑑權有以下優勢:
- 提升開發效率:鑑權與業務解耦,新增邏輯只需關注業務,無需引入鑑權;鑑權程式碼集中而非分散在多個業務模組,更新鑑權邏輯只需要更新鑑權模組而非所有業務模組;
- 降低成本:對於使用大規格函式進行後端服務的程式碼,無效請求可以直接由較小規格的鑑權函式攔截,降低大中規格資源服務的執行成本;
- 建立鑑權函式
和普通函式的建立流程一樣,只需要注意響應的格式,一個使用JWT 鑑權的簡單案例如下。

- 編輯介面,配置自定義鑑權
編輯對應的API,選擇自定義鑑權,選擇到我們建立的函式:

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

4.2 建立授權函式
基於以上自定義鑑權模式,開發者可以組合自己已有的鑑權邏輯放到自定義鑑權函式中。如果進一步想基於FunctionGraph 建立一個 “登入” 或token授權函式,可以考慮以下方案。
我們首先需要建立一個函式,該函式用於接收使用者登入請求,然後去資料庫請求,判斷使用者合法則返回鑑權token。
- 建立授權函式
建立一個普通的事件函式即可,一個簡單的示例如下,隨後可以為其建立APIG 觸發器。

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

五、“ChatGPT”的升級和“運維”
5.1 日誌與監控
使用函式,系統會自動收集使用者列印在控制檯的日誌,使用者無需處理日誌落盤,收集或直接上報。對於每一條請求日誌,FunctionGraph 還會顯示請求執行耗時,使用記憶體及請求狀態。
使用者可以基於關鍵詞,請求狀態進行過濾和檢索。

圖:函式使用者日誌頁面
同時,平臺自動收集函式執行指標,如呼叫次數,執行時間,錯誤次數,被拒絕次數,併發數等。

圖:函式監控
5.2 版本迭代
在使用者更新函式程式碼時,為保障“ChatGPT”業務穩定執行,可以配置APIG觸發器的後端服務指向函式別名:

圖:函式別名


圖:FunctionGraph別名灰度版本
擁抱Serverless,釋放生產力,函式工作流 FunctionGraph
