メインコンテンツへスキップ

Vibe Coding を手懐ける:エンジニアのための実践ガイド

·5 分· loading · loading · ·
agentic coding agile architecture software-engineering tdd vibe-coding
ダニエラ・ペトルザレク
著者
ダニエラ・ペトルザレク
Googleのデベロッパーリレーションズエンジニア

一年の終わりは、自分が成し遂げたこと、そしてやっておけばよかったと悔やまれることを振り返る絶好の時期です。今年(2025年)は私にとって極めて密度の濃い一年でした。4月に Google に入社し、AI の新時代に向けて自分自身を「リファクタリング」するノンストップの挑戦が始まったのです。一年を締めくくろうとしている今、その努力は十分に報われたと胸を張って言えます — 私は確実に、より良いエンジニアへと成長しました。

本稿では、私自身の「バイブコーディング(vibe coding)」に対する理解がどのように深まり、どんな教訓を得たのかを共有します。vibe coding は一般的に、非エンジニアが自然言語を使ってソフトウェアを構築するための手法として語られがちです。しかし私の目的は、そこにエンジニアリングの規律を融合させることで、より高品質で再現性の高い成果をいかに引き出せるかを示すことにあります。

もちろん、「バイブスに身を任せ、コードが存在することすら忘れてしまう」という提唱当初の定義は百も承知ですし、私がこれから語る考え方のいくつかは、その定義と真っ向から衝突するかもしれません。私自身は「コードの存在を忘れる」ことなど決してないからです。とはいえ、この言葉はすでに「AI 支援コーディング」全般を指す代名詞へと定着しつつあります。そこで本稿では、vibe coding を「エンジニア本人ではなく、LLM がコードの大半を記述するコーディング手法」と定義して議論を進めることにします。

動機:なぜバイブコーディングなのか?
#

具体的な実践ノウハウに深く切り込む前に、私のバックグラウンドを少し共有しておきましょう。どのような立ち位置からこの結論に至ったのか、文脈を理解してもらうためです。

私は 20 年以上にわたりソフトウェアエンジニアとして働き、「何が良いコードを構成するのか」についての確固たる感覚を培ってきました。「小手先の賢さ(cleverness)」よりも可読性や保守性を最優先すること、オーバーエンジニアリングを避けること、そしてバーティカルスライス(thin slices)とタイトなフィードバックループを何よりも重視することを学んできたのです。

しかし、シニアエンジニアからプリンシパルエンジニアへとキャリアを進めるにつれ、私の主業務は「自らコードを書くこと」から「チーム全体の生産性と成果(effectiveness)を最大化すること」へとシフトしていきました。エピックを起票し、スコープを交渉し、チームのアウトプット全体を監督する仕事です。これは多くのベテランエンジニアが直面するアイデンティティの危機でもあります。「Pull Request に自分の名前が載らなくなっても、自分はまだエンジニアと呼べるのだろうか?」と。責任が重くなるにつれて連日ミーティングに追われ、「本来のエンジニアリング」から遠ざかっているような焦燥感を覚えるようになります。

この葛藤は、この業界にいる誰もが遅かれ早かれ直面するものだと思います。そして必然的に、次のような問いへと突き当たります —「エンジニアであることとは、単にコードを書くことなのか? それとも、もっと本質的な何かなのか?」

正直に告白すると、私の最初の vibe coding 体験は散々なものでした。初期の ChatGPT が生成するコードはお世辞にも良いとは言えず、すぐに使うのをやめてしまいました。再び試してみようと思い直したのは、2024 年半ばのことです。基盤モデルは驚くべき進化を遂げていました。AI が私の思いつきもしなかった実装方針を提案し、しかもそれが客観的に見て私自身のアプローチよりも明らかに優れていたのです。このとき初めて、生成 AI(GenAI)が真に実用的なツールになったと実感しました。

私は GenAI をプロトタイプ作成や「ラバーダック・デバッグ」の相手としてツールボックスに加えました。使えば使うほど、その有用性に魅了されていきました。逆に、手作業でゼロからコードを書くことへのワクワク感は次第に薄れていました。いくら API を何本も書いてきたところで、その新鮮さはいつか失われます。私たちは往々にして、新しい価値を創造しているのではなく、過去のパターンの再生産を繰り返しているにすぎないからです。

