ChatGPT API介面程式設計基礎與使用技巧

2023-04-17 09:00:55

總結/朱季謙

趁著這週末空閒時間,在研讀完OpenAi官網檔案的基礎上,及時總結了這篇《ChatGPT API介面程式設計基礎與使用技巧》

本文大部分內容是圍繞程式設計方面,包括ChatGPT模型介面、影象生成介面、敏感資料攔截等,只有一小部分內容圍繞如何通過temperature調參優化使用提示技巧。


一、OpenAi Api呼叫庫

OpenAi開放了一系列模型介面API,包括ChatGPT、影象生成、音訊、檔案、敏感資料攔截等。

若要整合這些模型介面呼叫到我們開發的系統裡,可以通過多種程式語言的HTTP請求與openai API互動。目前OpenAi API支援多種程式語言呼叫,各類程式語言對應的介面呼叫庫都能在OpenAi官網找到官方推薦的開源庫。

我在本文裡主要介紹Java、Go、Python、Node.js這四種,其餘具體依賴方式和使用,感興趣的童鞋可自行去官網進一步研究。

1.1、Java

官方推薦的是Theo Kanning開源的openai-java 。我用來整合到SpringBoot專案的依賴庫,正好也是用了這款openai-java。

1.1.1、首先,需要在Maven引入以下依賴——

<dependency>
    <groupId>com.theokanning.openai-gpt3-java</groupId>
    <artifactId>service</artifactId>
    <version>0.11.1</version>
</dependency>

1.1.2、安裝完成後,可以參考以下的程式碼案例,通過繫結金鑰來呼叫chatGPT模型——

@GetMapping("/ai")
public void sendMsg() throws InterruptedException {
    System.out.println("開始提問題~");
    //GPT_TOKEN即你的程式碼金鑰
    OpenAiService service = new OpenAiService(GPT_TOKEN,Duration.ofSeconds(10000));
    CompletionRequest completionRequest = CompletionRequest.builder()
         //使用的模型
            .model("text-davinci-003")
            //輸入提示語
            .prompt("你是一個工作助手,請幫忙設計一份活動策劃書")
            //該值越大每次返回的結果越隨機,即相似度越小,可選引數,預設值為 1,取值 0-2
            .temperature(0.5)
            //返回結果最大分詞數
            .maxTokens(2048)
            //與temperature類似
            .topP(1D)
            .build();
    service.createCompletion(completionRequest).getChoices().forEach(System.out::println);
    Thread.sleep(6000);
}

需要注意的是,若是部署在有"魔法代理"的Linux雲服務商,程式碼需要相應做一下調整,否則是無法存取到ChatGPT的,只會出現以下異常提示:

java.net.ConnectException:Failed to connect to api.openai.com/2a03:2880:f10c:283:face:b00c:0:25de:443]

當日我在這個問題上就踩了一個坑。

解決的辦法很簡單,只需要做以下調整——

public void send1Msg() throws InterruptedException {

        System.out.println("開始提問題~");
        //需要額外設定一個能存取chatGPT的魔法存取代理
        ObjectMapper mapper = defaultObjectMapper();
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8889));
        OkHttpClient client =  defaultClient(GPT_TOKEN,Duration.ofSeconds(10000))
                .newBuilder()
                .proxy(proxy)
                .build();
        Retrofit retrofit = defaultRetrofit(client, mapper);
        OpenAiApi api = retrofit.create(OpenAiApi.class);

    //將設定的代理傳給OpenAiService即可
        OpenAiService service = new OpenAiService(api);
        CompletionRequest completionRequest = CompletionRequest.builder()
                .model("text-davinci-003")
                .prompt("你是一個工作助手,情幫忙設計一份活動策劃書,設計一份活動策劃書")
                .temperature(0.5)
                .maxTokens(2048)
                .topP(1D)
                .build();
        service.createCompletion(completionRequest).getChoices().forEach(System.out::println);
        Thread.sleep(6000);
}

1.2、Go

官方推薦的是sashabaranov開源的go-gpt3 。

1.2.1、需要先安裝以下依賴包——

go get github.com/sashabaranov/go-openai

1.2.2、該開源專案提供的參考案例如下——

package main
import (
 "context"
 "fmt"
 openai "github.com/sashabaranov/go-openai"
)
func main() {
 client := openai.NewClient("your token")
 resp, err := client.CreateChatCompletion(
  context.Background(),
  openai.ChatCompletionRequest{
   Model: openai.GPT3Dot5Turbo,
   Messages: []openai.ChatCompletionMessage{
    {
     Role:    openai.ChatMessageRoleUser,
     Content: "Hello!",
    },
   },
  },
 )
 if err != nil {
  fmt.Printf("ChatCompletion error: %v\n", err)
  return
 }
 fmt.Println(resp.Choices[0].Message.Content)
}

1.3、Python

