CodeContests における Claude 4、OpenAI Codex、Google Gemini 2.5 Pro の比較テスト
Claude 4のSonnetとOpusを徹底検証
本記事はAIによる翻訳です。誤訳の可能性があればコメント欄でお知らせください。
Created on August 27|Last edited on September 3
Comment
AnthropicのClaude Opus 4とSonnet 4は、コード生成、推論、そして開発者ワークフローへのシームレスな統合に焦点を当てた新世代の大規模言語モデルです。Claudeファミリーの強力な実績を土台に、これらのモデルはOpenAIのcodex-miniやGoogleのGemini 2.5 Proといった有力な同世代モデルと並んで登場し、エンジニアやソフトウェアチームにとって不可欠なツールとなることを目指しています。
本記事では、統一されたプログラムベンチマークとライブコード実行を用いて、Claude Opus 4 と Sonnet 4 が実務的なコーディングタスクの幅広い範囲でどのように性能を発揮するかを、能力と信頼性の両面から検証します。OpenAI と Google の現行モデルと結果を比較することで、最新の Claude モデルが現代の開発ニーズにどのように応えるのか、特にコード品質、問題解決力、効率が真に問われる場面において、明快で最新の見取り図を提示することを目指します。

目次
目次Claude 4の新機能は?LLMベンチマーク──知能の指標たり得る「北極星」なのか?私たちのベンチマーク:CodeContests指標としてのコード正確性実験 1:思考トークンはどれくらいが最適か?実験 2:Claude Sonnet 4 対 Claude Opus 4 対 Codex 対 Gemini 2.5 ProWeave の比較ビュー結論
Claude 4の新機能は?
Claude 4 は、透明性と安全性に強みを持つ Anthropic の取り組みを土台に、AI の推論、コード生成、エージェント型ワークフローで大きく前進しました。Claude 4 ファミリーには、コーディングや複雑なタスクで新たな最先端となる Claude Opus 4 と、劇的に強化され、これまで以上に高速・高精度・高知性になった Claude Sonnet 4 が含まれます。
強力な新モデルが2つあります。
- Claude Opus 4Anthropic史上最強のAI。難度の高いコーディング、マルチステップの推論、そして大規模なエージェント型ワークフローで卓越した性能を発揮します。既存のベンチマークを上回り、ソフトウェアエンジニアリングと研究においてクラス最高のパフォーマンスを実現します。
- Claude Sonnet 4Sonnet 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 などのプラットフォームから集めた 10,000 件超の実在する競技プログラミング問題を収録しています。各問題には自然言語の問題文、複数の公開・非公開テストケース、タグや難易度などのメタデータが含まれます。
CodeContests は、多様な問題タイプと厳格な評価設定により、コード生成モデルのベンチマークとして広く使われています。出題は LLM を前提に作られておらず、明確な推論、正確な実装、そしてテストケースでの実際の正答性が求められます。見かけ上もっともらしいコードでは不十分です。
この比較では、各モデルが未見の実在問題に取り組めるよう、公的テストスプリットの一部のみを使用します。これにより、Gemini 2.5 Pro、Codex、Claude 4 Sonnet と Opus が実際の競技プログラミング課題でどの程度の性能を発揮するかを、透明性のある現実的なかたちで示せます。
指標としてのコード正確性
異なる言語モデル間で公正かつ自動化された評価を行うため、軽量なカスタムのコード実行フレームワークを作成しました。各競技プログラミング問題については、モデルに自然言語の問題文だけを提示し、解として Python の関数を生成するよう促します。このフレームワークは、Gemini 2.5 Pro、Codex、Claude 4 Sonnet と Opus の呼び出し方法を標準化することで条件をそろえ、あらゆるコード行とテスト結果を直接比較可能にします。
今回のセットアップの要は、コード生成だけでなく、補助タスクにも LLM を使っている点です。具体的には、例示の入力文字列を有効な関数呼び出しに変換したり、実行用にデータを整形したりします。これにより、サンプル入力を Python の呼び出しにマッピングするなどのグルー作業を、すべての問題・すべてのモデルで一貫して行えるようにしています。
生成したコードを公開テストケースで実行した後、出力と期待される解答の比較には LLM を用います。これにより出力検証が大幅に堅牢になります。LLM は、見た目の書式差やわずかな浮動小数点の誤差があっても、意味的に同等な結果を認識できるため、通常の文字列比較では見落としやすいケースも正しく判定できます。
関数呼び出しと解答チェックを LLM で自動化することで、評価プロセス全体を再現可能かつ一貫したものにし、何よりも「実際の正しさ」—つまりモデルが生成したコードが実世界のテストケースを通過できるか—に焦点を当てられます。重視するのは常に見かけのもっともらしさではなく、実際の性能です。
実験 1:思考トークンはどれくらいが最適か?
最初の実験は基本的な問いに答えることを目的としています。すなわち、コード問題を解かせる際、Claude Sonnet 4 にどれだけの内部推論を求めるべきか。Claude は「思考」プロセスをきめ細かく制御できます。具体的には、budget_tokens を指定することで、最終回答を出力する前に内部推論(いわゆる「thinking blocks」)に費やせるトークンの上限を設定できます。
検証のため、標準設定(明示的な思考なし)から最大 24,000 トークンまで、さまざまな思考予算を試します。各設定ごとに、CodeContests の同一の競技プログラミング問題セットで Claude を実行します。フレームワークは各問題の自然言語による説明をモデルに渡して解答を取得し、実際のテストケースで実行して正解率とレイテンシの両方を測定します。
異なる設定で結果を記録することで、Claude の「思考予算」を増やしたときにコードの正確性と応答時間がどう変わるかを可視化できます。内部で考える余地を広げれば、より良いコードが書けるのか、それとも単に遅くなるだけなのか。今回の実験は、そのトレードオフを詳細にマッピングし、最適な性能が出るように推論の深さを調整できるよう設計しています。
評価用のコードは次のとおりです。
import osimport sysimport timeimport subprocessfrom datasets import load_datasetfrom litellm import completion as oai_completionfrom anthropic import Anthropicfrom google import genaiimport weavefrom weave.flow.eval_imperative import EvaluationLoggerfrom google.genai import typesimport reweave.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 OpenAIclient = 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_textprompt = ("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 SDKcodex_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-completionselif model.startswith("openai/"):from litellm import completion as oai_completionresponse = 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.opdef 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 contentdef 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 resdef 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() - startreturn result.stdout.strip(), result.stderr.strip(), latencyexcept subprocess.TimeoutExpired:return "", "Execution timed out.", timeoutexcept Exception as e:return "", str(e), 0.0def 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 = Truetask_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 installresult, error, latency = run_code_and_call_function(code, function_call)task_latencies.append(latency)if error:print(f"[{j}] Retry failed: {error}")all_passed = Falsecontinueelse:all_passed = Falsecontinueis_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 = Falseprint(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 = Falsetask_avg_latency = sum(task_latencies) / len(task_latencies) if len(task_latencies) > 0 else 0.0all_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.0eval_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 osimport sysimport timeimport subprocessfrom datasets import load_datasetfrom litellm import completion as oai_completionfrom anthropic import Anthropicfrom google import genaiimport weavefrom weave.flow.eval_imperative import EvaluationLoggerfrom google.genai import typesimport reweave.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 OpenAIclient = 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_textprompt = ("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_tokensif thinking_budget and int(thinking_budget) > 0:max_tokens = 8000 + int(thinking_budget)else:max_tokens = 8000create_kwargs = dict(model=model.replace("anthropic/", ""),max_tokens=max_tokens,messages=[{"role": "user", "content": prompt}],)# Only provide thinking if budget is positive and not Noneif thinking_budget and int(thinking_budget) > 0:create_kwargs['thinking'] = {"type": "enabled", "budget_tokens": int(thinking_budget)}client = anthropic_clientif streaming:with client.messages.stream(**create_kwargs) as stream:for event in stream:if event.type == "content_block_start":block_type = event.content_block.typeif 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.deltaif 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.textelif 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.opdef 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 contentdef 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 resdef 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() - startreturn result.stdout.strip(), result.stderr.strip(), latencyexcept subprocess.TimeoutExpired:return "", "Execution timed out.", timeoutexcept Exception as e:return "", str(e), 0.0def 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 wantreturn 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 = Truetask_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 installresult, error, latency = run_code_and_call_function(code, function_call)task_latencies.append(latency)if error:print(f"[{j}] Retry failed: {error}")all_passed = Falsecontinueelse:all_passed = Falsecontinueis_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 = Falseprint(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 = Falsetask_avg_latency = sum(task_latencies) / len(task_latencies) if len(task_latencies) > 0 else 0.0all_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.0eval_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 Sonnet と Claude Opus の正解率はそれぞれ 43% と 40%。Gemini 2.5 Pro は正解率 36% でした。全体として、Claude Sonnet 4 が Claude Opus 4 を上回ったのは興味深い結果ですが、今回の評価では Claude と Gemini の思考トークンを 4000 に制限しているため、思考予算を拡大した場合に各モデルがどうスケールするかも見てみたいところです。
Weave の比較ビュー
Weave の比較ビューは、複数のコーディングモデル間で推論の違いを明確に可視化できる点で特に有用です。各モデルの出力を横並びで表示することで、正確性や論理的一貫性の食い違いを即座に見つけられます。この直感的なインターフェースを使えば、あるモデルが失敗し別のモデルが成功する理由を素早く特定できます。

こうした洞察によって、コーディング性能の分析と最適化がいっそうやりやすくなります。結果だけでなく基盤となるコーディングスタイルも可視化することで、Weave の比較ビューは各モデルの推論能力を評価・改善する作業を簡潔にしてくれます。
結論
CodeContests ベンチマークにおける Claude 4 Sonnet、Claude 4 Opus、OpenAI の Codex、Gemini 2.5 Pro の評価は、実世界のコーディング課題への対応力について有益な示唆を与えます。結果として、Codex が他モデルを上回り、正解率で最高スコアを達成しました。一方で、この評価は Claude 系モデルにおける思考予算の重要性も浮き彫りにしており、思考予算を 12,000 トークンに増やすと正解率が大きく向上することが確認されました。
これらのモデルの比較は、特にコーディング課題の文脈において、大規模言語モデルの評価がいかに複雑かを改めて示しています。カスタムのコード実行フレームワークと LLM を用いたセマンティック同値性チェックを併用することで、公平かつ堅牢な評価プロセスを実現できます。結果からは、ベンチマークがモデル比較に有用である一方で、データリークや過学習の可能性があるため慎重に扱うべきだという示唆も得られます。
総じて、本評価はコーディングタスクにおける現行の大規模言語モデルの強みと限界の理解に資するものです。各モデルの性能を分析することで、開発者はアプローチを洗練し、モデルのパフォーマンスを最適化するとともに、解答の品質を高めることができます。
Add a comment
Iterate on AI agents and models faster. Try Weights & Biases today.