見出し画像

ChatGPTとOpenAIのAPIを使った、サーバサイドのシステムを構築したよ【AIタスクマスター】

この記事では、ChatGPTを駆使してサーバサイドのコーディング、構築した際の私見などをまとめています。

主に、すっかり最近のマイブームになっている、タスク管理のWEBサービスを具体例としています。

失敗談もまとめていますので、同様にしてサービスを構築したい方、提供したい方にはなにか発見があるかもしれません。

興味が無いよ、って方は「補足:ブラウザのデバッグを知ってどうするの、結局一般人に必要なの?」を見ておくことで、今後ある種の詐欺に遭わずにすむかもしれません。


意図しない挙動

こちら、最近気付いたことですが、箇条書きにせずに1行である程度複雑なタスクを連携すると、細分化してくれるようです。
こちら意図した挙動ではありませんが、AI側で察してやってくれるようです。

デパートに行くまでの段取りを組んでくれます。

なので、工程の段取りを組むことが苦手な人には、案外使えるかもしれません。

AIならではだなと思いますが、ここの実装ですが、後述する「めんどくさい処理はAIで」でも触れています。

プロンプト

以下に処理からぶっこ抜いて連携します。
これだけではありませんが、記事中にあるロジック、ソース、プロンプトは自由に使っていただいて構いません。その際には、可能な限り、どこからの引用かを明記していただければと思います。

$prompt = "あなたはタスク管理のエージェントとして振る舞います\n" .
"以下のタスクを実行します。どのような順序で実行したら最適でしょうか\n" .
"必要に応じてタスクを並び替え、順序を示したの後に理由も説明してください\n" .
"また、1つのタスクに対する理想的な時間配分も意識してください\n" .
"必ず例のように日付と時刻を入れてください\n" .
"例を以下にあげます。\n" .
"1.2024.01.01 12:00-12:30 メールを確認する\n" .
"2.2024.01.01 12:30-14:00 本を読む\n" .
"理由\n" .
"1.メールの確認は、重要な連絡や緊急のタスクがないか確認するために最初に行うべきです。\n" .
"2.自己研鑽、教養を身につける上で読書は重要です。\n\n" .
"順序を示してほしいタスクは以下です。タスクは省略せずに必ず割り当ててください。\n" .

プロンプト

尚、これは今時点の内容なので、今後変更する可能性はあります。
実際、これだけの長文を都度連携するとコストがかかります。英文にしたり、もっと必要最低限にしても動くようにすべきだと考えます。
それこそ、プロンプトエンジニアリングとしての腕の見せ所でしょう。

加えて、プロンプトインジェクションに対する処理も加えるべきでしょう。これについてはセキュリティの都合上省略します。

とんでもない実装

このWEBサービスでは、ユーザが入力した内容をOpenAIのAPIを通じて処理した後に、結果を表示しますが、その後ファイル変換を行う際にも、OpenAIのAPIを通じて処理されています。

初期の実装では、ここで表示されている情報をそのままに送信していました。
これは、つまり利用者が好き勝手な内容を送信出来たことを意味します。

PCのブラウザにはデバッグ機能が存在します。
この機能を使うことで、内容を改竄し、そのまま送信出来た問題がありました。
通常のWEBサービスでこれはあり得ません。なぜこんな実装をしていたのかというと、単にサーバ側で可能な限り情報を持ちたくなかったからです。

しかし、前述したように、好き勝手な情報を送れるのはマズいため、やむを得ずサーバ側の一時ファイル(3分だけ保持される)から送信するようにしています

補足:ブラウザからのデバッグのやり方

ブラウザに搭載されているデバッグ機能は、何かWEBサービスで問題が起きた際に解析するために有用です。
尚、この機能を使うことに違法性はありません。意図的に、何らか改竄をして、WEBサービスに損害を与える行為をした場合には、この限りではありませんが、通常、まともなサービスであれば、サーバ側で弾くはずです。
しかし、改竄を試みる等は、自分が作成したWEBサービスだけにしましょう。万が一もあるので。

以下、safariを例にご紹介しますが、Chromeやその他のブラウザでも同様の機能があります。

