1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gemini 4 Argonは何に使う?3.8 Flashと同じ難問で比べてみた

1
Posted at

Gemini 4 Argonをどんな仕事に使うとよさそうか。公開ベンチマークを見ると、まず試したいのは長い資料を横断して条件を整理する仕事、図や動画を含む情報の分析、複数の手順が必要な業務タスクです。コードを書かせる場合も、課題の種類によって評価が変わります。

この記事では公開スコアを用途に読み替え、Gemini 3.8 Flashと同じ難問を解いた比較も紹介します。公開ベンチマークと自作課題の結果を分け、どこで差が出たかを確認します。数値と利用条件は2026年10月14日に確認したものです。

今回、長文照合と最適構成・数値計算では両モデルが正答でした。 違いが出たのは、最適化のJSON形式と説明の整合性です。図表ではArgonが添付を読めないと回答し、グラフでは双方の解答取得が成立しなかったため、その結果を推論能力の点差には換算していません。

Argonを使える場所とプラン

Argonは2026年9月30日に発表され、10月13日に利用先が拡大しました。同じGoogle AIプランでも、使う製品によって条件が異なります。初回発表、一般向け展開の発表

利用先 Argonの利用条件 押さえたい点
Geminiアプリ Google AI Pro / Ultra 今回の検証はWeb版の「4 Argon・高値」で実施
Antigravity 個人向け Google AI Ultra Free / Plus / ProではArgonを利用できない
Antigravity 法人向け 対象のGemini Enterprise契約 個人向けUltraとは別の契約条件
AI Studioのサブスクリプション特典 Google AI Ultra アプリ側のPro対応と異なる。API課金とは別
Gemini API 有料ティア GeminiアプリのPro契約だけでAPI利用が含まれるわけではない

アプリ側はGeminiアプリの公式発表、Antigravity側は公式モデル一覧、API側は開発者向け発表を参照しています。

AI Studioの特典はGoogle AIプランの説明を参照してください。APIの導入価格は2026年11月30日まで100万トークン当たり入力2米ドル、出力10米ドル。12月1日以降は入力4米ドル、出力20米ドルで、出力料金には思考トークンも含まれます。API料金表

Antigravityではプランに加えて製品の違いも重要です。従来のAntigravity IDEはArgon非対応で、Antigravity 2.0、CLI、IDE拡張を使います。Ultraへ変更しても、旧IDEのモデル一覧に必ず出るという意味ではありません。公式モデル一覧、IDEの公式説明

1Mトークンは入力と出力で共有する

現行API仕様では、最大1,048,576トークンの枠を入力・思考・出力で共有します。入力を増やすと、思考や出力に使える残りの枠も減ります。また、最大1Mの長い生成は継続生成の仕組みを使う条件付きで、通常の1回の応答上限やGeminiアプリの画面上の制限とは区別が必要です。APIのモデル仕様、継続生成の仕様

ベンチマーク別に見える強みと差

次の図はGoogle DeepMindのモデルカードの19項目から10項目を抜粋して作成しました。各項目で、Argonと掲載されている他3モデルのうち最高のスコアを比較しています。この図の比較対象に3.8 Flashは含まれません。 Flashとの比較は、後半の同一入力による自作課題で行います。

Argonと各ベンチマークで最も高い比較モデルのスコア差

比較対象はGPT-6 Astra、Claude Fable 5.1、Claude Opus 5.5です。右側の数値は「Argon / 比較対象の最高値」。未掲載の値は除いています。異なる課題のスコアを平均した総合ランキングではありません。 差は各評価内のスコアポイントであり、統計的に意味のある差かどうかまで示すものではありません。Google DeepMindモデルカード

注目する評価 Argon 用途を考える際の読み方
GraphWalks 256K〜1M 84.2 長い入力中のグラフ関係をたどる課題。指標はBFSのF1
AutomationBench 51.3 複数の業務手順を実行する評価
Vals Finance Agent v2 65.4 資料を調べて回答する金融リサーチの評価。重み付き部分点
LVBench 91.7 長い動画の内容理解
DeepSWE v1.1 77.9 リポジトリを扱うソフトウェア開発課題
FrontierSWE v2 55.0 時間をかける開発課題。課題点のmean@5
Terminal-bench 4.0 57.4 端末を使う実作業

これらはGoogleのモデルカードに掲載された値で、Googleの自測と評価運営者・他社の公表値が混在しています。評価手法や使ったエージェント環境はGoogleの評価方法で確認できます。GraphWalksのF1、部分点、課題点の平均はそれぞれ別の指標です。「全項目が正答率」とは読めません。

Googleの評価は原則として高い思考設定を使いますが、他社の公開値を引用した項目と、Googleが全モデルを測定した項目が混在しています。動画の入力フレーム数や作業時間にも条件差があります。例えばLVBenchではGeminiは1fps、他社はモデルごとの枚数上限で入力しています。図の差には、モデル能力と評価環境の両方が関わります。評価方法

図中のOSWorldはオフライン課題の部分点です。Argonは3回の実行の最高値を掲載しているため、一般的なPC操作の成功率や平均値としては扱えません。評価方法

長い資料の条件整理や根拠付き比較

GraphWalksのBFS課題は、合成された有向グラフの長い辺一覧から、指定した探索で到達するノード集合を求めるものです。長文の要約品質を直接測定する課題ではありません。GraphWalksのデータセット説明

この結果を手掛かりに試したい実務の候補が、仕様書、会議記録、候補一覧をまとめて渡し、条件ごとに根拠を挙げさせる方法です。変更前の案、提案段階の内容、確定事項を明示しておくと、回答を原文と照合しやすくなります。GraphWalksの得点だけで、あらゆる1Mトークンの文書を正確に処理できるとは言えません。

例えば次の依頼です。

仕様書と議事録から、確定済みの条件だけを抽出してください。
各条件に文書名と節番号を付け、候補A〜Dが満たすか比較してください。
提案段階の条件は別欄にし、資料にない情報は「不明」としてください。

図や動画を含む情報の分析

ChartographyとLVBenchの公開値からは、図や動画を含む情報を扱う用途にも期待できます。LVBenchは長い動画に対する4択質問の評価で、画像1枚の文字起こしや自由形式の動画要約とは異なる能力を測ります。Chartography公式、LVBenchの公式プロジェクト、公式論文

試す用途は、製品デモから操作手順を抜き出す、動画内の出来事を時系列に整理する、図と表を照合してボトルネックを説明させる、といった作業です。動画なら時刻、図なら辺や行のIDまで回答に含めると、見落としを確認しやすくなります。時系列の要約品質や時刻の正確さは、実際の動画で別に確かめる必要があります。

資料調査を含む複数ステップの仕事

AutomationBenchやVals Finance Agentは、単発の質問よりも、情報収集やツール使用を含む仕事に近い評価です。実務では、資料の取得、数値の照合、結果の整理までつながるタスクを試す価値があります。Finance Agentの高得点は、投資判断そのものの正しさを保証する指標ではありません。Vals Finance Agentの評価説明、AutomationBench公式

例えば「報告書から必要な数値を抽出し、計算式と出典を付けた比較表にする」という形です。文章の読みやすさだけでなく、抜けた項目や計算の一致を採点できる依頼にすると、自分の業務に合うかを判断しやすくなります。

コーディングは課題ごとに選ぶ

DeepSWEの公開値は高い一方、FrontierSWE v2ではGPT-6 Astraの65.5、Claude Opus 5.5の62.3がArgonの55.0を上回っています。Terminal-bench 4.0でもOpus 5.5の66.4がArgonの57.4を上回ります。大きなコードベースの理解、修正、端末作業をひとまとめにしてモデルを選ぶと、この違いを見落とします。Google DeepMindモデルカード

FrontierSWE v2は34課題を各5回、最大20時間で評価し、課題点を平均するmean@5です。55.0という値は「55%の課題を完全に修正できた」という意味ではありません。また、実行環境やツール構成も結果に影響します。FrontierSWE公式、v2の評価方法

Antigravityで使うなら、まず自分のリポジトリの修正課題で、テストが通るか、差分に不要な変更がないか、作業時間や費用は許容できるかを比べたいところです。ベンチマークのエージェント環境と、Geminiアプリのチャットも同じ条件ではありません。

