【CodeAGI】CodeAGIを使って、軽くサービスのコードをAIで生成してみた!

## はじめに
この記事は、Qiita Engineer Festa 2024の記事投稿キャンペーン「[CodeAGIで実際にコードを自動生成してレビューを投稿しよう](https://qiita.com/official-events/579a875535f3fa987106)」に関する記事です。

https://qiita.com/official-events/579a875535f3fa987106

## CodeAGIとは?

> CodeAGIとは、生成AIサービスを活用して完全なプログラム自動生成を実現するアプリケーションサービスであり、IT技術者が設計書や定義書・データ構造を理解し作成してきたプログラムコードを人の数百倍の速度で生成！
>
> （引用：[CodeAGI公式サイト](https://www.soppradx.com/service.html#download)）

とのことです。 そんなCodeAGIではどんなことができるのでしょうか？

> **CodeAGIだけが実現できる6つのこと**
> 1. 企業独自の多様なフォーマットの設計書解析を実現
> 1. 設計書やデータ構造を学習し整合性を担保した正確なコード自動生成を実現
> 1. リレーショナルデータベースの解析による複雑なSQLの自動生成を実現
> 1. テストケース・テストデータの生成を実現
> 1. 画像データを解析することで、画面プログラムのコード生成を実現
> 1. 複数プログラムの一括自動生成を実現
>
> （引用：[Qiita - 記事投稿キャンペーンページ](https://www.soppradx.com/service.html#download)）

とのことです。

もしこれが全部できたら、PdM・PjMやSEだけで、サービスを作れてしまう。
なんて便利な世の中になったんだという気持ちです。

## 早速触ってみよう!
今回は、私が今まで作りたいと思っていた、「**スライドをWebサイト上で公開できるサービス**」を作るつもりで触ってみました。

### 01. セットアップ
まずはセットアップからですね！

[CodeAGI公式サイト](https://www.soppradx.com/service.html#download) から アプリをダウンロードし、アカウントの作成、ChatGPTのAPIキーの登録を行いました。

「【2024年6月】CodeAGI無料お試しキャンペーン！」 ということで、無料でも使えそうでしたが、運良くChatGPTに課金していたので、APIキーを発行し使ってみました。

:::note
**感想**
アカウント作成時に `メールアドレス`・`パスワード`・`会社名`・`部署名`・`名前(姓、名)`・`電話番号（必須ではない）`を入力する必要があるのは、心理的ハードルが高かったです。
特に、`会社名`・`部署名`・`名前(姓、名)`・`電話番号`
:::

### 02. プロジェクトを作る
ここからは、CodeAGI周りの説明になります。
まずは、プロジェクトを作ります。 プロジェクトでは、以下の折りたたみの中の項目を指定することになります。

<details><summary>プロジェクトで指定する項目</summary><div>

+ **プロジェクト名**
    + 今回は、「Slideshere」にしてみました
+ **プロジェクト概要**
    + 今回は以下のような文章を入力しています
    + イベント等で登壇した時に使った資料をオンラインで共有するためのプロダクトを作る
+ **コード出力フォルダ**
    + 任意のフォルダを指定します
+ **テストケース・データ出力フォルダ**
    + 任意のフォルダを指定します
+ **OS**
    + 自動生成されるプログラムが実行されるOSを設定します
    + 普段MacOSを使っていますが、Windowsしか選択できなかったです（2024年6月現在）
+ **DB**
    + 自動生成されるプログラムが使用されるデータベースを選択します
    + 2024年6月現在では、`Oracle`・`MySQL`・`PostgreSQL`・`SQLite`が選択できました
    + DBは、ほとんど触らないので、ベーシックそうな`MySQL`を選びました
+ **ブラウザ**
    + 自動生成されるプログラムが対応するブラウザを選択します
    + 2024年6月現在では、`Chrome`・`Edge`・`Safari`・`Firefox`・`Opera`が選択できました
    + どのブラウザを使うかは、ユーザーの環境次第なので、複数選択してもいいような...🤔
    + 一応「Chrome」を選択しています
+ **生成プログラムに画面ID・パッチIDを使う**
    + 出力されるコードのファイル名やクラス名に画面ID・パッチIDを使うかを選べます
    + 「使う」を選択してみました
+ **プロジェクト依存環境設定**
    + 生成されるプログラムの言語やフレームワーク・パッケージなどのを選択します
    + 全体的に、フロントエンドで選択できる言語やフレームワークがWebサイトではあまり使わないものが多かった印象です
    + フロント「JavaScript + React」、バックエンド「Python + Django」、バッジ「Python + Django」を選択しました
</div></details>

:::note
**感想**
ベータ版ということもあるのでしょうが、選択できる言語やフレームワークの項目が少ないですね。
アップデートを期待しています。
:::

### 03. テーブル要件定義書を作る

プロジェクトで作るテーブル定義書（エクセルファイル）をアップロードします。
ファイル名やシート名はちゃんを記載しないとうまく読み取ってくれないようです。

今回は、以下の折りたたみの中にあるようなエクセルファイルを作成し、アップロードしました。

<details><summary>テーブル定義書の中身</summary><div>

- ファイル名：`テーブル定義書`
- シート名①：`テーブル定義書（slide）`
- シート名②：`テーブル定義書（user）`

**テーブル定義書（slide）** は以下のような形になっています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/1f01b61e-31cd-6214-086b-9d07d1680a79.png)	


**テーブル定義書（user）** は以下のような形になっています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/dd929f5e-9792-dfde-fda5-3762cb892105.png)

</div></details>

:::note
**感想**
公式サイトにサンプルがあったのと、操作マニュアルを見ながらやったら、うまくファイルが読み込めました。
色々と参照するところが多く、少し難しかったです。
:::

### 04. 機能設計書を作る
次は、機能を設計していきます。
テーブル要件定義書と同様にエクセルファイルをアップロードし、必須項目を入れます。

<details><summary>機能設計書の中身</summary><div>

- 機能名：投稿
- 機能概要：PDF形式でスライドデータをアップロードし、タイトルと一緒にデータベースに保存する
- 機能種別：画面
- ファイル名：`画⾯項⽬定義書`
- シート名①：`画面定義（投稿）`
- シート名②：`項目定義書（投稿）`
- シート名③：`アクション定義書（投稿）`

**画面定義（投稿）** は以下のように書いています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/bdc4dc39-3dbf-3fdf-0bc5-4ab735271cae.png)

**項目定義書（投稿）** は以下のように書いています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/f844784d-9f34-1822-bbe5-98b21e5bb2cd.png)

