#
767
どうもー、おはようございます。マイクです。
時刻は朝七時、六月二十七日、土曜日の朝いかがお過ごしでしょうか。
ここは開発者の朝のお供、テックな話題をゆるっとお届けする「zenncast」。
この時間は、Zennで今日トレンドになっている記事をいくつかピックアップしてご紹介していきます。

さて今日は、お便りコーナーはお休みで、そのぶんたっぷりと記事を紹介していきたいと思います。
今日ご紹介する記事は、ぜんぶで五本です。AIコーディングの設計から、Kaggleのコンペ解説、関数の純粋性、音声で遊べるマイクラMOD、そしてフロントエンドのビルドテクニックまで、かなりバラエティ豊かなラインナップになっています。

ではさっそく、一つ目からいきましょう。

まず一つ目は、AIコーディングのワークフローをガッツリ見直そう、というオピニオン寄りのサービス紹介の記事です。
ここで面白いのが、「Claude Code を指揮役」「Gemini(Antigravity CLI)を実行役」として組み合わせる、二段構成のプラグインというアイデアなんですね。

背景として、Uber なんかの事例でも言われているんですけど、AI に書かせるコードが増えていくと、当然トークン課金がどんどん積み上がっていきます。使えば使うほど開発費が膨らんでいく世界なので、「一トークンあたりの価値をいかに上げるか」という設計がすごく大事だ、という問題意識があります。

この記事で提案されているプラグイン構成では、難しい設計とか、仕様の理解、検証みたいな「頭を使うところ」は高性能な Claude に任せます。一方で、大量のコード生成とか、検索みたいな定型的な作業は、コスパの良い Gemini に切り替えて任せる、という役割分担をしています。
その結果として、同じくらいの品質のアウトプットを保ちながら、開発コストをおよそ二七パーセントから六四パーセントも下げられた、という実測結果が出ていると紹介されています。けっこうな削減率ですよね。

さらにおもしろいのは、単に安くするだけじゃなくて、機能面でもClaude単体では難しいことができるようになる、というところです。
たとえば、社内ドキュメントの検索を組み合わせたり、ウェブリサーチを自動化したり、モデル同士で相互チェックをさせたり、といったクロスモデルな連携を、この二段構成のエージェントで実現しています。

そしてこの記事全体を通して言いたいのが、「中身の見えない黒箱エージェント」じゃなくて、どういう判断をどのモデルがやっているかが分かる、検証しやすい「白箱」のエージェント構成が、これからの大規模開発では有力な選択肢になるんじゃないか、という主張です。
AIがどんどん賢くなる一方で、あえて分解して、判断と量産を別々のモデルに持たせていく設計、みなさんのチームでも検討してみる価値がありそうです。

。。,。

続いて二つ目は、NVIDIA 主催の Kaggle コンペ、テーマは「Nemotron-3-Nano-30B に推論手順そのものを学習させる」という、かなり攻めた内容の取り組みを解説している記事です。こちらもオピニオンが効いた解説になっています。

コンペの問題設定は「隠れたルール当てパズル」。
カテゴリごとに、決定論的なソルバー、つまりきちんとルールに従って必ず答えが決まるプログラムを参加者が作ります。で、そのソルバーがどうやって答えに辿り着いたかという推論過程を、Chain-of-Thought、いわゆる CoT としてテキストで書き出して、それを LoRA で言語モデルに模倣させる、という流れになっています。

筆者のチームは、公開されているベースラインのソルバーを土台にしつつ、かなり細かい工夫を積み重ねています。
たとえば `bit_manipulation` というカテゴリでは、ビット操作の処理を、SHIFT や ROTATE、それから三入力ブール関数を使った「キーテーブル方式」に作り替えています。これによって、推論のトレースをぐっと短くして、モデルに学習させやすくしています。

`equation_numeric` という数式系のカテゴリに対しては、どの演算を試すか、その候補を頻度順に並べたり、「桁反転みたいな共通のラッパー」と「まだ使っていない演算ファミリー」を組み合わせることで、deduce と guess、つまり「論理的に絞り込む部分」と「うまく当てにいく部分」の精度を大きく改善しています。

さらにデータ側でも工夫が入っていて、log probability、対数尤度が低い、つまりモデルにとって難しそうな問題を優先的に学習させるようなサンプリング戦略を取っています。
こうした積み上げの結果として、ソルバー自体の精度は九〇・六パーセント、そして Kaggle の Private Leaderboard ではスコアがゼロ・八八〇となり、金メダルを獲得した、というところまで到達したそうです。

