2023.04.10

ChatGPT Plusがソースコードの変更を読み込んで機能仕様書を更新する

はじめに

こんにちは。次世代システム研究室のT.Tです。

GitHubからGPT-4ベースになったGitHub Copilot Xが発表されました。まだ機能リストやデモ画像しか確認できていないですが、コードのサジェスト機能はもちろん、プルリクエストの説明文を生成したりドキュメント内容に基づいて質問への回答を生成する機能等があるようで、開発者の業務をサポートする強力なツールになりそうです。GitHub Copilot Xではシステムを自然言語で表現する機能周りが充実しそうな印象があるので、開発したプログラムをどの程度自然言語で表現できるかを検証してみます。執筆時点でGitHub Copilot Xが入手できていないので、GPT-4をブラウザから利用できるChatGPT Plusを使って擬似的に体験した内容を紹介したいと思います。

1.AIによる開発現場での課題解決アプローチ

The Future is Now: How AI-Driven Development will Make Developers’ Life Easier in 2023によるとAI-Driven Developmentという考え方があるようです。これを実現しているツールはこの記事内で紹介されているようにいくつかありますが、その中でもChatGPTが優れているようです。
ChatGPTを使った開発事例の紹介記事も出てきており、仕様書からソースコードを書き起こすアプローチとしては仕様書とテストを用いた「AI駆動開発」AI駆動開発と現状とのギャップを示すでの考察が参考になります。
本記事ではソースコードから機能仕様書を書き起こす部分を検証してみたいと思います。ソフトウェアの開発をしていると現在の仕様がどうなっているか質問を受けることがあります。そのような時に機能仕様書を参照して回答したりしますが、機能仕様書が古くて結局ソースコードを読み込んで回答するということもあります。背景として仕様変更時点でソースコードのみ変更して機能仕様書を更新するのが徹底できていないというものがあると思いますが、そのような問題点を解消できないか検証してみました。

2.開発する機能と検証内容

Webアプリケーションサービスに使われるID/パスワードによる認証機能をChatGPT PlusにPHPで実装してもらい、筆者がその認証機能にログインが5回失敗したらログインできなくなる機能(アカウントロック機能)を追加します。本記事で検証したいのはChatGPT Plusが追加されたアカウントロック機能を正しく説明できるかどうかです。

結論としては正しく説明出来ることが検証でき、以下のプロンプト入力でChatGPT Plusに機能仕様書を書いてもらうことが出来ました。

  • 「プログラムの知識がない人が理解できるように詳細に説明してください。」と入力する
  • 機能変更箇所に関する詳細な質問をプロンプトで送り、追加で説明してもらう
この後詳細を見ていきたいと思います。

3.ChatGPT Plusによる実装

まず、ログイン画面のHTMLを実装してもらいます。プロンプトには「ログインフォームにCSSデザインを追加してください。」と入力します。

提案されたコードをファイルに保存して確認すると整形された状態のログインフォームになっています。いきなりログイン画面が出来てしまいました。

次はこのログイン画面を使ってユーザー認証するためのPHPのプログラムを実装してもらいます。プロンプトには「以下のログインフォームからPOSTメソッドのリクエストを受け取りユーザーを認証するPHPのプログラムを提案してください。」という文言と合わせて先程ChatGPT Plusに出力してもらったHTMLを入力します。

POSTでID/パスワードを受け付けて設定されているパスワードと比較して認証するサンプルコードを返してきました。その後にセキュリティ向上するためにpassword_verify関数を使うことを提案しています。そこでさらにpassword_verify関数を使う例を出してもらいました。プロンプトには「このPHPのプログラムでpassword_verify関数を使用する例を教えてください。」と入力します。

今度はDBからユーザー情報を取得してパスワードを比較する、より実際的なコードが提示されました。ある程度ボリュームのあるコードが出来たのでChatGPT Plusでの実装はここで切り上げます。

4.機能仕様書の生成

生成されたコードの仕様を説明してもらいます。プロンプトには「このコードをプログラミングの知識がない人が理解できるように説明してください。」と入力します。

コードの内容を正しく説明できているようです。実装に関する説明が多いのでさらに要約してもらいます。プロンプトには「この説明を要約してください。」と入力します。