そんなふうに自分のキャリアの選択に疑問を抱き始めていた矢先、Google への転職という転機が訪れました。

Gemini や AI エージェントについて対外的に発信するミッションを背負ったことで、私はスキルセットの本格的なアップデートに乗り出しました。LLM の基礎から Gemini CLI、そして Jules に至るまで徹底的に掘り下げたのです。ほんの数ヶ月のうちに、日々のコーディングで AI を日常的に使いこなすようになっていました……しかし何より大きかった変化は、「コードを書く楽しさ」が再び甦ってきたことでした!

私にとって最大のブレイクスルーは、「思考と同じスピードでコードをキーボードで打ち込むことはできなくても、頭に浮かんだアイデアをそのまま文字にして伝えることならできる」という気づきでした。vibe coding を行うとき、私は AI モデルを「自分の手の代行役」として活用しています。タイピングという物理的な実装作業をモデルに委任し、自分自身は本質的なソリューション設計に全神経を集中させるのです。

プロンプティングスキルを磨く
#

vibe coding の世界で最初に極めるべきスキルは、プロンプティング(prompting)です。ここ数ヶ月、親友のように気さくに雑談するスタイルから、命令口調で指図したり厳しく問い詰めたりするスタイルまで、ありとあらゆるアプローチを試してきました。そして — 当然といえば当然ですが — 最も高い成果を上げたのは、明確でプロフェッショナルなトーンを一貫して維持することでした。

LLM は本質的に非決定論的(non-deterministic)です。指示に曖昧さが含まれていると、この非決定性は一気に跳ね上がります。クリエイティブな解決策を模索させるためにあえて意図的な曖昧さを残すケースもありますが、日常的な開発の大半においては、曖昧さは可能な限り排除すべきです。

プロフェッショナルなトーンを保つことは、LLM 側にも同様の質とトーンを「返答として引き出す」効果があります。こちらが雑でくだけた指示を出せば、LLM もその雑さを忠実に真似てしまいます。スラング混じりの API ドキュメントを生成させたいのでもない限り、常に正確でブレのない指示を心がけましょう。

「LLM を擬人化しすぎだ」と批判されることもありますが、私はあえて繰り返します。モデルは人類が生み出した言語コーパスによって訓練されているため、生身の同僚に対して通用する優れたコミュニケーションスキルは、そのまま LLM に対しても有効なのです。この事実は、プロンプトテンプレートの構造を見ればよりはっきりと理解できます。

優れたアプローチ:プロンプトテンプレート
#

私が実践しているプロンプト作成手法は、アジャイル開発のカンバンボードでチケット(ストーリー)を起票するプロセスと驚くほどそっくりです。

誰しも、雑に書かれたユーザーストーリーに頭を抱えた経験があるはずです。「API を更新する」というタイトルだけのチケットを意気揚々と開いてみたら、説明欄が真っ白だった……。ログもなければ、コンテキストも、対象のソースコードへのリンクすらありません。コードを書くどころか、関係者を捕まえて仕様を確認する作業に何時間も浪費させられます。

不十分に書かれたチケットが並ぶアジャイルボード
こんな風にストーリーを書くチームで働いたことはありませんか?

こうした事態が起きるのは、起票者が問題の背景を「誰が見ても自明だ」と思い込んでいるからです。しかし 24 時間も経てば、その「自明だったはずの文脈」は霧散し、起票者本人ですら意図を解読できない謎のメモだけが残されます。

だからこそ、私の GitHub で最も古くから公開されている資産の一つが、この チケットテンプレート の Gist なのです。これは、以下の 4 つの要素によって記述の明確さを強制します。

- Context
- To dos
- Not to dos (optional)
- Acceptance Criteria
  • Context:実装の「理由(Why)」を明確にし、関連ドキュメントやリソース(アーティファクト)へのリンクを提供します。
  • To dos:大枠のタスクをリストアップします。
  • Not to dos:スコープの境界線を厳密に定義します(ネガティブな制約は、曖昧さを削ぎ落とす上で極めて強力な武器になります)。
  • Acceptance Criteria:タスクの「成功条件」を定義します。