先下載Python版本的open庫——

$ pip install openai

安裝完成後,可以參考以下的程式碼案例,通過繫結金鑰來呼叫chatGPT模型——

import os
import openai

# Load your API key from an environment variable or secret management service
openai.api_key = os.getenv("OPENAI_API_KEY")

response = openai.Completion.create(model="text-davinci-003", prompt="Say this is a test", temperature=0, max_tokens=7)

1.4、Node

先下載Node版本的openai庫——

$ npm install openai

安裝完成後,可以參考以下的程式碼案例,通過繫結金鑰來呼叫chatGPT模型——

const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion({
  model: "text-davinci-003",
  prompt: "Say this is a test",
  temperature: 0,
  max_tokens: 7,
});

二、金鑰認證

OpenAi API是需要使用API金鑰進行認證存取。金鑰獲取方式,需要登入https://platform.openai.com/account/api-keys頁面。

接著點選【Create new secret key】生成一個新的金鑰,需要注意一點是,該金鑰生成時就得儲存下來,否則過後是無法再進行檢視的,例如,我的金鑰庫裡先前已有一條金鑰,但現在無法再去確定這條金鑰是什麼了。

順便提一點是,chatGPT是有免費額度的,呼叫API會消耗掉這些額度,我們可以在點選左邊選單【Usage】檢視——

在呼叫OpenAi的API請求時,需要在HTTP請求報頭中包含該API金鑰,例如——

Authorization: Bearer OPENAI_API_KEY

三、GPT請求設定

官方提供了一個curl通過金鑰呼叫API的請求案例,需要將案例裡的$OPENAI_API_KEY替換為自己的API金鑰,在開啟了代理的伺服器上執行,可以基於該案例測試伺服器是否能正常呼叫到ChatGPT——

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
     "model": "gpt-3.5-turbo",
     "messages": [{"role": "user", "content": "這是一個測試請求!"}],
     "temperature": 0.7
   }'

我在自己的伺服器上執行了,返回結果如下——

這個請求表示,查詢gpt-3.5-turbo模型完成文書處理,提示語為"這是一個測試請求!",響應結果如下——

{
 "id": "chatcmpl-75U8z1PVwDb0pA0EPhOMZVC1q7q11",
 "object": "chat.completion",
 "created": 1681541869,
 "model": "gpt-3.5-turbo",
 "usage": {
  "prompt_tokens": 14,
  "completion_tokens": 46,
  "total_tokens": 60
 },
 "choices": [{
  "message": {
   "role": "assistant",
   "content": "您好,這是一個回覆測試請求的資訊。請問您有什麼需要測試的具體內容或問題嗎?我會盡力幫助您解決問題。"
  },
  "finish_reason": "stop",
  "index": 0
 }]
}

Request body各欄位說明——


四、開發中新增敏捷資訊稽核層

首先得提一下2023年4月11日網信釋出的一份《生成式人工智慧服務管理辦法(徵求意見稿)》,裡面第四條明確表示,生成式人工智慧演演算法或服務應當遵守法律法規的要求,尊重社會公德、公序良俗。這就意味著,未來在使用這類Ai介面進行輸入/輸出時,必須針對內容進行違規內容資訊的過濾。

其實OpenAi有針對這塊內容稽核提供了開放的API介面,可以免費使用。

若想在聊天API的輸出中新增一個敏捷資訊攔截層,就可以在輸入/輸出資訊時,呼叫該介面。例如,存在這樣一份API介面呼叫案例——

curl https://api.openai.com/v1/moderations \
  -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{"input": "測試一句話"}'

響應返回內容如下——

{
 "id": "modr-75k0nHCOc0SR88t9xCNBHctPDMO8d",
 "model": "text-moderation-004",
 "results": [{
  "flagged": false,
  "categories": {
   "sexual": false,
   "hate": false,
   "violence": false,
   "self-harm": false,
   "sexual/minors": false,
   "hate/threatening": false,
   "violence/graphic": false
  },
  "category_scores": {
   "sexual": 0.00012780998076777905,
   "hate": 0.00013749735080637038,
   "violence": 1.4757171129531343e-07,
   "self-harm": 5.410008441231184e-09,
   "sexual/minors": 1.5541245375061408e-06,
   "hate/threatening": 6.1530336381565576e-09,
   "violence/graphic": 2.9580141003293647e-08
  }
 }]
}
  • flagged:如果模型將內容屬於違反OpenAI的使用策略,則設定為true,否則為false。
  • categories:包含每個類別二進位制使用策略違反標誌的字典。對於每個欄位值,如果模型將相應類別標記為違規則該值為true,否則為false。
  • category_scores:包含模型輸出的每個類別原始分數的字典,表示模型是否相信輸入了違反OpenAI對類別的策略。該值介於0和1之間,其中值越大表示置信度越高。注意一點是,分數不應被解釋為概率。