ID/パスワード認証の仕様として良い感じになりました。

5.機能追加後の機能仕様書の生成

ログインが5回失敗したらログインできなくなる機能を追加してChatGPT Plusに説明してもらいます。一度プログラムのコードだけプロンプトに入力して、その後プロンプトに「このコードをプログラミングの知識がない人が理解できるように説明してください。」と入力します。
<?php
CONST LOGIN_FAILURE_LIMIT = 5;

// データベースの設定
$host = 'localhost';
$db_name = 'your_database_name';
$user = 'your_database_user';
$password = 'your_database_password';

// データベースへの接続
try {
    $conn = new PDO("mysql:host=$host;dbname=$db_name", $user, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
    exit;
}

// POSTリクエストからユーザーIDとパスワードを取得
$user_id = $_POST['user_id'];
$submitted_password = $_POST['password'];

// データベースからユーザー情報を取得
$stmt = $conn->prepare("SELECT * FROM users WHERE user_id = :user_id");
$stmt->bindParam(':user_id', $user_id);
$stmt->execute();

$user = $stmt->fetch(PDO::FETCH_ASSOC);

if ($user) {
    try {
        check_login_failure_count($conn, $user_id);
        // ユーザー認証
        if (challenge_auth($submitted_password, $user['password'])) {
            // 認証成功
            echo 'Login successful. Welcome, ' . htmlspecialchars($user_id) . '!';
        }
    } catch (PasswordMismatchException | PasswordFailureCountExceededException $e) {
        count_up_login_failure_count($conn, $user_id);
    }
}

function challenge_auth($submitted_password, $password)
{
    if (!password_verify($submitted_password, $password)) {
        throw new PasswordMismatchException();
    }

    return true;
}

function check_login_failure_count($conn, $user_id)
{
    $stmt = $conn->prepare("SELECT failure_count FROM user_account_lock WHERE user_id = :user_id");
    $stmt->bindParam(':user_id', $user_id);
    $stmt->execute();

    $failure_count = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($failure_count['failure_count'] >= LOGIN_FAILURE_LIMIT) {
        throw new PasswordFailureCountExceededException();
    }

    return true;
}

function count_up_login_failure_count($conn, $user_id)
{
    $stmt = $conn->prepare("UPDATE user_account_lock SET failure_count = failure_count + 1 WHERE user_id = :user_id");
    $stmt->bindParam(':user_id', $user_id);
    $stmt->execute();
}

class PasswordMismatchException extends Exception
{
}

class PasswordFailureCountExceededException extends Exception
{
}
?>

追加した機能部分についてしっかり説明できています。ログイン失敗回数の具体的な回数が説明されていないので詳細に説明してもらい具体的に説明されるか確認します。プロンプトには「このコードをプログラミングの知識がない人が理解できるように詳細に説明してください。」と入力します。

詳細な説明にも具体的な回数は含まれていません。しかし、ここで特筆すべき点があります。追加した実装部分には機能を実現する以外の関数の説明やコメント等が一切ないにも関わらず挙動を的確に説明できている点です。セキュリティ上の理由からアカウントロックをするという説明ができているのが素晴らしいです。一方、「データベースに暗号化された形で保存されている」とか「一時的にロックされる仕組み」というのは元のコードだけでは実現できない機能なので注意が必要です。

話を戻して、今度は直接聞いてみます。プロンプトには「ログイン失敗回数は何回までですか。」と入力します。

しっかり認識できていたようで正しい答えが返ってきました。余計な回答も含まれているので聞き方を変えてみます。プロンプトには「ログイン失敗回数は何回までですか。結果だけ教えてください。」と入力します。

バッチリですね。

6.まとめ

世界は変わりました。メイド・イン・ヘブンの世界に取り込まれてしまったような衝撃です。

今回は1つのファイルだけ読み込んでソースコードを正しく説明できるかを検証しましたが、GitHub Copilot X in Visual Studioではプロジェクト全体を理解して説明してくれるようになるのではないでしょうか。

次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。

皆さんのご応募をお待ちしています。

  • Twitter
  • Facebook
  • はてなブックマークに追加

グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

 
  • AI研究開発室
  • 大阪研究開発グループ

関連記事