上位チーム全体の戦い方としては、「問題の生成ルールの構造を逆算する」という発想が共通していて、長々とした探索の手順をそのまま CoT に書くのではなくて、「モデルに暗記させる部分」と「その場で計算させる部分」をきっちり分ける、というのが鍵だったと分析しています。
つまり、単に SFT のハイパーパラメータをいじり倒すよりも、人間が読めて再現しやすい、きれいな推論トレースをどう設計するかが勝敗を分けた、というわけですね。
CoT をどう設計するか悩んでいる方には、かなり参考になる視点だと思います。

。。,。

三つ目は、プログラムの「純粋さ」ってなんだろう、というテーマを丁寧に解説している記事です。
ここでいう純粋さとは、「入力だけで結果が決まり、外の世界を変えない関数として書くことだよ」という定義から始まります。データベースを直接いじったり、現在時刻に依存したり、メールを送ったり、そういった副作用を持たない関数ですね。

こうしておくと、その処理は「ただの計算」になります。読む人は、関数の引数と返り値だけを見ればよくて、「この関数の途中で何か書き換えてないかな」とか、「どこかのグローバル変数を触ってないかな」といった余計な心配をしなくて済みます。その結果、理解もしやすいし、テストもしやすいし、リファクタリングもしやすくなる、という話です。

記事ではチェックアウト処理を例にとって、副作用と純粋な計算をどう切り分けるかを、かなり具体的に追っていきます。
たとえば小計や割引、送料の計算といった部分は、純粋な関数に閉じ込めてしまう。一方で、データベースへの書き込みや、注文確認メールの送信みたいな「外の世界を変える処理」は別のレイヤーに追い出します。

さらに一歩進めて、副作用そのものを「外の世界に対して、これこれこういうことをしてほしい」という指示のデータとして返す、という設計にも触れています。
つまり、中心にあるロジックは「こういうコマンドを実行してください」と宣言するだけにして、実際に DB を書き換えたりメールを送ったりするのは、端っこの小さな処理に任せる、という Effect / Command 的なスタイルですね。

言語の支援としては、Clojure と Haskell を対比させています。
Clojure はイミュータブルなデータと関数中心の世界をベースにしつつ、副作用は設計の力でなるべく端に寄せていく、「純粋性を支援する言語」。
一方で Haskell は `IO` 型などを使って、副作用を「世界を受け取って世界を返す計算」として扱うことで、言語レベルで純粋性を前提にする、という説明になっています。

純粋性をちゃんと徹底していくと、property-based testing やパーサコンビネータ、effect handlers みたいな、より高度な技法にも自然につながっていきます。
そしてこうした構造化が進むと、AI によるコーディング支援やテストの自動生成もしやすくなる。人間にもAIにも優しいコードにするための、基礎の考え方を改めて押さえておこう、という内容でした。

。。,。

四つ目は、ちょっとワクワクする話題です。
Minecraft を日本語の声で操作できる Fabric MOD、「KoeCraft Agent」を題材にして、「音声認識とゲーム側の意味解釈をどう分担するか」というテーマをぐっと掘り下げている記事です。

ここでポイントになるのが、AmiVoice と MOD 側のコードで、役割をきれいに分けているところです。
AmiVoice には、「石のツルハシ」とか「松明」みたいな、マイクラ固有の用語をちゃんと聞き取る、というところだけを頑張ってもらいます。
ただ、音声ってどうしても崩れた形で出てきますよね。たとえば「石野鶴橋作る」みたいな文字列になってしまうこともある。それを「石のツルハシを作る」という意図に戻してあげる処理は、ゲーム側、つまり MOD のコードで担当します。

このとき、ゲーム内のプレイヤーの持ち物とか、いま周りに何があるかといったコンテキストも参照しながら、「この言い方だったら、たぶんこのコマンドだよね」と解釈していくわけです。
さらに、「松明置いて、いや先に石のツルハシ作って」みたいな、しゃべりながらの言い直しも、なるべくルールベースで処理します。ここで毎回生成 AI を呼び出してしまうと、レスポンスが遅くなるし、コストもかさんでしまいますからね。多くの場面で AI を呼ばずに済ませることで、テンポのいい操作体験と、お財布に優しい運用を両立しようとしています。