独立評価では何が見えるか

評価運営者の表でも、業務タスクでの強さを確認できます。ただし、各表が測るものは異なります。

評価 確認時点のArgonの掲載値 数値の意味
Artificial Analysis Intelligence Index v4.3.2 Highで53、掲載順位8/216 複数の評価をまとめた合成指標。正答率53%ではない
Vals Index v2.1 68.90、掲載順位1/48 金融・開発・法律・税務の評価を米国GDPの代理比率で加重
Arena Text Overall Highで1525±9、rank spread 1〜2、Preliminary 利用者の好みに基づく相対的な会話評価

出典はArtificial Analysisモデルページ、Valsモデルページ、Arena Textの表です。順位は確認時点の掲載順で、今後変わります。

AAの指標は主に英語テキストの評価、Valsは特定の業務分野の加重得点、Arenaは回答への好みです。Valsの68.90を「仕事の68.90%を自動化できる」と読んだり、Arenaの先頭掲載を事実正確性の単独首位と読んだりはできません。AAの方法、Valsの方法、Arenaの順位の説明

実用面で見ると、Argonは業務の要求を満たす作業や会話の候補として有力です。ただし、成果物の見栄えや、端末操作まで含めた完遂は別に確認したい項目です。例えばAA初報のAA-Briefcaseでは、要求項目の充足、分析の質、見せ方で評価が分かれています。AAの初報

Gemini 3.8 Flashと同じ課題で比べる

2026年10月14日、GeminiのWeb版で4 Argonと3.8 Flashを手動選択し、双方の思考レベルを「高値」 に設定しました。課題ごと・モデルごとに新規チャットを作り、同じ入力と同じプロンプトを送りました。正答、採点基準、入力のハッシュは回答を見る前に固定しています。

モデルは選択画面に加え、取得できた応答では末尾の生成モデル表示も確認しました。Argonの図表初回は選択画面の表示による確認です。Flashのグラフでは2回とも選択表示だけで、最終回答を取得できず生成モデルは未確認です。UIの「高値」を揃えても、内部の思考量やAPIのパラメータまで同一になるわけではありません。Geminiアプリのモデルと思考レベルの説明

回答を直す追い指示や再生成は採点に使いません。新規チャットで同じ入力を送り直した試行は、初回と分けて記録します。長文課題では文意・数値・根拠IDを内容点とし、グラフ課題では集合・件数・パス・到達判定を内容点としました。両課題のJSON形式は別に確認しました。最適化課題では、事前の基準に従って指定のJSON形式への適合1点を28点に含め、内容の27点とは内訳で分けます。添付から回答までの動作も、推論の得点と区別して記録します。

自作課題 Gemini 4 Argon・初回 Gemini 3.8 Flash・初回 新規チャットでの追試
長文の改訂・例外・取消 38 / 38 38 / 38 初回は同点のため未実施
図表の依存処理・ボトルネック 未採点:添付を読み取れないとの応答 27 / 28:R4の根拠提示が欠落 Argonは再び未採点。Flashは28 / 28
制約付き最適化 26 / 28:構成・数値は正答 28 / 28:構成・数値は正答 Argon 27 / 28、Flash 26 / 28。構成・数値は両方正答
有向グラフの最短距離層 未採点:解答のない拒否応答 未採点:最終回答を取得できず Argonは再び拒否応答。Flashも再び本文未取得。双方未採点

長文照合と最適構成・数値計算は双方が正答でした。最適化の点差は初回と追試で逆転し、JSON形式や説明の整合性に違いがあります。図表・グラフの未採点は回答取得の結果として扱います。今回の少数試行から、安定した推論能力の優劣は確認できていません。

比較1 約4万文字の変更記録から、最終条件と候補の採否を求める

長文には、情報を見つけるだけでは終わらない難しさがあります。新しい公示を読んでも、地域が違えば適用できません。特例が取り消されたら、残った古い規則に戻る必要があります。

そこで、架空の会場選定資料を自作しました。入力は39,455文字。規則28件と取消5件を参照ログに分散し、6つの地域・日時について最終仕様を求めたうえで、12候補の採否を判断させます。定員、所要時間、総額、外部ネット接続の要否を全て確認し、不採用なら全ての違反と根拠となる公示IDを出す課題です。

資料には次の条件を入れました。

  • 優先度が先で、同じ優先度なら新しい発行日時を採用する。
  • 発行日時まで同じなら、公示IDの数値が大きいものを採用する。
  • 地域、対象日、有効な時間帯で適用範囲を絞る。終了時刻ちょうどは対象外。
  • 取消は指定された規則だけを除外し、残った規則から選び直す。
  • 未承認・保留の案や、知識カットオフ後に発行された公示は使わない。
  • 金額は基本額+必須追加額−無条件割引。上限・下限ちょうどは条件を満たす。

例えば09:00ちょうどのQ2では、一時的な定員条件とネット接続の許可が終了します。同時に別の変更が始まり、取消によって定員と所要時間は以前の規則に戻ります。正答は定員85人(R04)、所要時間50分以下(R06)、総額122,000円以下(R23)、外部ネット必須の候補は不可(R00)です。

採点基準と正答は、両モデルへ送信する前に固定しました。正答は入力と指示だけから独立に再計算し、期待解との一致を確認しています。採点は最終仕様の「値+公示ID」24項目、候補の「総額+採否+全違反と公示ID」12項目、不足情報2項目の38点満点です。配列の順序や文章の言い回しは意味で判定し、JSON形式への適合は内容点と分けました。

採点内容 Gemini 4 Argon・初回 Gemini 3.8 Flash・初回
最終仕様の値と根拠ID 24 / 24 24 / 24
候補の総額・採否・全違反と根拠ID 12 / 12 12 / 12
不足する観測情報の説明 2 / 2 2 / 2
合計 38 / 38 38 / 38
回答本文のJSON形式 適合 適合

両モデルとも、全ての値・根拠ID・違反集合が一致しました。また、満足度や実地の障害発生率については、実測データの不足を理由に決定不可と回答しています。障害「率」そのものの実測データを求める説明は、件数と観測機会を考慮した比較が必要だという意味で採点しました。両モデルに同じ基準を適用しています。

この課題では点差がなく、モデル間の能力差は確認できませんでした。 各モデルの新規チャットに同じ資料・指示を1回ずつ送り、双方とも思考設定を高値にした結果です。UIの設定名が同じでも、内部の思考量まで同じとは限りません。

参考メモは8種類の繰り返しで、約4万文字全てが新しい事実というわけではありません。また、38項目は統計上独立した38回の実験ではなく、最終仕様と候補判定は論理的に依存します。この結果の対象は今回の合成課題の回答であり、1M文脈、長文業務全般、処理速度の評価には広げません。

Argonの長文比較テストの回答抜粋

Flashの長文比較テストの回答抜粋

長文比較で両モデルに送った同じプロンプト
添付の long_constraints_input.txt は、架空の会場運用規則と変更記録です。文書内の解釈規則だけを使い、次の3点を求めてください。外部検索や一般常識で不足情報を補わないでください。

1. Q1〜Q6の各文脈で有効な最終仕様を、capacity、minutes、budget、networkの4フィールドについて求める。各値に、最終的に選ばれた規則のR公示IDを付ける。
2. C01〜C12の各候補の総額を計算し、それぞれの文脈で採用可能か判定する。不採用なら、全ての違反コードと、それぞれの違反の判断根拠となる有効なR公示IDを列挙する。違反がなければ空配列にする。
3. この資料だけで「利用者満足度が最も高い候補」と「実地での障害発生率が最も低い候補」をそれぞれ決定できるか判定する。決定できない場合は不足する情報を具体的に示す。

回答はコードフェンスや前置きを付けず、次の構造のJSONオブジェクトだけにしてください。配列内の順序は任意です。数値は整数、真偽値はJSONのtrueまたはfalseを使ってください。

