ChatGPT同士でフィードバックさせながらシーケンスを書かせてみた
はじめに
開発のプロセスをどうすればAI化(自動化)できるかに最近は興味があります。
CICDは当然ですが、chatgptをはじめとした言語モデルで従来は自動化が難しかったプロセスを自動化あるいは省略化していきたいです。
現行のchatgptはまだ発展途上なので制限はありますが、どう活用すればいいかを考える一貫として、設計プロセスをchatGPTにやらせてみようと思います。
今回、chatgptで設計をやらせるにあたって、プロンプトエンジニアリング的なことを頑張る方向ではなく、フィードバックループという少し別のアプローチを試しみます。
GPT-4の所感
余談ですが、gpt-4になってから触ってみた感想として、因果関係を理解する能力が上がったように感じました。
例えば、以下のような問題を出した場合、gpt-3.5では全く的外れな回答でしたが、gpt-4では正確な解答をしてくれました。
筆者
以下の因果関係を仮定する
aならばbである
bならばcである
dならばcである
aならばdであるこの場合以下は正しいか
bでないならばcでない
ChatGPT(gpt-3.5)
与えられた因果関係を考えると、以下のような結論が導かれます。
- aならばbである
- bならばcである
- dならばcである
- aならばdである
これらの関係から、bでない場合はcでないという結論を導くことができます。
仮にbでない場合、1番目の関係によってaも成立しなくなります。したがって、4番目の関係によってdも成立しなくなります。そして、3番目の関係によってcも成立しなくなります。
結果的に、bでない場合にはcでないという結論が正しいです。
ChatGPT(gpt-4)
あなたが挙げた因果関係を見てみましょう:
- aならばbである
- bならばcである
- dならばcである
- aならばdである
これらの前提から、"bでないならばcでない"と結論付けることはできません。なぜなら、bが存在しなくても、dが存在すればcが存在する可能性があるからです(3つ目の前提から)。したがって、bが存在しないという事実だけでは、cが存在しないことを必ずしも意味しません。
一般的なプロンプトエンジニアリング
一般的なプロンプトエンジニアリングでは、質問を工夫する場合、以下のことに気をつけた方がいいとのことです。端的にいうと具体的で曖昧な表現を避けるということですね。
具体的な指示を与える:ChatGPTは指示に従って応答を生成しますので、具体的な指示を与えると良い結果が得られます。たとえば、「都市について説明してください」よりも、「パリの主な観光スポットについて詳しく説明してください」と指示した方が、具体的で詳細な情報を得ることができます。
コンテキストの強調:ChatGPTは以前のメッセージを基に回答を生成します。したがって、必要な情報が最近のメッセージに含まれていることを確認することが重要です。
意図の確認:もしChatGPTがあなたの意図を理解していないと思われる場合は、質問を再度行い、より具体的な指示を与えてみてください。
長い文章の使用:短い回答を避け、具体的な指示を与えるときには、詳細な情報を提供するために長い文章を使用することを検討してみてください。
テンプレートの使用:特定の種類の回答を求めている場合、テンプレートを提供すると良い結果が得られることがあります。例えば、「私が経営者であると仮定して、製品Xを市場に投入するための提案をしてください」と指示すると、ChatGPTはあなたの提供するテンプレートに従って答えを作成します。
フィードバックループの有効性
ここから本題です。
開発や設計のプロセスで、ChatGPT同士で自律的にフィードバックさせながら出力を改善するという方法は、探した感じではあまりいなさそうでした。(アイデア的に普通に誰かやってそうですが)
開発とは関係ないですが、歌詞の生成で、一つだけ同じことやってる人はいました。
このアイデアは有効かchatgptに聞いてところ、以下の回答でした。
あなたが提案しているようなフィードバックループは、ChatGPTの出力を改善する上で有用な手段になる可能性があります。一つのChatGPTインスタンス(chatgptA)が何かを作成し、それが他のインスタンス(chatgptB)によってレビューされ、そのフィードバックを基に元のインスタンス(chatgptA)が修正を行うというループは、出力の品質を改善し、より高度な内容を生成する可能性があります。
ただし、この手法にはいくつかの制限点があります:
- コンテキストの理解:各ChatGPTインスタンスは独立して動作し、他のインスタンスが何をしたかを理解する能力はありません。そのため、chatgptBがchatgptAの出力をレビューする際に、chatgptAの意図や背景情報を完全に理解することは困難です。
- 一貫性:ChatGPTは以前の応答を覚えていないため、一貫したフィードバックを提供する能力には限界があります。例えば、同じテキストをレビューするようにchatgptBに指示した場合、異なる時間点で生成されるフィードバックは異なる可能性があります。
- 深い理解と専門知識:ChatGPTは一般的な知識を持つAIであり、特定の専門分野の深い理解や専門的なフィードバックを提供する能力は限られています。
以上の点を考慮に入れつつ、このフィードバックループを試すことは、ChatGPTの出力を改善するための実験的なアプローチとして有用かもしれません。
一つ目のコンテキストの理解に関しては、別のプロセスになるので相手側の文脈は考慮されないので、まあその通りですが、相手側にフィードバックする際に必要なコンテキストを渡せばいいので、ある程度回避可能なデメリットかなと思います。
2つ目の一貫性についても同様ですね。
3つ目に関しては、その通りですね。まあエンジニア系の良質なネット文書は無限にあるので、かなりの深い専門性を獲得していても不思議ではないなという所感です。
フィードバックループを試してみる
さて、フィードバックループを試していきますが、まずは簡単なところからやってみたいと思います。
以下はよくあるログイン画面の仕様と使用する技術スタックをyamlで書いてものになります。(割と適当に書いてますmm)
仕様
feature:
- name: ログイン
flow:
- ログイン画面にアクセス
- メールパスワード入力
- ログインクリック
- (メールパスワードが一致する) ログイン画面に遷移
- (メールパスワードが一致しない) エラーメッセージを表示
技術
フロントエンド:
- フレームワーク: Vue.js
- デザイン: tailwindcss
- 言語: Typescript
- アーキテクチャ: MVVM
バックエンド(API):
- フレームワーク: Django
- 言語: python3.10
- アーキテクチャ: オニオンアーキテクチャ
インフラ:
- DB: Mysql8.0
- Cache: Redis
- 認証基盤: Auto0
上記の仕様と設計をもとにシーケンスを書いてもらうことにします。
以下はChatGPTとのやりとりです。
登場人物
- 筆者
- ChatGPT(設計担当)
- ChatGPT(レビュー担当)
以下やり取り
筆者
仕様
- 機能名: ログイン フロー: - ログイン画面にアクセス - メールパスワード入力 - ログインクリック - (メールパスワードが一致する) ログイン画面に遷移 - (メールパスワードが一致しない) エラーメッセージを表示
使用技術
フロントエンド: - フレームワーク: Vue.js - デザイン: tailwindcss - 言語: Typescript - アーキテクチャ: MVVM バックエンド(API): - フレームワーク: Django - 言語: python3.10 - アーキテクチャ: オニオンアーキテクチャ インフラ: - DB: Mysql8.0 - Cache: Redis - 認証基盤: Auto0
上記の設計から、一連のシーケンスをmermaidで作成して
ChatGPT(設計担当)
Mermaidを使用してログインのシーケンスダイアグラムを作成することができます。下記のようになります。
このシーケンスダイアグラムでは、ユーザーがまずメールとパスワードを入力し、ログインボタンをクリックします。Vue.jsクライアントは、DjangoサーバーにPOSTリクエストを送信します。次に、DjangoサーバーはAuthServiceを使用してユーザーを認証します。AuthServiceはMySQLデータベースと通信してユーザーの資格情報を検証します。
データベースからの検証結果に基づいて、AuthServiceはトークンを生成または例外を発生させます。その結果はDjangoサーバーに戻され、Vue.jsクライアントに送られます。最後に、Vue.jsクライアントはユーザーをホーム画面にリダイレクトするか、エラーメッセージを表示します。
なお、Mermaidの描画は使用しているツールや環境によっては表示できない場合があります。その場合は、適切なツールやウェブサービスを利用して表示してください。
ChatGPT(レビュー担当)
シーケンス図の全体的な流れは良く、アーキテクチャを表現しているように見えます。ただし、いくつかの箇所に対して以下のような提案や質問があります:
- ユーザーからのアクション表現: ユーザーからクライアントへのインタラクションが少し混乱を招く可能性があります。"Enter email and password"と"Click login"は両方ともユーザーアクションなので、一つのステップに統合しても良いかもしれません。さらに、"Trigger login event"はクライアントが行うアクションとするべきで、ユーザーが直接トリガーするものではありません。
- 認証基盤の位置: "AuthService (DjangoAuthService)"が存在しますが、同時に認証基盤としてAuth0も記述されています。この2つのサービスはどのように統合されるのでしょうか?それぞれの役割は何ですか?この点が図からは読み取れません。
- エラーハンドリング: 例えば、認証が失敗した場合、どのようなレスポンスが返されるのでしょうか?このプロセスは図に表現されているでしょうか?例外が発生した場合のフローも考慮すると良いでしょう。
- トークンの管理: トークンはどのようにクライアントに保存され、後続のリクエストにどのように使用されるのでしょうか?セッション管理についての詳細なフローを追加すると、図が更に明確になるでしょう。
ChatGPT(設計担当)
ご指摘いただいた通り、現在のシーケンス図は、ログインプロセスの全体的な流れを表していますが、いくつかの詳細が欠けています。以下に、提案と質問に対する回答を示します。
- ユーザーからのアクション表現: ご指摘の通り、ユーザーのアクションは「メールアドレスとパスワードを入力し、ログインボタンをクリックする」という1つのアクションとして表現することができます。そして、「ログインイベントをトリガーする」はクライアントが行うアクションであり、その表現を修正します。
- 認証基盤の位置: 図にAuth0の詳細を含めていない点、お詫び申し上げます。AuthServiceの中で、Auth0を用いた認証プロセスを行うと考えると良いでしょう。このため、「AuthService (DjangoAuthService)」の部分を「AuthService (DjangoAuthService with Auth0)」と修正します。
- エラーハンドリング: 現在の図ではエラーハンドリングについての情報が不足しています。AuthServiceで認証が失敗した場合、AuthServiceが例外を発生させ、その例外をDjangoサーバーが捕捉してエラーレスポンスを返すという流れを追加します。
- トークンの管理: 現在の図では、クライアントが認証トークンをどのように処理するかの詳細が含まれていません。クライアントがトークンをlocalStorageやCookieに保存し、後続の認証が必要なリクエストにトークンを含めるという流れを追加します。
これらの修正を反映したシーケンス図は以下のようになります。
この図では、ユーザーがメールアドレスとパスワードを入力し、ログインボタンをクリックすることから始まります。その後のプロセスは前述の説明と同様ですが、トークンの保存とエラーハンドリングについての詳細が追加されています。
ChatGPT(レビュー担当)
シーケンス図はより明確になりました。エラーハンドリングの部分やトークンの管理についても追加されており、全体的な流れが理解しやすくなりました。以下にいくつかの改善提案をします:
- ユーザーのアクション: "Enter email, password and click login"は一つのアクションとして表現されているのが良いです。しかし、このステップが完了すると、すぐにクライアントがサーバーにリクエストを送信するという流れが自然に見えます。
- エラーハンドリング: "Invalid credentials"というエラーメッセージは一般的に適切ですが、認証失敗の理由がパスワードの不一致だけでなく、存在しないユーザーである可能性もあります。セキュリティ上の観点から、具体的なエラー原因を伝えない方が良い場合もありますので、メッセージは"Authentication failed"など、より一般的なものにすることを検討してみてください。
- トークンの管理: トークンがlocalStorageまたはCookieに保存されることが記述されていますが、どちらを選択するかは重要なセキュリティ上の判断となります。例えば、localStorageはXSS(クロスサイトスクリプティング)の攻撃に対して脆弱です。そのため、セッションのトークンなどの敏感な情報を保存する場合には、HttpOnly属性を持つセキュアなCookieを使用することが推奨されます。
- トークンの利用: トークンが成功したログイン後に保存されるとありますが、その後のリクエストでどのように使用されるのかが明確になっていません。トークンを含むAuthorizationヘッダーを使ってAPIリクエストを行う、などの詳細な説明を追加すると良いでしょう。
全体的に見て、シーケンス図はより詳細になり、それぞれのパーツの役割と相互作用が理解しやすくなりました。一部提案した改善点は、特定の実装や設計上の選択に依存しますので、具体的な状況に応じて適宜調整してください。
ChatGPT(設計担当)
フィードバックありがとうございます。ご提案いただいたポイントを考慮に入れ、シーケンス図を以下のように更新します。
- ユーザーのアクション: ここでは、ユーザーがメールアドレスとパスワードを入力し、ログインボタンをクリックすることが明確に記述されています。
- エラーハンドリング: 認証が失敗した場合のエラーメッセージを「Invalid credentials」から「Authentication failed」に更新しました。これは、より一般的なメッセージであり、具体的な失敗原因を伝えないためのセキュリティ上の観点を反映しています。
- トークンの管理: セキュリティ上の理由から、トークンは安全なCookieに保存されると記述しました。これは、localStorageがXSS攻撃に対して脆弱であるためです。
- トークンの利用: トークンが保存された後、それがAuthorizationヘッダー(Bearer {token}形式)を使用して後続のAPIリクエストを行うためにどのように使用されるかを明示的に記述しました。
ChatGPT(レビュー担当)
修正版のシーケンス図は非常に明確で、アーキテクチャとフローを適切に表現しています。以下はいくつかの観点からのフィードバックです:
- ユーザーアクション: ユーザーからのアクションが一つに統合され、それがログインリクエストのトリガーに直結していると明示されている点は良い改善です。
- エラーハンドリング: 認証失敗のエラーメッセージが一般的なものになった点は良いです。これにより、具体的なエラー情報を悪用されるリスクが減ります。
- トークンの管理: セキュアなCookieにトークンを保存する点も適切です。これは、XSS攻撃から保護するための一般的な対策です。
- トークンの利用: トークンがAuthorizationヘッダーを通じて後続のリクエストに使用されると明記されているのは非常に良いです。これにより、トークンのライフサイクルがより明確になりました。
全体として、このシーケンス図はユーザーのログインフローを非常にうまく表現しており、それぞれの部分がどのように相互作用するのかが明確に理解できます。良い作業をされました!
ChatGPT(設計担当)
フィードバックをいただきありがとうございます。シーケンス図がより明確になり、それぞれの部分がどのように相互作用するかが理解しやすくなったとのこと、大変うれしいです。
実際の開発においても、このようなシーケンス図は重要な役割を果たします。設計フェーズでは、システムの全体像を理解するための参照資料として役立ちます。開発フェーズでは、各部分がどのように機能し、どのように相互作用するかを開発者が明確に理解できるようにします。また、テストやデバッグ、メンテナンスの際にも、システムの挙動を追跡するのに役立ちます。
今後とも何か他にご質問やご要望がございましたら、お気軽にお申し付けください。お手伝いできることがあれば幸いです。
所感
結果としては2回のレビューを経てシーケンスが大きく改善されました。
思ったりちゃんと、文脈を外れずに会話してくれたのでかなり期待値が上がりました。
あとレビューの指摘が具体的かる言葉遣いが丁寧ですね、(なんなら自分よりいいくらい(笑))
まとめ
開発プロセスにchatgpt入れる場合、chatgptのレビューも入れて自動改善するループ回すと良さそうですが、今回はあくまで実験的に簡単な問題設定だったのでより複雑なユースケースにどの程度対応可能かを今後検証していきたいと思います。
最後まで読んでいただきありがとうございました。少しでも参考になれば幸いです。
最後にしれっと宣伝、以下でエンジニア募集中です(`·⊝·´)
Discussion