Blog スタッフブログ

システム開発

[ChatGPT]ChatGPT APIを使って会社紹介botを作ってみた

こんにちは、株式会社MIXシステム開発担当のBloomです。

3月2日にChatGPTのAPIが公開されました。以前書いた記事ではChatGPTにSwiftのコードを書いてもらいましたが、今回はAPIを利用して、弊社の紹介をしてくれるAI botを構築してみましょう。

実際にやってみた

まずはOpenAIプラットフォームからAPIキーを発行しましょう。

Account API-Keys- OpenAi API

では、実際にPHPからChatGPT APIを実行してみましょう。今回はcurlを利用してAPIをコールします。

<?php
header("Content-Type: application/json; charset=utf-8");

$json = file_get_contents("php://input");
$data = json_decode($json, true);
if( $data != null && isset($data['messages']) ){
    echo callChatGptApi($data["messages"]);
}
else {
    echo json_encode(['result' => false]);
}

function callChatGptApi($messages) {
    // $messagesは[["role": "user", "content": ユーザ入力], 
    // ["role": "assistant", "content": AI出力]]
    // の形式です。

    $api_key = "APIキー";
    $model = "gpt-3.5-turbo";
    // 最初にAIへ役割を与えるシステムメッセージです。この内容を詳細に書くほどより指向的なAI botになります。
    $system_content = <<< EOF
あなたは株式会社MIXで利用しているOpenAI ChatGPT APIテストのために確保されたAIです。
株式会社MIXはおもにシステム開発を行っている会社であり、アプリ開発、Web制作、Webデザインが主な業務です。
公式ホームページのURLは https://mixltd.jp/ です。
EOF;
    $system = ["role" => "system", "content" => $system_content];
    $contents = array();
    $contents[] = $system;
    foreach($messages as $message) {
        $contents[] = ["role" => $message["role"], "content" => $message["content"]];
    }

    $header = ["Authorization: Bearer ".$api_key,
        "Content-type: application/json"];

    $params = json_encode(
        ["messages" => $contents,
	    "model"=> "gpt-3.5-turbo"]);

    $curl = curl_init("https://api.openai.com/v1/chat/completions");
    $options = [CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => $header,
        CURLOPT_POSTFIELDS => $params,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => false];
    curl_setopt_array($curl, $options);
    $response = curl_exec($curl);
    $httpcode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
    return $response;
}
?>

JSON形式で受信したmessagesをもとにChatGPTAPIの実行結果をクライアントへ返却する原始的なAPIです。

また、ChatGPT APIへPOSTするパラメータは最低限に省略しています。詳細はこちらから確認してください。

このままこのAPIをコールするクライアント側アプリも実装して確認してみましょう。クライアント側のコードは一部を抜粋して掲載させていただきます。

一例として今回はSwift iOSアプリから利用しています。

import UIKit
struct Message: Codable {
    let role: String
    let content: String
}
struct ChatResponse: Codable {
    struct Usage: Codable {
        let prompt_tokens: Int
        let completion_tokens: Int
        let total_tokens: Int
    }
    struct Choice: Codable {
        let message: Message
        let finish_reason: String?
        let index: Int
    }
    let id: String
    let object: String
    let created: Int
    let model: String
    let usage: Usage
    let choices: [Choice]
}

class ViewController: UIViewController {
    // storyboard上で設置したメッセージ履歴表示用TableViewと入力用TextFieldです。
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var messageField: UITextField!

    // メッセージの履歴です。APIへは都度これまでの履歴の全てを送信する必要があります。
    var messages: [Message] = []
    
    // storyboard上で設置した送信ボタンから実行するメソッドです。
    @IBAction func sendTouchUpInside(_ sender: Any?) {
        guard let message = messageField.text, !message.isEmpty else { return }
        guard let message = messageField.text, !message.isEmpty else { return }
        let newMessage = Message(role: "user", content: message)
        messages.append(newMessage)
        // [Message]を受け取りpost、戻り値をChatResponse型へJSONデコードし渡すCodableを利用したAPI関数です。
        // APIの実装は以前の記事を参考にしてください。
        APIConnection.shared.postApi(param:  self.messages) { json in
            if let data = data {
                self.chatSucceed(response: json)
            }
        }
        messageField.text = ""
        messageField.resignFirstResponder()
        tableView.reloadData()
    }
    
    func chatSucceed(response: ChatResponse) {
        if let message = response.choices.first?.message {
            messages.append(message)
            tableView.reloadData()
        }
    }
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return messages.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let message = messages[indexPath.row]
        // Stroyboard上で設定したCellを利用しています。この部分の実装は適宜改変してください。
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: message.role)!
        let label = cell.viewWithTag(1) as! UILabel
        label.text = message.content
        return cell
    }
}

実行結果

これだけで簡単にAI botを実装することができました。

料金としてはここまでのやりとりのToken数合計が1036であるため、おおよそ0.28円前後になります。

過去のメッセージも送信する必要があるため、Token数は指数関数的に増加します。料金と相談して最大スレッド数を調整しましょう。Maxトークン数にも注意が必要です。

実際のサービスとして運用する場合はsystemメッセージをさらに詳細に記述したり、プロンプトインジェクションによる不適切な返答の回避のための対策が必要になるためご留意ください。

参考文献

Chat Completion – OpenAI API