1.デバッグしたいページで左クリックを押し、要素の詳細を表示します。

macのトラックパッドであれば、2本指で押し込んだ際に表示されるメニューです。

2.下部に以下のような表示が出てきますが、そうしたら、赤枠で囲われた照準のようなマークを押して、検証したい要素にカーソルを持って行き、クリックします。

要素タブには、実際に表示している画面のHTMLで記述された要素が見られるので、直接そこに移動しても大丈夫です。

3.今回であれば、変更したい箇所でダブルクリックをし、適当に置き換えてみます。

例えば、フルマラソンをする、に置き換えると、表示上もそう変わりますね🏃‍♂️

初期の実装では、この状態でICS変換をすると、そのままICSファイルにも変更が適用されていました。(今は修正されています。)

補足:ブラウザのデバッグを知ってどうするの、結局一般人に必要なの?

例えば以下のような画面を見たことは無いでしょうか。

実際の銀行のWEBサービスだと思ってください

口座残高がいっぱいあって良いですね!
これも、先ほど述べたデバッグ機能を使えば改竄が容易です。なのでよく、稼げるよ!と紹介されている何かしらの記事において、その証拠、根拠としてこういったスクリーンショットがありますが、何ら意味を為さないのです。

国家予算を超えてやる💰

当然ですが、ここをいくら増やしても虚しくなるだけです。実際の銀行に預けているお金が増えることはありません。

では、これが何の意味を為すのかですが、見せたくない情報をマスキングすることに役立ちます。
例えば、何らかのWEBサービスをスクリーンショットにとって、やり方を共有したいとき等にも有用です。

先ほどの画面にある、山田太郎様のところを、同様に変更してあげる事で、誤って本名を全世界に晒すことを防げます。

一応書いておきますが、何でもそうですが悪意を持って使用した場合、最終的に法律により罰せられる可能性があるのでご注意ください。

めんどくさい処理はAIで

話を戻しまして、本WEBサービスの面倒臭い処理は基本的にOpenAIのAPIに丸投げしています。
具体的に、ICS変換をかける際には、「ICS変換してよ」とAPIに投げることで実現しています。

メリットとしては、このロジックの開発が不要になります。
通常、ICS変換を実現するためには、渡されてきた情報を解析して変換する、そこそこ複雑なロジックを組まないといけませんが、それが不要になります。

デメリットとしては、作成する都度、API使用のコストが発生します。

こちら、見極めのポイントだと思っていて、とにかく速くリリースしたい時には、工数がかかる開発を切り出して、そこはもうOpenAIのAPIにぶん投げるのも手だと考えています。
その後で、そのロジックを開発して差し替えれば良いのでは無いかと考えています。

エモいデザイン?

本WEBサービスでは、やたらと絵文字が使われており、一部の世代からは違和感を感じますが、一応昨今の流行を意識したつくりになっています。

自分はもう若者では無いので、ズレている可能性はありますが、

  • 「。」を文末に使用しない

  • !は許容されるが、絵文字の❗は使用してはいけない

  • 絵文字を重ねて使用してはいけない

が今の文化のルールだそうです。

これらを踏まえて、ChatGPTに作成してもらったのが、あの文章です。

多分、自分が意識的に主流の書き方をするより、センスが良いのでは無いでしょうか。

また、下部には懐かしの「リンクフリーです」という文言もあります。
これも意図したもので、古い文化を持ってくることでエモさを感じるそうです。(ズレているかもしれませんが。)

いずれにせよ、作成するうえでChatGPTに文章全体を連携して、整えてもらうことは、やはりある一定は有用では無いかと思います。

補足:このデザインに意味はあるのか

厳密に成果を測定したい場合は、ABテストを実施してみるのも有用でしょう。
アンケートを設置しても良いですが、わざわざそれを回答してくれる人もそういないでしょうし、実際に表示された結果から、どのような使われ方がされているかを測定してみるとはっきりと分かります。(今回自分が作成したものには実装しておりません。)

