Figmaでデザインしたユーザー登録機能を、GPT-4oで再現したら惜しかった

[link-1]:https://www.figma.com/ja-jp/ "Figma Home page"

## はじめに
最近の生成AIの進化は早く、コード生成、画像認識の精度も日に日に上がってきています。
与えられた画像からコードを生成する、というタスクも多くの方が取り組まれていましたが、実際にどのくらいの精度になるのか気になったので実験してみました。

## 準備
[Figma][link-1]はブラウザ上でデザインや開発を行うことができるツールです。
今回の検証にあたり、初めてFigmaを使ってみましたが、機能が分かりやすく、すぐにデザインすることができました。
検証のために、以下のようなユーザー登録を行う画面の画像を用意しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2039603/48b37ca0-8637-0d70-f5b2-4833f31b88ca.png)

GPT-4oでどのくらい再現できるのかを試してみます。

## プロンプト
画面の見た目だけでなく、使用文字制限など他の機能要件も満たせるかどうかを確認するために、以下のようなプロンプトを入力しました。
プロンプトエンジニアリングでチューニングはせず、思いついたままに入力しています。
```:プロンプト
添付した画像のようにHTMLとCSSを書いてください。ただし、以下の要件を満たすこととします。
## 機能要件
|分類|番号|概要|
|---|---|---|
|データ|1|ユーザー名は半角英数字16文字以下にする|
|データ|2|パスワードで使用できる文字は半角英数字とアンダースコアのみとする|
|データ|3|パスワードは8文字以上64文字以下にする|
```

## 結果
GPT-4oが出力したコードは後に記載していますので、その通りに表示した画像を並べてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2039603/f6f4bbaf-639f-9679-290b-5b95f22caf3a.png)

### 再現できている点および良かった点
- 項目の日本語は正しく出力できている
- 画像からは確認できないが、パスワードが一致しているかどうかを判定するプログラムが追加された
- もともとの入力画像より余白が適切で見やすい
- 入力欄のまわりに影をつけて見やすくなった
- 「登録する」ボタンにカーソルを合わせたときに色を変えてくれるという、機能要件で指定していなかった機能を実装してもらった

### 再現できていない点および課題
- プレースホルダーを読み取ることができていない
- 一番上の「ユーザー登録」の背景が作れていない
- 日本語のユーザー名が登録できる
- 「登録する」という文字の背景色がもともとは青色だが、生成されたのは緑色
- コンテナの幅が固定で、デバイスによってはスクロールが必要になりそう

## 結論
枠の大きさやフォントなどは見やすく調整されるので、たたき台としては十分な機能があると感じました。一方で、色の認識には課題があり、薄い色を認識できなかったり、色の差異を間違えたりすることがあります。
生成AIは、今後もより精度が高くなっていくので、これらの課題も改善されていくとは思います。
自分では考えていなかった機能やデザインも提案してくれるので、デザインの洗練にもなりそうです。

GPT-4oをもとに改良したものをGitHubリポジトリにあげましたので、リンクを記載します。

https://github.com/mhal-teddy/register-form

## 生成AIが出力したコード
生成AIが実際に回答したコードを記載します。(2024年6月現在)
### HTMLファイル
```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h2>ユーザー登録</h2>
        <form id="registerForm">
            <div class="form-group">
                <label for="username">ユーザー名</label>
                <input type="text" id="username" name="username" maxlength="16" required>
            </div>
            <div class="form-group">
                <label for="email">メールアドレス</label>
                <input type="email" id="email" name="email" required>
            </div>
            <div class="form-group">
                <label for="password">パスワード</label>
                <input type="password" id="password" name="password" pattern="^[a-zA-Z0-9_]+$" minlength="8" maxlength="64" required>
            </div>
            <div class="form-group">
                <label for="confirmPassword">パスワード確認</label>
                <input type="password" id="confirmPassword" name="confirmPassword" pattern="^[a-zA-Z0-9_]+$" minlength="8" maxlength="64" required>
            </div>
            <button type="submit">登録する</button>
        </form>
    </div>
    <script src="script.js"></script>
</body>
</html>
```

### CSSファイル
```css
body {
    font-family: Arial, sans-serif;
    background-color: #f9f9f9;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.container {
    background-color: white;
    padding: 20px;
    border-radius: 5px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    width: 300px;
    text-align: center;
}

h2 {
    margin-bottom: 20px;
    color: #333;
}

.form-group {
    margin-bottom: 15px;
    text-align: left;
}

label {
    display: block;
    margin-bottom: 5px;
    color: #333;
}

input {
    width: 100%;
    padding: 8px;
    box-sizing: border-box;
    border: 1px solid #ccc;
    border-radius: 4px;
}

button {
    width: 100%;
    padding: 10px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}
```

### JavaScriptファイル
```javascript
document.getElementById('registerForm').addEventListener('submit', function(event) {
    event.preventDefault();
    
    const password = document.getElementById('password').value;
    const confirmPassword = document.getElementById('confirmPassword').value;

    if (password !== confirmPassword) {
        alert('パスワードが一致しません。');
        return;
    }

    alert('登録が成功しました！');
});
```