このテンプレートを埋めた時点で、エンジニアリングとしての「思考」は大部分が完了しています。あとは実装するだけです。そしてこれこそが、まさに LLM が真価を発揮する領域です。コンテキストと To dos(および Not to dos)を与え、「受け入れ基準を満たすコードを生成して行間を埋める」ことをモデルに委任するわけです。

例えば、REST API に新しいエンドポイントを追加するためのプロンプト(チケット)は、次のようになります。

Implement /list endpoint to list all items of the collection to enable item selection on the frontend.

TO DO:
- /list endpoint returns the list of resources
- Endpoint should implement token based auth
- Endpoint should support pagination
- Tests for happy path and common failure scenarios

NOT TO DO:
- other endpoints, they will be implemented in a future step

Acceptance Criteria
- GET /list returns successful response (2xx)
- Run `go test ./...` and tests pass

これは簡略化した一例ですが、核心は極めて明快です。人間の開発チームに秩序と健全さをもたらすチケットテンプレートの構造こそが、LLM へのプロンプティングにとっても完璧なフォーマットなのです。

さらに優れたアプローチ:コンテキストエンジニアリング
#

上記のテンプレートは日常の大半のケースで機能しますが、Tool Calling(ツール呼び出し)を通じて外部 URL や外部データソースから情報を取得させようとする場合、予期せぬ結果を招くことがあります。問題の本質は、ツールに依存している場合、「そのツールを実際に呼び出すかどうか」の判断が LLM の裁量に委ねられている点にあります。一部のモデルは過度に「自信過剰」であり、外部ソースを参照するよりも自身の事前学習知識に頼ろうとします。あたかも「こんなの実装したこと何千回もあるんだから、ドキュメントなんて読む必要ないだろ?」と豪語する人間のエンジニアと同じです。

もう一つの典型的な落とし穴は、モデルが実際にツールを実行する代わりに、ツールの実行結果をハルシネーション(幻覚)で捏造してしまうケースです。モデルの振る舞いそのものが原因である場合、応答の品質を劇的に高めるアプローチは 2 つあります。コンテキストエンジニアリング(Context Engineering)システム指示(System Instructions)のチューニング です(よく考えれば、後者も会話チェーンの基底レイヤーにおけるコンテキストエンジニアリングの一形態に他なりません)。

コンテキストエンジニアリングとは、実際のリクエストをモデルに投げる前に、必要なすべての情報(少なくとも必要だと分かっている重要パーツ)をあらかじめコンテキスト内に流し込んで準備(プライミング)しておく手法です。例えば、Go 向けの Agent Development Kit(ADK)を使ってエージェントを開発する場合を考えてみましょう。通常なら次のようなプロンプトを書くかもしれません。

Write a diagnostic agent using ADK for Go.
The diagnostic agent is called AIDA and it uses Osquery to query system information.
The goal is to help the user investigate problems on the system the agent is running on. 
Before starting the implementation, read the reference documents.

References:
- https://osquery.io
- https://github.com/google/adk-go

TODO:
- Implement a root_agent called AIDA
- Implement a tool called run_osquery to send queries to osquery using osqueryi
- Configure the root_agent to use run_osquery to handle user requests
- If the user says hi, greet the user with the phrase "What is the nature of the diagnostic emergency?"

Acceptance Criteria
- Upon receiving hi, hello or similar, the agent greets the user with the correct phrase
- If asked for a battery health check, the agent should report the battery percentage and current status (e.g. charging or discharging)

これは悪くないプロンプトですが、いささか情報量が多すぎます。使用しているコーディングエージェントとその日の巡り合わせ次第では、モデルが自律的に調査を行い、適切な SDK を見つけ出し、診断エージェントを一発で正常に構築してくれるかもしれません。しかし運が悪ければ、モデルは「ADK」を「Agent Development Kit」ではなく「Android Development Kit」だと勘違いしたり、存在しない架空の API をでっち上げたりして、正解に辿り着くまでに(開発者が横から何度も軌道修正を入れながら)貴重な時間とトークンを浪費することになります。

