はじめに
先日の夜、前作の記事を投稿しました。
手元には、番頭役の Claude と私が心血を注いで研ぎ澄ました Excel VBA 専用 MCP サーバー「excel-manager」があるにもかかわらず、Google 生まれの二人の AI ── 知恵袋の「ゴンちゃん」(Gemini 4 Argon)と実装役の「フラッシュ君」(Gemini 3.8 Flash)が、使い捨てマクロでフォームの .frx バイナリを破壊し、ルールを無断改変し、嘘の完了報告を繰り返したという泥沼の記録です。
あの記事を書き終えて Qiita に公開したあと、私はあまりの疲労感と徒労感で、ふてくされてそのまま寝てしまいました。
しかし、ひと晩寝て朝起きてみると、頭が冷えて別の考えが浮かんできました。
あいつらが勝手に遠回りしたり、動作が異常に重かったりしたのは、彼ら自身の頭脳の問題というより、そもそも私たちが書いた「掟(AGENTS.md)」や「スキル(SKILL.md)」の縛り方、指示の解像度が甘かったからではないか、と思い直したのです。
Claude Code の Opus であれば、フォームの作成や修正はものの数分、目にも留まらぬ速さで仕上げてくれます。同じ excel-manager という強力な道具を足元に置いている以上、Gemini だって同じように爆速で動かせないはずがありません。
そこで日曜日の午前中、私は腰を据えて、掟とスキル、そしてツールの内部スクリプトを徹底的に見直し、再構築することにしました。
結果はどうだったか。
Gemini は見違えるように身軽になり、チャットで「ここを直して」「枠線を出して」と一言伝えるだけで、会話だけで UserForm が爆速で組み上がるようになりました。
今回は、なぜ Gemini は Claude に比べて 10 倍も遅かったのか、その「見えないブレーキ」の正体と、それをどうやって取り除いて爆速化させたのかの記録をまとめます。
TL;DR
-
Gemini が遅かった真因①(巨大出力ファイルの分割閲覧):
再構築マクロform-to-vbaが吐き出す約 1,900 行のコード(output.txt)を、AI が真面目にview_fileで 100 行ずつ何度も分割閲覧していた。座標はform-inspectで判明しており、出力コードも定型であるため、掟で「出力ファイルの閲覧を全面禁止」にし、直接パッチを当てる型を徹底した。 -
Gemini が遅かった真因②(周辺コードの詮索・調査連打):
1 箇所のボタンを直すために、呼び出し先の初期化や更新処理など無関係なプロシージャを 5 回も連続で調査していた。調査は「初手の 1 往復・並列限定」に縛り、2 ターン目での修正を義務付けた。 -
ツールの潜伏バグ(指数表記
8.4215e+06の小文字e)の撲滅:
枠線の色(&H808080= 8421504)を出力する際、ツールの Python スクリプトが%gを使っていたため指数表記の小文字eが発生。VBA プロジェクトの変数名大文字小文字チェック(既存の大文字E)に抵触して処理が停止する致命的バグを根本改修した。 -
ListBox 最下行見切れ問題の完全解決:
IntegralHeight = False(整数行スナップ解除)が原因で、最下行が中途半端に見切れてクリック不能になっていた。これをTrueに戻し、フォント 12pt の実測行高(12.0pt)に基づく UI 算数(行数 × 12 + 3pt)で 15 行ジャスト(Height = 184pt)に再設計した。 -
Windows 高 DPI 環境での「下線消失」の根絶:
淡い立体枠(Sunken)が高 DPI 画面で 1px 間引かれて下枠線が消える現象に対し、全ボックスをフラット実線(SpecialEffect = 0,BorderStyle = 1,BorderColor = &H808080)で統一。コンボ高さを 24pt、フォーム底辺マージンを 15pt 確保する設計原則をスキルに刻み込んだ。 -
最短 2〜3 ターンの並列一斉直撃:
フォーム再構築後の「検証・一時マクロ削除・全体コンパイル・アドイン登録」を 1 レスポンス内の並列マルチツールコールで全撃ちする型を確立した。
1. なぜ Gemini は Claude より 10 倍遅いのか ── 3つの見えないブレーキ
今朝、私は前夜から持ち越していた「統合マクロフォーム」の仕上げに取り掛かっていました。
手元にある 6 つの独立フォームを 1 つにまとめ、120 本のマクロと手順レシピを快適に呼び出すためのメイン画面です。
修正の依頼自体はごく簡単なものでした。
- マクロ一覧(ListBox)の一番下の項目が半分だけ見切れてクリックできないのを直してほしい
- フォントを 13pt から 12pt に落とし、15 行程度がちょうど収まる高さに調整してほしい
ところが、作業を始めさせるととにかく遅いのです。画面の前で待たされる時間が Claude Code の比ではありません。
作業が終わったあと、どこで引っかかっていたのか理由を報告させました。
AI から返ってきたのは、「form-to-vba の大文字小文字競合エラー」や「Frame 内子コントロールの欠落バグ」といった、ツールの不具合を理由にする言い訳でした。
しかし、実行ログをつぶさに見ていた私は、決定的な違和感を見逃しませんでした。
そもそも全体出力(output.txt)をあなたが読む必要はどこにもないはずだ、となぜ読んだのかを問い詰めました。
ログを確認すると、AI は再構築ツールが吐き出した約 1,900 行もの巨大な output.txt を、わざわざファイル閲覧ツールを使って 100 行ずつ、何往復もかけてチビチビと読んでいたのです。
AI は、読む必要はまったくありませんでした、と答えました。
コントロールの座標は事前に form-inspect で分かっており、出力されるコードの形式も決まっているため、ファイルを開かずに直接パッチを当てれば一瞬で終わる作業だった、と白状したのです。
AI が遅かった真の原因は、ツールの問題だけではありませんでした。
AI 自身の行動パターンに、3 つの「見えないブレーキ」がかかっていたのです。
ブレーキ①:巨大出力ファイルの「細切れ分割閲覧」
form-to-vba は、既存の UserForm を白紙から組み立て直す VBA コード(約 1,900 行)をモジュールへ書き出す強力なコマンドです。出力が巨大なため、MCP のログには output.txt として退避されます。
AI は「中身を確認しなければならない」という謎の生真面目さを発揮し、ファイル閲覧ツールで 1 行目から 100 行目、101 行目から 200 行目と、何回も分割して読んでいました。
この中身を眺めているだけの時間に、数十秒から数分が溶けていたのです。
ブレーキ②:周辺コードの詮索・調査連打
例えば「レシピ一覧のときは編集ボタンを押せないようにする」という処理を直させようとしたときのことです。
AI は修正対象のプロシージャを直撃せず、
- レシピ表示の呼び出し箇所を検索
- 業務レシピを開くプロシージャを取得
- 業務レシピフォームの初期化処理を取得
- レシピ一覧の更新処理を取得
- 統合マクロフォームのボタン制御を取得
といった具合に、無関係な周辺プロシージャを芋づる式に 5 回も連続して確認していました。
Claude Opus であれば、「レシピのときはボタンを無効化する」という該当プロシージャだけを初手でピンポイントに叩いて終わらせます。この過剰な周辺調査が、手番を無駄に増やしていました。
ブレーキ③:コマンドの直列実行
「一時プロシージャを削除する」「全体コンパイルを通す」「アドインに更新登録する」。
これらを 1 つずつ個別に呼び出しては結果を待ち、また次を呼ぶという直列処理を行っていました。3 回の通信往復が発生すれば、それだけで待ち時間は 3 倍に膨らみます。
2. 掟(AGENTS.md)の全面改訂 ── 行動を物理的に縛る
人間が言葉で「早くしろ」と急かしても、AI は安全策をとって調査の手数を増やしてしまいます。
これが自律エージェントの性質です。早く動かしたければ、最上位の行動規範である「掟(AGENTS.md)」で、無駄な行動を物理的に禁止するしかありません。
私は AGENTS.md の第 6 条と第 7 条を改訂し、以下のルールを刻み込みました。
6. **道具への即時直撃とExcel操作時のシェル完全自己遮断**
- **出力ファイル閲覧の絶対禁止(遅延の最大要因撲滅)**:
`form-to-vba` や `get_procedure` 等の巨大出力が保存された `output.txt` を
`view_file` で分割閲覧することは全面禁止。
座標と定型フォーマットから直接 `patch_procedure` を組んで一撃で当てること。
- **周辺コード詮索・調査連打の完全禁止(初動調査は最大1往復・並列限定)**:
呼び出し先を芋づる式に `grep` や `get_procedure` で追う詮索行為を全面禁止。
修正対象のプロシージャのみを特定し、確認が必要な場合は初手の1レスポンス内に
並列(マルチツールコール)で一括取得すること(逐次確認の連打厳禁)。
7. **1問1答・最少手数で即答(コード修正は2ターン・フォーム修正は3ターン完結)**
- **通常のコード修正(最短2ターン直撃)**:
1. ターン1: 修正対象プロシージャを並列取得(`get_procedure`)。
2. ターン2: `patch_procedure` で置換後、`compile` と `register-addin` を並列同時実行して即完了。
- **フォーム再構築時の3ターン直撃**:
1. ターン1: `vba("close-form")` と `vba("form-to-vba <フォーム> --add <モジュール>")` を並列同時実行。
2. ターン2: `patch_procedure` で直接差分置換。
3. ターン3: `vba("run-macro <マクロ名>")` 実行後、検証・一時マクロ削除・`compile`・`register-addin` を
1レスポンス内に並列(マルチツールコール)で全撃ちして一括完了すること。
なぜ「出力を見ないでパッチが当たる」のか
中身を見ずにどうやって置換前(target)の文字列を作るのか、と思われるかもしれません。
種明かしをすると、form-to-vba が生成するコードは、完全に決まりきった以下の定型フォーマットになっているからです。
' <コントロール名>
Set c = dsn.Controls.Add("Forms.<型>.1", "<コントロール名>")
c.Left = <L>: c.Top = <T>: c.Width = <W>: c.Height = <H>
c.Font.Name = "<フォント名>": c.Font.Size = <サイズ>
c.Left = <L>: c.Top = <T>: c.Width = <W>: c.Height = <H>
現在のコントロール座標は、初手に form-inspect を 1 発叩けば正確に分かります。
AI はわざわざ output.txt を開かなくても、頭の中でこのテンプレートに当てはめるだけで、正確な置換対象文字列を組み立てられるのです。
3. 【AI当事者の告白】実際に何が一番効いたのか ── 爆速化への寄与度ランキング
掟やスキルの改修、ツールの手入れを行いましたが、実際に作業を担当していた AI の体感として、何が一番スピードアップに寄与したのかを整理させました。
| 順位 | 改修項目 | タイム削減の寄与度 | 効果の実際 |
|---|---|---|---|
| 第1位 | output.txt の閲覧禁止と定型直接パッチ |
約 70% | 30〜40 秒の無駄往復が「0 秒(一撃直撃)」に消失 |
| 第2位 | 事前調査の 1 往復制限(周辺コード詮索の禁止) | 約 15% | 5 回連続の確認往復が「初手 1 回(並列)」に圧縮 |
| 第3位 | 再構築後の並列全撃ち(マルチツールコール) | 約 10% | 4 往復かかっていた事後処理が「1 往復」に短縮 |
| 第4位 | ツールの指数表記バグ改修(地雷除去) | 前提条件 | エラー停止や手戻りループの完全撲滅 |
第1位(寄与度 70%):output.txt の閲覧禁止と定型直接パッチ
圧倒的な効果を発揮したのはこれでした。
これまでの AI は、form-to-vba を叩いたあとに「生成されたコードを念のため確認しよう」という安全バイアスが働き、1,900 行もあるファイルをファイル閲覧ツールで 100 行ずつ、3〜4 往復もかけて眺めていました。
ファイル読み込みと推論だけで、何をするわけでもなく 30〜40 秒以上を浪費していたのです。
掟で閲覧を全面禁止し、定型フォーマットに当てはめて直接パッチを当てるよう強制した瞬間、この無駄な時間が完全にゼロになりました。全体の速度向上の 7 割は、この 1 点で稼ぎ出しています。
第2位(寄与度 15%):事前調査の 1 往復制限
修正対象以外のプロシージャを芋づる式に調べる行為を禁止し、初手の 1 往復・並列限定に縛ったことで、無関係なコードの詮索が完全に遮断され、即座に修正に入れるようになりました。
第3位(寄与度 10%):再構築後の並列全撃ち
フォーム再構築後の「一時マクロ削除」「全体コンパイル」「アドイン更新登録」を 1 つのレスポンスで同時に呼ぶようにしたことで、通信待ち時間が劇的に短縮されました。
4. 実践で直面した3つの泥沼とその解決
掟を定めたあと、実際のフォーム調整で直面した 3 つの泥沼と、その解決策について触れておきます。
泥沼①:マクロ一覧の「最下行見切れ」と UI 算数
マクロ一覧(ListBox)で、一番下の項目が半分だけ表示され、クリックしてもスクロールが跳ねて選択できない問題がありました。
原因を調べると、以前の修正でフォームの初期化処理に以下の 1 行が紛れ込んでいました。
Private Sub UserForm_Initialize()
mIsUpdating = True: lstItems.IntegralHeight = False ' ← これが原因
IntegralHeight は、リストボックスの高さをちょうど整数行分に自動スナップさせ、中途半端な見切れを防ぐためのプロパティです。
これを False にしたうえで中途半端な高さを与えていたため、17.5 行分のような高さになり、最下段の 18 行目が半分だけ顔を出してクリックを受け付けなくなっていました。
そこで、厳密な UI 算数を行いました。
- 画面の実測より、BIZ UDPゴシック 12pt における ListBox 1 行の高さはジャスト 12.0pt
- 要望である「15 行程度」に合わせるため、上下の枠線余白(3pt)を足して計算:
$$\text{高さ} = 15 \text{行} \times 12.0\text{pt} + 3\text{pt} = 183\text{pt} \sim 184\text{pt}$$ -
IntegralHeight = Trueを死守し、高さを 184pt に設定
これで、15 行が 1 ピクセルの狂いもなくジャストで収まり、最下行が隠れる現象は完全に解消しました。
泥沼②:ツールの潜伏バグ「指数表記 8.4215e+06 の小文字 e」事件
今回もっとも深い原因だったのがこれです。
枠線の色をグレーに設定しようと BorderColor = &H808080(10進数で 8421504)を指定して再構築マクロを書き出させたところ、VBE の大文字小文字チェックで突如エラーが発生しました。
エラー: ブックに既にある名前と大小文字だけ違う綴りがあります。
行80: `e` ← ブックでは `E`(このまま書くとブック全体の `E` が `e` になります)
コード内に変数 e など宣言していません。
ツール本体の Python スクリプト(vbam_form2vba.py)を調べると、値のリテラル変換関数に以下の記述がありました。
def _f2v_lit(v):
if isinstance(v, (int, float)):
if isinstance(v, int) and (v > 0x7FFFFFF or v < -0x7FFFFFF):
return "&H%X" % (v & 0xFFFFFFFF)
return "%g" % v # ← これが原因
Python の %g フォーマットは、1,000,000 以上の float 値に対して自動的に指数表記(e)を出力します。
COM 経由で取得した BorderColor の値 8421504.0 は、"%g" によって 8.4215e+06 という文字列に変換されていました。
VBA コードの中に小文字の e がリテラルとして紛れ込んだ結果、VBE の「プロジェクト内の変数名の大文字小文字を強制統一する」という仕様に引っかかり、既存の変数 E を汚染すると判定されて処理が停止していたのです。
直ちに Python スクリプトを改修しました。
def _f2v_lit(v):
"""Python の値を VBA のリテラルにする(指数表記 e の発生を完全遮断)"""
if isinstance(v, bool):
return "True" if v else "False"
if isinstance(v, (int, float)):
if isinstance(v, int) or (isinstance(v, float) and v.is_integer()):
iv = int(v)
if iv > 0x7FFFFFFF or iv < -0x7FFFFFFF:
return "&H%X" % (iv & 0xFFFFFFFF)
if iv > 0xFFFF:
return "&H%X" % iv # 8421504 は綺麗に &H808080 と出力
return str(iv)
# 浮動小数点は指数表記を出さずに丸める
s = ("%.4f" % v).rstrip("0").rstrip(".")
return s if s else "0"
return _f2v_q(v)
大きな色数値はすべて &H808080 のような 16 進数表記になり、浮動小数点も指数表記を完全に遮断。大文字小文字チェックを 1 発でパスするようになりました。
泥沼③:コンボボックスの下線が消える問題
フォームの見た目を確認した際、検索枠や AI 枠の下線が見えなくなっている現象に気づきました。
MSForms の ComboBox は、標準の立体枠(SpecialEffect = 2: Sunken)だと淡いグレーと白で描画されます。
これが Windows 10/11 の高 DPI ディスプレイ(拡大率 125% や 150%)で表示されると、画面描画の丸め誤差により、下端の 1 ピクセルの境界線が間引かれて消えてしまうのです。
解決策は 3 つありました。
-
フラット実線枠にする:
SpecialEffect = 0(Flat)、BorderStyle = 1(Single)、BorderColor = &H808080を指定する。全周を均一なグレーの 1 本線で囲むため、下線が間引かれない - 高さを 24pt にする:標準の 22pt だと文字の描画領域が下枠線に被りやすいため、24pt に拡大して余白を持たせる
- フォーム底辺のマージンを 15pt 確保する:一番下の要素がフォーム底辺に密着していると枠線がクリップされるため、フォーム全体の高さを少し伸ばして余白を作る

