Clineの衝撃

※ この記事は個人がClineを試してみた、というメモ用の記事です。Clineに関する新情報は何もありません。

ClineというAIコーディングツールがすごいです。今まで生成AIを利用したコーディングというと

- ChatGPTに依頼してコードを生成させる
- ChatGPTに既存のコードを貼り付けて、エラーを修正してもらう
- プログラムを作動させて出力したエラー内容を貼り付けて教えてもらう

などでしたが、ClineはVSCodeの拡張として動作し、ワークスペース内の情報を自律的に理解して、自動的にコード修正→テストまで行ってくれるのが凄いです。

### 最初に

- Clineにはfork版がいくつかありますが、この記事ではネイティブのClineを利用しました。
- Clineだけを使うとAPI使用量がヤバいので、ChatGPTなどの定額サービスや、Github Copilotの併用が現実的です
- 今回のテストではOpenAIのGPT-4oやanthropicのClaude 3.5 Sonnetを利用しました。この2つならClaude 3.5 Sonnetの方がコストに対する性能が良いとされています
    - コスパを求めるならdeepseekを利用するのが良いとされていますが、中国企業のサービスなので情報の扱いに不安が残ります。また、2025/2/5現在はUnder MaintenanceとなっておりAPIの新規利用登録ができないようです

### 作成したアプリ

野球関連のイベントの余興で、参加者のライトニングトークの発表順を決めるアプリを作成しました。

![20241118.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/a584a7cb-4901-91f4-213b-b34e400479fd.gif)

イメージとしてはドラフト会議の選択希望選手のパネルです。

![20250205_11-49-20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/76a7a230-7f03-3818-89e8-9af558794a77.jpeg)

事前に参加者から希望する発表順を申請してもらい、それをcsvデータとしてアプリに持たせます。

```csvs
name,content
テスト ユーザー01,1番目
テスト ユーザー02,5番目
テスト ユーザー03,5番目
テスト ユーザー04,4番目
テスト ユーザー05,4番目
テスト ユーザー06,9番目
テスト ユーザー07,1番目
テスト ユーザー08,1番目
テスト ユーザー09,6番目
```

次へ、ボタンを押すたびに参加者と希望順が表示されます。希望順番が重複したら、重複した人でドラフトのくじを引いてもらう、というイベント進行でした。

※ ドラフトのくじ引きがしたかった

### アプリの作り方

まずですが、このアプリを作るのに**私自身はコードを1行も書いていません。** ChatGPTにやりたい事を投げ、初期の設計を提案してもらいました。それをClineに投げました。

![20250205_11-54-29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/55af8990-aa00-d1c0-d2d1-3f1d3b1aa0b3.jpeg)

※ プロンプトが長いので折りたたみます

<details>
<summary>投げたプロンプト</summary>

```
以下のようなアプリケーションの作成をお願いします。

以下のようなデータ列があります。

| 氏名 | 回答 |
| --- | --- |
| 回答者の氏名01 | 回答内容01|
| 回答者の氏名02 | 回答内容02|
| 回答者の氏名03| 回答内容03|

これを何かの定義ファイルに保持するとします。例えばcsv形式としましょう。

Webブラウザ経由でアプリケーションにアクセスした時には、タイトルと「次へ」ボタンの2つのみが表示されたページが開きます。「次へ」を押すと
回答者の氏名01  回答内容01
が表示されます。さらに「次へ」を押すと、既に表示されている
回答者の氏名01  回答内容01
に加えて
回答者の氏名02  回答内容02
が表示されます。

表示形式ですが、クイズ番組のパネルのようなイメージで表示される想定です。

以上がアプリケーションの機能です。

その2. 技術スタックについて

私は不慣れですが、Reactでお願いします。

以下の通り、自分で途中まで作成しました。まずはこの通りにアプリケーションを作ってください。

ディレクトリ構成

quiz-reveal/
├── src/
│   ├── app/
│   │   ├── page.tsx
│   │   └── layout.tsx
│   ├── components/
│   │   ├── ui/
│   │   │   ├── button.tsx
│   │   │   └── card.tsx
│   │   └── QuizReveal.tsx
│   └── data/
│       └── answers.csv
├── public/
├── tailwind.config.js
└── package.json

src/components/QuizReveal.tsx

import React, { useState } from 'react';
import { Card, CardHeader, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';

const QuizReveal = () => {
  // サンプルデータ（後でCSVから読み込む形に変更可能）
  const answers = [
    { name: "回答者の氏名01", content: "回答内容01" },
    { name: "回答者の氏名02", content: "回答内容02" },
    { name: "回答者の氏名03", content: "回答内容03" }
  ];

  // 現在表示している回答のインデックスを管理
  const [currentIndex, setCurrentIndex] = useState(0);
  // 表示済みの回答を管理
  const [revealed, setRevealed] = useState([]);

  // 「次へ」ボタンのクリックハンドラ
  const handleNext = () => {
    if (currentIndex < answers.length) {
      setRevealed([...revealed, answers[currentIndex]]);
      setCurrentIndex(currentIndex + 1);
    }
  };

  return (
    <div className="min-h-screen bg-gray-100 p-8">
      <Card className="mx-auto">
        <CardHeader>
          <h1 className="text-2xl font-bold text-center">回答パネル</h1>
        </CardHeader>
        <CardContent>
          <div className="flex flex-wrap gap-4 justify-center">
            {revealed.map((answer, index) => (
              <div
                key={index}
                className="aspect-square w-64 p-4 bg-blue-100 rounded-lg shadow-md transition-all duration-500 animate-fade-in flex flex-col justify-center"
              >
                <div className="text-gray-700 text-center text-4xl mb-4 font-bold">
                  {answer.content}
                </div>
                <div className="text-blue-800 text-center text-sm">
                  {answer.name}
                </div>
              </div>
            ))}
          </div>
          
          <div className="mt-6 text-center">
            <Button
              onClick={handleNext}
              disabled={currentIndex >= answers.length}
              className="px-6 py-2"
            >
              次へ
            </Button>
          </div>
        </CardContent>
      </Card>
    </div>
  );
};

export default QuizReveal;



src/app/page.tsx

import QuizReveal from '@/components/QuizReveal';

export default function Home() {
  return (
    <main>
      <QuizReveal />
    </main>
  );
}

src/data/answers.csv

name,content
回答者の氏名01,回答内容01
回答者の氏名02,回答内容02
回答者の氏名03,回答内容03
```
</details>

