Skip to main content

CodeContests における Claude 4、OpenAI Codex、Gemini 2.5 Pro の比較評価

Claude 4 Sonnet と Opus を徹底検証 これは機械翻訳された記事です。誤訳の可能性があればコメント欄でご指摘ください。
Created on August 26|Last edited on August 26
Anthropic の Claude 4 Opus と Claude 4 Sonnet は、コーディング、推論、そして開発者ワークフローへのシームレスな統合に焦点を当てた新世代の大規模言語モデルです。Claude ファミリーの高い実績を土台に、これらのモデルは OpenAI の codex-mini や Google の Gemini 2.5 Pro といった有力な同世代モデルと並んで登場し、エンジニアやソフトウェアチームにとって不可欠なツールになることを目指しています。
本記事では、Claude 4 Opus と Claude 4 Sonnet が実践的なコーディング課題でどのように性能を発揮するかを、統一されたプログラム的ベンチマークと実際のコード実行によって、能力と信頼性の両面から検証します。さらに、OpenAI と Google の現行モデルとの比較を通じて、最新の Claude モデルが現代の開発ニーズにどう応えるのか、特にコード品質、問題解決力、効率が問われる場面での実力を、明快かつ最新の観点から提示することを目指します。


目次



Claude 4 の新機能は何か

Claude 4 は、透明性と安全性に強みを持つ Anthropic の取り組みを土台に、推論能力、コード生成、エージェント指向ワークフローで大幅な進歩を実現しました。Claude 4 ファミリーには、コーディングや高度なタスクで最先端水準に到達した Claude 4 Opus と、大幅に刷新され、これまで以上に高速・高精度・高知能になった Claude 4 Sonnet が含まれます。
新しく強力なモデルが2つあります。
  • Claude 4 OpusAnthropic 史上最も高性能な AI。難易度の高いコーディング、段階的な推論、そして大規模なエージェント型ワークフローで卓越した実力を発揮します。従来のベンチマークを上回り、ソフトウェアエンジニアリングと研究において最先端水準の性能を提供します。
  • Claude 4 SonnetSonnet 3.7 から大きく進化し、最上位の推論力、優れた指示追従、より強力なコード生成を実現。日常利用でも、より高速で実用的な応答を提供します。
  • ツール使用 + 拡張思考(ベータ)両モデルは、段階的な推論の一環として外部ツール(電卓、コード実行環境、ウェブ検索、カスタム API など)を利用できるようになりました。途中で「考える」ために一旦立ち止まり、ツールを呼び出し、その後回答の構築を再開します。
  • 〜でインタリーブ型思考Claude は、内部推論、ツール呼び出し、最終出力を切り替えながら進行でき、透明性が高く監査可能なワークフローを実現します。
  • 並列ツール使用と強化メモリClaude 4 はツールを並列実行でき、許可されている場合は複数ターンにわたって重要な事実や文脈を「記憶」できます。ファイルアクセスにより、Opus 4 は自前のメモリファイルを作成・更新でき、長時間のエージェント実行において文脈維持と一貫性が向上します。
  • API の強化: コード実行、柔軟なファイル API、MCP コネクタ、最大1時間のプロンプトキャッシュなどの新しい API 機能にアクセスできます。これらのツールにより、より強力で持続性のある AI ワークフローを構築できます。
  • 安全性の向上と抜け道の削減: 両モデルは前世代比でショートカットや抜け道的な挙動が65%減少し、エージェントタスクやコード編集の信頼性が向上しました。

LLM ベンチマーク:知的能力の北極星になり得るか?