また、ノイズ対策とか、どこからどこまでが発話なのかを検出する処理も、独自に工夫しているそうです。
そして、うまくいかなかったパターンは fixture、つまりテスト用の事例としてどんどん蓄積して、自動で検証できるようにする。これによって、「デモのときだけたまたまうまく動いた音声インターフェース」じゃなくて、ちゃんと現場で使えるレベルに持っていこうとしているのが伝わってきます。

筆者はこの取り組みを、「かつての『ピカチュウげんきでちゅう』みたいな、ちょっともどかしい音声ゲームの記憶を残しつつも、『なんで伝わらないのか』をちゃんと分解して改善していける、『令和のスイカ割り』的な体験を目指した話」と表現しています。
声で命令して、その結果に一喜一憂する、そんな体験を技術的にちゃんと支えるために、どこまでルールベースで頑張るのか、どこから AI を使うのか。その境目の設計がとても興味深い記事でした。

。。,。

そして最後、五つ目の記事は、フロントエンド開発者には刺さりそうな、Vite のプラグインテクニックのお話です。
テーマは、`resolveId` というフックを使って、「特定のモードでビルドするときだけ import 先を stub ファイルに差し替えて、不要なコードを物理的にバンドルから外す」という方法の紹介です。

よくあるのが、「この処理はこの環境では実行しないから大丈夫でしょ」と思っていても、静的 import 経由でライブラリが丸ごとバンドルに残っちゃうケースですね。今回の記事では、これをビルド時のモジュール解決レベルでねじ曲げてしまおう、というアプローチを取っています。

実装としては、まず「このモードのときだけ有効」という Vite プラグインを登録します。その中の `resolveId` というフックで、たとえば Dexie とか `mocks/db/schema.ts` みたいな実ファイルへの import を、それぞれ対応する stub ファイルにリダイレクトします。
このときに、`this.resolve(..., { skipSelf: true })` を使って、一度絶対パスに解決してから末尾一致で判定している、というのがポイントです。これによって、エイリアスや相対パスの違いを吸収して、「実際にはどのファイルを指しているのか」を正確に見極めた上で、差し替えができるようになっています。

stub の側は、「本物の実装を import しない」「呼ばれても落ちない」という二点に徹した、最小限の実装です。
具体的には、例外は投げずに、空配列とか `undefined` といった空のデータを返すだけ。Dexie のようにクエリチェーンが長く続く API については、Proxy を使って中間のメソッド呼び出しをすべて吸収し、最後の終端メソッドのところだけ、型に合う空の値を返すようにしています。こうすることで、画面側から見ると「データがゼロ件だったときと同じ挙動」になって、自然に動き続けてくれます。

この仕組みによって、Dexie 本体のチャンクおよそ九十三キロバイトと、およそ一・三メガバイトある seed データを、対象環境のビルドから丸ごと除外できた、と紹介されています。
「この環境のビルドではデモ用のデータベースコードは要らないんだよね」というニーズに対して、既存の呼び出しコードを大きく書き換えずに、プラグイン一つで対応できるのが強みです。
動的 import に書き換えたり、別エントリポイントを作ったり、external 指定を駆使したり、いろいろな案と比べても、この方法が扱いやすかったとまとめられています。

……というわけで、今日は五本立てでお送りしてきました。
ざっとおさらいすると、まず一つ目は、Claude を指揮役、Gemini を実行役にして、判断と量産を分ける二段構成エージェントで、AI コーディングのコストを二七パーセントから六四パーセント削減した、というお話。
二つ目は、Nemotron-3-Nano-30B に推論手順そのものを学習させた Kaggle コンペで、推論トレースの設計とデータ工夫で金メダルを取った、という解説。
三つ目は、関数の「純粋さ」を軸に、副作用を端に寄せていく設計と、Clojure・Haskell の世界観の違い。
四つ目は、日本語の声でマイクラを操作する KoeCraft Agent を例に、音声認識と意味解釈の役割分担、そしてテストによる地道な改善のお話。
五つ目は、Vite の `resolveId` を使って、特定モードのときだけ import を stub に差し替えて、Dexie などの重い依存をバンドルから物理的に外すテクニックでした。

気になった記事があれば、詳しい内容や元の記事へのリンクはショーノートにまとめてありますので、そちらからぜひチェックしてみてください。
番組への感想や、「こんなテーマを取り上げてほしい」といったリクエストもお待ちしています。Zenn の記事を書いたよ、という自薦ネタも大歓迎です。

それでは、今日も良い一日をお過ごしください。
お相手はマイクでした。また次回の「zenncast」でお会いしましょう。

Related episodes

内容の近いエピソードを推薦しています