三分鐘搭建一個自己的 ChatGPT (從開發到上線)

米開朗基楊發表於2023-03-13

原文連結:https://icloudnative.io/posts/build-chatgpt-web-using-laf/

影片教程:https://www.bilibili.com/video/BV1cx4y1K7B2/

OpenAI 已經公佈了 ChatGPT 正式版 API,背後的新模型是 gpt-3.5-turbo,這是 OpenAI 目前最先進的模型,響應速度更快,價格更便宜。

作為開發人員,我們還是希望透過 API 將 ChatGPT 和相關模型整合到自己的產品和應用中,尷尬的是,目前無法訪問 ChatGPT API,原因大家都懂得。於是網上出現了各種各樣的 API 反代服務,我們可以直接透過反代服務來變相訪問 ChatGPT API。

即使我們解決了 API 的訪問問題,還要準備一個開發環境,比如對於 Node.js 客戶端來說,需要準備一個 Node.js 環境。

有沒有一種簡單快捷的方法來呼叫 ChatGPT API 呢?

那當然是用 Laf 了。

Laf 是一個完全開源的一站式雲開發平臺,提供了開箱即用的雲函式,雲資料庫,物件儲存等能力,讓你可以像寫部落格一樣寫程式碼。

GitHub:https://github.com/labring/laf

如果你希望快速瞭解 Laf 的用法,可以參考這篇文章:三分鐘學會 Laf

言歸正傳,下面我們開始計時,三分鐘時間用 Laf 實現一個自己的 ChatGPT!

前提條件:你需要準備一個 ChatGPT 賬號並且生成一個 API Key (這一步可以問 Google )

雲函式教學

首先需要登入 laf.dev,然後新建一個應用。

點選開發按鈕進入開發頁面。

在 NPM 依賴皮膚中點選右上角的 +

然後輸入 chatgpt 並回車進行搜尋,選擇第一個搜尋結果,儲存並重啟:

重啟之後,自定義依賴項中便出現了 chatgpt。

然後就可以像我一樣新建一個雲函式名字叫 send,並寫入以下內容:

import cloud from '@lafjs/cloud'
export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })

  let res = await api.sendMessage('“雞你太美”指的是中國大陸哪位男藝人?給你個提示,他喜歡唱、跳、籃球、Rap')
  console.log(res.text)

  return res.text
}

API Key 是透過環境變數 CHAT_GPT_API_KEY 傳入的,所以我們還需要建立一個環境變數。點選左下角的設定圖示:

依次選擇「環境變數」--> 「新增環境變數」,輸入環境變數的名稱和值,然後點選「確定」,再點選「更新」,便會重啟應用。

現在點選右上角的「執行」,即可除錯執行。

Perfect!現在我們來試試新增追蹤上下文的功能。其實也很簡單,只需要在對話時傳入上一次對話的 ID 即可,程式碼如下:

import cloud from '@lafjs/cloud'
export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })

  let res = await api.sendMessage('“雞你太美”指的是中國大陸哪位男藝人?給你個提示,他喜歡唱、跳、籃球、Rap')
  console.log(res.text)

  // 傳入 parentMessageId 追蹤上下文
  res = await api.sendMessage('不對,他姓蔡,請重新回答', {
    parentMessageId: res.id
  })
  console.log(res.text)

  return res.text
}

執行一下看看:

好厲害,竟然兩次就答對了我的問題!

好了,現在才開始真的計時,因為剛剛是教學環節,不計入耗時?

雲函式

接下來我們就可以開始動手打造自己的 ChatGPT 了,首先把上一節的函式替換為下面的內容:

import cloud from '@lafjs/cloud'

export async function main(ctx: FunctionContext) {
  const { ChatGPTAPI } = await import('chatgpt')
  const data = ctx.body

  // 這裡需要把 api 物件放入 cloud.shared 不然無法追蹤上下文
  let api = cloud.shared.get('api')
  if (!api) {
    api = new ChatGPTAPI({ apiKey: cloud.env.CHAT_GPT_API_KEY })
    cloud.shared.set('api', api)
  }

  let res
  // 這裡前端如果傳過來 parentMessageId 則代表需要追蹤上下文
  if (!data.parentMessageId) {
    res = await api.sendMessage(data.message)
  } else {
    res = await api.sendMessage(data.message, { parentMessageId: data.parentMessageId })
  }
  return res
}

現在應該很好理解這個函式了吧?

前端

我們要實現的是 Web 版 ChatGPT,所以還需要一個前端頁面。首先需要安裝 Laf 的 SDK:

$ npm install laf-client-sdk

接下來,需要建立一個 cloud 物件:

import { Cloud } from "laf-client-sdk"; 

// 建立 cloud 物件 這裡需要將 <appid> 替換成自己的 App ID
const cloud = new Cloud({
  baseUrl: "https://<appid>.laf.dev",
  getAccessToken: () => "", // 這裡不需要授權,先填空
});

這裡我們看一下前端的核心程式碼,非常的簡單,就是把提問的內容和上下文 id 傳入雲函式就可以了。

async function send() {

// 我們提問的內容
const message = question.value;

let res;
// 與雲函式邏輯一樣,有上下文 id 就傳入
if (!parentMessageId.value) {
  res = await cloud.invoke("send", { message });
} else {
  res = await cloud.invoke("send", { message, parentMessageId: parentMessageId.value });
}

// 回覆我們的內容在 res.text 

// 這個是上下文 id
parentMessageId.value = res.id;
}

到這一步 我們已經可以發資訊給 ChatGPT 並且拿到回覆的訊息了。

我們只要稍微加億點點細節,就可以變成這樣:

加完這點細節之後,基本開發工作就完成了,接下來就是把專案上線分享給你的朋友,順便裝個杯。

說到上線我們現在應該要去買一臺伺服器安裝 Nginx,配置 Nginx,解析域名,繫結域名...

NO NO NO 我不允許你浪費年輕而美好的生命,life is short, you need laf ?

上線

開啟你的 Laf,點選儲存介面 --> 點選上方加號 --> 建立一個許可權為 readonly 的儲存桶(名字隨意)。

建立完之後,在你的前端專案中執行打包命令。我這裡用的是 npm run build

打包完畢之後找到打包好的 dist 資料夾,像我一樣把 dist 檔案裡面的所有東西都上傳到我們剛剛建立的儲存桶裡面,記住是原封不動的上傳哦,檔案就是檔案,資料夾就是資料夾。

上傳完畢之後,發現右上角有一個 “開啟網站託管”,點一下它!

點完之後出來一個連結,我們點選一下訪問看看是啥東西。

哦!我的老天鵝呀 這不就是我剛剛開發的專案嗎??

恭喜,到這裡你的專案已經上線了,快分享給你的好朋友吧!


相關文章