脱力駆動開発記

ゲームアプリを作るエンジニアの技術メモ

MENU

【ChatGPT/CloudFunctions】CloudFunctionsからChatGPTのAPIを呼ぶ

FirebaseのCloudFunctionsからChatGPTのAPIを呼び出します。 わかりやすくChatGPTのAPIと言っていますが、厳密には「OpenAIのCreate chat completionAPIを呼ぶ」になります。 どちらでも良いと思いますが、「ChatGPTのAPI」と言った方が通じやすそうではありますね。

前回の記事でAPIキーSecretManagerに設定して取得する方法をまとめましたが、その方法を使用します。

www.stmn.tech

そもそもなぜAPIキーを隠す必要があるのか?という話ですが、OpenAIのAPIは有料で結構高いです。 一番高いGPT-4モデルを使用すと1,000トークンあたり0.12ドル(約15.6円)かかります。 うっかりAPIキーが流出すると、すぐに上限まで実行されてしまう可能性があります。

呼ぶAPI

今回呼ぶChatGPT APIのURLは

https://api.openai.com/v1/chat/completions

です。 ドキュメントはこちらです。 platform.openai.com

今回はプロンプトはサンプルのままの"Say Hello!"(ハローと言え!)にしておきます。

コード

早速ですがコードです。TypeScriptで記述しています。

chat.ts

import superagent = require("superagent");
import functions from "firebase-functions";
import {defineSecret} from "firebase-functions/params";
import {Response, Request} from "express";
const apiKey = defineSecret('API_KEY');

export async function postChatCompletionApi(req:Request, res:Response) {
    try {
        const url = "https://api.openai.com/v1/chat/completions";
        const messages:Message[] = [];
        const prompt = 'Say Hello!';
        const systemPrompt:Message = {
            role: "system",
            content: prompt,
        };
        messages.push(systemPrompt);
        const request: ChatCompletionRequest = {
            model: "gpt-3.5-turbo", // GPT4を使う場合は gpt-4 を指定する
            messages: messages,
            temperature: 0.7, // 高ければ高いほどよりランダム性の高い回答が返ってくる
            max_tokens: 500, // トークン数の上限を指定する
        };
        const response =
            await superagent
                .post(url)
                .send(request)
                .set('Authorization', `Bearer ${apiKey.value()}`);
        res.status(200).send(response.body);
        // レスポンス返して
    } catch (e) {
        console.log(e);
    }
}

// ChatGPT API用の定義
type ChatCompletionRequest = {
    model:string,
    messages:Message[],
    temperature:number,
    max_tokens:number,
}
type Message = {
    role:string, // system,user,assistant
    content:string, // the contents of the message.
    name?:string, // Author
}

index.ts

import chat = require("./chat");

import {defineSecret} from "firebase-functions/params";
const apiKey = defineSecret('API_KEY');

const app = express();
app.use(express.json());
app.use(express.urlencoded({
    extended: true,
}));

app.post("/chat/call", async (req, res) => {
    await chat.postChatCompletionApi(req, res);
});

const api = functions
    .runWith({secrets: [apiKey]})
    .region("asia-northeast1").https.onRequest(app);

module.exports = {
    api,
};

CloudFunctionsの受け口としてexpressを使用していて、CloudFunctionsからAPIを叩く部分ではsuperagentを使用しています。

これで試しにローカルでCloud Functionsをデプロイして実行してみます。

自分はこういうAPIを呼ぶテストのときはPostmanを使用しています。

早速Postmanで実行してみると以下のようなレスポンスが返ってきます。

いい感じに返ってきていますね。これで、ChatGPTのApiKeyを隠した状態で実行できました。

「Hello! How can I assist you today?」

とのことです。

こちらは「Hello!と言え」としか言っていないのに、追加で「How can I assist you today?」と聞いてくるところに3.5みを感じます。

ということで以上です。次はUnityのクライアントからこのAPIを呼んでいきます。