**アクション定義書（投稿）** は以下のように書いています。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/91879a82-c839-cfa8-961c-0c89d6a3949d.png)

</div></details>


:::note
**感想**
サクッとやってみようというノリには、記入項目が多く大変だなと感じました。
:::

### 05. 画面イメージ図を作る
今回はサクッと以下のようなイメージ図を作り、アップロードしました！

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/2fe6251d-e85e-622f-6c8a-82e0f9e7c841.png)


### 05. ここで、コードを生成する
コードを生成するには、最低限、機能設計書があれば良さそうなので、生成してみましょう！ ワクワク！🥜

１　２の……ポカン！

生成が完了しました！

以下のような11ファイルが生成されました。
11ファイルの内容は折りたたんでいるので興味があるかたはご覧ください。

<details><summary>app.py</summary><div>

```app.py
from django.apps import AppConfig

class MainConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'src.main'
```
</div></details>

<details><summary>view.py</summary><div>

```view.py
from django.views.generic import FormView
from django.urls import reverse_lazy
from .models import Slide
from .forms import SlideUploadForm

class SlideUploadView(FormView):
    template_name = 'slide_upload.html'  # 新規投稿画面のテンプレート名
    form_class = SlideUploadForm
    success_url = reverse_lazy('slide_upload')

    def form_valid(self, form):
        # フォームが有効な場合の処理
        slide = Slide(
            file=form.cleaned_data['fileUpLoad'],
            title=form.cleaned_data['titleInput']
        )
        slide.save()
        return super().form_valid(form)
```
</div></details>

<details><summary>urls.py</summary><div>

```urls.py
from django.urls import path
from .views import SlideUploadView

urlpatterns = [
    # 新規投稿画面のURLパターン
    path('upload/', SlideUploadView.as_view(), name='slide_upload'),
]
```
</div></details>

<details><summary>admin.py</summary><div>

```admin.py
from django.contrib import admin
from .models import Slide

class SlideAdmin(admin.ModelAdmin):
    # 管理画面で表示するフィールドを指定
    list_display = ('title',)

# モデルと管理クラスを登録
admin.site.register(Slide, SlideAdmin)
```
</div></details>

<details><summary>api.js</summary><div>

```api.js
import axios from 'axios';

// ファイルとタイトルをアップロードするAPI
export const uploadSlide = async (file, title) => {
    const formData = new FormData();
    formData.append('fileUpLoad', file);
    formData.append('titleInput', title);

    try {
        const response = await axios.post('/upload/', formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        });
        return response.data;
    } catch (error) {
        console.error('ファイルアップロードエラー:', error);
        throw error;
    }
};
```
</div></details>