ABテストは、二つのバージョン(AとB)を比較する実験的手法です。例えば、ウェブサイトのデザイン変更を考えている際に活用されます。既存のデザインをA、新しいデザインをBとし、これらをランダムに異なるユーザーグループに表示します。その後、訪問者の行動を分析し、どちらのデザインがより高いコンバージョン率(購入率やサインアップ率など)を達成するかを検証します。この方法は、直感ではなくデータに基づいて意思決定を行うのに役立ち、ウェブサイトの効果を最大化するのに有効です。ABテストは、マーケティング、製品開発、ウェブデザインなど様々な分野で利用されています。

ABテストとは(ChatGPTより)

バグってた

これは単なる自分の反省ですが、問題ないと思っていた箇所がバグっていたこともありました。

1.構成管理がフォルダに戻った

折角Saucetreeを最近インストールしたのに、フォルダ管理をしています。
これもこれで悪くはないですが、修正された箇所が分かりにくいのと、何より意図しない修正が紛れ込む危険性があります。

このように管理されています。
異なるプロジェクトですが、Saucetree等からgit管理を行う場合、修正された内容の追跡も容易ですし、戻すのもまた容易です。何より、レビューがしやすいです。

2.テストの範囲

リリース(公開)する前には当然テストをしますが、その都度全機能をテストするわけにはいきません。
今回、自分が作成したサービスの範囲でなら、全ての条件をやっても大した負担にはなりませんが、通常は修正した範囲だけであったり、代表として、1つだけ流れで試験するものです。

自分の場合、この辺の計画が今回は杜撰でした。
試験項目の作成も、ChatGPTはお手の物なので、きちんと作ってもらって、テストするというのは大切です。サボらないようにしましょう。

まとめ

今回、サーバサイドの開発(といってもPHPだけですが)は初めてで、JavaScriptによる抑止と、サーバ側での抑止を実装する、という経験は新鮮でした。

例えば、ユーザーが入力した後に、5秒待ってねとする処理は以下のように実現しています。

JavaScript

    // 送信ボタンを取得
    var submitButton = document.querySelector("button[type='submit']");

    // 送信ボタンを非活性化し、スタイルを変更
    submitButton.disabled = true;
    submitButton.classList.add("btn-inactive");

    // 5秒後に送信ボタンを再活性化
    setTimeout(function() {
        submitButton.disabled = false;
        submitButton.classList.remove("btn-inactive");
    }, 5000);

    // 送信処理後、convert-to-icsボタンを表示し、非活性化する
    var icsButton = document.getElementById("convert-to-ics");
    // icsButton.style.display = 'block';
    icsButton.disabled = true;
    icsButton.classList.add("btn-inactive");
    
    // 5秒後にconvert-to-icsボタンを再活性化
    setTimeout(function() {
        icsButton.disabled = false;
        icsButton.classList.remove("btn-inactive");
    }, 5000);

ただし、先ほどのデバッグ機能を使えば、これを改竄することもできます。

そこで、サーバ側、今回であればPHPの側でも時間を計測して抑止する処理を書いています。

PHP

// 連続リクエストのチェック
if (isset($_SESSION['last_request_time'])) {
    $elapsed = time() - $_SESSION['last_request_time'];
    if ($elapsed < REQUEST_INTERVAL) { 
        http_response_code(429); // HTTPステータスコードを設定
        echo json_encode(['error' => '連続したリクエストを検知しました。お手数ですが5秒ほどお待ちいただき、再度はじめから実行をお願いします。(サーバ)']);
        exit;
    }
}

であれば、果たしてJavaScriptで実装する必要があるのか、という話になりますが、JavaScriptでこういったロジックを実装しておくことは、ユーザーの使いやすさに帰結してきます。
使う都度、サーバから異常だよ、と返されるよりは親切に設計できます。
例えば、ボタンを非活性にする、つまり押せないようにしておくことで、利用者は今は使えない、と意識することができます。

ちなみに、この辺は後々ChatGPTから指摘されたところです。初期バージョンはひたすらサーバからエラーを返すようにしていました。

一応、サーバ側も構築するというのは、そこそこ難易度が高い作業では無いかと考えています。昨年、実はこういったサービスを作ろうと考えていましたが、挫折していました。
当時のChatGPTまたは、特に自分の力不足ですが、今こうしてとりあえず作る事が出来た、というのは極めて大きな成長を感じますし、嬉しい限りです。

