Vibe Coding をやってみた所感 (Go言語でのTCPフォワーダー開発事例)

Page content

最近巷で話題の Vibe Coding を、周回遅れではあるが体験してみました。

その際に感じたこと、得られた知見をここに記しておきます。

TL;DR

  • Vibe Coding は、プログラマにとって非常に有用な開発手法の一つ
  • AI によってプログラマが職を失うのは、まだ当分先の話だと感じた(具体的な期間は不明)
  • 特に非同期処理の設計や実装において、LLM はまだ課題を抱えているように見受けられる

開発環境

今回の Vibe Coding は、以下の環境で実施しました。

  • エディタ: VS Code
  • LLM: Claude Sonnet 4

Claude Sonnet 4 は、現時点でのコーディング性能においてトップクラスのLLMとして 評価されているため、Vibe Coding の可能性を試すには最適な選択だと考えました。

お題: TCPフォワーダーの開発

今回は、以下の要件を満たすTCPフォワーダーを Vibe Coding で開発することに挑戦しました。

  • 使用言語: Go言語
  • 機能: TCPのフォワード接続(転送元と転送先のペア)の中継
  • セッション維持と再接続: 転送元または転送先のどちらかが切断された場合でも、 セッションを維持し、自動的に再接続を試みる(データ再送機能は含まない)
  • 多重接続管理: 複数のフォワード接続ペアを同時に管理できること
  • データ形式: 転送するデータはテキスト(ASCII)に限定
  • 設定方法: コマンドラインオプションで接続ペア (例: `-f :8080=localhost:80` のような形式)を指定できるようにする
  • 性能要件: Go言語のgoroutineを効果的に活用し、高効率なデータ転送を実現すること

LLMとのやりとりと開発プロセス

上記の大まかな指示を Claude Sonnet 4 に与え、開発を開始しました。

フェーズ1: 初期コード生成と課題

最初に生成されたコードは、 1組のフォワード接続を中継するだけのシンプルなものでした。 具体的には、「複数同時管理」「セッション維持」「再接続」といった 重要な要件が無視された状態でした。

また、初期コードはかなりの処理が1つの関数に集約されており、 可読性や保守性に問題がありました。 そこで、ある程度の処理単位で具体的に指示を与え、関数の分割と整理を行わせました。

フェーズ2: 要件の追加とLLMの挙動

次に、無視された要件(複数同時管理、セッション維持、再接続)を追加指示し、 コードの再生成を依頼しました。

この段階で「複数同時管理」には対応してくれましたが、 「セッション維持」と「再接続」は依然として無視されていました。 再度、これらの要件を追加するよう指示。

しかし、どうも意図がうまく伝わらないようでした。 「再接続」機能は実装されるものの、 「セッション維持」(例えば、一方の接続が切れてももう一方の接続を維持し続ける状態)は 実現できないコードが生成されました。

フェーズ3: 非同期処理の壁

そこで、「セッション維持」の概念をより詳細に、 ステップに分割して指示を出すことにしました。

しかし、やはり状況は改善しませんでした。 特に Go言語の goroutine を使った非同期処理の扱いがどうにも雑で、 明らかにバグを含んでいるコードが頻繁に生成されました。

非同期処理は一見しただけでは問題が分かりにくく、 生成されたコードを丹念に追って論理的な矛盾がないかを確認するのは非常に困難です。

これをAIがコードを生成するたびに検証するのは、 精神的にも時間的にも大きな負担となりました。 何度かやり取りを繰り返しましたが、なかなか意図した実装にはたどり着きませんでした。

この経験から、非同期処理のような複雑なロジックを「ふんわりしたプロンプト」で AIに任せるのは非常に困難であると痛感しました。

フェーズ4: 方針転換と具体的指示

この状況を打開するため、一度方針を転換しました。 これまでのAI任せだったフォワード接続の確立処理について、 こちらからドラスティックな変更を指示することにしました。

具体的には、

  • 接続先、接続元それぞれをどのように接続するか
  • 処理をどのように goroutine に分割するか
  • どの情報を chan (チャネル) を使って受け渡すか
  • どのように処理の同期や待合せを行うか

といった点を詳細かつ具体的に指示しました。

この具体的な指示によって、大枠の変更は無事に完了しました。

しかし、この変更で新しい処理が追加された際、 これまで使用していた古い処理が削除されずにそのまま残ってしまうという現象が見られました。 通常であれば、使わないコードは削除するか、 既存のコードを改良する形で修正されるものですが、 LLM はそのような配慮をしてくれないようです。

このような試行錯誤を繰り返し、 どうにか約1日がかりで目的の TCP フォワーダーツールを完成させることができました。 個人的な感想としては、もし最初から自分で実装していれば、 もう少し短い時間で開発できたのではないかと思います。

所感: Vibe Coding の可能性と限界

今回の Vibe Coding を通して、いくつかの重要な知見を得ました。

  • 大枠の設計には有用: Vibe Coding は、 ツールの全体像やコードの大枠を生成させる際に非常に有用だと感じました。 初期段階のプロトタイピングにおいては、大幅な時間短縮が期待できます。
  • 詳細な実装は人間に軍配: しかし、コードの細部、特に複雑なロジックや特定の要件を満たす実装に関しては、 AIに完全に任せるよりも、プログラマ自身が主導して進めた方が効率的であると感じました。
  • 設計案の提示は必須: ある程度、自分の中で設計案が固まっている場合は、 それをAIに具体的に指示して進める方が、AI任せにするよりも遥かに良い結果が得られます。 AIは必ずしもベストプラクティスを出力するわけではないため、 自身の経験に基づいた最適なアプローチを積極的に伝えるべきです。
  • コードレビューの重要性: AIが生成したコードを理解する際、 自身の想定している設計のコードであればレビュー時の理解が早く、正確にできます。 多少ベストプラクティスから外れていても、自分が理解しやすい、 やりやすい形であることの重要性を再認識しました。

なお、今回開発したコードの規模はコメント込みで約400行程度でした。 この程度の規模であっても、AIがその都度生成するコードを確認し、 的確な指示を出し続ける作業はかなりの集中力と疲労を伴います。

特に非同期処理に関しては、コードの動きを正確に理解するのに苦労しましたし、 潜在的な不具合がないかを判断するのも非常に骨が折れる作業でした。

今回の経験から、 特に Claude Sonnet 4 は Go言語の goroutine を使った非同期処理において、 まだ得意とは言えない挙動を見せると感じました。 そのため、非同期処理をAIに丸投げするのは避けるべきでしょう。

結論

以上の経験から、今回の Vibe Coding の結論は以下の通りです。

  • Vibe Coding は、プログラマにとって非常に役立つ強力な開発手法の一つ
  • AI によってプログラマが職を失うのは、まだ当分先の話だと感じている(具体的な期間は不明)
  • 非同期処理の設計や実装は、LLMが最も苦手とする領域の一つであり、まだその課題は大きい