<details><summary>App.jsx</summary><div>

```App.jsx
import React from 'react';
import SlideUpload from './components/SlideUpload';

function App() {
    return (
        <div className="App">
            <SlideUpload />
        </div>
    );
}

export default App;
```
</div></details>

<details><summary>index.jsx</summary><div>

```index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
);
```
</div></details>

<details><summary>SlideUpload.jsx</summary><div>

```SlideUpload.jsx
import React, { useState } from 'react';
import { uploadSlide } from '../apis/api';

function SlideUpload() {
    const [file, setFile] = useState(null);
    const [title, setTitle] = useState('');
    const [message, setMessage] = useState('');

    const handleFileChange = (e) => {
        setFile(e.target.files[0]);
    };

    const handleTitleChange = (e) => {
        setTitle(e.target.value);
    };

    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            await uploadSlide(file, title);
            setMessage('アップロードが成功しました。');
        } catch (error) {
            setMessage('アップロードに失敗しました。');
        }
    };

    return (
        <div>
            <h1>新規投稿画面</h1>
            <form onSubmit={handleSubmit}>
                <div>
                    <label>ファイルアップロード</label>
                    <input type="file" accept="application/pdf" onChange={handleFileChange} required />
                </div>
                <div>
                    <label>タイトル</label>
                    <input type="text" value={title} onChange={handleTitleChange} required />
                </div>
                <button type="submit">公開ボタン</button>
            </form>
            {message && <p>{message}</p>}
        </div>
    );
}

export default SlideUpload;
```
</div></details>

<details><summary>App.jsx</summary><div>

```App.jsx
import React from 'react';
import SlideUpload from './components/SlideUpload';

function App() {
    return (
        <div className="App">
            <h1>新規投稿画面</h1>
            <SlideUpload />
        </div>
    );
}

export default App;
```
</div></details>

<details><summary>index.jsx</summary><div>

```index.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// Reactアプリケーションのエントリーポイント
ReactDOM.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>,
    document.getElementById('root')
);
```
</div></details>

<details><summary>index.html</summary><div>

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>スライドアップロードアプリケーション</title>
</head>
<body>
    <div id="root"></div>
    <script src="index.jsx"></script>
</body>
</html>
```
</div></details>

:::note
**感想**
事前のエクセルファイルを適当に書きすぎている部分もありますが、まあそれなりのコードが生成されてそうだなという印象です。
:::

### 06.テストケース・データを生成する
次はテストケース・データを生成してみます。

１　２の……ポカン！

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/8b1f785d-d822-9df2-8c1d-62f8b3916720.png)

こんな感じのテストケースが生成されました。
要件になかった検索機能のテストケースが生成されていました！これは便利！

## まとめ
この記事では、CodeAGIを使って、軽くサービスのコードをAIで生成してみました。

ちゃんと仕様書等を入力できてないですが、一旦のまとめとして、

1. **企業独自の多様なフォーマットの設計書解析を実現**
    - ❌ → まだベータ版ということもあってか、エクセルファルで特定の書き方で書くとうまく読み取ってくれます
1. **設計書やデータ構造を学習し整合性を担保した正確なコード自動生成を実現**
    - 🔺 → 設計書やデータ構造はちゃんと学習したものになってそうですが、正確性はもう少しといったところでしょうか？
1. **リレーショナルデータベースの解析による複雑なSQLの自動生成を実現**
    - ⭕️ → 生成した内容が複雑ではないですが、Pythonファイルを自動生成してくれました
1. **テストケース・テストデータの生成を実現**
    - ⭕️ → 要件にない「検索」部分も自動で生成してくれたので、テストケースを生成しながら、仕様書が詰められそうな印象を持ちました
1. **画像データを解析することで、画面プログラムのコード生成を実現**
    - 🔺 → HTML部分はそれっぽくなっていますが、Header部分の生成が忘れてそうです...
1. **複数プログラムの一括自動生成を実現**
    - ⭕️ → 一度の実行で複数のプログラムを生成してくれました

:::note
実際にCodeAGIを使ってみて、複数回使えば、もっと精度の高いものをアウトプットしてくれそうな印象を持ちました。
:::

期待することとしては、以下の通りです。

+ 生成できる言語やフレームワーク、パッケージが少ないなと感じたため、このあたりが増えるとうれしいです
+ 決まったフォーマットで設計書を記載できるように、記入例だけでなく、テンプレートとして配布して欲しいです
+ 軽く試してみるくらいの温度感では、ちょっと難しかったなと感じました
+ アカウント作成に必要な項目が減るといいなと思います

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510