ちなみに、採算度外視なので赤字ですが、まあ、勉強用の教材を買ったと思えば安いです。(自分の稼働は0円とし、ChatGPTもろもろ費用も考えないものとする🙄)

しかし、思い立ったことをこうやってサクッと実現できるのは大変素晴らしい時代です。原型となるものはおおよそ6時間でできましたし、今に至るまで総稼働は20時間もかかっていません。
まともにこれが作れるエンジニアを雇うと、ピンキリですが、1時間約5,000円として、10万円くらいかかってくるでしょうし、これプラス品質の担保であったり、保守等の維持費も考えると、人だけで50万〜100万は余裕でかかるでしょう。
そう考えると、凄い時代だなぁと思います。

当然と言えば当然ですが、まともにサービスを展開する上では、きちんと理解したエンジニアを雇うのは未だに有用です。ChatGPTは自ら動いてくれるわけでは無く、こちらが働きかけないと動いてくれません。
逆に、受け身のエンジニアはChatGPT未満になるでしょう。エンジニア側から、提案したり、自発的に動けないと厳しくなるなぁ、と痛感します。

おまけ:ChatGPTから気をつけておけよ、と言われた範囲

PHPを使用したサーバサイドの構築において、クライアントサイド(JavaScript)による入力制御だけに頼らず、サーバサイドでの入力チェックとバリデーションを徹底することは非常に重要です。ここでは、サーバサイドでのセキュリティ実装の要点と、その他の注意点について説明します。

### サーバサイドでの入力チェックとバリデーション

1. **入力検証(Validation)**:
- **型チェック**: 送信されたデータが予想される型(例:文字列、数値)であることを確認します。
- **フォーマットチェック**: データが正しいフォーマット(例:メールアドレス、電話番号)になっているかを確認します。
- **長さチェック**: 入力値の長さが指定の範囲内であることを確認します。

2. **データのサニタイズ(Sanitization)**:
- 不要または危険な文字を削除またはエスケープします。例えば、HTMLタグやSQLインジェクションに利用される特殊文字です。

3. **エラーメッセージの適切な管理**:
- 具体的すぎるエラーメッセージは攻撃者に情報を与える可能性があるので、一般的なエラーメッセージを使用します。

### セキュリティ対策

1. **SQLインジェクション対策**:
- プレースホルダやパラメータ化されたクエリを使用して、SQLインジェクション攻撃を防ぎます。

2. **クロスサイトスクリプティング(XSS)対策**:
- 出力時にデータを適切にエスケープすることで、XSS攻撃を防ぎます。

3. **クロスサイトリクエストフォージェリ(CSRF)対策**:
- トークンを使用して、フォームが正当なソースから送信されたものであることを確認します。

4. **セッション管理**:
- セッションIDの漏洩を防ぐために、セキュアなトランスポート層(HTTPS)を使用します。
- セッション固定攻撃を防ぐために、ログイン後にセッションIDを再生成します。

5. **エラーハンドリング**:
- エラー情報をユーザーに表示しないようにし、ログに詳細な情報を記録します。

### パフォーマンスとメンテナンス

1. **コードの最適化**:
- 効率的なアルゴリズムとクエリを使用して、サーバーの負荷を減らします。

2. **キャッシング戦略**:
- 頻繁にアクセスされるデータや静的リソースをキャッシュすることで、応答時間を短縮します。

3. **定期的なコードレビューとアップデート**:
- セキュリティパッチやライブラリのアップデートを定期的に行います。

### まとめ

PHPを用いたサーバサイドの開発においては、クライアントサイドの制

御だけではなく、サーバサイドでの入力チェックとバリデーションが不可欠です。さらに、SQLインジェクション、XSS、CSRFなどの一般的なセキュリティリスクへの対策を行うこと、効率的なコードの記述と定期的なメンテナンスも重要です。これらの対策を総合的に行うことで、安全で信頼性の高いWebアプリケーションを構築することが可能になります。

ChatGPTより


この記事が気に入ったらサポートをしてみませんか?