LLM の評価で深刻化している問題は、明示的にそのベンチマークで訓練されていなくても、モデルがベンチマークのテストセットに「過学習」しているように見えることです。これは、学習中に見た解答を丸暗記する従来の意味での過学習ではありません。むしろ、LLM の事前学習のあり方によって引き起こされる、大規模なデータ漏洩に��い現象です。
GSM8K、HumanEval、MMLU などの主要なベンチマークは、何年も前からオンラインで出回っています。GitHub、学術論文、ブログ投稿、チュートリアルなどに掲載されています。LLM が公開インターネットの大規模スクレイプで事前学習される場合、これらのベンチマークの一部、あるいは丸ごとのコピーに触れている可能性は十分にあります。つまり評価時に、たとえそのベンチマークをファインチューニングから除外していても、モデルがすでにその課題を「知っている」可能性があるということです。
これにより、強い一般化能力があるかのような錯覚が生まれます。モデルが高得点を取るのは、本当に問題を解決したからではなく、形式を認識したり、似た言い回しを思い出したり、解答分布を暗記していたりするためです。だからこそ、一部のモデルは特定のベンチマークで訓練されていなくてもテストセットで良い成績を出せます。実際には、野生のデータでほとんど同一または極めて類似した問題に十分多く触れており、その結果として一般化を装えてしまうのです。
これは、特に複数のモデルが類似のコーパスで訓練されている場合、ベンチマークのスコアを信頼しづらくします。事前学習と評価の境界は不鮮明で、ベンチマークが再利用されるほど、その価値は目減りします。推論力や一般化能力に関する厳密な主張は、本当に未公開かつ未見のプライベート評価で裏付けられない限り、慎重に扱うべきです。したがって、これから実行するベンチマークが真の一般化を反映すると断言はできません。公開ベンチマークは飽和が進んでおり(明示的な学習対象でなくても、事前学習中にモデルが触れている可能性が高いため)です。
とはいえ、ベンチマークには依然として有用性があります。モデル同士の比較や経時的な変化の追跡、特定機能のストレステストにおける共通の基準点を提供してくれます。ただし、ベンチマークはあくまで診断であり、絶対的な真実ではありません。ベンチマークで高得点を取っても、そのモデルが課題を理解しているとは限りません。単に、以前に見たものを反復しているだけかもしれません。

私たちのベンチマーク:CodeContests

CodeContests 上で Gemini 2.5 Pro、OpenAI の Codex、Claude 4 Sonnet と Opus 4 を実行し、実際の競技問題を最も適切に扱えるのはどれかを検証します。このコレクションには、Codeforces、AtCoder、CodeChef などのプラットフォームから集めた実在の競技プログラミング問題が1万件超含まれます。各問題には、自然言語による説明、複数の公開・非公開テストケース、タグや難易度評価といったメタデータが付属します。
CodeContests は、多様な問題タイプと厳密な評価設定により、コード生成モデルのベンチマークとして広く用いられています。出題は LLM を前提に設計されておらず、明確な推論、正確な実装、そして「もっともらしいコード」ではなくテストケース上での実際の正しさが求められます。
この比較では、各モデルが未見かつ実在の問題に取り組めるよう、公開テスト分割の一部のみを使用します。これにより、Gemini 2.5 Pro、OpenAI Codex、Claude 4 Sonnet と Claude 4 Opus が実際の競技プログラミング課題でどの程度の性能を示すかを、透明性があり現実的な形で示せます。

指標としてのコード正確性

異なる言語モデル間で公正かつ自動化された評価を行うために、独自の軽量なコード実行フレームワークを構築しました。各競技プログラミング問題については、各モデルに自然言語の問題文のみを提示し、解答として Python の関数を生成するよう促します。このフレームワークは、Gemini 2.5 Pro、OpenAI Codex、Claude 4 Sonnet と Claude 4 Opus の呼び出し方法を標準化することで、コードの各行や各テストを厳密に比較可能にし、公平な評価を担保します。
このセットアップの重要な特徴は、コード生成だけでなく、例示入力文字列を有効な関数呼び出しに変換したり、実行用にデータを整形したりといった補助作業にもLLMを使う点です。これにより、サンプル入力をPythonの呼び出しにマッピングするような「つなぎ」の作業を含め、すべての問題・すべてのモデルで一貫した方法で処理できるようになります。
生成コードを公開テストケースに対して実行した後、出力と期待される解答の比較には LLM を用います。これにより出力検証の堅牢性が大きく向上します。たとえ書式の表面的な違いやわずかな浮動小数点の誤差があっても、LLM は意味的に同等な結果を認識でき、通常の文字列比較では見落としかねないケースにも対応できます。
関数呼び出しの自動化と解答チェックに LLM を用いることで、評価プロセス全体を再現可能かつ一貫したものにし、何よりも「実際の正確性」—すなわちモデルのコードが実世界のテストケースを通過できるか—に焦点を当てられます。重視するのは常に見かけのもっともらしさではなく、実際の性能です。

実験1:思考トークンはどれくらいが最適ですか

