【Webアプリ自作】自前のAIチャットボットをローカルPHPサーバで爆速構築してみよう！

## カップラーメンを待つ間に自前のAIチャットWebアプリをローカルサーバに構築したい人向けの記事です。

今やChatGPT、Bingなどを使えば教えてくれるレベルのプログラムではありますが、コピペでそのまま使えるWebアプリの備忘録です。Webアプリを作ることができるPythonライブラリにStreamlitやGradioがありますが、GUIの自由度やカスタマイズ性に関しては限りがあるので、一から作ります。

ローカルサーバでデモアプリ的に実行することを前提としているため、**セキュリティ対策は無視しているので注意してください**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/9b850283-b5ad-c7c1-1a03-ac996d2b3e21.png)



# 最低限実現したいこと
- OpenAIのAPIなど、外部APIをたたいて動かすAIチャットWebアプリを作る
  - まずはOpenAIのAPIを利用する
  - 後で、FastAPIなどで別途立てたローカルサーバのAPIに置き換え可能にする
- CSSなどのデザインは後で載せていく（まずは真っ白な画面でよい）
- ローカルサーバで動かすので、**今はセキュリティ対策は考えない**

# 画面の要件
- いままでのチャット内容を画面にためていく
- 応答待ちの時は「生成しています」という文言を表示させる（非同期処理）

# 1分目. PHPをインストール

以下からPHPをインストールし、PATHを通しておきます（Windowsの場合）。

https://windows.php.net/

# 2分目. PHPの機能設定

今後の拡張を考慮し、マルチバイト文字列の扱いなど、よりPHPを使いやすくするために初期設定を変更します。以下のサイトを参考にさせていただきました。
https://memorva.jp/memo/dev/windows_php.ini_extension_mbstring.php

php.ini-productionをphp.iniとしてコピーし、中身に記述されているPHPの利用機能を変更します。以下のコメントアウト解除し、タイムゾーンを東京にセットします。

```ini
extension_dir = "ext"
extension = mbstring
extension = openssl
memory_limit = 512M
date.timezone = Asia/Tokyo
```

# 3分目. チャットWebアプリの実装

以下の３ファイルをUTF-8で保存してください。

画面はHTML、非同期処理はJavaScript(jQueryを利用)、APIを実際にたたくのはPHP、という構成です。

```html:index.html
<!DOCTYPE html>
<html>
<head>
    <title>Chat with GPT-3</title>
</head>
<body>
    <div class="chat-container">
        <div id="chat-output" class="chat-output"></div>
        <input id="chat-input" class="chat-input" type="text" placeholder="質問を入力..." />
        <button id="send-button" class="send-button">送信</button>
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="chat.js"></script>
</body>
</html>
```

```javascript:chat.js
$(document).ready(function() {
    $('#send-button').click(function() {
        var inputText = $('#chat-input').val();
        $('#chat-output').append('<div class="user-message">' + inputText + '</div>');
        $('#chat-input').val('');

        $('#chat-output').append('<div class="ai-message">生成しています...</div>');

        $.ajax({
            url: 'chat.php',
            type: 'POST',
            data: {
                'message': inputText
            },
            success: function(response) {
                $('.ai-message').last().text(response.trim());
            },
            error: function() {
                $('.ai-message').last().text('エラーが発生しました。');
            }
        });
    });
});
```

```php:chat.php
<?php
$openai_url = "https://api.openai.com/v1/chat/completions";
$api_key = "ここにOpenAI APIキーを入力してください";
$message = $_POST['message'];

$options = [
    'http' => [
        'method' => 'POST',
        'header' => [
            'Authorization: Bearer ' . $api_key,
            'Content-Type: application/json'
        ],
        'content' => json_encode([
            "model" => "gpt-3.5-turbo",
            "messages" => [
                [
                    "role" => "system",
                    "content" => "あなたはプロフェッショナルのAIアシスタントです。"
                ],
                [
                    "role" => "user",
                    "content" => $message
                ]
            ]
        ])
    ]
];

$context = stream_context_create($options);
$result = file_get_contents($openai_url, false, $context);

if ($result === FALSE) {
    /* エラー発生時の処理 */
    echo 'エラーが発生しました';
} else {
    $data = json_decode($result, true);
    file_put_contents("response.json" , $result); //レスポンスJSON確認用
    print_r($data['choices'][0]['message']['content']);
}
?>
```

# 4分目. PHPサーバを立てて実行する

3分待つタイプのカップラーメンであれば、この段階でできあがりました。少し麺をすすりながら、PHPサーバを立ててWebブラウザでアクセスしてみましょう。

```powershell: PowerShellで実行した場合
cd path/to/html # 3ファイルを作成したディレクトリに移動
php -S localhost:8000
```

ブラウザで`localhost:8000`にアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/773ca848-6119-786e-73f3-9fc0b889fe65.png)


画面は質素すぎますが、無事チャットができるようになりました。
あとはCSSでデザインを載せたり、PHP側の処理を追加したり、ローカルのLLMを使って推論するAPIを自前で用意したりして、自分だけのオリジナルWebアプリにしてみましょう！

ごちそうさまでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373557/0b3eb6d3-0d6d-75ba-3c0c-2d6053f7154e.png)