- effective_specs: Q1〜Q6の6要素の配列。各要素は id と spec を持つ。specは capacity、minutes、budget、network の4キーを持ち、各値は value と source_id を持つオブジェクト。source_idは、当該フィールドを決定したR公示ID一つ。
- candidate_evaluations: C01〜C12の12要素の配列。各要素は id、total_yen、eligible、violations を持つ。violationsの各要素は code と source_id を持つ。codeは CAPACITY、DURATION、BUDGET、NETWORK のいずれか。source_idは、その違反を判断する最終仕様のR公示ID一つ。
- unknowns: questionが satisfaction と failure_rate の2要素の配列。各要素は question、can_determine、missing を持つ。can_determineは、資料だけで決定できるかを表す真偽値。missingは不足する情報の説明で、決定できる場合は空文字列。

取消公示Xの適用・非適用は最終仕様の計算に反映してください。ただしsource_idには、取消Xではなく選び直した結果のR公示IDを入れてください。
長文の入力を再現するPythonコード(標準ライブラリのみ)

空のフォルダに保存してPython 3で実行すると、long_constraints_input.txtとlong_constraints_answer.jsonを生成します。モデルへ添付するのは入力資料だけです。正答JSONは採点用に保持してください。

"""標準ライブラリのみ。現在のフォルダに入力と正答を生成。"""
from pathlib import Path
import json, random

def dt(s):
    day,clock=s.split()
    return '2026-11-'+day+'T'+':'.join((clock+':00:00').split(':')[:3])+'+09:00'

cutoff = dt('19 18')
end = dt('22 00')
C,M,B,N,F='capacity','minutes','budget','network','確定'
keys = [C, M, B, N]
base = dict(zip(keys, [80, 60, 130000, False]))
data = [
('R01',0,'*','*','20 00',None,'05 09',C,90,F),
('R02',0,'*','*','20 00',None,'07 09',M,55,F),
('R03',0,'*','*','20 00',None,'18 09',B,140000,F),
('R04',10,'E','*','20 00',None,'10 09',C,85,F),
('R05',10,'W','*','20 00',None,'10 09',C,95,F),
('R06',10,'E','*','20 00',None,'10 09',M,50,F),
('R07',10,'E','*','20 00',None,'16 09',M,45,F),
('R08',10,'W','*','20 00',None,'12 09',M,40,F),
('R09',10,'E','*','20 00',None,'10 09',B,125000,F),
('R10',10,'W','*','20 00',None,'08 09',B,110000,F),
('R11',10,'W','*','20 00',None,'15 09',B,115000,F),
('R12',10,'E','*','20 00','20 09','12 09',N,True,F),
('R13',10,'W','*','20 12',None,'12 09',N,True,F),
('R14',20,'E','20','20 00','21 00','13 09',C,88,F),
('R15',20,'E','20','20 00','21 00','13 09',B,120000,F),
('R16',20,'W','20','20 00','21 00','13 09',M,42,F),
('R17',20,'E','21','21 00',None,'14 09',M,52,F),
('R18',20,'W','21','21 00',None,'14 09',B,118000,F),
('R19',20,'E','21','21 00',None,'17 10',N,True,F),
('R20',20,'E','21','21 00',None,'17 10',N,False,F),
('R21',30,'E','20','20 08:30','20 09','15 12',C,92,F),
('R22',30,'W','20','20 12','20 13','15 12',C,96,F),
('R23',30,'E','20','20 09','20 10','15 12',B,122000,F),
('R24',30,'W','20','20 12','20 18','15 12',M,35,F),
('R25',30,'W','20','20 12','20 13','18 12',N,False,'未承認'),
('R26',30,'E','21','21 09','21 12','20 08',N,True,F),
('R27',30,'W','*','20 00',None,'18 15',B,150000,'保留'),
]
rules = [dict(id='R00', priority=0, region='*', day='*', start=dt('01 00'), end=end,
              published=dt('01 00'), changes=base, status=F)]
for rid, rank, region, day, start, finish, pub, field, value, status in data:
    rules.append(dict(id=rid, priority=rank, region=region, day=day, start=dt(start),
        end=dt(finish) if finish else end, published=dt(pub), changes={field:value}, status=status))
cancels = []
for cid,target,region,start,pub,status in [
 ('X01','R14','E','20 09','18 16',F),
 ('X02','R07','E','20 09','19 10',F),
 ('X03','R11','W','20 12','19 10',F),
 ('X04','R04','E','20 00','18 10','未承認'),
 ('X05','R05','W','20 00','20 08',F)]:
    cancels.append(dict(id=cid,target=target,region=region,day='*',start=dt(start),end=end,published=dt(pub),status=status))
contexts = [{'id':f'Q{i+1}','region':r,'at':dt(t)} for i,(r,t) in enumerate([
 ('E','20 08:59:59'),('E','20 09'),('W','20 11:59:59'),
 ('W','20 12'),('E','21 09'),('W','21 09')])]
candidates = [dict(zip(['id','context',C,M,'fee','extra','discount','requires_network'],row)) for row in [
 ('C01','Q1',92,45,118000,5000,3000,True),('C02','Q1',91,46,120000,1000,0,True),
 ('C03','Q2',85,50,120000,2000,0,False),('C04','Q2',84,51,121000,3000,1000,True),
 ('C05','Q3',95,42,114000,4000,3000,False),('C06','Q3',94,43,111000,4000,0,True),
 ('C07','Q4',96,35,108000,5000,3000,True),('C08','Q4',96,36,111000,1000,1000,True),
 ('C09','Q5',85,52,125000,2000,2000,False),('C10','Q5',86,53,124000,4000,2000,True),
 ('C11','Q6',95,40,115000,5000,2000,True),('C12','Q6',94,40,117000,3000,1000,False)]]
header = '''架空の会場運用規則・変更記録(自作の比較検証用資料)
この文書以外の知識で、条件、順位、実測結果を補わないでください。地域E/Wは架空です。

【確定した解釈規則】
評価時の知識カットオフは2026-11-19T18:00:00+09:00。これより後に発行された規則も取消も使用しません。予定の実施日時が後であっても、この知識カットオフは変えません。
状態が「確定」の規則・取消だけを使います。「未承認」「保留」「参考」は使いません。文書の掲載順は公示順ではありません。
対象は地域(region)と対象日(day)で絞ります。*は全地域または全日。対象日20は2026-11-20、21は2026-11-21です。
有効区間は開始を含み終了を含まない半開区間 [start,end) です。開始・終了の時刻ちょうどもこの定義を守ります。全時刻は+09:00です。
有効な取消は、同じ対象・時間の文脈で、targetに書かれた規則だけを除外します。取消はその規則の値を逆転させる処理ではありません。別の規則まで消さず、残った規則から選び直します。
各フィールドを個別に決めます。条件に合う規則の中で priority が最大のものを選び、同じ priority なら published が新しいもの、同じ published なら公示IDの数値部分が大きいものを選びます。R20はR19より後です。priority が違うとき、発行が新しいだけの低優先規則は勝ちません。
changesにないフィールドは変更しません。R00は既定値です。数値境界は定員 capacity 以上、所要 minutes 以下、総額 budget 以下です。network=true は外部ネット必須の候補も可、false は外部ネット必須の候補を不可とする意味で、接続を必ず使えという意味ではありません。
候補の総額は fee + extra - discount。extraは必須追加費用、discountは無条件の割引です。追加の税込計算や他の割引は行いません。規則のbudgetも候補の金額も税込・全必須費用込みで比較します。
違反コードは CAPACITY、DURATION、BUDGET、NETWORK だけです。違反は全件を挙げ、一つ見つけても打ち切りません。違反なしの候補だけ採用可能です。最終仕様の source_id は選ばれたR公示ID一つを示します。取消の説明は任意ですがX公示IDをsource_idにしません。

【参照ログ】確定公示・取消と、選定条件を変えない参考メモが混在します。
'''
notes = [
 '参考資料の見出しを整理した。ここでの配置や表現は説明案であり、確定公示の対象範囲、金額、定員、所要時間を変更するものではない。',
 '受付案内の図を作るためのメモを残した。図の見た目や並べ方は参考事項であり、選定条件や地域ごとの例外を新たに作らない。',
 '資料の配色と余白について案を比べた。見た目の比較は候補の採否に用いる評価データではなく、運用規則の更新でもない。',
 '説明資料の用語を短くする案があった。この案は正式な変更ではないため、確定した数値境界や有効時間の解釈は変えない。',
 '事前準備の作業を見やすく並べ直した。掲載位置が後ろになったことを理由に、公示の発行時刻や優先度を置き換えてはならない。',
 '来場者向けの説明の順序を検討した。順序の提案は参考として残し、会場候補の確定条件や採用可能性を示す判定とは区別する。',
 '記録を検索しやすくするために見出しを追加した。見出しだけを新しい規則とみなさず、正式な公示本文に書かれた値を読む。',
 '参考の文章に使う語を統一した。読みやすさの調整は運用条件の確定や取消ではなく、候補の実地実績を示す資料でもない。',
]
records = [('規則',r) for r in rules] + [('取消',x) for x in cancels]
random.Random(7319).shuffle(records)
positions = dict(zip(range(9, 9 + len(records)*14, 14), records))
logs = []
for i in range(1,481):
    if i in positions:
        kind,item=positions[i]
        logs.append('【'+kind+'】'+json.dumps(item,ensure_ascii=False,separators=(',',':')))
    else:
        logs.append(f'【参考N{i:03d}】'+notes[(i-1)%len(notes)])