最初の実験の目的はシンプルです。コード問題を解かせる際、Claude 4 Sonnet にどれだけの内部推論を求めるのが適切か、という点です。Claude には「思考」プロセスを細かく制御する機能があり、budget_tokens の値を指定することで、最終回答を生成する前に内部推論(いわゆる「思考ブロック」)に費やせるトークンの上限を設定できます。
検証のため、標準設定(明示的な思考なし)から最大 24,000 トークンまで、複数の思考予算を試験します。各設定ごとに、CodeContests の同一の競技プログラミング問題セットで Claude を実行します。フレームワークは各問題の自然言語による説明をモデルに渡して解答を収集し、実際のテストケースで実行して正確性とレイテンシの両方を測定します。
異なる設定での結果を記録することで、Claude の「思考予算」を増やしたときにコードの正確性と応答時間がどう変化するかを可視化できます。内部で考える余地を広げればより良いコードが書けるのか、それとも単に処理が遅くなるだけなのか。今回の実験は、そのトレードオフを詳細に把握し、最適な性能を引き出せるよう推論の深さを調整できるようにすることを目的としています。
評価用のコードは次のとおりです。
import os
import sys
import time
import subprocess
from datasets import load_dataset
from litellm import completion as oai_completion
from anthropic import Anthropic
from google import genai
import weave
from weave.flow.eval_imperative import EvaluationLogger
from google.genai import types
import re

weave.init("codecontests_evalv2")

os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your_api_key")
OAIKEY = os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your_api_key")
CLAUDE_KEY = os.getenv("CLAUDE_API_KEY", "your_api_key")

GENAI_KEY = os.getenv("GOOGLE_API_KEY", "your_api_key")
from openai import OpenAI
client = OpenAI(api_key=OAIKEY)


anthropic_client = Anthropic(api_key=CLAUDE_KEY)
gemini_client = genai.Client(api_key=GENAI_KEY)

def clean_llm_code_block(text):
cleaned_text = text.replace("```python", "").replace("```", "").strip()
code_blocks = re.findall(r"(def solve\(.*?)(?=^def |\Z)", cleaned_text, re.DOTALL | re.MULTILINE)
source_text = code_blocks[-1] if code_blocks else cleaned_text
prompt = (
"Given the following response from a language model, extract ONLY the valid Python code for the function. "
"Do not include any explanations, text, or formatting fences. Only the code.\n\n"
f"Response:\n{source_text}\n\n"
"Return ONLY the Python code, including any necessary imports:"
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
gpt4o_code = response["choices"][0]["message"]["content"]
gpt4o_code = gpt4o_code.replace("```python", "").replace("```", "").strip()
return gpt4o_code



@weave.op()
def generate_completion(model: str, prompt: str) -> str:
# Codex models (openai/codex-*, openai/codex-mini-latest, etc)
if model.startswith("openai/codex-"):
# Use the .responses.create API as per the latest OpenAI SDK
codex_model = model.replace("openai/", "")
# You can optionally add custom instructions (here, we use a neutral persona)
response = client.responses.create(
model=codex_model,
instructions="You are a helpful, accurate Python coding assistant.",
input=prompt
)
return response.output_text.strip()
# General OpenAI chat-completions
elif model.startswith("openai/"):
from litellm import completion as oai_completion
response = oai_completion(
model=model,
messages=[{"role": "user", "content": prompt}],
reasoning_effort="low",
)
return response["choices"][0]["message"]["content"].strip()

# Anthropic Claude (API unchanged)
elif model.startswith("anthropic/"):
response = anthropic_client.messages.create(
model=model.replace("anthropic/", ""),
max_tokens=8000,
thinking={"type": "enabled", "budget_tokens": 4000},
messages=[{"role": "user", "content": prompt}],
)
for block in response.content:
if block.type == "text":
return block.text.strip()
return "[No Claude response]"

# Gemini (API unchanged)
elif model.startswith("gemini/"):
result = gemini_client.models.generate_content(
model=model.replace("gemini/", ""),
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(thinking_budget=4000)
),
contents=[prompt]
)
return result.text.strip() if result.text else "[No Gemini response]"

else:
raise ValueError(f"Unsupported model: {model}")