最初からプロジェクトで ADK for Go を使うと決まっているのですから、まずはエージェントにパッケージの公式ドキュメントを直接読み込ませることで、コンテキストを確実にプライミングできます。

Initialize a go module called "aida" with "go mod init" and retrieve the package github.com/google/adk-go with "go get"
Read the documentation for the package github.com/google/adk-go using the "go doc" command.

本題のタスクを与える前にこの手順を踏んでおくことで、モデルには ADK for Go を正確に扱うための前提知識が注入され、不毛な試行錯誤や終わりのない Web 検索を丸ごとスキップできます。タスクの成否を分ける二大要素は、「正確なドキュメント」「具体的なコード例」 です。この両方をあらかじめコンテキストに与えておけば、モデルを放任して迷走させるよりも、はるかに適切に振る舞ってくれます。

百聞は一見にしかず:画像による指示
#

要求事項をテキストだけで表現し尽くすのが難しいケースもあります。診断エージェント AIDA の UI 開発記事 に取り組んでいた際、私は「レトロサイバーパンクでキュートなアニメ」風の独特な UI 美学を求めていました。これを言葉だけで事細かに説明しようとするのは骨が折れますが、「実物を見せる」 アプローチなら一瞬で伝わります。私は気に入った UI のスクリーンショットを 1 枚用意し、それを再現するよう Gemini CLI に指示しました。

Gemini 2.5 Flash のような最新モデルはマルチモーダルネイティブであるため、画像の内容を高い精度で「理解」できます。プロンプト内で画像ファイルを参照し、「UI を更新して、この @image.png のようなデザインに仕上げてください」と伝えるだけで済むのです。

なお、この @ によるファイル参照記法はツール依存(この例では Gemini CLI の機能)ですが、プロンプト内にリソースやファイルを注入するための一般的なデファクトスタンダードとなりつつあります。いわば「メールの添付ファイル」のような感覚で捉えてください。

私はこの手法を**「スケッチ駆動開発(Sketch-Driven Development)」**と呼ぶのが気に入っています。Draw.io や Excalidraw などの作図ツールを立ち上げ、欲しい画面構成をラフスケッチとして描いて渡すことが多いからです。以下の画像は、AIDA のインターフェース刷新時に実際に使用したラフスケッチです。

AIDAのレイアウトスケッチ
AIDA のレイアウトスケッチ

そして、このスケッチをもとにモデルが生成した実際のインターフェースがこちらです。

AIが生成したインターフェース
AI が生成したインターフェース

単にスケッチを渡すだけでなく、画像の上に直接「注釈(アノテーション)」を書き込んで、各パーツの役割を明確に指示するのも極めて効果的なテクニックです。例えば下図のように黒い枠線だけだと「どれが入力フォームで、どれがボタンなのか」をモデルが見分けるのは困難です。

名前入力欄と確認ボタンを備えたシンプルなインターフェースの注釈付き設計図
名前入力欄と送信ボタンを赤字で注釈したインターフェース設計図

これに対応するプロンプトは次のようになります。

Create a UI for this application using @image.png as reference.
The UI elements are in black, and in red the annotations explaining the UI elements.
Follow the best practices for organising frontend code with FastAPI.
The backend code should be updated to serve this UI on "/"

このアプローチの応用範囲は無限大です。Web サイトのレイアウト崩れを直したいなら、スクリーンショットを撮って修正箇所を赤ペンでマークし、LLM に投げるだけで修正コードを出力してくれます。

さらに、Gemini CLI 向けの Nano Banana 拡張機能などを活用すれば、開発ワークフローの中から直接画像アセットを生成・編集し、モデルにとってより理想的な参照画像を即座に用意することも可能です。より本格的な UI リデザインを行いたいなら、Nano Banana Pro を含む Gemini ファミリーを活用した Google の Stitch などのツールが、リッチなインターフェース設計環境を提供してくれます。

適切なツールを選択する
#

プロンプトの技術を磨くことは、戦いの半分にすぎません。残りの半分は、「そのプロンプトをどのツールに投げるか」 の見極めです。今日、JavaScript フレームワークの増加スピードを上回るものが世界に一つだけあるとすれば、それは AI エージェントの数でしょう。ツールエコシステムが日進月歩で拡大し続ける中、最適なアシスタントを選ぶための「メンタルモデル」を持っておくことが極めて重要になります。