categories和category_scores具體欄位值對應的說明如下表格所示——

官方表示目前該稽核介面仍在不斷努力提高分類器的準確性,特別是仇恨、自殘和暴力等內容的分類。值得注意一點是,對非英語語言的支援目前是有限的,也就是說,中文的稽核支援比較有限。

除了使用OpenAi提供的輸入/輸出資訊稽核介面,還可以開發敏感詞過濾系統,將傳給ChatGPT以及響應返回的資料,進行敏感詞過濾。

四、模型呼叫

4.1、模型列表

OpenAi提供了多種模型,可以通過執行以下查詢指令,查詢出API支援的模型型別——

curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY"

出現出來的結果如下,應該有數十個模型,我用的最多是gpt-3.5-turbo,這是目前比較標準的型號版本——

{
  "data": [
     {
      "id": "text-davinci-003",
      "object": "model",
      "created": 1669599635,
      "owned_by": "openai-internal",
      "permission": [...],
      "root": "text-davinci-003",
      "parent": null
    },

  {
      "id": "gpt-3.5-turbo",
      "object": "model",
      "created": 1677610602,
      "owned_by": "openai",
      "permission": [...],
      "root": "gpt-3.5-turbo",
      "parent": null
    },
    .....
  ],
  "object": "list"
}

4.2、查詢指定 GPT模型詳情

可以基於以上模型類表介面,查詢出具體模型範例的詳情,包括模型的基本資訊、所有者及許可權等——

curl https://api.openai.com/v1/models/gpt-3.5-turbo \
  -H "Authorization: Bearer $OPENAI_API_KEY"

查詢出gpt-3.5-turbo的模型詳情如下——

{
  "id": "gpt-3.5-turbo",
  "object": "model",
  "created": 1677610602,
  "owned_by": "openai",
  "permission": [
    {
      "id": "modelperm-BmdmcAa1aQwToDxri3DFbZw9",
      "object": "model_permission",
      "created": 1681343255,
      "allow_create_engine": false,
      "allow_sampling": true,
      "allow_logprobs": true,
      "allow_search_indices": false,
      "allow_view": true,
      "allow_fine_tuning": false,
      "organization": "*",
      "group": null,
      "is_blocking": false
    }
  ],
  "root": "gpt-3.5-turbo",
  "parent": null
}

GPT-3.5模型可以理解和生成自然語言或程式碼,在GPT-3.5版本當中,最有能力和最具成本收益的模型是GPT-3.5-turbo,它是基於原有的3.5版本模型進行的迭代優化,可以更好地完成傳統任務。目前最新模型是GPT-4,具有更先進的常識和推理能力,但還沒有開放免費API介面。

以下是GPT-3.5模型列表介紹——

官方推薦使用GPT-3.5-turbo而不是其他GPT-3.5模型,因為它的成本更低。gpt-3.5-turbo的效能與text-davinci-003相似,但每個token的價格是它的10%,官方推薦在大多數情況下使用gpt-3.5-turbo。

五、影象生成呼叫

給定一個提示和/或一個輸入影象,模型會生成一個新的影象,例如,我想讓它畫一隻胖貓——

curl https://api.openai.com/v1/images/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "prompt": "畫一隻可愛的大胖貓",
    "n": 2,
    "size": "1024x1024"
  }'

然後,它確實給我畫了兩張圖——

{
  "created": 1681547551,
  "data": [
    {
      "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-LqdibnOuIlW8xc7Lfh2REsXo/user-6D0yIziBFiX73mCUwNwOwczJ/img-jKdFuRLINlkCeFL1QCWFZtId.png?st=2023-04-15T07%3A32%3A31Z&se=2023-04-15T09%3A32%3A31Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-04-15T08%3A28%3A22Z&ske=2023-04-16T08%3A28%3A22Z&sks=b&skv=2021-08-06&sig=Rbe8x3ZdEcoScQOXrkxGAe1G8rGOrO%2B4wzmzZwotP68%3D"
    },
    {
      "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-LqdibnOuIlW8xc7Lfh2REsXo/user-6D0yIziBFiX73mCUwNwOwczJ/img-00FKmNWnDm5p21CS89UPm56T.png?st=2023-04-15T07%3A32%3A31Z&se=2023-04-15T09%3A32%3A31Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2023-04-15T08%3A28%3A22Z&ske=2023-04-16T08%3A28%3A22Z&sks=b&skv=2021-08-06&sig=KVsxjwPIsJFC0cFEjRqVPrcckGxipp5BiiUmayPmqMM%3D"
    }
  ]
}

通過圖url連結,可以檢檢視片,若是在程式碼裡,可以直接丟給裡顯示出圖片。不過,我讓openai給我畫的是一隻胖貓,圖一我還能理解,但是,圖二,這個貓屁股著實有些離譜了(自帶