世界を動かす技術を、日本語で。

2年間のバイブコーディングを経て、手書きに戻りました

概要

  • AIコーディングの最初の驚きとその限界に気づく過程
  • 仕様書を詳細に書いてもAIの成果物は期待通りにならない現実
  • AIエージェントによるコードは一見良さそうに見えても全体的な整合性に欠ける問題
  • 人間による手書きコーディングの優位性の再認識
  • 本質的な品質や責任を考慮した場合のAI活用の課題

AIコーディングの現実と限界

  • AIコーディング の出発点は、ほとんどの人が 簡単なタスク を与えて驚く体験
  • 段階的に 大きなタスク を任せてさらに感動する流れ
  • SNS(例: X)で 雇用喪失 への不安やAIの進化について投稿する傾向
  • ここで止まらずに進んだ人は、AIコーディングの 本質的な難しさ を理解する少数派

エンジニアが直面するAIの壁

  • 本格的な開発現場では、AIに より大きなタスク面倒なリファクタ を試す流れ
  • 一方で、AIは 理解力の高さ に驚かせつつも、 明らかな誤りや一貫性のなさ を見せる
  • モデルに怒っても意味がないため、 自分のプロンプトや指示の曖昧さ を反省する思考
  • 仕様を明確にすればAIは完璧に作れる」という幻想を持つ

仕様書駆動開発の落とし穴

  • Obsidianなどで 詳細な仕様書 を作成し、AIに指示する試み
  • しかし、現実の開発では 仕様書や設計書は常に変化・進化 するもの
  • AIエージェントは、 一度決めた仕様から逸脱できず、柔軟な対応が苦手
  • 問題が複雑化すると、エージェントは 途中で投げ出す か、無理やり進めてしまう傾向

AI生成コードの落とし穴

  • AIが書くコードは 見た目が良く、プルリクエストも一見優秀
  • しかし、 全体のコードベースを通して読むと一貫性や構造的な整合性がない
  • 単体では正しいが、全体としては破綻したコード になりがち
  • 例えるなら、 小説の一部は良いが、全体の章としては成立していない 状態

人間によるコーディングへの回帰

  • AIによる高度なコード を何ヶ月もレビューした結果、「これでは出荷できない」という結論
  • ユーザーの信頼やデータ保護 を考えると、AI生成コードでは責任が持てない
  • 結局、 手書きコーディング の方が 速く、正確で、創造的かつ生産的 であると再認識
  • すべてのコストを考慮すると、 AIより人間の方が効率的 な場合が多いと実感

まとめ

  • AIコーディングは 驚きと期待 から始まるが、 現実は甘くない
  • 仕様書や設計の進化にAIは追従できず、全体最適化も困難
  • 品質・責任・信頼性 を重視するなら、 人間の手による開発 が依然として最良の選択

Hackerたちの意見

振り返ってみると、納得できる話だね。エージェントは、孤立した状態で見栄えのいい変更単位を書くんだ。自分自身やプロンプトには一貫性があるけど、全体への配慮はない。構造的な整合性への配慮もないし、隣接するパターンへの配慮もなかった。まあ、でもこれに対抗する方法はいくつかあるよ。俺のやり方は、自分のコードベースを理解して、LLMの出力を見ることだ。LLMのおかげで、コードを書くのが早くなるし、あまり知らなかったプログラミングの概念を発見することもできる。例えば、今まで使ったことがなかったTailwind CSSをたくさん使うことになった。でも、だからといって自分のコードベースを知らなくてもいいわけじゃない。概念的にバラバラな状態でいるのが(一時的に)許せるなら別だけど。俺は、バイブコーディングが新しいプロジェクトのための高忠実度プロトタイプを素早く作るのに素晴らしいと思ってる。作って、雰囲気を感じながら、アプリが自分の思い描いた通りになるまで進めていくんだ。その後、リファクタリングしてスケールさせる。今は、JS/JSXが4009行になってる。まだプロトタイプをバイブコーディングしてるところだ。最近、コードベースを見て、すぐに改善できるところを見つけたから、それをやった。でも、10K行に達したら、実際にエンジニアリングを始める必要が出てくると思う。