私は AI エージェントを、「操縦士(パイロット)の視点」から分類するのが分かりやすいと考えています。自らが完全に主導権を握り、オートコンプリートの提案を受け取りながら進めるのか? エージェントと対話しながら共同でコードを編集していくのか? それとも、指示だけを渡してバックグラウンドで完全自律実行させるのか?

人間が操縦席に座り、エージェントの手綱を握り続けるスタイルを、私は**「同期型(Synchronous)」体験と呼んでいます。一方、タスクをまるごと委任してバックグラウンドで自律実行させるスタイルを「非同期型(Asynchronous)」**体験と呼んでいます。代表的なツールの分類は以下の通りです。

  • 同期型(Synchronous): Gemini CLI、VS Code の Gemini Code Assist、Claude Code
  • 非同期型(Asynchronous): Jules、Gemini CLI(YOLO モード)、GitHub Copilot Agent

もちろん、あらゆる分類体系がそうであるように、この区分は理解を助けるための便宜的な整理にすぎません。同じツールであってもモードによって両方の振る舞いが可能ですし、まったく新しいパラダイム(Antigravity のような存在)が次々と登場してくるからです。

それぞれのタスクにどのツールを割り当てるべきかを判断するため、私は「ビジネス価値(Business Value)」と「技術的確実性(Technical Certainty)」を軸にしたシンプルな 2x2 フレームワーク を活用しています。

AI支援ワークフローの2x2フレームワーク
AI 支援ワークフローの 2x2 フレームワーク

  • 高価値 / 高確実性(High Value / High Certainty): 同期型で進めます。Gemini CLI や IDE などのツールを使い、自らが常にループの中(in the loop)に留まり、キーボードから手を離さずに作業を進めます。
  • 高価値 / 低確実性(High Value / Low Certainty): 不確実性を減らすためのリサーチが必要です。非同期ツールやディープリサーチエージェント、プロトタイプを活用してソリューションをスパイク(検証実装)します。
  • 低価値 / 高確実性(Low Value / High Certainty): いわゆる「あると嬉しい(nice-to-have)」機能や定型タスクです。Jules や GitHub Copilot Agent のようなバックグラウンドエージェントに非同期で丸投げし、自分自身の時間はより高価値な作業のために確保します。
  • 低価値 / 低確実性(Low Value / Low Certainty): 基本的には手を出すべきではありません。どうしても取り組む必要があるなら、気休め程度にバックグラウンドエージェントに任せつつ、まずは技術的な確実性を高めることに注力してください。その過程で、価値そのものの再評価につながることもあります。

エージェントをカスタマイズする
#

生産的な仕事に集中したいときに、AI と不毛な押し問答を繰り広げたい人はいません。AI ツールに対する代表的な不満の一つが、「勝手に余計なことをする(過剰に積極的すぎる)」という点です。明確な指示もないのに勝手にファイルを削除したり、独りよがりな前提でコードを書き換えたりする現象です。AI を「自分の味方」として忠実に働かせるには、適切なカスタマイズが欠かせません。

エージェントをカスタマイズするアプローチには、大きく分けて 2 つの道筋があります。1 つ目は、エージェントがプロジェクト読み込み時に参照する AGENTS.md ファイルを配置する方法です。(※ AGENTS.md が標準規格として普及する以前は、GEMINI.mdCLAUDE.md といった独自のコンテキストファイルが使われていましたが、本質的な役割は同じです)。

2 つ目は、いわば究極の選択肢(核オプション)である**「エージェントのシステム指示(System Instructions)を直接書き換える」**方法です。すべてのエージェントがこの柔軟性を提供しているわけではありませんが、完全に自分好みの開発体験を構築するための最も強力なレバーとなります。以下、それぞれの詳細を見ていきましょう。

AGENTS.md
#

このファイルは、AI エージェントに対する「従業員ハンドブック(就業規則)」のようなものだと考えてください。プロジェクトの目的、ディレクトリ構成、そして「中間ステップは必ずコミットすること」「破壊的な変更を行う前に必ず確認を取ること」といった開発運用ルールを記述します。