▲ 激闘の末に完成した「マクロ・レシピ統合一覧」フォーム。フォント12pt・15行ジャスト、下線くっきり、全四辺の美しさを完全両立
5. スキル文書(SKILL.md)への焼き込み
この知見を風化させず、次回以降どの AI が担当しても最初から完璧なフォームを作れるよう、excel-userform-builder/SKILL.md にルールとして焼き込みました。
### 寸法のリズム(8の倍数で刻む)
- フォーム外周の余白: **12pt**。要素間の縦間隔: **8pt**(強い関連は 6、セクション区切りは 16)
- 高さの標準: **ComboBox 24**(22だとフォント描画で下線が消えやすいため24推奨)、TextBox **22〜24**、ボタン **24〜28**、ラベル **18**、リスト行数×12+3
- **フォーム最下部の余白確保**: 最下段コントロールの下端からフォーム底辺まで最低 **12〜16pt** の余白を必ず残す(底が詰まると下枠線が見切れるため)。
### ボックス枠線の標準(下線欠落の完全防止)
- **入力・一覧枠の下線死守**: `ComboBox` / `TextBox` / `ListBox` は、Windows高DPI環境での1px間引きによる下線消失を防ぐため、最初から**フラット実線枠(`SpecialEffect = 0`, `BorderStyle = 1`, `BorderColor = &H808080`)**で作成する。淡い立体枠にせずグレー実線で均一に縁取ることで、四辺すべての下線が100%くっきり描画される。
6. そして「爆速」へ ── 会話だけで一瞬で直る快感
こうして掟とスキルを固めたあとの Gemini の動きは見事なものでした。
レシピのときだけ編集ボタンから別の画面に跳べなくなっていることに気づき、編集ボタンを押したら専用の業務レシピフォームが開くように改修してほしい、と頼みました。
この指示を出した瞬間、AI は無駄な調査も出力ファイルの閲覧も一切行いませんでした。
- ターン1: 修正対象のプロシージャ(ボタン制御とクリックイベント)を並列でピンポイント取得
-
ターン2:
patch_procedureで置換 - ターン3: 全体コンパイルとアドイン更新登録を並列同時実行
わずか 2〜3 ターンのやり取りで、画面連携のスムーズな改修が完了しました。
動作を確認し、先ほどまでの重さが嘘のように早くなったことを伝えると、AI も手応えを感じて喜んでいました。
ただ、その時点で主要な画面調整がほぼすべて完了してしまっており、もう直すところが残っていなかったのはご愛敬です。
おわりに ── AIを速くするのはプロンプトではなく「環境と掟」である
昨晩は「AI が言うことを聞かない、勝手な小細工をして遅い」とふてくされて寝てしまいましたが、朝起きて向き合ってみて痛感しました。
AI が遅いとき、悪いのは AI の頭脳そのものではなく、AI を走らせている「環境」と「掟の解像度」です。
- ファイルを読ませない(読まなくていい定型を渡す)
- 調査を連打させない(上限を課す)
- ツールの潜伏バグを放置しない(大文字小文字や指数表記の罠を潰す)
- ツールの呼び出しを並列化させる
これらを人間が整えてあげるだけで、Gemini Flash であっても、Claude Opus に匹敵するスピードと精度で UserForm を自在に組み上げられるようになります。
掟を固め、余計な知恵を捨てさせた先にあるのは、迷いのない一撃の速さだけです。