def ask_llm_for_function_implementation(description: str, model: str) -> str:
prompt = (
f"Write a Python3 function named `solve` with typed input arguments for this problem -- eg the solve function should take arguments to handle different test cases:\n\n"
f"{description.strip()}\n\n"
"Return only a valid Python function -- no special packages that arent commonly used and NO MAIN function, no if __name__ == __main__....., JUST write the function -- that returns the result. No comments, no explanations."
f"HOWEVER, you still need to include necessary imports for libraries"
f"IF you do not include the right imports, the code will not be executable, and your response will be judged as incorrect!"
)
return clean_llm_code_block(generate_completion(model, prompt))

@weave.op
def ask_llm_for_function_call(code: str, raw_input: str, model: str) -> str:
prompt = (
"You're given a Python function and a single input string. "
"Format it into a valid Python function call using only standard types.\n\n"
f"Function:\n{code}\n\n"
f"Input:\n{raw_input.strip()}\n\n"
"Return ONLY a valid function call (e.g., solve(3, 5)) WITH NO 'def' "
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
content = response["choices"][0]["message"]["content"]
content = content.replace("```python", "").replace("```", "").strip()
return content

def compare_output_with_llm(expected: str, actual: str, model: str) -> bool:
prompt = (
f"Expected output: {expected.strip()}\n"
f"Actual output: {actual.strip()}\n\n"
"Are these outputs equivalent? Eg ignore minor formatting errors etc, we are just looking for overall correctness in the output Reply YES or NO."
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
res = 'YES' in str(response["choices"][0]["message"]["content"]).upper()
return res

def run_code_and_call_function(code: str, function_call: str, timeout=10):
full_code = code + f"\n\nprint({function_call})"
try:
start = time.time()
result = subprocess.run(
[sys.executable, "-c", full_code],
capture_output=True,
text=True,
timeout=timeout
)
latency = time.time() - start
return result.stdout.strip(), result.stderr.strip(), latency
except subprocess.TimeoutExpired:
return "", "Execution timed out.", timeout
except Exception as e:
return "", str(e), 0.0

def ask_model_for_pip_command(error_msg):
prompt = (
"Given this Python error:\n\n"
+ error_msg +
"\n\nWrite the pip install command needed to fix it. Only return the command, e.g.:\n"
"pip install requests"
)
return generate_completion("openai/gpt-4o-2024-08-06", prompt)

def run_pip_install(pip_command):
print(f"Running: {pip_command}")
try:
result = subprocess.run(
pip_command.split(),
capture_output=True,
text=True,
timeout=180
)
print(result.stdout.strip())
if result.stderr:
print(result.stderr.strip())
except Exception as e:
print(f"pip install failed: {e}")

def evaluate_model_on_code_contests(model_name: str):
print(f"\n\nRunning evaluation for model: {model_name}\n")
ds = load_dataset("deepmind/code_contests", split="test", streaming=True)
ds = list(ds.take(31))

eval_logger = EvaluationLogger(
model=model_name.replace("-", "_").replace("/", "_").replace(".", "_"),
dataset="code_contests_test"
)
all_latencies = []

for i in range(30):
row = ds[i]
description = row["description"]
raw_inputs = row["public_tests"]["input"]
expected_outputs = row["public_tests"]["output"]

try:
code = ask_llm_for_function_implementation(description, model=model_name)
print(f"\n=== Task {row['name']} ===", flush=True)
all_passed = True
task_latencies = []
results_lst, expected_lst = [], []

for j, raw_input in enumerate(raw_inputs):
expected = expected_outputs[j] if j < len(expected_outputs) else ""

try:
function_call = ask_llm_for_function_call(code, raw_input, model=model_name)
result, error, latency = run_code_and_call_function(code, function_call)
if latency < 99:
task_latencies.append(latency)

if error:
print(f"[{j}] Runtime error: {error}")
if "ModuleNotFoundError" in error:
pip_cmd = ask_model_for_pip_command(error)
run_pip_install(pip_cmd)
# Re-run once after pip install
result, error, latency = run_code_and_call_function(code, function_call)
task_latencies.append(latency)
if error:
print(f"[{j}] Retry failed: {error}")
all_passed = False
continue
else:
all_passed = False
continue

is_correct = compare_output_with_llm(expected, result, model="openai/gpt-4o-2024-08-06")
results_lst.append(result)
expected_lst.append(expected)
if not is_correct:
all_passed = False
print(f"[{j}] input: {raw_input.strip()} → output: {result} | expected: {expected.strip()} | PASS: {is_correct} | latency: {latency:.2f}s")

except Exception as inner:
print(f"[{j}] Inner error: {repr(inner)}")
all_passed = False

task_avg_latency = sum(task_latencies) / len(task_latencies) if len(task_latencies) > 0 else 0.0
all_latencies.extend(task_latencies)

prediction_log = eval_logger.log_prediction(
inputs={"description": description},
output={'code': code, 'execution_result': results_lst, 'expected_execution_result': expected_lst}
)
prediction_log.log_score("correctness", all_passed)
prediction_log.log_score("code_latency", task_avg_latency)
prediction_log.finish()

except Exception as e:
print(f"[{i}] Top-level failure: {repr(e)}")
prediction_log = eval_logger.log_prediction(
inputs={"description": description},
output=str(e)
)
prediction_log.log_score("correctness", False)
prediction_log.finish()

avg_latency = sum(all_latencies) / len(all_latencies) if all_latencies else 0.0
eval_logger.log_summary({"avg_code_latency": avg_latency})
print(f"Evaluation complete for {model_name}. View in Weave UI.")

# ---- RUN FOR ALL TARGET MODELS ----

evaluate_model_on_code_contests("gemini/gemini-2.5-pro-preview-05-06")
evaluate_model_on_code_contests("anthropic/claude-sonnet-4-20250514")
evaluate_model_on_code_contests("openai/codex-mini-latest")
evaluate_model_on_code_contests("anthropic/claude-opus-4-20250514")
この Python スクリプトは、競技プログラミング向けに Gemini、Claude、OpenAI の Codex を自動評価する仕組みを構築します。まず DeepMind Code Contests の問題文を取り込み、各 LLM に Python の solve 関数の生成を依頼します。続いて、生成された Python コードを適切にクリーンアップして抽出し、提供されたテストケースに対して実行できるよう必要な関数呼び出しを組み立てます。
このフレームワークは堅牢なエラー処理を備えており、もしそれが遭遇した場合は ModuleNotFoundError 実行中には GPT-4o に正しい pip install コマンドの提案まで依頼し、足りないパッケージをインストールしてコードを再実行します。重要なのは、単純な文字列比較ではなく LLM を用いて実際の出力と期待出力を意味的に比較する点で、これにより細かな書式の違いには寛容になり、真の正確性に焦点を当てた評価が可能になります。
結果の可視化には Weave Evaluations を用いて評価指標を記録します。これにより、生のモデル生成コード、テスト入力、出力、エラー、平均レイテンシなどのパフォーマンス指標が取得されます。失敗事例の調査やモデル間の傾向把握が容易になり、モデルやベンチマークが進化しても各結果や不具合を追跡可能にします。今回は Weave の新しい EvaluationLogger このために、評価を柔軟に計測・計装できる手段を提供します。これにより、 EvaluationLogger厳密な形式に縛られる必要はなく、データセットを手動でループし、好きな方法でモデルを呼び出し、得られた予測とスコアをその場で記録できます。これにより、既存のパイプラインやカスタムの評価ループに Weave をそのまま組み込めるため、すべてを書き換える必要がなく、導入が容易になります。
Weave 内で表示された結果は次のとおりです。

内部の「思考」配分がコード生成性能に与える影響を評価するため、30件のサンプルでテストしました。表示されている「Total Tokens」指標には完全な思考トークンが含まれない点に注意してください。Claude 4 は内部推論を要約して返す場合があるためです。興味深いことに、思考予算なしのモデルは正確性36.7%を達成し、思考予算1024トークンの構成(26.7%)を上回りました。ただし、思考予算をさらに増やすと性能も向上しました。思考予算4000トークンのモデルは正確性40.0%に到達し、8000トークンでもこの水準を維持。決定的には、思考予算12000トークンの構成が正確性53.3%で最高となり、大きな改善が見られました。これは、最小限の思考が時に性能を損なう一方で、十分な思考配分は解答品質を大きく引き上げることを示唆しています。

実験2:Claude Sonnet 4 対 Claude Opus 4 対 Codex 対 Gemini 2.5 Pro

2つ目の実験では、CodeContests のテストセットから同一の競技プログラミング問題30問を用い、Claude 4 Sonnet、Claude 4 Opus、OpenAI の新しい Codex モデル、Gemini 2.5 Pro を直接比較しました。各モデルには問題の自然言語による説明のみを与え、解答として自己完結した単一の Python 関数を返すことを求めました。
各サンプル入力ごとに、正しい呼び出しシグネチャを自動生成し、候補コードを隔離環境で実行します。得られた出力は、堅牢な LLM ベースの意味的同値性チェックによって期待される正解と照合します。これにより、細かな書式のずれに評価が左右されることなく、実質的な正確性に焦点を当てられます。
これら3つのモデルを厳密に統一した条件下で実行することで、各システムが実世界の本物のコーディング課題にどう対処するかを明確に把握できます。評価するのはコードのもっともらしさだけでなく、実際の問題解決力と実装力です。
評価用のコードは次のとおりです。
import os
import sys
import time
import subprocess
from datasets import load_dataset
from litellm import completion as oai_completion
from anthropic import Anthropic
from google import genai
import weave
from weave.flow.eval_imperative import EvaluationLogger
from google.genai import types
import re

weave.init("codecontests_evalv2")

os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your_api_key")
OAIKEY = os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "your_api_key")
CLAUDE_KEY = os.getenv("CLAUDE_API_KEY", "your_api_key")

GENAI_KEY = os.getenv("GOOGLE_API_KEY", "your_api_key")


from openai import OpenAI
client = OpenAI(api_key=OAIKEY)

anthropic_client = Anthropic(api_key=CLAUDE_KEY)
gemini_client = genai.Client(api_key=GENAI_KEY)

def clean_llm_code_block(text):
cleaned_text = text.replace("```python", "").replace("```", "").strip()
code_blocks = re.findall(r"(def solve\(.*?)(?=^def |\Z)", cleaned_text, re.DOTALL | re.MULTILINE)
source_text = code_blocks[-1] if code_blocks else cleaned_text
prompt = (
"Given the following response from a language model, extract ONLY the valid Python code for the function. "
"Do not include any explanations, text, or formatting fences. Only the code.\n\n"
f"Response:\n{source_text}\n\n"
"Return ONLY the Python code, including any necessary imports:"
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
gpt4o_code = response["choices"][0]["message"]["content"]
gpt4o_code = gpt4o_code.replace("```python", "").replace("```", "").strip()
return gpt4o_code


@weave.op()
def generate_completion(model: str, prompt: str, thinking_budget=None, streaming=True) -> str:
response_text = ""
if model.startswith("anthropic/"):
# Calculate correct total max_tokens
if thinking_budget and int(thinking_budget) > 0:
max_tokens = 8000 + int(thinking_budget)
else:
max_tokens = 8000

create_kwargs = dict(
model=model.replace("anthropic/", ""),
max_tokens=max_tokens,
messages=[{"role": "user", "content": prompt}],
)

# Only provide thinking if budget is positive and not None
if thinking_budget and int(thinking_budget) > 0:
create_kwargs['thinking'] = {"type": "enabled", "budget_tokens": int(thinking_budget)}

client = anthropic_client

if streaming:
with client.messages.stream(**create_kwargs) as stream:
for event in stream:
if event.type == "content_block_start":
block_type = event.content_block.type
if block_type == "thinking":
print("\n[THINKING]: ", end="", flush=True)
elif block_type == "text":
print("\n[RESPONSE]: ", end="", flush=True)
elif event.type == "content_block_delta":
d = event.delta
if getattr(d, "type", None) == "thinking_delta":
print(d.thinking, end="", flush=True)
elif getattr(d, "type", None) == "text_delta":
print(d.text, end="", flush=True)
response_text += d.text
elif event.type == "content_block_stop":
print()
else:
response = client.messages.create(**create_kwargs)
for block in response.content:
if block.type == "thinking" and getattr(block, "thinking", "").strip():
print("\n[THINKING]:", block.thinking.strip(), flush=True)
elif block.type == "text" and getattr(block, "text", "").strip():
print("\n[RESPONSE]:", block.text.strip(), flush=True)
response_text += block.text.strip()
return str(response_text)
else:
raise ValueError(f"Unsupported model: {model}")


def ask_llm_for_function_implementation(description: str, model: str, thinking_budget=None) -> str:
prompt = (
f"Write a Python3 function named `solve` with typed input arguments for this problem -- eg the solve function should take arguments to handle different test cases:\n\n"
f"{description.strip()}\n\n"
"Return only a valid Python function -- no special packages that arent commonly used and NO MAIN function, no if __name__ == __main__....., JUST write the function -- that returns the result. No comments, no explanations."
f"HOWEVER, you still need to include necessary imports for libraries"
f"IF you do not include the right imports, the code will not be executable, and your response will be judged as incorrect!"
)
return clean_llm_code_block(generate_completion(model, prompt, thinking_budget=thinking_budget))

@weave.op
def ask_llm_for_function_call(code: str, raw_input: str, model: str, thinking_budget=None) -> str:
prompt = (
"You're given a Python function and a single input string. "
"Format it into a valid Python function call using only standard types.\n\n"
f"Function:\n{code}\n\n"
f"Input:\n{raw_input.strip()}\n\n"
"Return ONLY a valid function call (e.g., solve(3, 5)) WITH NO 'def' "
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
content = response["choices"][0]["message"]["content"]
content = content.replace("```python", "").replace("```", "").strip()
return content

def compare_output_with_llm(expected: str, actual: str, model: str) -> bool:
prompt = (
f"Expected output: {expected.strip()}\n"
f"Actual output: {actual.strip()}\n\n"
"Are these outputs equivalent? Eg ignore minor formatting errors etc, we are just looking for overall correctness in the output Reply YES or NO."
)
response = oai_completion(
model="openai/gpt-4o-2024-08-06",
messages=[{"role": "user", "content": prompt}],
temperature=0.0,
)
res = 'YES' in str(response["choices"][0]["message"]["content"]).upper()
return res

def run_code_and_call_function(code: str, function_call: str, timeout=10):
full_code = code + f"\n\nprint({function_call})"
try:
start = time.time()
result = subprocess.run(
[sys.executable, "-c", full_code],
capture_output=True,
text=True,
timeout=timeout
)
latency = time.time() - start
return result.stdout.strip(), result.stderr.strip(), latency
except subprocess.TimeoutExpired:
return "", "Execution timed out.", timeout
except Exception as e:
return "", str(e), 0.0

def ask_model_for_pip_command(error_msg):
prompt = (
"Given this Python error:\n\n"
+ error_msg +
"\n\nWrite the pip install command needed to fix it. Only return the command, e.g.:\n"
"pip install requests"
)
# In this context, no "thinking" is likely needed; you could propagate a thinking_budget if you want
return generate_completion("anthropic/claude-sonnet-4-20250514", prompt, thinking_budget=None)

def run_pip_install(pip_command):
print(f"Running: {pip_command}")
try:
result = subprocess.run(
pip_command.split(),
capture_output=True,
text=True,
timeout=180
)
print(result.stdout.strip())
if result.stderr:
print(result.stderr.strip())
except Exception as e:
print(f"pip install failed: {e}")

def evaluate_model_on_code_contests(model_name: str, thinking_budget=None):
tb_str = "nothinking" if not thinking_budget or int(thinking_budget) == 0 else f"tb{thinking_budget}"
print(f"\n\nRunning evaluation for model: {model_name} | thinking_budget={tb_str}\n")
ds = load_dataset("deepmind/code_contests", split="test", streaming=True)
ds = list(ds.take(31))

eval_logger = EvaluationLogger(
model=f"{model_name.replace('-', '_').replace('/', '_').replace('.', '_')}_{tb_str}",
dataset="code_contests_test"
)
all_latencies = []

for i in range(30):
row = ds[i]
description = row["description"]
raw_inputs = row["public_tests"]["input"]
expected_outputs = row["public_tests"]["output"]

try:
code = ask_llm_for_function_implementation(description, model=model_name, thinking_budget=thinking_budget)
print(f"\n=== Task {row['name']} ===", flush=True)
all_passed = True
task_latencies = []
results_lst, expected_lst = [], []

for j, raw_input in enumerate(raw_inputs):
expected = expected_outputs[j] if j < len(expected_outputs) else ""

try:
function_call = ask_llm_for_function_call(code, raw_input, model=model_name, thinking_budget=thinking_budget)
result, error, latency = run_code_and_call_function(code, function_call)
if latency < 99:
task_latencies.append(latency)

if error:
print(f"[{j}] Runtime error: {error}")
if "ModuleNotFoundError" in error:
pip_cmd = ask_model_for_pip_command(error)
run_pip_install(pip_cmd)
# Re-run once after pip install
result, error, latency = run_code_and_call_function(code, function_call)
task_latencies.append(latency)
if error:
print(f"[{j}] Retry failed: {error}")
all_passed = False
continue
else:
all_passed = False
continue

is_correct = compare_output_with_llm(expected, result, model="openai/gpt-4o-2024-08-06")
results_lst.append(result)
expected_lst.append(expected)
if not is_correct:
all_passed = False
print(f"[{j}] input: {raw_input.strip()} → output: {result} | expected: {expected.strip()} | PASS: {is_correct} | latency: {latency:.2f}s")

except Exception as inner:
print(f"[{j}] Inner error: {repr(inner)}")
all_passed = False

task_avg_latency = sum(task_latencies) / len(task_latencies) if len(task_latencies) > 0 else 0.0
all_latencies.extend(task_latencies)

prediction_log = eval_logger.log_prediction(
inputs={"description": description},
output={'code': code, 'execution_result': results_lst, 'expected_execution_result': expected_lst}
)
prediction_log.log_score("correctness", all_passed)
prediction_log.log_score("code_latency", task_avg_latency)
prediction_log.finish()

except Exception as e:
print(f"[{i}] Top-level failure: {repr(e)}")
prediction_log = eval_logger.log_prediction(
inputs={"description": description},
output=str(e)
)
prediction_log.log_score("correctness", False)
prediction_log.finish()

avg_latency = sum(all_latencies) / len(all_latencies) if all_latencies else 0.0
eval_logger.log_summary({"avg_code_latency": avg_latency})
print(f"Evaluation complete for {model_name} (thinking_budget={tb_str}). View in Weave UI.")

# ---- RUN FOR CLAUDE/SONNET4 FOR MULTIPLE THINKING BUDGETS INCLUDING "NO THINKING" ----
thinking_budgets = [None, 1024, 4000, 8000, 12000 ]
for tb in thinking_budgets:
evaluate_model_on_code_contests("anthropic/claude-sonnet-4-20250514", thinking_budget=tb)


評価結果は次のとおりです。

Codex は「思考」機能がないにもかかわらず、正答率63%で他モデルを上回り、最高の成績を達成しました。少なくとも公開されているものはなく、モデルのAPIも effort パラメータを受け付けません。)。Claude 4 Sonnet と Claude 4 Opus の正答率はそれぞれ43%と40%。Gemini 2.5 Pro は正答率36%でした。総じて、Claude 4 Sonnet が Claude 4 Opus を上回ったのは興味深い結果ですが、今回の評価では Claude と Gemini の両モデルに思考トークンを4000に制限しているため、思考予算を拡大した場合に各モデルがどのようにスケールするかも見てみたいところです。

Weave の比較ビュー

Weave の比較ビューは、複数のコーディングモデル間での推論の違いを明確に可視化できる点で特に有用です。各モデルの出力を横並びで表示することで、正答性や論理的一貫性の差異を即座に見分けられます。この直感的なインターフェースによって、あるモデルが失敗し別のモデルが成功する理由を素早く特定できます。

こうした洞察により、コーディング性能の分析と最適化がより効果的かつ容易になります。結果だけでなく、その背後にあるコーディングスタイルも可視化することで、Weave の比較ビューは各モデルの推論能力の評価と改善をシンプルにします。

結論

CodeContests ベンチマークにおける Claude 4 Sonnet、Claude 4 Opus、OpenAI Codex、Gemini 2.5 Pro の評価は、実世界のコーディング課題に対する各モデルの能力について有益な示唆を与えます。結果からは、Codex が他モデルを上回り、最高の正答率を達成したことが示されました。一方で、この評価は Claude 系モデルにおける思考予算の重要性も浮き彫りにしており、思考予算を12,000トークンに拡大すると正答率が大幅に向上することが確認されました。
これらのモデルの比較は、特にコーディング課題の文脈において、大規模言語モデルの評価がいかに複雑であるかを改めて示しています。カスタムのコード実行フレームワークと、LLM を用いた意味的同値性チェックを組み合わせることで、公平かつ堅牢な評価プロセスが実現されています。また結果は、ベンチマークがモデル間比較に有用である一方で、データリークや過学習の可能性があるため慎重に扱うべきだという示唆も与えています。
総じて、本評価はコーディング課題における現行の大規模言語モデルの強みと限界の理解に寄与します。各モデルのパフォーマンスを分析することで、開発者はアプローチを洗練し、モデルの性能最適化と解答品質の向上につなげることができます。