はじめに
AI に計算をさせると、桁の多い数でうっかり間違える、という話があります。それを防ぐ機能が Code Execution です。モデルに Python のコードを書かせて実際に実行させ、その結果を使って答えさせます。
ただ、最近のモデルはかなり計算に強く、素の状態でも多くの計算を正確にこなします。では Code Execution はどこから効いてくるのか。私は gemini-3.5-flash で、同じ計算を「直接答えさせた場合」と「Code Execution で実行させた場合」で比べ、境界を探りました。
なお本記事の検証は、Gemini API(google-genai SDK、APIキー認証)で行いました。ブラウザ版の Gemini ではなく、プログラムから API を呼び出したものです。Google Cloud(GEAP / Vertex AI)経由でも、クライアントの初期化を変えるだけで同じツールが使え、結果も基本的に同じになります。仕様や料金は変わりうるため、最新の情報は公式ドキュメントで確認してください。
Code Execution とは
Code Execution は、モデルに Python コードを生成させ、それをサンドボックス環境で実行させるツールです。モデルは実行結果を見て、必要なら書き直しながら最終的な答えにたどり着きます。
いくつか制約があります。
- 実行できるのは Python のみ。1回あたり最大30秒、再プロンプトなしで最大5回まで実行できる。
- 使えるライブラリは NumPy、Pandas、Matplotlib、Seaborn などに限られ、自前のライブラリは入れられない。
- Code Execution の有効化そのものに追加料金はなく、入出力トークンぶんだけ課金される。
実装
google-genai SDK では、tools に Code Execution を渡すだけです。生成されたコードと実行結果は、レスポンスの各パートから取り出せます。
from google import genai
from google.genai import types
client = genai.Client()
resp = client.models.generate_content(
model="gemini-3.5-flash",
contents="100の階乗を、Pythonコードを書いて実行し正確に求めてください。",
config=types.GenerateContentConfig(
tools=[types.Tool(code_execution=types.ToolCodeExecution())],
),
)
for part in resp.candidates[0].content.parts:
if part.executable_code: # モデルが書いたコード
print(part.executable_code.code)
if part.code_execution_result: # 実行結果
print(part.code_execution_result.output)
この「Code Execution あり」と、ツールを外して普通に答えさせる「直接(暗算)」で、同じ問題を解かせて比べました。
検証① 中程度の計算では差が出なかった
まず、桁がそこそこ大きい計算を7問投げました。巨大な掛け算、べき乗、階乗、素数の和、二乗和などです。
結果は、直接もCode Executionも7問すべて正解でした。
| 問題(一部) | 直接 | Code Execution |
|---|---|---|
| 123456789 × 987654321(18桁の積) | ✅ | ✅ |
| 2の64乗 | ✅ | ✅ |
| 25の階乗(26桁) | ✅ | ✅ |
| 最初の50個の素数の和 | ✅ | ✅ |
18桁になる掛け算や、26桁になる25の階乗まで、gemini-3.5-flash は暗算で正確に答えました。この範囲なら、わざわざ Code Execution を使うまでもありません。
検証② 極端な計算で境界が見えた
そこで、直接では原理的に厳しいレベルまで難易度を上げました。全桁を正確に書く必要がある巨大な数や、大きな数の素数判定です。
| 問題 | 直接(暗算) | Code Execution |
|---|---|---|
| 20桁 × 20桁の積 | ✅ | ✅ |
| 100の階乗(158桁) | ❌ | ✅ |
| 2の200乗(61桁) | ❌ | ✅ |
| フィボナッチ数列の200番目 | ✅ | ✅ |
| 1〜10000の3乗の和 | ✅ | ✅ |
ここで差が出ました。100の階乗(158桁)と2の200乗(61桁)は、直接だと途中の桁がずれて誤答になりました。全桁を正確に暗算するのは、さすがに厳しいということです。
一方 Code Execution は、これらをすべて正確に解きました。桁が何桁になろうと、Python が計算するので破綻しません。
面白いのは、20桁 × 20桁の積やフィボナッチ200番目は、直接でも正解したことです。つまり境界はきれいな一線ではなく、「全桁を正確に書く必要があり、かつ桁数が一定を超える」ような、直接では破綻するタイプの計算で Code Execution が効いてくる、という形でした。
生成されたコードを見る
Code Execution の良さは、結果だけでなく、どう計算したかがコードとして残ることです。素数判定では、モデルは次のようなコードを書いて実行していました。
def is_prime(n):
if n <= 1:
return False
if n <= 3:
return True
if n % 2 == 0 or n % 3 == 0:
return False
i = 5
while i * i <= n:
if n % i == 0 or n % (i + 2) == 0:
return False
i += 6
return True
print(is_prime(9999999967)) # -> True
しかもこの後、sympy.isprime() でも同じ結果になることを確かめていました。3乗の和の問題でも、ループでの合計と公式 (n(n+1)/2)² の両方を計算し、一致するか自分で検算しています。
答えだけを出す直接回答と違い、根拠のコードと検算が残るので、結果を信頼しやすく、後から確認もできます。これは、正確さと同じくらい実用上の価値があります。
使いどころ
今回の実測をふまえた整理です。
- 直接で十分:一般的な桁数の計算、簡単な集計。3.5 Flash はこの範囲なら素で正確なので、Code Execution はむしろオーバーヘッド。
- Code Execution が効く:全桁が必要な巨大な数値、厳密さが要る計算、大きな数の判定、正しさの根拠(コード)を残したい場面。
- データ処理:Pandas などが使えるので、表形式のデータの集計や整形にも向く(今回は計算中心に検証)。
要は、「モデルの暗算が破綻する領域」と「根拠を残したい場面」で Code Execution を選ぶ、という使い分けになります。
まとめ
| 観点 | 実測からの結論 |
|---|---|
| 中程度の計算 | 直接もCode Executionも正確。差は出ない(3.5 Flashが強い) |
| 巨大で厳密な計算 | 100!や2の200乗など全桁が必要な計算は直接が崩れ、Code Executionが正確 |
| 素数判定 | 10桁の数は直接では判定しきれず、Code Executionは確実 |
| 透明性 | コードと検算が残り、結果を信頼・確認しやすい |
| 使い分け | 普通の計算は直接、破綻する計算や根拠が要る場面はCode Execution |
Code Execution は「常に使うべき魔法」ではありませんでした。3.5 Flash は多くの計算を素でこなすので、中程度なら不要です。ただ、暗算が破綻する巨大で厳密な計算や、根拠のコードを残したい場面では、確実さがはっきり効きます。モデルの限界を見極めて、そこで使うのが賢い使い方です。

