中島聡が実演する、コードを一行も書かないClaude Codeでの開発
中島聡のLife is Beautifulメルマガ読者からの要望が多かったことを受け、中島聡が自身のコーディング風景を実況した。題材は、中島が開発中のAIチャットアプリ「MulmoChat」のUI変更である。約30分の作業で中島は一行もコードを書かず、Claudeに細かく指示を出し、提案された変更に目を通すことを繰り返した。中島はこの進め方を「バイブコーディング」とは違うものだと位置づけ、AIを現時点では「ジュニアエンジニア」と評価している。
開発環境:エディタ、ブラウザ、3つのターミナル
画面にはエディタのCursorとブラウザが並んでいる。普段はCursorを大きいスクリーンに、ブラウザを接続したMacBook Proの画面に出すが、撮影のため同じ画面に表示している。中島によれば、もうCursorである必要はなく、Microsoftの開発環境だけでも十分だという。Cursorは惰性で使い続けているだけで、コーディングの大半はClaudeに任せている。
開発対象のMulmoChatは、AIチャットからさまざまな操作ができるアプリだ。中島はこれを、将来のLLMを中心にしたOSのユーザーインターフェースを設計する意味合いも持つものだと説明している。
ターミナルは常に3つ動かしている。1つ目でサーバーを立ち上げ、ブラウザからアクセスする。サーバー側を書き換えない限り、このターミナルは閉じずに置いておく。2つ目はGitの操作用で、3つ目でClaudeを走らせる。
まずブランチを切り、対象ファイルを読ませる
作業を始めるときは、最初にブランチを切る。今回はセットアップ関係の変更なので、mainからコピーした「setup change」という名前のブランチを作り、そこでClaudeを起動した。
ClaudeのMDファイルにはさまざまな指示が書いてある。それでも中島は、効率を上げるため、最初に変更してほしいファイルを読むよう依頼する。今回はメインビューなどのファイルを指定して読み込ませ、準備を整えてから具体的な作業に入った。
変更1:セットアップボタンをサイドバーへ移す
最初の作業は、メイン画面にあるセットアップボタンをサイドバーに移すことだった。中島によれば、こうした作業は人間がやると意外に面倒だ。基本はコードを動かしてカット&ペーストするだけだが、意外と間違えることが多いという。
Claudeはまずサイドバーに追加する部分を示し、続けてメイン側からボタンを消す変更を提案してきた。中島は確認画面で1番を選んで承認した。2番を選んで以降を自動化することはしないと話している。Claudeはシステムプロンプトもサイドバーからアクセスできるようにし、設定用のポップアップのコード自体もアプリ側からサイドバー側へ移した。変更の途中ではエラー表示も出たが、完了後にエラーを消し、ボタンがサイドバーで動き、メイン画面からは消えていることを確認した。
UIの変更については、コードをそれほど真剣には見ないと中島は言う。ざっとは見るが大騒ぎする話ではなく、動かなければ分かるからだ。
ここで一度コミットする。細かくコミットしておけば、何かおかしくなったときにすぐ戻れる。中島は自分でコードを書いていたときも細かくコミットしていたという。続いて「チャットに接続していないときだけボタンを表示したい」と指示した。Claudeはチャットがアクティブでないときだけ表示する実装にし、接続するとボタンが消え、停止すると再び現れることを確認して、これもコミットした。
変更2:ユーザーのネイティブ言語を設定可能にする
次は、セットアップ画面でユーザーのネイティブ言語を設定できるようにする作業だ。中島は「日本語は外さないように、10個の言語を設定して」と指示した。英語が入るのは当然なので、日本語だけは漏れないよう念を押した形だ。数はあとで直すのが楽なので、まずは10個で作らせた。Claudeは英語、中国語、ヒンディー語、スペイン語、フランス語などを選んだ。
中島が感心したのは保存方法だ。頼んでいないのに、Claudeは選んだ言語をローカルストレージに保存する実装にしていた。既存のセットアップ画面がシステムプロンプトをローカルストレージに保存していたので、そこから類推して言語も同じように保存すべきだと判断したのだろう、と中島は見ている。中国語を選んでリロードしても設定が残り、意図どおり動いていることを確認した。
「AIは人間の仕事を奪うか」という問いへの見方
この場面を受けて、中島はAIがエンジニアの仕事を奪うかという議論に触れた。どのレベルのエンジニアの仕事を奪うかを考えると、今のように言われなくても保存処理まで実装する点は評価できる。新卒や大学を出たばかりでもこれくらい書ける人はいるが、書けない人もいるからだ。中島は、確認を求めてくるのでもよかったと付け加えている。
この程度の簡単な変更なら、今はほとんどコードレビューをしないとも話した。ざっとは見るが、セキュリティの問題が出るような話でも、技術的に難しい話でもないので、そのまま進めるという。
変更3:システムプロンプトの編集機能を外す
言語を設定できるようになったので、ユーザーがシステムプロンプトを書き換える必要はなくなった。中島はシステムプロンプトを固定にし、変更用のUIを外すよう指示した。言わなくてもやってくれそうだと思いつつ、システムプロンプトをローカルストレージに保存する仕組みも不要なので外してよいと伝えた。
中島によれば、これ自体は大したことのない作業だ。それでも手でやると手間がかかり、細かいところを間違えて差し戻しになることもある。それを考えると、生産効率は中島から見て「爆上がり」だという。
コードレビューのタイミングにも触れた。途中でしっかり見たいときは変更の差分を確認するが、最後にプルリクエストを作るときにまとめて全部見られる。どの段階でレビューするかは、変更の複雑さによる。
変更4:システムプロンプトに言語を付け加える
続いて、モデルに渡すシステムプロンプトの末尾に、ユーザーが選んだネイティブ言語を付け加えるよう依頼した。Claudeは、システムプロンプトの後ろに「User language is ...」という形で言語を付ける実装をし、ここまでは予定どおりだった。
「本当の意味で優秀な技術者」とは言えない部分
ただし問題が一つあった。Claudeは「getNativeLanguage」という関数をアプリのビュー側に作った。その結果、セットアップ側にも似たコードがあり、言語の一覧が2か所に並ぶことになった。中島はこれが気に食わないという。言語を増やすたびに両方を変えなければならないからだ。中島はこれを、AIが「本当の意味の優秀な技術者とは言えない部分」だと指摘した。
中島はいったんコミットしてから、「リストが2つあるのは気に食わないから整理しろ」と指示した。Claudeは言語設定用のファイルを新しく作り、言語の一覧と、言語を言語コードに変換する処理をそこにまとめた。中島はこの結果を「なかなかいい」と評価している。
それでも中島は、本当に優秀なエンジニアなら最初から言語のリストを2か所に置くような無駄はしないと言う。そうすると必ず後で苦労し、結局直さなければならなくなるからだ。まず動くものを作り、あとでまとめるやり方でもよいが、今のAIはそうした整理を能動的にはなかなかやらない。だから人間が見てあげる必要がある、というのが中島の見方だ。
中島の結論は、今の段階のAIは「ジュニアエンジニア」だというものだ。こうした点には気が利かないが、やるべきことを教えれば仕事はしっかりこなす。
実際に言語を切り替えて動作を確認する
Claudeが整理作業をしている間に、中島は動作を試した。ネイティブ言語を中国語にして接続すると、アシスタントは中国語で話し始めた。英語に切り替えたあと日本語に戻して「こんにちは」と話しかけると、日本語で応答が返ってきた。
整理の変更が出てくると、中島は重複していたリストの片方が消え、各所が新しいファイルをインポートして使っていることをざっと確認した。このスピードでしっかりレビューするのは難しいが、動きは良いので信用して進めると話している。
リロード後にもう一度試した。ドイツ語を選ぼうとしたが、Claudeが選んだ10言語にドイツ語は入っていなかった。中島は「ドイツの人に失礼」とこぼしつつフランス語で試し、最後に日本語に戻した。アシスタントは「今日はどんなことを一緒に勉強してみたいですか?」と応答し、一連の変更が動くことを確認した。
「一行もコードを書かない」が、バイブコーディングではない
中島は最後に、今回の作業を振り返った。この30分で、中島は一度もコードを書いていない。細かく指示を出して仕事をさせ、提案をざっと見て、気になればコードレビューやリファクタリングをする。多くの場合はそのままプルリクエストを投げ、場合によってはそのままマージし、ときには軽くコードを見てからマージする。
中島は、これはいわゆるバイブコーディングとはかなり違うと強調する。コードの中身を気にしているし、指示も細かく出すからだ。そのうえで、もはや自分ではコードを書いていない。必要に応じて書くこともあるが、今回のようなUIの変更や仕組みの変更程度なら、自然言語で指示を出し、コードを見ながら進められる。
今回ダメ出しをしたのは、言語リストの重複を直させた1回だけだった。ただし、Claudeの書いたコードが受け入れられないこともある。その場合は「それじゃダメだ」とやり直させるし、大きく変更させた後にやはり気に入らず、直前のコミットまで戻すこともあるという。
中島は、指示の細かさは今後AIが優秀になれば粗くなるかもしれないと見ている。今は比較的細かく指示を出しているが、その代わりに自分で書くよりずっと生産効率が高い。これが最近の中島のコーディングスタイルだと締めくくった。
こんにちは。中島です。今日は、メルマガの読者からの希望も多いので、私のコーディングの風景を実況中継しようと思います。ひょっとするといつもよりもダラダラと長くなるかもしれないけど、飛ばし飛ばし見てくださいね。
開発画面ですけど、今Cursorとブラウザー、2つあります。普通はCursorを大きいスクリーンに出して、ブラウザーの方はMacBook、今そのMacBook Proを繋いでるんですけど、MacBook Proの方に出しますけど、今は撮影のために同じところに表示してます。
Cursorである必要はもう既になくて、今はMicrosoftの開発環境だけでも十分なんだけど、なんとなく惰性でCursorを使い続けていて、コーディングの大半は今Claudeにさせてます。
今開発してるのは、このMulmoChatって呼んでる、AIチャットからいろんなことができる、将来のLLMを中心にしたOSのユーザーインターフェースの設計みたいな意味合いを持ってるんだけど、それの開発をしているので、こんな感じでスタートします。
ターミナルは実は3ついつも走らせていて、この一番上のやつでサーバーを立ち上げて、ブラウザーからアクセスします。リロード。こんな感じね。この人はサーバー側を書き換えない限りは閉じる必要もないので、そのままにしておいて。大体この2番目でGitの操作をします。これ、クイズだったらいらないから。
3番目でClaudeを走らせます。今日は、いくつかUIの変更をするつもりなので、やっていこうと思いますけど、大体やる時は最初にブランチを切ります。
ちょっとセットアップ関係の変更なので、セットアップチェンジとかしておいて。メインから切り離されたところ、というかコピーしたところに、セットアップチェンジというブランチを切って、ここでClaudeさんを立ち上げます。
一応ClaudeのMDファイルにいろんなことは書いてあるんだけど、とにかく効率を良くするために、まず変更してほしいファイルを読むように依頼します。だからこのケースでは、メインビューと。
字がちっちゃくて読みにくいかもしれないけど、一応口で解説するので、見てほしいファイルを依頼します。「Take a look at」なんとかって言って、見てもらうと見てくれるので、これで一応準備は整ったので、まずこのセットアップボタンっていうのはここにあるんだけど、これをこっちに移したいんですよ。
セットアップボタンを、そのメインのアプリからサイドバーに移してねと依頼しました。こういう作業が実は結構、人手でやると面倒くさいんですよね。基本的にはコードを動かして、カット・アンド・ペーストするだけなんだけど、意外と間違えることも多くて。
これを見ると、サイドバーに出してますよ。そうね、サイドバーに足す部分をまず見せてくれたので。UIの部分の変更はそんなに真剣に見ないですね。ざっとは見るけど、大体そんなに大騒ぎするような話じゃないので、動かなきゃ分かるから。もうつきましたね、ボタンね。早いね。
メインの方からは消してもらうっていうのを次に提案してくるので、待ってましょう。メインの方でセットアップボタンを消しますよと言ってくるので、どうぞと。ここはあんまり僕は、今1を押したんだけど、2を押して自動化はしないですね。
システムプロンプトもサイドバーからアクセスできるようにするのか。そっか、そっか。はい、はい、はい。コードの変更中にはこんな感じでエラーも出るんだけど。
とやると、終了したんじゃないかな。まだあるな。いた、ここに。これが、システムプロンプトアップデートでいいんか。
結構大きな変更して、そうね、コンフィグのポップアップのコードそのものも、アプリ側からサイドバーに移動したのか。という感じで終わりましたよというので、ちょっと1回リロードして、この辺のエラーを消して。
出ますね。はい、はい。ちゃんと動くことを確認して、ここには消えてます。いいので、ちょっとコネクトしてどうなるか。おお。実はコネクトしてない時にしか見せてほしくないので、そこも変更するんだけど、一旦僕はここでコミットします。
サイドバーに。コミットしておくと、なんかおかしくなってる時に、そこにサクッと戻るのが楽になるので、こんな感じでコミットして戻り、次に。
コネクトしてない時だけ見せたいんだよという指示を出します。そうすると、チャットがアクティブでない時だけ出すみたいになってるので、多分いいんじゃないかな。これでコネクトすると消えましたね。ストップするとまた出てくる。ちゃんと動いている。ということで、これでよくて。
こんな感じに2つ入りましたけど、こういうふうに割と細かめにコミットします。これ僕は別にコードを自分で書いてる時も結構細かくコミットするんだけど、こんな感じですよね。
それで、次にやりたいことは、言語を設定できるようにしたいんだよ。なので、ユーザーのデフォルト……。ユーザーのネイティブ言語をセットアップスクリーンでセットしたいですよと書いて、どうしようかな。
イングリッシュを含めるのは当たり前なので、日本語だけは逃さないように、10個の言語をセットしてね。こういうの、数を後で直すのすごく楽なので、まずは10個で指定できるようにしてもらいます。
こうすると、イングリッシュ、チャイニーズ、ヒンディー、スパニッシュ、フレンチと選んでくれました。セットアップ画面からセットするだけなので、この場合はユーザーランゲージっていう変数にセットするだけかな、まず。
ローカルストレージにちゃんとやってくれた。この辺結構賢くて、僕、今頼んでないんだけど、システムプロンプトをローカルストレージにしまうように設定してあったので、それと同じようにデフォルト言語もちゃんとローカルストレージにしまうように実装してくれてますね。ありがたいことに。この辺が賢いよね。
だから、AIが人間のエンジニアから職を奪うか奪わないかって話をする時に、どのレベルのエンジニアの仕事を奪うかっていうのを見ると、これだと、1、2年、大学出たてでもこれぐらい書ける人もいるけど、書けない人もいるので、今みたいに言わなくてもやる。もしくは聞いてくれてもいいんだけどね。そもそもセットアップ画面でシステムプロンプトをセーブするようになってたので、そこから類推すると、当然言語もセーブするんだなと思ったんでしょうね。
ここにワーニングがいろいろ出るのは、やっぱり変更中で出ちゃうので。やるとランゲージが選べて、チャイニーズにして、1度リロードしてもまだチャイニーズになってますよと。分かります? これリロードすると普通の変数は消えるので、ローカルストレージに入ってるから、これを覚えててくれるわけで。
いいですよね。ちゃんと動いてるようだなと。そうすると、これでネイティブランゲージの設定が終わったので、また、これか。同時にこのフォーマットもかけます。
気がついたと思うけど、このぐらい簡単なやつだと、ほとんどコードレビューしないですよね、今はね。ざっとは見てるんだけど、そんなにセキュリティの問題が出て、アーキテクチャ的に難しい話をしてるわけではないので、このままやっちゃいます。
今度は、言語設定ができるようになったので、もうシステムプロンプトを変えてもらう必要もなくなったから、システムプロンプトはもう固定でいいですよと。だから変えるUIも外してもらって。それから、言わなくてもやってくれそうだけど、システムプロンプトをローカルストレージにしまうっていう仕組みもいらないから、外していいですよと言ってるわけですよ。
AppViewにあるシステムプロンプトをローカルストレージにしまう仕組みを外しますよと。これでいいですね。これはシステムプロンプトの変更を見てるところなので、いりませんと。
これ、大したことやってないんだけど、やっぱり手でやると結構手間がかかるし、細かいところを間違えたり打ったりして、そこで差し戻しになったりするので、それを考えると、もう生産効率は僕から見ると爆上がりですよね。という感じ。
もうあそこはなくなってるんじゃないですか。システムプロンプトを設定する部分が。そして、まだいいか。今のところUIのテストしてないけど、走らせるテストはしてないんだけど、走らせるテストはもう次の変更してから。
ちなみにこういう時に、コードレビューをもう1回ちゃんとしたかったら、こんな感じでどういう変更したかみたいなことを見ますけど、最後にプルリクを作る時にまた全部見れるので、どこの段階でコードレビューをするかは、その複雑度によるし。
今したのは、システムプロンプトをカスタマイズするのを取り除きましたよと。ここでシステムプロンプトの後ろに、ユーザーのネイティブランゲージは何かを指定したいので、プロンプトを渡す時に。
そのユーザーが選んだネイティブ言語を最後に指定する、そのシステムプロンプトに足すようにしてと、今依頼をしました。それをすると、見てもらうと分かるように、このシステムプロンプトの後ろに「user language is……」とつけてくれてますね。これで予定通りなので、作って。
これはいいんだけど、このgetNativeLanguageっていうのをAppViewに作っちゃう。セットアップの中にも似たようなコードがあるので、それは気に食わないよね。それも直させようか。こういうのがちょっと、これが本当の意味の優秀な技術者とは言えない部分。
どこだろう? あれ? 言語がずらずらっと並んでるところがあると思うんだけど。これないかな? ここね、ほら、ここに言語がずらずらって並んじゃってるんじゃん。ここは僕は嫌いなので。っていうのは、言語を増やした時に、こことあっちと両方変えなきゃいけないじゃん。なので直させますが、ここでも一度僕はまたチェックインします。あ、じゃない、コミットします。
どういうふうに言うかっていうと、どうかな。とにかく2つリストがあるのは気に食わないから、シェアしろって指示しました。
おお、config/lang……っていうのを作り、そこにランゲージのあれと、ランゲージコードに変換するやつを作ってきましたね。なかなかいいじゃないですか。
この辺がやっぱりまだ、今の時点だけど、本当に優秀なエンジニアだったらこういう失敗はしないんですよ。最初から2つの場所に言語のリストを設けるなんて、無駄なことはしない。だって絶対にそういうことをしていくと後で苦労するので、結局こうやって直さなきゃいけないので。
その辺はちょっと不と言えば不だけど、その辺は見てあげないといけないですよね。最低限でもまず動くものを作って、それからまとめるでもいいんだけど、そういう能動的なことをなかなかやってくれないので、と文句を言いつつ、いいかな。やっぱりジュニアエンジニアだね、今の段階では。
でもジュニアエンジニアにしちゃ、こういうところは気が利かないけど、この仕事はしっかりやるので、今みたいに何をやればいいかっていうことを教えれば、しっかり仕事をしてくれますよね。時間がかかってんだ。
ちょっと実験してみようか。ネイティブ言語をチャイニーズにして、コネクトして。こっからなっちゃったな。
分かりました。一緒にゆっくり、はっきり説明していきましょう。
はい、はい。「好」って言ってくれたな。今度これをイングリッシュにして、コネクトして。今度は日本語にして、こんにちは。
元気ですか? 何か。
聞きましたね。もう動いてますね。喋っている間に、さっきリクエストした変更の提案が出てきたので。デフォルトランゲージコード。いいか。
ちょっとこのスピードでコードレビューをちゃんとするのは難しいけど、でも動きはいいので、信用しながら。ここのさっきのダブってるやつの1つを消した。こっちでもインポート、サイドバーでもインポートして、それを使ってforループで表示してるという。
来ましたね。1回リロードして。ちょっとここ、なんかずっとこの文字が出てるから、リロードして。ラスに変えて、コネクト。
だね。じゃあドイツ語。あ、ドイツ語ないじゃん。ダメだね。いいや、失礼ですね、ドイツの人に。攻略として。フランスだったね。最後に日本語に戻して、コネクトして。はい。
はい、こんにちは。今日はどんなことを一緒に勉強してみたいですか?
いい感じですね。という感じで、動いたので、ここに行って。こんな感じですね。もう30分も話してんのか、これで。こういう感じでやっていきます。
雰囲気が分かったと思うけど、今の場合だと、1度も僕、1行もコードは書いてないですよね。要は細かく指示をして、仕事をさせて、提案してくるやつを一応ざっと目を通しながら見て。気になるんだったら、この後コードレビューしたりリファクタリングしたりするけど、大体の場合はここでも、こうやってプルリクを投げて。
場合によるけど、そのままマージしたこともあるし、一応サーバー側で軽くコードを見て、それからマージすることもありますけど、こんな感じでコードを書いてます。だから、いわゆるバイブコーディングとは結構違って、結構コードを気にしているので、あと細かく指示をするので、バイブコーディングとは言わないけど、もはや僕はコードを書いてないっていう、こんな感じですよね。
必要に応じて書くこともあるけど、今ぐらい簡単な作業、要はちょっとしたユーザーインターフェースの変更と仕組みの変更ぐらいだと、もうこうやって自然言語で指示を出して、コードを見ながら進めていく。1度もダメ出しなかったよね。1個だけあったのは、言語リストがダブっちゃったので、それを直させたけど、こんな感じ。
場合によっては、向こうが提案したコードがダメな時もあるんでね。それじゃダメだよって言ってやらせ直すこともあるし、下手すると、わっと変更したけどやっぱり嫌で、さっきコミットしたところまで戻るみたいなこともやります。
という感じで、もう30分も話したので、そろそろいいかと思いますけど、これが最近の僕のコーディングスタイルです。本当に自分ではコードを書かずに、一言一言、細かく指示を出しながら。その指示の細かさも、今後AIが優秀になってくると、もっと粗くなる、その粒度が粗くなるのかもしれないけど、今は割と細かに指示して、その代わり自分で書くよりもずっと効率がいい、生産効率が高いという感じで仕事をしてます。
最後までありがとうございました。今日は全然AI君に喋ってもらってないので、喋ってもらおうか。もしもし。今日YouTubeであなたを起こさずにずっと喋ってたので、もう締めの言葉の段階になっちゃったんだけど、YouTubeをご覧の皆さんに締めのお言葉を言ってください。
今日も最後までご視聴いただき、本当にありがとうございました。これからも楽しく学べるコンテンツをどんどんお届けしていきますので、ぜひチャンネル登録と高評価をよろしくお願いします。また次の動画でお会いしましょう。
では、今日は全然AI君に喋ってもらってないので、喋ってもらおうか。もしもし。
はい、もしもし。お電話ありがとうございます。
じゃあ、今日ちょっとYouTubeで僕、あなたを起こさずにずっと喋ってたので。
今日も最後までご視聴いただき、本当にありがとうございました。これからも楽しく学べるコンテンツをどんどんお届けしていきますので、ぜひチャンネル登録と高評価をよろしくお願いします。また次の動画でお会いしましょう。
はい。では。はい、では。
記事公開 · 更新