これを受けてClineが自動的にいろいろと作業を行ってくれます。

※ この時は何も設定をしていなかったので英語での回答になっていますが、設定する事で日本語で回答してくれます。

![20250205_11-56-46.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/1a155d56-d4c7-103a-8eba-2a92945f52a3.jpeg)

### 実際の動き

文章で説明しても中々体験できないと思うので、動画で貼り付けます。冒頭のアプリは既に作成してしまったので、このアプリに対しての変更をClineを通じて依頼します。

冒頭のアプリは回答者1名毎にパネルを表示していく形式ですが、ドラフト会議では最初から12球団分のパネルが画面に表示され、回答(実際のドラフト会議では指名選手)が1球団毎に表示されていきます。このアプリも、(Clineが)そのように改修したいと思います。

以下がその動画です。開始から1分ほどでコードの変更が終了しました。
※ 動画は2倍速で撮影しているので全部で30秒ほどです

![20250205video-01-01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/cf1b28b7-81a7-182c-13c1-5eec2f33d481.gif)

ここから、ブラウザでの自動テストも実施してくれます。

※ この動画は4倍速です
※ 自分用メモ：Qiitaの不具合?かなにかで、gif画像が正常に表示されないので後で直す

![20250205video-01-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/846d87a0-61f8-ae1b-6f51-8586ae76cfcd.gif)

![20250205video-01-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/d8e36915-efd1-d054-52a4-a9a05cd0012a.gif)

残念ながらブラウザでの自動テストは失敗し、さらにコードを修正しようとしますが、自前でlocalhost:3000にアクセスしてアプリケーションが正常動作している事を確認できたため、Clineはここで止めています。

実際に出来上がったアプリがこちら。ドラフト会議っぽくなってます。

![20250205-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/5bd5777c-dcb8-2184-95fe-da9ef9f2fa47.gif)

かかった金額は $0.14 = 20円程度でした。

![20250205_15-53-33.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/4449d64e-92e1-6bef-a2c8-ec1085a30004.jpeg)

### 感想

冒頭で書いた通り、ChatGPTやGithub Copilotに依頼してプログラミングを進めることも**やろうと思えばできる**が、Clineによる体験は全く別物と言ってよい。特に私のように詳しくないフレームワークでごにょごにょしてたらエラー出まくって「よ～分からんけど直してくれ～！」と依頼したらマジで直してくれるのでヤバいです。

懸念点として、今回は非常に簡単なアプリで試したが、これがもっと複雑だったりクラウドのPaaSやシステム間連携が必要なアプリだと少し不安が残るな、ということ。1回質問する毎にAPI使用料金がかかるので、コストは気にする必要がある、ということ。

ただ可能性は無限大だし、ChatGPTが出て移行、いろんな生成AIツールが出た中で一番感動したレベルなので、これからもAPI料金は気にせずガンガン使っていきたいです。

### 参考になる記事

- [プログラマとCLINE - これはパンドラの箱なのか - YouTube](https://www.youtube.com/watch?v=dK8rhWMfQ5I)
- [Clineを利用した開発が超快適なので、使っている.clinerulesを解説します](https://zenn.dev/berry_blog/articles/c72564d4d89926)