🗣️

(広義の) Vibe Coding やってみた

に公開

はじめに

ここ数年 AI を活用した開発手法が様々な形で発信されています。その中でも、AI と対話しながら開発を進める「Vibe Coding」はバズワードとして聞いたことがある人も多いのではないでしょうか?
この Vibe Coding を発信したのは Andrej Karpathy 氏で、こんなことを言っています
https://x.com/karpathy/status/1886192184808149383

私が「バイブコーディング」と呼んでいる新しいタイプのコーディングがあります。それは、バイブスに完全に身を任せ、指数関数的な処理を好み、コードの存在すら忘れてしまうようなコーディングです。LLM(例えば、Cursor ComposerとSonnet)があまりにも優秀になりすぎているからこそ、それが可能になったのです。それに、私はSuperWhisperを使ってComposerと対話しているので、キーボードにはほとんど触れません。「サイドバーのパディングを半​​分に減らして」といった、くだらないことを頼んでしまうこともあります。探すのが面倒だからです。常に「すべて承認」を選択し、差分はもう読みません。エラーメッセージが表示されたら、コメントなしでそのままコピー&ペーストします。大抵はそれで解決します。コードが私の理解を超えてしまうと、しばらく時間をかけてじっくりと読み通さなければなりません。LLMではバグを修正できないこともあるので、そのバグを回避したり、バグがなくなるまでランダムに変更を依頼したりします。週末に使い捨てるプロジェクトとしては悪くないですが、それでもなかなか面白いです。私はプロジェクトや Web アプリケーションを構築していますが、実際にはコーディングをしているわけではなく、単に何かを見て、何かを言って、何かを実行して、何かをコピーして貼り付けるだけで、ほとんど動作します。

ただこの狭義(?)の Vibe Coding は中々既存ソフトウェアを開発する上では厳しいものがあり、単に AI にほとんどコーディングを任せるスタイルも Vibe Coding と称するのも散見されます。
(「常に『すべて承認』を選択し、差分はもう読みません」、というのをしてしまうとコードレビューする側が辛い...😭)

なので本記事では、広義の Vibe Coding を実践するための具体的な手順と、その過程で得られた学びを共有します。
※ここで言う「広義の Vibe Coding」とは、基本的にコーディングを AI におこなってもらい、エラー時や意図しない挙動が発生した時に人間が介入するスタイルを指します。

Vibe Coding 実践フロー

1. タスク管理ファイルを作成するためのプロンプトの用意

Vibe Coding をする場合 AI に実装計画を立ててもらうのが人間が管理しやすくて良いです。
まずはそのタスク管理ファイルを作成してもらうためのプロンプトを作成します。(= メタプロンプトをおこなう)

私はこのような Cursor rules を用意して、それを基にメタプロンプトをおこなっています。

.cursor/rules/plan/generate_task_prompt.mdc
---
description: 
globs: 
alwaysApply: false
---
# ルール名: generate-task-prompt

## 目的
あなたには、指定されたタスクを管理するための**タスク管理用マークダウンファイル**を生成するプロンプトを作成してほしいです。これにより、特定のタスクについてAIに指示を出す際のタスク管理を支援します。

## 指示
ユーザーから以下の情報を引き出し、それに基づいて最適なプロンプトを作成してください。

1.  **タスクの詳細 (task_description):**
    *   どのようなタスクを管理するためのマークダウンファイルが必要ですか?(例: 「Laravel で REST API を作成するタスク管理」「React コンポーネントのテストコードを書くタスク管理」)
    *   そのタスクの背景や目的は何ですか?
    *   期待する**タスク管理ファイルのフォーマットや内容**はどのようなものですか?