自分のコードベースを理解して、LLMの出力を見るのが俺のやり方だ。そうすると、バイブコーディングじゃないよ。バイブコーディングの核心、ほぼ唯一の要件は、コードを見ないことなんだ。製品の結果だけを見る。

AIはすごく危険だよ。簡単なことを非常にうまくやってしまうから、新しいプログラマーが基本的なことを学ぶのを妨げるんだ(「ああ、AIに生成させればいいや」って)。それが、彼らが中間的で難しいことやメタなことを本質的に学ぶのを妨げる。俺はCSの教師だから、今ここに大きな危険があるのを感じてるし、学生にもはっきり言ってる:コードを書く必要があるんだ。機械にコードを書かせちゃダメだよ。確かに、機械はコードを書くことができる。君は学生なんだから、コードはまだ難しくない。でも、君がコードを書く必要があるんだ。

デンマークでCSの学生の外部試験官をやってるけど、君とは意見が違う。業界で必要なのは、自分で考えられるソフトウェアエンジニアで、ビジネスとやり取りできて、そのニーズを理解できる人たちだ。そして、彼らはコンピュータの仕組みを理解している必要がある。今得られているのは、大量生産されたコーダーで、古い設計やソフトウェア構築の方法を教えられているから、それを叩き直さなきゃいけない。人々が組み立てラインのようにコードを書けるかどうかは特に気にしない。ボトルネックを特定して解決できるかどうかが大事なんだ。ビジネス価値を迅速に提供できるかどうかもね。抽象化を行うタイミングを知っている(ほとんどないけど)ことも重要だ。クソみたいなコードが年間2ドルのコストで済むなら、毎時間それに費やすのが100-200ドルになることを知っている開発者が欲しい。君のカリキュラムはここら辺とは違うかもしれないけど、ここでは正直、30年前に教わったことと同じことだ。実際のコンピュータサイエンスの部分はほとんどなくなって、さらに多くのOOPやデザインパターンのクソみたいなものに置き換わっている。とはいえ、今の学生にCSを教える方法が全くわからない。多くの学生がChatGPTやClaudeを使うだろうから、君が何をしても関係ない。ここでの成績の統計を見ているとそう感じる。最初の9年間は、俺はよく調整された採点者だったけど、ここ1年半くらいは、通常、最高点か最低点のどちらかで、その間は何もない。これが俺を本来いるべき場所から外れさせているけど、ここにいる全員の統計的な調整に合っている。俺はCS教育の成果しか見ていないけど、年を取った今でも、当時LLMがあったらどれだけ手を抜いていたか想像できる。インターネットがもたらしたすべての気晴らしを言うまでもない。

ウエイトリフティングみたいなもんだよね。フォークリフトを使ってもできるけど、自分の力をつけたいならフォークリフトじゃダメなんだ。これが学問におけるAIの根本的な問題だと思う。肉体的な作業には「痛みなくして得るものなし」ってのが当てはまるのはみんな知ってるけど、学びにも同じことが言えるよね。もちろん、職場では結果を出すことが重要になるから、学びとは違う側面もあるけど、それでも高いレベルの思考ができる人は必要だよ。