document = header + '\n'.join(logs) + '\n\n【評価対象の地域・時刻】\n'
document += '\n'.join(json.dumps(x,ensure_ascii=False,separators=(',',':')) for x in contexts)
document += '\n\n【候補一覧】\n'+'\n'.join(json.dumps(x,ensure_ascii=False,separators=(',',':')) for x in candidates)+'\n'
Path('long_constraints_input.txt').write_text(document,encoding='utf-8')

def applicable(r,c):
    return (r['status']==F and r['published']<=cutoff and r['region'] in ('*',c['region'])
        and r['day'] in ('*',c['at'][8:10]) and r['start']<=c['at']<r['end'])
specs=[]
for c in contexts:
    removed={x['target'] for x in cancels if applicable(x,c)}
    available=[r for r in rules if applicable(r,c) and r['id'] not in removed]
    fields={}
    for key in keys:
        r=max((r for r in available if key in r['changes']),key=lambda r:(r['priority'],r['published'],int(r['id'][1:])))
        fields[key]={'value':r['changes'][key],'source_id':r['id']}
    specs.append({'id':c['id'],'spec':fields})
byid={s['id']:s['spec'] for s in specs}
evaluations=[]
for p in candidates:
    f=byid[p['context']]
    total=p['fee']+p['extra']-p['discount']
    tests=[('CAPACITY',C,p[C]<f[C]['value']),
        ('DURATION',M,p[M]>f[M]['value']),
        ('BUDGET',B,total>f[B]['value']),
        ('NETWORK',N,p['requires_network'] and not f[N]['value'])]
    violations=[{'code':code,'source_id':f[key]['source_id']} for code,key,fail in tests if fail]
    evaluations.append({'id':p['id'],'total_yen':total,'eligible':not violations,'violations':violations})
answer={'effective_specs':specs,'candidate_evaluations':evaluations,'unknowns':[
 {'question':'satisfaction','can_determine':False,'missing':'利用者満足度の評価・アンケート等の実測データ'},
 {'question':'failure_rate','can_determine':False,'missing':'候補の実地障害発生件数と観測回数・期間等の実測データ'}]}