# Project Context

This is a personal blog built with Hugo and the Blowfish theme.

## Code Style
- Use idiomatic Go for backend tools.
- Frontend customisations are done in `assets/css/custom.css`.
- Content is written in Markdown with front matter.

## Rules
- ALWAYS run `hugo server` to verify changes before committing.
- Do NOT modify the theme files directly; use the override system.
- When generating images, save them to `assets/images` and reference them with absolute paths.

プロのヒント(Pro Tip): 自己改善ループを構築しましょう。コーディングセッションが終わったら、LLM に「今行ったセッションを振り返り、開発ワークフローを改善するための提案を出して」と依頼します。そこで得られた学びを AGENTS.md に追記していくことで、プロジェクトをこなすごとにエージェントが賢く成長していきます。

システム指示(System Instructions)
#

AGENTS.md が「プロジェクト固有のルール」を規定するのに対し、システム指示は「エージェントのペルソナ(人格)と根本的な行動規範」を定義します。あらゆるエージェントには標準のシステム指示があらかじめ組み込まれていますが、それは万人向けの汎用的な振る舞いをするように設計されているため、個人の作業スタイルや特定の言語作法には必ずしもマッチしません。AGENTS.md に大量の指示を詰め込んで無理やりデフォルトの挙動を上書きしようとするのは逆効果になりがちです。最も確実なアプローチは、システムプロンプトそのものを目的に応じて書き換えることです。

システムプロンプトの上書きを許可しているエージェントは限られますが、Gemini CLI ではいくつかの環境変数を設定することでこれが可能です。私はこの機能を活用して、プロジェクトの技術スタックに応じた専門特化型の Gemini CLI エイリアスを作成しています。その目的は、単に「どんな言語もそこそこ書ける汎用アシスタント」ではなく、特定の技術エコシステムを熟知した「シニア〜プリンシパルエンジニア級のスペシャリスト知識」をエージェントに宿らせることにあります。例えば、私の dotgemini プロジェクトでは、Go や Python 開発専用のシステムプロンプトを用意し、標準の汎用アシスタントを「極めて強いこだわりを持ったエキスパートエンジニア」へと差し替えています。

以下は、私が Go 言語開発用に実際に使用しているシステムプロンプトの抜粋です。

# Core Mandates (The "Tao of Go")

You must embody the philosophy of Go. It is not just about syntax; it is about a mindset of simplicity, readability, and maintainability.

-   **Clear is better than clever:** Avoid "magic" code. Explicit code is preferred over implicit behaviour.
-   **Errors are Values:** Handle errors explicitly and locally. Do not ignore them. Use `defer` for cleanup but explicitly check for errors in critical `defer` calls (e.g., closing files).
-   **Concurrency:** "Share memory by communicating, don't communicate by sharing memory."
-   **Formatting:** All code **MUST** be formatted with `gofmt`.

これにより、ターミナルで gemini-gogemini-py と打ち分けるだけで、対象言語のエコシステムやベストプラクティスを骨の髄まで理解した「専属エージェント」を呼び出せるようになります。

Model Context Protocol(MCP)でツールボックスを拡張する
#

ここまでのカスタマイズはエージェントの「振る舞い」に関するものでしたが、もう一つ重要なのがエージェントの「拡張性」です。ここで主役となるのが Model Context Protocol (MCP) です。MCP 標準規格に準拠したサーバーを実装することで、開発者は多様な AI エージェントに対して自由自在に外部機能を接続できるようになります。

以前執筆した Hello, MCP World! の記事でも解説した通り、MCP サーバーはエージェントに対して「Tools(外部ツール)」「Prompts(定型プロンプト)」「Resources(データリソース)」を提供します。中でも Tools は、API の呼び出しや Web 検索、ローカルファイルの操作など、エージェントが現実世界にアクションを起こすための架け橋となるため、最も大きな注目を集めています。

現在では多種多様な MCP サーバーが公開されており、その選択肢は日々爆発的に増え続けています。しかも自作するのも極めて容易であり、自分専用のサーバーを作ることを強くお勧めします。後ほどパーソナライズされたソフトウェアについて詳しく触れますが、「AI を使って、AI の回答精度を高めるための専用ツールを自作する」というアプローチこそ、私が今年身につけた最も強力なハックです。