教える内容は少し適応する必要があるかもしれない。コードがどう動くかを教えることは、コーディングの仕方を教えるよりも重要だ。ほとんどの学術的なコンピュータサイエンティストは、プログラマーとして特にスキルが高いわけではないしね。少なくとも、私は自分が学術的でなくなってから(博士号を取得した後)そのほとんどを学んだ。これでいいんだ。プログラミングを学ぶことは、コンピュータサイエンスを勉強する副産物であって、核心的な目標ではない(これはいつも明確に理解されているわけではない)。ここでの良いアナロジーはアセンブラでのプログラミングだ。1980年代に初めてコンピュータを手に入れたとき、機械語レベルでプログラムを手動で作成するのは非常に一般的だった。特にゲームに関してはね。90年代後半にはほとんど消えてしまったけど、Roller Coaster Tycoonのようなゲームは、そういう風にコーディングされた最後の成功例の一つだった。C/C++が主流になって、今ではほとんどのゲームスタジオがエンジンをライセンスして、C#やLUAのような言語でたくさんの作業をしている。私はアセンブラプログラミングを意味のある量やったことがない。私がコンピュータサイエンスを学んでいた時(94-99)には、ほとんど関連性のないスキルになっていた。2年目に、架空のCPUのためのインタープリターを作ったことがある。私たちのコンパイラの授業は、Eric Meyerのような人たちが教えていて(後にMSでF#のようなものに取り組んだ)、彼らはそれを機会にして、みんなに関数型プログラミングを教えようとしていた。振り返ってみると、それは実際に良いスキルだった。関数型プログラミングへの関心が10年後にかなり高まったからね。このアナロジーのポイントは、コンパイラは重要なツールだってこと。コンパイラをアセンブラで作ることができることよりも、どうやって機能するかを理解する方が重要だよ。多くの人はコンパイラに関わることはないし、自分のオペレーティングシステムやデータベースを作ることもない。でも、どうやって機能するかを理解するのは役立つ。コンパイラがどう機能するかを教える目的は、プログラミング言語がどのように作られ、どんな制約があるかを理解することなんだ。

簡単なことをうまくやってくれないことがあって、余計にイライラするよ。僕はWindows開発をやってるけど、GDIのことはまだ混乱する。メモリDC、互換DC、DIB、DDB、DIBSECTION、bitblt、setdibitsとかね… AIもこの辺はダメだよ。比較的簡単なタスクを手伝ってもらおうとすると、ほぼ毎回、選んだ理由を説明させると問題が見つかって謝って、ぐるぐる回ってる。あるAI(どれか忘れたけど)なんて、PetzoldのWindowsプログラミングの本を参照するべきだって言われたこともあるよ。もう手伝えないってさ。」

100%同意だね。でも、25年の開発経験がある身としては、もう退屈な部分をあまりやらなくて済むのは本当にありがたいよ。

教師として、学生がコードを書くことを学ぶためのテクニックってありますか?

金属加工の授業について読んだことがあるんだけど、先生が最初に各生徒に金属のブロックとヤスリを渡して、そこからレンチを作らせるんだって。成功したら、次は機械工具の使い方を学ぶって感じ。金属を切る感覚を養うのが目的なんだ。 -- 僕の木工の先生は、手動の平面を使う方法を教えてくれた。薄くて透明になるくらいの木を削れるようになったんだ。それで、二つの板をほとんど見えない隙間でつなげられるようになった。ジョインターではそこまで上手くできなかったよ。

そうだね!自分でやってみるか、道具が何をしているのかをよく観察してから使うのが一番だよ。HDLで機能するプロセッサを全部作る必要はないけど、デジタルロジックやコンピュータアーキテクチャの基本は理解しておくべきだよ。OSをアセンブリで書く必要はないけど、アセンブリがバイナリにどう変換されるかや、リソース管理、IPC、ファイルシステムの基本を理解するのは、低レベルの仕事をするなら必須だね。CS専攻なら、アルゴリズムやデータ構造は絶対必要だし、独学やブートキャンプでフロントエンド開発を学んでいるなら、HTMLやDOM、イベント、CSSの仕組み、JSのコアコンセプトを学ぶべきだよ。Reactだけじゃダメだよ。道具がうまくいかない時や新しい道具が出てきた時に役立つからね。

エージェントは、数週間にわたって仕様を進化させる能力がないだけでなく、最初に決めたことから後で逸脱しない決定をする。それは君の仕事だ。コーディングエージェントの素晴らしいところは、「デザイン変更:すべてのAPIインタラクションは、新しいクラスを通じて行う必要がある。そのクラスは認証やリトライ、レートリミットの調整を行う」と言えば、更新が必要な場所を数十箇所、あるいは数百箇所見つけて、全部修正してくれることだ。(そして、自動テストスイートがリファクタリングが正しく機能したか確認するのを手伝ってくれるよ。だって、元の機能を作ったときに自動テストスイートを構築させたんだから、そうだよね?)自分で全てのコードを打ち直す(俺の解釈では「手書き」)のは、エージェントの管理スキルがないから、彼らに作った混乱を片付けさせられないというのは、短絡的に感じる。

Hacker Newsで議論の続きを見る