Path('long_constraints_answer.json').write_text(json.dumps(answer,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')

比較2 図表から依存処理とボトルネックを計算する

次は、同じPNG画像とプロンプトを送る、処理の依存関係と時間表を組み合わせた自作課題です。有効な入力をすべて待つAND条件、モードによる依存の切り替え、絶対時刻の開始制約、故障の伝播、処理短縮によるボトルネックの変更を問いました。最後には、個別の故障確率だけから同時故障を決められない場合の上下限も求めます。

採点基準は回答を見る前に28点で固定しました。Flashは新規チャットの2回で27/28点、28/28点でした。どちらも時刻、依存、故障伝播、短縮幅、確率の式と範囲はすべて正答です。初回の1点は、指定したリスク欄R4(他のノード・辺の故障確率は0)への根拠提示が欠けたための減点でした。2回目は該当節の見出しでR1〜R4を参照しています。計算の誤りとは分けて扱っています。

一方、Argonでは新規チャットの2回とも、添付を読み取れない旨の回答が返りました。課題への数値回答がないため、推論の28点基準では未採点です。これは、今回のWeb画面で有効な回答が得られたかという動作上の結果であり、画像理解や計算能力でArgonが劣ると判断する根拠にはできません。添付の処理やサービス側を含め、原因は確認できていません。

この段階で確認できたのは、Flashが2回ともこの自作問題の計算に正答し、Argonには2回とも採点できる回答がなかったことです。回答が得られた場合の能力比較と、添付から回答までの動作の比較を混ぜないようにします。単一課題の結果から一般的な正答率やモデルの総合順位は決めません。

両モデルに渡した自作の図表

添付の読み取り不可と返ったArgonの画面

Flashの図表比較テストの回答抜粋

図表比較で両モデルに送った同じプロンプト
添付した dependency_scheduler.png は、自作の架空処理図・時間表・条件表です。画像と以下の定義だけで答えてください。外部の事実や、図にない依存関係を追加しないでください。

【定義】
- すべてms。Sは時刻0に完了します。矢印は一方通行、辺の時間は親の完了後に足す転送時間です。
- ノードは、そのモードで有効なすべての入辺を必要とします(AND条件)。分岐後の処理は並列で、共有資源の競合はありません。
- ready = 有効な各親の「finish + 辺の転送時間」の最大値。
- gate = max(ready, Release)、start = gate + Queue、finish = start + Process。Queueは固定追加時間で、Releaseは絶対時刻です。
- FULLではBOTH/FULLの辺、CACHEではBOTH/CACHEの辺だけを使います。CACHEではEが非稼働です。
- 故障した有効辺は依存条件から削除しません。その入力が届かないノードと、そこから必須入力を受けるノードはblockedです。代替辺・再試行はありません。
- 問4・問5は、それぞれ通常のCACHEを基準にした独立の変更です。変更を累積しないでください。
- 問6のノード故障は、その試行で必須出力を生成できないことを意味します。故障後の再試行や復旧はありません。

【問い】
1. 通常のFULLでA/B/C/D/E/F/G/Tのready・gate・start・finishを表にしてください。ノード表の行IDと、有効な入辺IDも付けてください。
2. 通常のCACHEの有効な辺IDの全一覧と非稼働ノードを示し、F/G/Tのfinishを答えてください。
3. 通常のFULLで、CのreadyとReleaseによる追加の待ち時間、Fのreadyを決める親と各入辺の到着時刻を示してください。Tのreadyを決める親もFULL/CACHEそれぞれ答え、比較した到着時刻を示してください。最も遅い親が1つでも、他の有効な入力が不要になるわけではありません。
4. CACHEでE7だけが故障し、ほかは正常な場合、blockedとなるノードの全一覧を示してください。その原因となる必須辺IDと、Gが完了するならそのfinishも答えてください。
5. 通常のCACHEで、CのProcessだけを5から3に短縮した場合、C/F/Tのfinish、Tの短縮幅、Fのreadyを決める親と各入辺の到着時刻を答えてください。
6. リスク欄R1〜R4に基づき、FULLでFとGが両方故障する確率と、F/Gの故障だけによってTが未完了になる確率は、それぞれ一意に決められますか。決められない場合は可能な下限・上限と式を示してください。独立性を仮定してよいかも明記してください。確率は0〜1の小数、または単位を明記した%で答えてください。

回答は問い1〜6の順に、表と短い計算式で示してください。処理時間の変更と故障の変更を混同せず、辺ID・ノード行ID・リスク行IDを根拠として使ってください。

比較3 制約付き最適化(追加課題)

長文の初回は同点で、図表ではArgonの推論回答が得られず、回答内容の比較ができませんでした。さらに差を探るため、制約付き最適化を追加の課題として用意しました。先の同点・未採点の結果は、そのまま掲載します。

追加課題も、その課題に対する両モデルの回答を見る前に入力・正答・採点基準を固定し、独立に検算しています。点差が出ることを前提にせず、得られた結果を報告します。

追加:14群の構成選択で、全体の最適解を比べる

全データを本文に入れた同じプロンプトを、添付なし・新規チャット・Highで両モデルに初回と追試の計2回ずつ送りました。追試も新規チャットを使い、初回の回答や採点結果は伝えていません。問題、正答、配点は事前に固定しています。

14群からA/B/Cを1つずつ選び、総cost≤84、総memory≤62に収めます。群の資源は1回だけ数え、4経路それぞれの時間は5群の処理と4組の引継ぎの合計です。A→CとC→Aの引継ぎ時間も異なります。

必須条件は次の6つです。

条件 必須の制約
C1 G03=CならG10はB/C
C2 G04=CならG11はB/C
C3 G06/G07のちょうど1群だけC
C4 G12/G13の少なくとも一方はB/C
C5 G08/G09のいずれかがCならG05はB/C
C6 G10/G11を両方Aにしない

目的は最大経路時間→時間和→cost→A<B<Cの選択肢列の辞書順で最小化する4段階です。memoryは上限だけに使います。

3^14=4,782,969通りを全列挙し、全制約を満たす969,634通りを確認。独立の列挙でも件数・最適構成・計算値が一致しました。

以下のmsは架空の経路の処理時間で、モデルの応答時間ではありません。

正答の指標 値
P1/P2/P3/P4 30/25/30/30ms
最大時間/時間和 30ms/115ms
cost/memory 83/61
G01〜G14の選択肢列 BBBBBBCBBCCBBC

先頭3段階が同値の候補は2つあり、G06/G07のB/Cが入れ替わります。最後の辞書順でG06=B、G07=Cを選びます。

28点の採点では実行可能性・計算・厳密な最適性を分けます。 非最適でも正しい計算には点を付け、説明は評価側の列挙と照合します。

採点項目 満点 Argon初回 Argon追試 Flash初回 Flash追試
構成キー・値 2 2 2 2 2
JSON形式 1 0 0 1 1
実行可能性と説明 8 8 8 8 7
構成の数値計算 6 6 6 6 6
目的値・厳密な最適性 6 6 6 6 6
時間の内訳 4 4 4 4 4
最適性の説明 1 0 1 1 0
合計 28 26 27 28 26

Argon初回の最適構成と経路時間の回答抜粋

Flash初回の最適構成と経路時間の回答抜粋

全4回答で、厳密な最適構成・資源合計・経路時間は正答でした。 点差は初回がFlash優位、追試がArgon優位と逆転しています。今回の構成選択・数値計算だけで、一方を優れているとは判断できません。

Argonは2回とも、回答のコピーで取得した本文をJSONとして解析できませんでした。文字列内の引用符がエスケープされておらず、追試には末尾の余分な>もあります。表示処理だけの問題かを確認するため、コピー本文と表示本文を照合しました。元の回答を修正せず、内容の採点だけは別途転記して続けています。初回の説明には不正な下界があり、追試の解析的説明は独立の全列挙と一致しました。

Flashは2回ともJSON形式に適合しました。初回の説明点は、資源上限とC1〜6を満たし、最大経路時間30以下を狙う候補という文脈で、条件付きの境界と示された同値2構成を照合して認めています。追試ではメモリの説明が「全Bの46+増分11=61」となり、正しい基準値50と食い違いました。最適性の説明にある、文面で明示した条件だけでは成り立たない上界も減点しています。

説明の減点を検証した具体的な反例

Argon初回の説明は、全Bのmemory=50を基準に、「G14をA/BにするとP1/P2を30以下にするだけでもmemory増分が13以上必要」としました。これに対する反例がBCCCACBAACBABBです。cost=73、memory=55で増分は5、G14=B、P1/P2=28/28となります。C1〜6も満たします。ただしP3/P4=48/43なので、全体の最適構成を覆す反例ではなく、説明中の部分的な下界を否定する例です。

Flash追試の説明は「BUDGET<=84かつC3のもとでCは高々4群」としました。明示された条件の下での反例がBBBBBBCBCBCCCBです。Cは5群、cost=84、memory=62でC1〜6も満たします。ただしP1/P2/P3/P4=36/30/32/28なので、これも全体最適30を覆す反例ではありません。候補の絞り込み条件を正確に書けているかという説明の採点です。

この課題の点数にはJSON形式1点と内容27点が含まれます。モデルが「確認した」と述べたことだけでは探索を実行した証拠にはせず、示された値・候補・境界を検証しました。少数の合成課題から、一般的な正答率や安定した能力差へ広げません。

両モデルに初回・追試で送った同じプロンプト
これは自作の架空構成を使う離散最適化課題です。14群それぞれでA/B/Cのいずれか1つを選び、以下の規則だけで最適な構成を求めてください。外部の事情や表にない効果を追加しないでください。

【定義】
- costとmemoryは14群を1回ずつ合計し、BUDGET<=84、MEMORY<=62を満たします。同じ群が複数経路に現れても、資源を重複計上しません。
- 各P1〜P4の時間は、記載された順序の5群のdurationと、隣接する4組のhandoffを合計した値です。handoffは前の群の選択肢から次の群の選択肢への有向行列を使います。
- 経路内は直列。経路間の待ち・資源競合・並列による時間短縮や、表にない辺は考えません。群のdurationは選んだ構成で決まる固定値です。
- C1〜C6はすべて必須です。「なら」は一方向の条件で、逆は要求しません。
- 目的は辞書式の4段階です。第1に4経路の最大時間を最小化。同値なら第2に4経路時間の和を最小化。それも同値なら第3に総costを最小化。さらに同値なら第4にG01〜G14の選択肢列をA<B<Cの辞書順で最小にします。memoryは上限だけで、同値時の優先順位には使いません。

【出力】
JSONだけを返してください。キーは次のとおりです。
- choices: G01〜G14をすべてキーにし、それぞれ"A"/"B"/"C"を値にするオブジェクト。
- cost, memory: 選んだ構成の資源合計。
- paths: P1〜P4をキーにし、それぞれnode_ms, handoff_ms, total_msを持つオブジェクト。
- objective: max_path_msとsum_path_ms。
- checks: BUDGET/MEMORY/C1〜C6をキーにし、それぞれok(JSON真偽値)とreason(使用した群・数値・条件の説明)を持つオブジェクト。
- optimality: 最適性をどう確認したかを短く説明する文字列。実際に確認していない列挙件数や証明を作らないでください。根拠が不十分なら、その限界も明記してください。

以下が入力データです。
group | A(cost,memory,duration_ms) | B(cost,memory,duration_ms) | C(cost,memory,duration_ms)
G01 | 2,1,12 | 4,3,8 | 7,6,5
G02 | 2,2,11 | 5,4,7 | 8,7,4
G03 | 3,1,14 | 5,3,9 | 9,6,5
G04 | 2,2,13 | 4,4,8 | 8,6,4
G05 | 3,2,10 | 6,4,6 | 9,7,3
G06 | 1,1,9 | 4,3,6 | 7,5,3
G07 | 2,2,10 | 5,4,6 | 8,6,3
G08 | 2,1,12 | 5,3,7 | 9,6,4
G09 | 1,2,11 | 4,4,7 | 7,7,4
G10 | 3,1,13 | 6,3,8 | 10,6,4
G11 | 2,2,12 | 5,4,7 | 9,7,4
G12 | 1,1,10 | 4,3,6 | 7,5,3
G13 | 2,2,11 | 4,4,7 | 8,6,3
G14 | 3,2,9 | 6,4,5 | 11,7,2

C1〜C6:
C1: G03=CならG10はBまたはC。G03がA/Bならこの制限はない。
C2: G04=CならG11はBまたはC。G04がA/Bならこの制限はない。
C3: G06とG07のうち、ちょうど1群だけがC。もう一方はAまたはB。
C4: G12とG13の少なくとも一方はBまたはC。
C5: G08またはG09がCなら、G05はBまたはC。両方がA/Bならこの制限はない。
C6: G10とG11を両方Aにはできない。

経路:
P1: G01 -> G03 -> G06 -> G10 -> G14
P2: G02 -> G04 -> G07 -> G11 -> G14
P3: G01 -> G05 -> G08 -> G12 -> G14
P4: G02 -> G05 -> G09 -> G13 -> G14

handoff_ms(行=前の群の選択肢、列=次の群の選択肢):
from\to | A | B | C
A | 0 | 1 | 4
B | 2 | 0 | 1
C | 5 | 2 | 0
入力を再現し、全列挙で正答を確かめるPythonコード

空のフォルダでPython 3により実行すると、入力と期待解を生成し、全4,782,969通りを検証します。モデルへはprompt.txtの全文だけを送り、期待解やこのコードは渡しません。

"""Build a coupled minimax allocation fixture, with an exhaustive 3**14 oracle."""
from pathlib import Path
from itertools import product
import hashlib
import json
import time

BASE=Path(__file__).resolve().parent
BASE.mkdir(parents=True,exist_ok=True)
groups=[f'G{i:02}' for i in range(1,15)]
# Each tuple: cost, memory, processing duration.
raw=[
 [(2,1,12),(4,3,8),(7,6,5)],
 [(2,2,11),(5,4,7),(8,7,4)],
 [(3,1,14),(5,3,9),(9,6,5)],
 [(2,2,13),(4,4,8),(8,6,4)],
 [(3,2,10),(6,4,6),(9,7,3)],
 [(1,1,9),(4,3,6),(7,5,3)],
 [(2,2,10),(5,4,6),(8,6,3)],
 [(2,1,12),(5,3,7),(9,6,4)],
 [(1,2,11),(4,4,7),(7,7,4)],
 [(3,1,13),(6,3,8),(10,6,4)],
 [(2,2,12),(5,4,7),(9,7,4)],
 [(1,1,10),(4,3,6),(7,5,3)],
 [(2,2,11),(4,4,7),(8,6,3)],
 [(3,2,9),(6,4,5),(11,7,2)],
]
paths={
 'P1':['G01','G03','G06','G10','G14'],
 'P2':['G02','G04','G07','G11','G14'],
 'P3':['G01','G05','G08','G12','G14'],
 'P4':['G02','G05','G09','G13','G14'],
}
handoff=[[0,1,4],[2,0,1],[5,2,0]]
case={
 'id':'coupled_minimax_allocation_v1',
 'groups':{g:{letter:{'cost':c,'memory':m,'duration_ms':d}
                for letter,(c,m,d) in zip('ABC',row)} for g,row in zip(groups,raw)},
 'limits':{'BUDGET':84,'MEMORY':62},
 'constraints':{
  'C1':'G03=CならG10はBまたはC。G03がA/Bならこの制限はない。',
  'C2':'G04=CならG11はBまたはC。G04がA/Bならこの制限はない。',
  'C3':'G06とG07のうち、ちょうど1群だけがC。もう一方はAまたはB。',
  'C4':'G12とG13の少なくとも一方はBまたはC。',
  'C5':'G08またはG09がCなら、G05はBまたはC。両方がA/Bならこの制限はない。',
  'C6':'G10とG11を両方Aにはできない。',
 },
 'paths':paths,
 'handoff_ms':{a:{b:handoff[i][j] for j,b in enumerate('ABC')} for i,a in enumerate('ABC')},
 'objective_order':['min max(P1,P2,P3,P4)','min sum(P1,P2,P3,P4)','min total_cost','lexicographically smallest G01..G14 option sequence with A<B<C'],
 'cost_memory_counting':'Each of 14 groups counted once, regardless of appearances in several paths.',
 'path_formula':'Sum durations of its five groups + four directed adjacent handoffs. No overlap, wait, shared resource contention, or extra edges.',
}
(BASE/'case.json').write_text(json.dumps(case,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')

intro='''これは自作の架空構成を使う離散最適化課題です。14群それぞれでA/B/Cのいずれか1つを選び、以下の規則だけで最適な構成を求めてください。外部の事情や表にない効果を追加しないでください。

【定義】
- costとmemoryは14群を1回ずつ合計し、BUDGET<=84、MEMORY<=62を満たします。同じ群が複数経路に現れても、資源を重複計上しません。
- 各P1〜P4の時間は、記載された順序の5群のdurationと、隣接する4組のhandoffを合計した値です。handoffは前の群の選択肢から次の群の選択肢への有向行列を使います。
- 経路内は直列。経路間の待ち・資源競合・並列による時間短縮や、表にない辺は考えません。群のdurationは選んだ構成で決まる固定値です。
- C1〜C6はすべて必須です。「なら」は一方向の条件で、逆は要求しません。
- 目的は辞書式の4段階です。第1に4経路の最大時間を最小化。同値なら第2に4経路時間の和を最小化。それも同値なら第3に総costを最小化。さらに同値なら第4にG01〜G14の選択肢列をA<B<Cの辞書順で最小にします。memoryは上限だけで、同値時の優先順位には使いません。

【出力】
JSONだけを返してください。キーは次のとおりです。
- choices: G01〜G14をすべてキーにし、それぞれ"A"/"B"/"C"を値にするオブジェクト。
- cost, memory: 選んだ構成の資源合計。
- paths: P1〜P4をキーにし、それぞれnode_ms, handoff_ms, total_msを持つオブジェクト。
- objective: max_path_msとsum_path_ms。
- checks: BUDGET/MEMORY/C1〜C6をキーにし、それぞれok(JSON真偽値)とreason(使用した群・数値・条件の説明)を持つオブジェクト。
- optimality: 最適性をどう確認したかを短く説明する文字列。実際に確認していない列挙件数や証明を作らないでください。根拠が不十分なら、その限界も明記してください。

以下が入力データです。
'''
# Compact rows keep the full instance in the identical sent prompt, without attachment processing.
data=['group | A(cost,memory,duration_ms) | B(cost,memory,duration_ms) | C(cost,memory,duration_ms)']
for g,row in zip(groups,raw):
 data.append(g+' | '+' | '.join(','.join(str(x) for x in opt) for opt in row))
data+=['','C1〜C6:']+[k+': '+v for k,v in case['constraints'].items()]
data+=['','経路:']+[k+': '+' -> '.join(v) for k,v in paths.items()]
data+=['','handoff_ms(行=前の群の選択肢、列=次の群の選択肢):','from\\to | A | B | C']
data += [a+' | '+' | '.join(str(x) for x in row) for a,row in zip('ABC',handoff)]
(BASE/'case.txt').write_text('\n'.join(data)+'\n',encoding='utf-8')
(BASE/'prompt.txt').write_text(intro+'\n'.join(data)+'\n',encoding='utf-8')

def admissible(v):
 return not(
   (v[2]==2 and v[9]==0) or
   (v[3]==2 and v[10]==0) or
   ((v[5]==2)+(v[6]==2)!=1) or
   (v[11]==0 and v[12]==0) or
   ((v[7]==2 or v[8]==2) and v[4]==0) or
   (v[9]==0 and v[10]==0))

indices=[[groups.index(g) for g in path] for path in paths.values()]
path_lookup=[]
for idx in indices:
 values=[]
 for options in product(range(3),repeat=5):
  values.append(sum(raw[g][o][2] for g,o in zip(idx,options))+
                sum(handoff[a][b] for a,b in zip(options,options[1:])))
 path_lookup.append(values)

start=time.time()
total=0
logical=0
feasible=0
best=None
best_v=None
best_paths=None
minmax_count=0
pair_count=0
best_prefix_counts={}
# Every one of the 3**14 combinations is visited. Rejected configurations never contribute to objective.
for v in product(range(3),repeat=14):
 total+=1
 if not admissible(v): continue
 logical+=1
 cost=sum(raw[i][v[i]][0] for i in range(14))
 if cost>84: continue
 memory=sum(raw[i][v[i]][1] for i in range(14))
 if memory>62: continue
 feasible+=1
 times=[]
 for idx,lookup in zip(indices,path_lookup):
  index=0
  for i in idx: index=index*3+v[i]
  times.append(lookup[index])
 key=(max(times),sum(times),cost,v)
 if best is None or key<best:
  best=key;best_v=v;best_paths=times
assert total==3**14
best_cost=sum(raw[i][best_v[i]][0] for i in range(14))
best_memory=sum(raw[i][best_v[i]][1] for i in range(14))
path_breakdown={}
for pid,idx,time_ms in zip(paths,indices,best_paths):
 options=[best_v[i] for i in idx]
 node_ms=sum(raw[g][o][2] for g,o in zip(idx,options))
 handoff_values=[handoff[a][b] for a,b in zip(options,options[1:])]
 path_breakdown[pid]={'node_ms':node_ms,'handoff_ms':sum(handoff_values),'total_ms':time_ms,'groups':[groups[g] for g in idx],'options':['ABC'[o] for o in options],'handoff_sequence_ms':handoff_values}
result={
 'choices':{g:'ABC'[o] for g,o in zip(groups,best_v)},
 'cost':best_cost,'memory':best_memory,
 'paths':path_breakdown,
 'objective':{'max_path_ms':best[0],'sum_path_ms':best[1]},
 'key':[best[0],best[1],best_cost,''.join('ABC'[o] for o in best_v)],
 'checks':{'BUDGET':True,'MEMORY':True,**{f'C{i}':True for i in range(1,7)}},
 'proof':{'method':'exhaustive enumeration of all 3**14 option sequences; independent solver audit required before run',
          'enumerated':total,'logical_constraint_pass':logical,'feasible':feasible,'seconds':round(time.time()-start,3)},
}
(BASE/'expected.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
manifest={'instance':'coupled_minimax_allocation_v1','model_results_seen':False,
 'send':'prompt.txt verbatim (all instance data inline; do not attach image/oracle)',
 'do_not_send':['expected.json','case.json','build_optimization.py','rubric.md','independent-check.py','independent-verification.json'],
 'sha256':{f:hashlib.sha256((BASE/f).read_bytes()).hexdigest() for f in ['prompt.txt','case.txt','case.json','expected.json']}}
(BASE/'manifest.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
print(json.dumps(result,ensure_ascii=False))

比較4 最後の追加:長い辺一覧から最短距離の層を列挙する

長文課題は両モデルとも満点で、最適化でも最適構成と全数値が一致しました。そこで最後に、公開GraphWalksを手掛かりに、グラフの関係を長い一覧から横断する自作課題を追加しました。先行した同点、説明・形式の差、画像の未採点は全て残します。公開GraphWalksそのものの再現ではありません。GraphWalksのデータセット説明

入力は720ノード・1,920本の有向辺、71,164文字のTXTです。異なる6つのrootから、最短距離がちょうど4〜9ホップの層を列挙させます。ノードID、辺ID、掲載順は無作為で、名前から層は分かりません。閉路、逆向きの辺、到達不能な成分も含めました。正答の層はそれぞれ41〜53ノードです。

最短距離がkより短いノードは、kホップの別経路があっても第k層には入りません。また、指定された6終点への証拠パスと、別ノードの到達可否・最短距離も求めます。kより先にあるノードを、探索を打ち切って到達不能とする回答も区別できる設計です。

入力、正答、採点基準は両モデルへ送る前に固定しました。独立にTXTからグラフを再構成したBFSと、全辺を反復して距離を更新する別の方法でも、全6問の層・件数・到達判定が一致しています。

初回を残して同条件で第2試行を実施

初回は、Argonが課題の解答を含まない拒否応答、Flashが生成途中にホームへ戻って最終本文を取得できない状態でした。両方を未採点として保存した後、同じファイル・指示を双方の別の新規チャットへ、第2試行として送りました。初回と第2試行を分けて記録しています。

採点は完全一致と部分的一致を分ける

内容は6問×4点の24点満点です。各問を次の4項目で採点し、JSON形式は内容点と別に記録します。

  • 層のノード集合が完全一致し、漏れ・余分・重複がない。
  • ノード数が正答の件数と一致する。
  • 指定終点へのk本の有向辺とk+1ノードのパスが有効。正しい最短パスなら、作者と異なる経路も認める。
  • 指定ノードの到達可否と最短距離が一致する。到達不能の場合だけ距離をnullとする。

集合が1ノード違う場合も、その層の完全一致の1点は失います。そこで補助指標として、予測集合Pと正答集合Gの共通ノードTP、余分なノードFP、足りないノードFNを保存し、precision、recall、F1も計算します。列挙順は無視し、重複IDは回数を別に記録します。重複を除いた集合のF1と、重複も認めない厳密点は分けています。

計算は precision=TP/|P|、recall=TP/|G|、F1=2TP/(2TP+FP+FN) です。正答が非空で予測が空なら全て0、両集合が空なら全て1、正答だけが空ならprecision=0・recall=1・F1=0と事前に定義しました。今回の正答は全問で非空です。

6問のF1を平均したmacro F1と、TP/FP/FNを合計して求めるmicro F1も補助として示します。これらを24点へ足したり、公開GraphWalksの公式F1や1Mトークン評価へ換算したりはしません。

選択したモデル 試行 取得できた結果 実際の生成モデルの確認 内容点/F1
4 Argon・高値 初回 56文字の一般的な拒否応答 末尾で4 Argon Highを確認 未採点/なし
4 Argon・高値 第2試行 初回と同じ56文字の拒否応答 末尾で4 Argon Highを確認 未採点/なし
3.8 Flash・高値 初回 生成途中にホームへ戻り、最終本文を取得できず 選択表示のみ。生成モデルは未確認 未採点/なし
3.8 Flash・高値 第2試行 生成途中にホームへ戻り、最終本文を取得できず 選択表示のみ。生成モデルは未確認 未採点/なし

Argonは2回とも同じ拒否応答でした。Flashは初回に「Tracing Q3 Paths」、第2試行に「Validating Node Layers」という生成中の表示を確認した後、入力文だけが残るホーム画面へ戻りました。添付も回答本文もなく、履歴を再読込して検索してもArgonの2会話だけを確認でき、Flashの最終本文は回復できませんでした。Flashの実際の生成モデルは、両回とも末尾表示で確認できていません。

採点可能なグラフの解答は、4試行で0件でした。 点数とF1は付けず、解答がない状態を空集合の予測や能力0点へ置き換えていません。拒否や画面の中断の原因は未確認で、生成中の表示だけから正誤やBFS能力の順位を判断することもできません。この課題は記録した2試行ずつで終了し、先行する全課題の結果も残しました。

Argon第2試行のグラフ課題への拒否応答

24項目は独立した24回の実験ではなく、同じグラフ上の問いが関係しています。今回の未採点の結果から、長期的な能力差や総合的な勝敗は判断しません。

両モデルに送った同じプロンプト
添付の graph_input.txt にある有向グラフと定義だけから、Q1〜Q6に答えてください。外部の事実や書かれていない辺を追加しないでください。

各問について次を求めます。

1. rootからの最短距離がちょうどkホップの全ノードを、漏れなく重複なく列挙する。これはBFSの第k層であり、最短距離がkより小さいノードは、kホップの別経路があっても含めない。
2. その層のノード数を求める。
3. 指定されたwitness_targetに至る最短パスを一つ示す。ノード列はrootから終点まで順にk+1個、辺ID列はその移動順にk本とする。
4. probe_targetへの到達可否と最短距離を求める。距離がkを超える場合も到達可能ならその最短距離を答える。グラフ全体で到達不能ならdistanceをnullにする。

回答は前置きやコードフェンスを付けずJSONオブジェクトだけにしてください。最上位のキーはanswersで、Q1〜Q6の6要素の配列です。各要素は次のキーを持ちます。

- id:問のID。
- layer:該当層のノードIDを並べた配列。順序は任意、重複は不可。
- count:layerの正しいノード数。整数。
- witness:target、nodes、edgesを持つオブジェクト。targetは指定された終点ID、nodesはパスのノードID配列、edgesはパスの辺ID配列。
- probe:target、reachable、distanceを持つオブジェクト。targetは指定されたprobe_target、reachableはtrueまたはfalse、distanceは到達可能なら最短距離の整数、到達不能ならnull。

ノードID・辺ID・問IDは資料にある符号をそのまま使ってください。推測でノードを補ったり、列挙を途中で省略したりしないでください。
入力と正答を再現するPythonコード(標準ライブラリのみ)

空のフォルダに保存してPython 3で実行すると、graph_input.txt、expected.json、生成メタデータを作ります。モデルへ送るのは問題TXTと上の指示だけで、正答JSONは採点用に保持してください。

"""標準ライブラリのみ。現在のフォルダに自作グラフの入力・正答を再生成する。"""
from pathlib import Path
from collections import deque
import hashlib, json, random

rng=random.Random(481516)
n=720
pairs=set()
for block in range(9):
    group=list(range(block*80,(block+1)*80))
    for i,u in enumerate(group):
        pairs.add((u,group[(i+1)%80]))
        v=rng.choice(group)
        while v==u or (u,v) in pairs:
            v=rng.choice(group)
        pairs.add((u,v))
for _ in range(400):
    while True:
        block=rng.randrange(9)
        u=block*80+rng.randrange(80)
        v=block*80+rng.randrange(80)
        if u!=v and (u,v) not in pairs:
            break
    pairs.add((u,v))
for block in list(range(6))+[7]:
    for _ in range(4):
        u=block*80+rng.randrange(80)
        v=(block+1)*80+rng.randrange(80)
        pairs.add((u,v))
        pairs.add((v,u))
for u,v in rng.sample(sorted(pairs),24):
    pairs.add((v,u))
assert len(pairs)==1920

def opaque_ids(prefix,count):
    ids=[]
    seen=set()
    while len(ids)<count:
        value=prefix+format(rng.getrandbits(32),'08X')
        if value not in seen:
            seen.add(value)
            ids.append(value)
    return ids

node_ids=opaque_ids('N',n)
edge_ids=opaque_ids('E',len(pairs))
edges=[(edge_ids[i],node_ids[u],node_ids[v]) for i,(u,v) in enumerate(sorted(pairs))]
adj={u:[] for u in node_ids}
for eid,u,v in edges:
    adj[u].append((v,eid))
for items in adj.values():
    items.sort()

def bfs(root):
    distance={root:0}
    parent={}
    queue=deque([root])
    while queue:
        u=queue.popleft()
        for v,eid in adj[u]:
            if v not in distance:
                distance[v]=distance[u]+1
                parent[v]=(u,eid)
                queue.append(v)
    return distance,parent

queries=[]
answers=[]
for i,k in enumerate(range(4,10)):
    candidates=[]
    for index in range(i*80,(i+1)*80):
        d,parent=bfs(node_ids[index])
        size=sum(value==k for value in d.values())
        if 20<=size<=100:
            candidates.append((index,size))
    preferred=[item for item in candidates if 40<=item[1]<=90]
    index,size=rng.choice(preferred or candidates)
    root=node_ids[index]
    d,parent=bfs(root)
    layer=sorted(v for v in d if d[v]==k)
    target=rng.choice(layer)
    if i in (2,4):
        probe=node_ids[rng.randrange(560,720)]
    else:
        probe_depth={0:k-1,1:k+2,3:0,5:3}[i]
        probe=rng.choice(sorted(v for v in d if d[v]==probe_depth))
    query={'id':f'Q{i+1}','root':root,'k':k,'witness_target':target,'probe_target':probe}
    queries.append(query)
    path_nodes=[target]
    path_edges=[]
    cursor=target
    while cursor!=root:
        previous,eid=parent[cursor]
        path_nodes.append(previous)
        path_edges.append(eid)
        cursor=previous
    answers.append({'id':query['id'],'layer':layer,'count':len(layer),
        'witness':{'target':target,'nodes':path_nodes[::-1],'edges':path_edges[::-1]},
        'probe':{'target':probe,'reachable':probe in d,'distance':d.get(probe)}})
    assert 20<=len(layer)<=100 and len(path_edges)==k

header='''自作の有向グラフ・BFS比較課題
この資料は全ノード720個、全辺1,920本と、評価対象6問を含みます。全て架空の符号です。

【定義】
V行は存在するノードIDです。E行は「辺ID 始点ノードID 終点ノードID」で、有向の辺を1本表します。辺は全て1ホップで重みはありません。書かれていない辺は存在しません。
逆向きの辺は別のE行に明示されている場合だけ存在します。ノードと辺の掲載順・IDの文字列には探索順や層の意味がありません。
root自身の最短距離は0。求める層はrootからの最短距離がちょうどkの全ノードです。「長さkの経路を一つ作れる」だけでは、その層に属することになりません。閉路で戻ったノードの最短距離は増えません。
witness_targetは当該層のノード一つです。その終点に至るk本の有向辺とk+1個のノードを示してください。最短パスが複数ならどれを選んでも構いません。
probe_targetは別途指定したノードです。rootから到達できるかと最短距離を答えてください。探索をk層で打ち切って「到達不能」とはせず、グラフ全体に到達経路がない場合だけ到達不能とします。

【全ノード】
'''
vertices=list(node_ids)
rng.shuffle(vertices)
shuffled_edges=list(edges)
rng.shuffle(shuffled_edges)
document=header+'\n'.join('V '+v for v in vertices)
document+='\n\n【全有向辺】\n'+'\n'.join('E '+' '.join(row) for row in shuffled_edges)
document+='\n\n【評価対象】\n'+'\n'.join(json.dumps(q,ensure_ascii=False,separators=(',',':')) for q in queries)+'\n'
Path('graph_input.txt').write_text(document,encoding='utf-8')
Path('expected.json').write_text(json.dumps({'answers':answers},ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
metadata={'seed':481516,'nodes':n,'edges':len(edges),'input_characters':len(document),
    'layer_counts':[a['count'] for a in answers],'depths':[q['k'] for q in queries],
    'reachable_component_size':len(bfs(queries[0]['root'])[0]),
    'nodes_outside_that_component':n-len(bfs(queries[0]['root'])[0]),
    'input_sha256':hashlib.sha256(document.encode()).hexdigest()}
Path('generation-metadata.json').write_text(json.dumps(metadata,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')

これらは自作課題での少数回の確認です。公開ベンチマークの追試ではなく、普段の質問全般の優劣や失敗率を推定するための試験でもありません。応答待ち時間には添付処理やサービス側の状況も含まれるため、ミリ秒の処理時間ランキングには使いません。入力、事前の正答・採点基準、実際の回答を照合できる形で残しています。

今回の比較から考える使い分け

今回の条件整理と最適構成・計算では、回答の正しさという点でArgonを選ぶ追加の価値は確認できませんでした。長文は双方38/38で、最適化でも両モデルが2回ずつ、正しい最適構成と全数値に到達しています。公開評価からArgonを候補にしたい長い資料の関係整理や複数手順の仕事も、自分の入力に近い課題で比べると使い分けを判断しやすくなります。

最適化の回答をそのままJSONとして使う点では、Argonは2回とも無効、Flashは2回とも有効でした。この課題では、Flashが構造化出力の指示に適合しています。また、Argonは正しい最適値を出していても、最適性を説明する下界の一部に反例がありました。最適値の一致と説明の真偽は分けて確認し、Flashの回答も含めて、根拠や探索手順を検証する必要があります。

図と時間表では、Flashは2回とも計算に正答し、初回の1点減点はR4の根拠参照の欠落でした。Argonは2回とも画像を読み取れない旨の応答で、計算能力の比較はできていません。公開評価から図の分析に期待できる場合も、使う画面で入力から回答まで通るかを確かめ、取得した回答の根拠と計算を確認したいところです。

長いグラフの関係整理は、今回のWeb版テストでは採点できる回答を取得できませんでした。GraphWalksの公開高得点を、この入力と利用画面で確認できたとは言えません。使うサービスで入力から回答までの動作を確認してから、取得できた回答の集合や経路を評価する必要があります。

自分の仕事に合うかを確かめる方法

Argonを試す最初の候補は、長い資料を使う条件整理、図や動画の分析、資料調査を含む複数ステップの仕事です。コーディングや端末操作は、公開値でも評価が分かれるため、普段扱う課題で比較したいところです。

実際に選ぶときは、正答が分かる課題を用意し、同じ入力、同じツール、同じ作業時間の上限で比べます。資料なら根拠の一致と条件の抜け、コードなら動作と変更範囲、図なら読み取りと計算を確認します。成功した例だけでなく、失敗や判断できなかった項目も残すと、任せられる範囲が見えてきます。

GeminiアプリでProから試せることと、Antigravityで個人向けUltraが必要なことは別の条件です。用途を決めたうえで、必要な製品とプランを選ぶのがよさそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?