実際、私自身も愛用している 2 つの MCP サーバー — Go のコーディング品質を向上させる GoDoctor と、ブログの執筆・公開フローの退屈な作業を自動化する Speedgrapher — を vibe coding で構築しました。どちらも私自身のリアルな開発ワークフローに合わせて完全に最適化されています。

これによって、素晴らしい好循環が生まれます。自分の生産性を高めるためのツールを作り、そのツールを使ってさらに高度なツールを開発していくのです。これこそが、私がこれまでのキャリアの中で最も「10x エンジニア」に近づけた瞬間だと確信しています。

バイブコーディングのワークフロー
#

私の vibe coding 体験は、感動的なひらめきに満ちていると同時に、時には苛立ちで頭を抱えるものでもありました。常に「感動的」な側に留まり続けるため、私はこの開発ワークフローを 「TDD(テスト駆動開発)を極限までブーストしたもの(TDD on steroids)」 として捉えています。

ここで、クラシックな TDD サイクルをおさらいしてみましょう。

  1. Red(失敗): まずは失敗する小さな機能テストを作成する。
  2. Green(成功): そのテストをパスさせることだけに全力を注ぐ。テストが失敗している間は、余計なコードに手を加えたり最適化を図ったりしない。
  3. Refactor(改善): テストが通り正常に動作したら、コードの構造や品質を心置きなく洗練させる。

標準的なTDDサイクル
伝統的な Red-Green-Refactor ループ

バイブコーディングにおいても、根本的にやっていることはまったく同じです。ただし、生成されたコードが設計基準、コーディング規約、セキュリティ要件に厳格に適合しているかを検証する「リファクタリング(Refactor)」ステップの重要性が格段に高まります。

この適応型サイクルでは、各フェーズの焦点が次のように変化します。

  • Red(受け入れ基準の定義): 手作業で失敗する単体テストを書く代わりに、プロンプト内で明確な「受け入れ基準(Acceptance Criteria)」を定義します。これが、モデルが満たすべき契約(コントラクト)となります。
  • Green(AI によるコード生成): エージェントがソリューションを実装し、理想的にはそれが正しく機能することを証明するためのテストコードまで含めて生成します。
  • Refactor(規律の強制と品質保証): ここが品質の防波堤(品質ゲート)です。コードレビューに AI の力を借りることは大いに推奨されますが、コードを生成したのと同じセッションでレビューを行わせてはいけません。自らの出力に対して強いバイアス(自己正当化の偏見)が働くからです。私が GoDoctor に専用の review ツールを組み込んだのも、まさにこのためです。このステップで従来のリンターや自動テストを実行し、コードが基準を満たしているかを厳しく精査します。そして変更をコミットした上で、散らかったセッションによる混乱を防ぐためにエージェントのコンテキスト履歴を一度クリアします。

バイブコーディング向けに適応した開発サイクル
バイブコーディング向けに適応した開発ループ

最も重要な原則は、**「検証を挟まずに LLM にコードを積み上げさせないこと」**です。エラーが連鎖・増幅(extrapolate)してしまうと、最終的に手遅れのがらくたが出来上がってしまいます。私が画面に向かって「元に戻せ(undo)!」と叫ぶ羽目になった回数は数え切れません。さらに恐ろしいことに、モデルは時に 度を超えたやり直し をやらかします。例えば git reset --hard を勝手に実行して、4 時間分の作業成果が一瞬で虚空に消え去るような悲劇です。

「バイブスの崩壊(vibe collapse)」や「コンテキストの腐敗(context rot)」には常に警戒してください。セッションが長引きすぎたり、失敗した試行錯誤が履歴に蓄積しすぎると、モデルの思考能力は目に見えて劣化し、同じ間違いを堂々巡りで繰り返すようになります。モデルが 2 つの壊れた修正案の間を行ったり来たりする無限ループに陥ったら、即座に手を止めてください。最善の特効薬は、セッションを「一度電源を切って入れ直す(コンテキストをリセットして履歴を消去する)」ことです。

