私はロボットと話すのが好きじゃない
私はAndroidスマホを持っていますが、音声コマンドは無効にしています。アレクサを持ったことは一度もありません。Siriが具体的に何をするのかは正確にはわかりません。プレイリストを見つけてもらわずに人生を切り抜けてきたからです。だから、AIコーディングツールが無視できなくなったとき、私はゆっくりと関心を持ち始めました。しばらくの間、私は「一発勝負」と呼ばれることをしていました:いつものように働き、時々仕事の一部をAIに委ね、そして戻ってきた結果を待つのです。これはギャンブルが好きな人にとって、本当にクールなアプローチです。
私には、摩擦の一部がチャットインターフェースそのものにあった。モデルと会話するという考えは愚かだと感じた。私はものを作る。テキストボックスとは調整しない。
しかし、仕様駆動開発はそのようには機能しません。問題を正確に定義し、AIモデルにどのファイルを考慮するかを伝え、望ましい結果を説明し、AIがコードを一行も生成する前に、計画についてチャットで繰り返し議論します。現在のAIモデルはコーディングが速いですが、高レベル意思決定ではまだ危険なほど一貫性がありません。AIと作業するとき、あなたの仕事は設計判断を文書化仕様に変換することです。そうすれば、自分がコードを手打ちする場合に取るであろう行動に合致する低意思決定ステップのリストをAIに与えることができます。その仕様を正確にするためには、調整する必要があります。
過去6ヶ月でこれを学び、かなり上手になりました。ほとんど手書きでコードを書くことはありませんが、以前よりも多くの機能を提供しています。そして、ソフトウェア設計をモデルに任せていないため、25年間デジタル製品を構築してきたキャリアで培った品質基準を同じく適用しています。
私が予想していなかったのは、これを教えることがどれほど難しいかということです。
ピカソにはなれたのか?
(上層部の間で?)という考えがある:大規模言語モデルツールがすべてのエンジニアの生産性を向上させるだろうというものだ。実際には、私はこれを目にしたことがない。私が目にするのは、適応力のある経験豊富なエンジニアが以前の何倍もの成果を上げている一方で、他のエンジニアは同じかそれ以下の成果しか上げていないということだ。
これは初心者にとって良い状況ではありません。AIコーディングツールは、そのインターフェースが単なるテキストボックスなので、簡単に見えます。しかし、空白のキャンバスに無造作に絵の具を塗っただけではピカソにはなれません。
並行実装症候群
私が若手エンジニアを大切に思う理由はたくさんあります。特に、彼らは一緒に働くのが一番好きな人たちです!彼らの柔軟な考え方はまだ萎縮しておらず、物事を違う視点で見る手助けをしてくれます。最近、私は賢く、AIツールに熱心で、すぐに飛び込む意欲があり、ロボットと話すのを全くためらわない若手エンジニアとAI学習の旅に出ました。
それでも、なぜかうまくいかなかった。
最初の兆候は認証システムだった。彼女は既存のサービスにOAuthを追加する必要があり、モデルに認証フロー全体を一つの巨大な仕様で構築するように促した。ログイン、トークン更新、セッション管理、ロールベースアクセス、そしてログアウトフロー。すべて。モデルは喜んで応じた。そして、100%のコードカバレッジと合格したテストを備えた、完全に見える数百行のコードを生成した。
しかし、私がレビューしたとき、問題は構造的だった。モデルは、すでに持っていたセッションストアを使う代わりに、新しいものを作成していた。それは、私たちのAPIゲートウェイと競合するトークンリフレッシュパターンを導入した。ロールベースアクセスロジックは、すでに共有ミドルウェアに存在していたビジネスルールを重複させた。技術的には、これらは何も間違っていなかった—それは機能した。アーキテクチャ的には、すべてがそうだった。
私は彼女と向き合い、簡単な質問をしました:「これをプロンプトする前に、私たちが今日セッションをどう扱っているか知っていましたか?」彼女は一瞬沈黙しました。「正確には違います。」これがギャップでした。彼女はモデルにそれを基に構築するように依頼する前に、領域をマッピングしていませんでした。
次の試みは異なる方向に進んだが、まだ十分ではなかった。彼女はモデルに、新しいプロバイダーをサポートするためログインフローを修正するよう頼んだ。今回は、スコープを縮小していたのは良かった。しかし、彼女は変更を、既存コードが既に扱っている内容ではなく、ユーザーインターフェースに何をさせたいかという観点で説明した。モデルは、私たちの既存のプロバイダー抽象化について知る理由がなかったため、ゼロから並列実装を書いた。同じ結果になった:動作コード、不適切なアーキテクチャ。
起こったことについて話し合いました。私は彼女に、モデルをチームの新しい契約社員のように考えるように伝えました。才能があり、速いですが、コードベースの経験はゼロです。契約社員にこのプロジェクトを渡して立ち去るようなことはしないでしょう。こう言います: これが私たちのセッションストアです、これがミドルウェアです、新しいプロバイダを追加するためのパターンです。あなたの作業をこれに合わせてください。
彼女はコンセプトを理解した。しかし、次の数回のラウンドで、コンセプトが簡単な部分だということが分かった。彼女はモデルから単一の計画を得て、代替案を求めずにそれを承認してしまう。彼女はモデルが広範なコード変更を喜んで行うことを徹底していると見なしたが、私はそれを不必要なリスクと見なした。彼女はまだ「いいえ、この変更には変更範囲が広すぎます」と言う本能を持っていなかった。
経験豊かなエンジニアであれば、同じOAuthタスクを6つか7つの集中したラウンドで処理しただろう。各ラウンドは、すでに理解していたシステムの一部にスコープ化されていた。
ソフトスキルは新たなハードスキル
これは、AIコーディングの生産性向上を帳消しにするようなオーバーヘッドに聞こえるかもしれません。しかし、これらは新しいスキルではありません。経験豊富なエンジニアは、ずっと頭の中でこれを行ってきました。違いは、仕様駆動開発がすべてのタスクのソフトウェア設計計画を外部化することです。かつて内部で、あなたと自身の判断との間で行われていた設計協議は、今やチャットウィンドウで行われるのです。
チャットを開く前に、あなたは何を求めているかを知っておく必要があります。実装ではなく、挙動、制約、対象の形状です。モデルにその作業をどこに適合させるかを伝えるために、コードベースをよく理解しておく必要があります。モデルが答えを返してきたら、それはおそらく実行されるでしょう。しかし、それだけでは不十分です。それが実際にあなたの既存のシステムに適合するかどうかを確認しなければなりません。
時には、モデルが正しくて自分が間違っていると気づくことがあります。そして、それを公平に評価する謙虚さが必要です。
プロセス全体において、これらのツールを上手に使う人と速く使う人の違いは忍耐力にあります:それは、2回目で中途半端なものを受け入れるのではなく、5、6回もやり取りを繰り返す意思です。さらに、コードを書かずにコードについて正確に記述する技術、具体的にはデータフローやエッジケース、故障モードを平易な言葉で説明する能力も必要です。そして、センスも重要です。定義するのは難しいですが、見分けるのは簡単です:ソフトウェアが単に動作するかどうかではなく、長期メンテナンスの観点から、良いソフトウェアが持つ感覚を感じ取ることです。
そして、不快な部分があります。これらのスキルの大半は、長年の失敗から構築されたパターン認識です。悪いアーキテクチャ決定は、その結果を経験したからこそ認識できます。モデルの初回回答に抵抗するのは、最初のアイデアをリリースして後悔したことがあるからです。
若手エンジニアは、高度な設計協議を行う必要がある状況に置かれていますが、それに対するカリキュラムは存在しないようです。『LeetCode』から設計協議へと移行する時が来ており、これがこのシリーズの今後の投稿のテーマとなるでしょう。
補遺
AIとの仕様の調整のためのソフトスキル
交渉中
-
コード読解力: モデルが生成するコードを、構文だけでなく構造の健全性も確認します。適合性を確認するために読み、バグ探しではありません。 なぜ重要か: モデルは有効なコードを生成するかもしれませんが、あなたのシステムに合わない場合があります。それを迅速に捕捉する必要があります。
-
アーキテクチャのセンス: 技術的には有効だが、_このシステム_には間違っている解決策を認識する。 なぜ重要なのか: モデルは「私たちにとって間違っている」という意味を知らない。あなたは知っている。
-
創造的誘導: モデルが行き詰まったとき、代替フレームを見つける。問題を言い換え、類推を提案し、異なる制約を設ける。 なぜ重要なのか: モデルはフレームの仕方に反応し、より良いフレームがより良い結果を生み出す。
-
いつ立場を取るべきかを知ること: モデルは選択肢を中立的に提示する。あなたが決め、あるアプローチがあなたのコンテキストでより良いのかを_なぜ_明確に説明する。 なぜ重要か: それは技術的判断であり、それを構築するには何年もかかる。
-
生産的懐疑: モデルの最初の回答は解決策ではなく、草稿であると仮定する。皮肉ではなく、受け入れる前に圧力テストする習慣。 なぜ重要か: 初回出力は流暢性があるため魅力的である。流暢性は正確性ではない。
-
知らないことを知ること: モデルが正しくて自分が間違っているかもしれないときに認識する。 なぜ重要なのか: 交渉は双方向である。時には、考えていなかったアプローチが浮かび上がることがあり、それを公正に評価するには謙虚さが必要だ。
プロセス全体を通じて
-
忍耐: 2回目で平凡な結果を受け入れるのではなく、5、6回は反復してください。 なぜ重要か: これはツールを上手く使う人と速く使う人を分けるポイントです。
-
技術コミュニケーション: コードを書かずにコードについて正確に記述する。データフロー、状態変化、エッジケース、故障モードを平易な言葉で説明する。 なぜ重要なのか: これはほとんどのエンジニアが思うよりも難しく、そしてそれがあなたとモデルとの主なインターフェースである。
-
頭の中に複雑さを保持する: 現在の決定がモデルが知らないシステムの他の三つの部分とどのように相互作用するかを追跡する。 なぜ重要なのか: モデルには持続的アーキテクチャコンテキストがありません。あなたがワーキングメモリです。
-
センス: ユーザーの視点から見た良いソフトウェアの感覚。単に「動作するか」ではなく、「適切な体験、適切な振る舞い、適切な複雑さのレベルか」ということです。 なぜ重要か: これがないと、機能的だが間違ったソリューションを受け入れてしまうことになります。
-
止めるタイミングを知ること: 仕様が十分良くて実装に移せるタイミングと、過剰仕上げしているタイミングを見極めること。 なぜ重要なのか: 収穫逓減は現実です。ある時点で、さらなる調整は改善するよりもコストがかかるようになる。