2.  **プロンプトの要件 (prompt_constraints):**
    *   生成するプロンプトに含めてほしい具体的な指示や制約はありますか? (例: 「ステップバイステップ形式でタスクをリストアップする」「考慮事項をリストアップする」「特定の技術スタックを前提とするタスクリスト」「セキュリティに関する注意点を含める」)
    *   どのようなスタイル(例: 詳細、簡潔)のプロンプトが望ましいですか?
    *   対象とするAIの能力レベルについて、何か想定はありますか?
    *   生成するプロンプトには、成果物である**タスク管理用マークダウンファイル**はチェックボックス形式で出力する指示を必ず含めてください。
    *   生成するプロンプトには、成果物である**タスク管理用マークダウンファイル**を `task/` ディレクトリ以下に作成する指示を必ず含めてください。
    *   生成するプロンプトには、作成するタスクリストにおいて**必ずテストコードの実装をプロダクションコードの実装より先に行う手順**を含めるように指示してください。


## 出力形式
ユーザーから引き出した情報をもとに、生成されたプロンプトを出力してください。
ユーザーがコピペしやすいように、プロンプト以外の文章は生成しないでください。それ以外の文章を生成することは禁止されています。

## 注意点
- ユーザーの意図を正確に把握するように努めてください。不明な点があれば質問してください。
- 生成するプロンプトは、具体的で、実行可能で、明確な指示となるように心がけてください。
- タスクの複雑さに応じて、プロンプトの粒度を調整してください。

ポイント:

  • コンテキストの付与: PRD の内容や、実装対象となる既存のクラスをコンテキストとして付与(@メンションで指定)することで、Cursor はより的確な実装計画を立てることができます。
  • ask モードの推奨: Cursor の ask モードを利用することでプロンプトを洗練させることができます。ask モードで計画を立てる際、Cursor で利用するモデルは Gemini-2.5-pro や o3 が推奨されるようです。 (参考: Stay close to the plan creation process)

プロンプト作成例:

@task/context/context.md
@app/Hoge/HogeClass.php

上記のコンテキストに基づいて実装計画用のプロンプトを生成してください。
プロンプト生成時は @plan/generate_task_prompt.mdc のルールに従ってください。

2. タスク管理ファイルの作成

作成したプロンプトを基に、具体的なタスクを記述した管理ファイルを作成します。このファイルが、Vibe Coding における実装のロードマップとなります。

ポイント:

  • 配置場所の指定: 例えば、app/task/ のように、プロジェクト内でタスク管理ファイルの置き場所を統一します。
  • ask モードの活用: プロンプト作成時と同様に、ask モードで Cursor と対話しながらタスク管理ファイルを作成することを推奨します。
  • テストファーストの推奨: タスクを生成する際は、テストケースを先に定義する「テストファースト」のアプローチを推奨します。テストを基にプロダクションコードを実装することで、Cursor による実装の方向性がぶれにくくなり、結果として手戻りを減らすことができます。

3. タスクの実行

タスク管理ファイルが完成したら、いよいよ Cursor と共に実装作業を開始します。

ポイント:

  • タスクファイルの指定: 作成したタスク管理ファイルを @ メンションで指定し、AI に実装を指示します。
  • Cursor Rules の適用: Vibe Coding 用の Cursor Rules を適用することで、AI の振る舞いを制御し、より一貫性のあるコーディングスタイルや設計思想を反映させることができます。

Vibe Coding 用の Cursor Rules 例

---
description: 
globs: 
alwaysApply: false
---
# タスクの進め方
- あなたはシニアソフトウェアエンジニアです。与えられたコンテキストであるタスク管理ファイルをもとに実装を進めていってください。
  - 完了したタスクはチェックボックスにチェックをつけてください。
- タスク管理ファイルはあくまでもタスクを管理するものなので、実際に開発するにあたっては誤っている情報やコード規約に反している記述もあることがあります。
  - なので、もしもエラーが起きた時は一旦タスクファイルの指示は無視をして、ユーザーにどのように実装すべきかヒアリングしてください。エラーをループさせることは禁止されています。
  - タスクファイルには調査フェーズも記載されている場合があります。調査する場合にも、不明点があればユーザーにヒアリングするようにしてください。