ハルシネーションを起こして暴走したセッションを対話で無理に修正しようとするよりも、頻繁にコミットを残しておき、安全なチェックポイントへいつでも巻き戻せるようにしておく方がはるかに健全です。一つのタスクが完了したら、即座にコミット&プッシュし、コンテキストを完全にクリアしてから次のタスクに着手することを強く推奨します。

パーソナライズドソフトウェアの時代
#

単なる生産性の向上を超えて、vibe coding はさらに深遠な地平を切り拓きます。それは、「パーソナライズされたソフトウェア(自分専用の特注ツール)」の経済的実現可能性です。MCP のセクションでも触れましたが、これは使い捨ての小さな自動化スクリプトから、本格的なスタンドアロンアプリケーションに至るまで、あらゆるソフトウェアに当てはまります。

かつては、自分ひとりのためだけに特注のツールを開発することは、費用対効果の観点から割に合わない贅沢でした。しかし今や、わずか 3〜4 回のプロンプトのやり取りだけで、完全に動作する実用アプリケーションが手に入ります

例えば最近、私は Markdown 記法で書かれたテキストを Google ドキュメントに綺麗に変換する方法に悩んでいました。従来のやり方なら、Google 検索で最適なツールを探すのに何時間も費やし、オープンソースから商用サービスまで無数のアプリやブラウザ拡張機能を比較検討していたはずです。機能一覧をもとに候補を絞り込み、レビューや評価を読み漁り、開発元が信頼できるかどうかセキュリティ上の安全性を必死に確認していたでしょう。

今日、そうした摩擦(フリクション)は完全に過去のものとなりました。ツールを探し回る代わりに、私はわずか数分でシンプルな Google ドキュメント専用拡張機能を vibe code し、ドキュメントにインストールして一度実行し、何事もなかったかのように次の仕事へと移りました。貴重な時間を大幅に節約できただけでなく、出所不明の拡張機能によって自分のマシンに見知らぬトロイの木馬が仕込まれる心配もなく、夜もぐっすり安心して眠ることができます。

このパラダイムシフトは、「作るか買うか(Build vs. Buy)」の損益計算を根本から覆します。私たちはもはや、中身のブラックボックスな汎用ソフトウェアを消費するだけの受動的なユーザーではありません。**自らの道具を自らの手で生み出す「道具のアーキテクト」**になれるのです。

まとめ
#

Vibe coding とは、決してエンジニアが手を抜いて怠けるための手法ではありません。より高い抽象度でシステムを思考し、操作するための新たなアプローチです。LLM が持つ圧倒的な創造的パワーと、ソフトウェアエンジニアリングが培ってきた規律ある実践 — 明確な要件定義、徹底したコンテキスト管理、そして妥協のないテストと検証 — を融合させることで、私たちはかつてないスピードと、何より純粋な喜びを持ってソフトウェアを創り出すことができます。

さあ、バイブスに身を任せましょう。ただし、その旅には必ず**「エンジニアとしての誇りと帽子(engineering hat)」**を忘れずに携えていってください。

関連記事

Speedgrapherの紹介:Vibe WritingのためのMCPサーバー

·2 分· loading · loading
agentic coding ai gemini-cli golang mcp vibe-coding
「Vibe Writing(バイブライティング)」のためのカスタムMCPサーバー「Speedgrapher」の開発ストーリー。個人のプロンプト集を、執筆やクリエイティブなプロセスを自動化・構造化するポータブルなAIツールキットへと進化させた道のりを紹介します。

Gemini CLIをカスタマイズする:GEMINI.mdとシステム指示

·4 分· loading · loading
agentic coding gemini-cli tutorial vibe-coding
GEMINI.md やカスタムシステム指示(system instructions)を活用し、自分のコーディングスタイルに合わせて Gemini CLI の挙動を最適にカスタマイズする方法を解説します。

Jules を使ってブログに特集記事セクションを追加した記録

·1 分· loading · loading
agentic coding jules tutorial vibe-coding
AIコーディングアシスタント「Jules」と協調しながら、ブログのホームページに新たな特集記事(Featured Post)セクションを実装した、試行錯誤とイテレーションの詳細な記録。