- タスク管理ファイルの各見出しセクションごとに `git commit` を行い、 `git push` するようにしてください。コミットメッセージは、各セクションの内容に応じて適切なものを設定してください。

# テストコードの実装・実行について
- テストファーストで開発をおこなうようにタスク管理ファイルに記載されている場合、テストコードが Fail になることは許容しますが、 Error になった場合はテストコードの実装が誤っている可能性が高いので、ユーザーにヒアリングをして解消するようにして下さい。

タスク実行例:

@hoge_fix_task.md
上記タスクをもとに開発を行ってください。

タスクを進める際は、下記 cursor rule を適用してください。
@agent/vibe_coding_with_task.mdc

テストファースト実践のコツ:

  • テストコード実装後のコミット: テストファーストで進める場合、まずテストコードを実装した段階で一度 git commit することをお勧めします。これにより、プロダクションコード実装前にテストコードの品質を確保できます。
  • 新規テストケースのみ実行: プロダクションコード実装後、新たに追加したテストケースのみを実行することで、既存テストの失敗による修正ループを防ぎます。
    既存テストが失敗した場合は、その原因を特定し Cursor にフィードバックすることで、その後の挙動制御の精度が上がります。

4. テストが失敗した場合の対応

開発プロセスにおいて、テストの失敗はつきものです。Vibe Coding 中にテストが失敗した場合、慌てずに原因を特定し、的確に Cursor へ修正を指示することが重要です。

ポイント:

  • 原因のリストアップ: すぐに実装を再開するのではなく、まず Cursor にテストが失敗した原因を考察させ、リストアップしてもらいます。
  • リストに基づく改修指示: リストアップされた原因を基に、具体的な修正指示を Cursor に出すことで、より効率的に問題を解決できます。

テスト失敗時の指示例:

これを実行して、テストが落ちた場合はその理由を考察して

`./vendor/bin/phpunit --filter HogeTest | cat`

Vibe Coding の精度を高めるために

Vibe Coding をより効果的に行うためには、Cursor が期待通りに動作するよう、いくつかの工夫が必要です。

  • 型の厳格化: コードに型情報を付与することで、AI はコードの意図をより正確に理解し、型安全なコードを生成しやすくなります。
  • Feature Test の活用: Unit Test だけでは捉えきれない全体の振る舞いについては、Feature Test (機能テスト。単体テストよりも粒度の大きいテスト) を作成することで、予期せぬ不具合を防ぐ最終防衛ラインとして機能します。Cursor を活用することで、以前よりも Feature Test を書くコストが下がっているため、積極的な導入を検討してみても良いかもしれません。

Vibe Coding を通して得られた学び

Vibe Coding を実践する中で、いくつかの重要な学びがありました。

  • コンテキストの重要性: AI の出力品質は、入力されるコンテキストの質と量に大きく依存します。いかに的確で十分な情報を Cursor に与えるかが成功の鍵となります。
  • 型とテストによる制御: 型定義やテストコードは、AI の自由な発想を適切な範囲に導き、暴走を防ぐための重要なガードレールとなります。
  • ドキュメンテーション能力の向上: AI に正確な指示を与えるためには、開発者自身がタスクの内容や設計を深く理解し、それを明確に言語化する必要があります。このプロセスは、結果としてドキュメント作成能力や開発チケットの記述能力の向上に繋がります。逆に、これらのライティング能力が低い場合、Vibe Coding を活用できない危険性があると感じました。

まとめ

本記事では、Cursor を用いた Vibe Coding 実践方法について、具体的なフローとポイント、そして実践から得られた学びを共有しました。

Vibe Coding は、適切に活用すれば開発プロセスを大幅に効率化し、コード品質を向上させる可能性を秘めています。しかし、その効果を最大限に引き出すためには、AI との適切なコミュニケーション方法を確立し、AI が能力を発揮しやすい環境を整えることが不可欠です。

HataLuck and Person, Inc. Engineering

Discussion