
Summary
この文書の要点
- 論理上限100は性能実績や到達目標ではなく、適応window、resource capと重ねて使う安全上の天井です。
- 初期4件を1秒間隔で投入し、成功時は段階的に増やし、provider失敗時は半減させることで、一斉投入による負荷の増幅を避けます。
- PUBLICまたはINTERNALの独立read-only作業だけをGLMへ送り、秘密候補、危険path、分類不能な入力は送信前に拒否します。
- GLMの分析は未信頼の候補として扱い、実変更、採否、高影響判断、テスト、デプロイは単一のwrite ownerと決定的verifierが担当します。
「100並列」は同時起動数ではなく、実行windowの論理上限です
大量のAI処理を扱うとき、バッチに含まれるタスク数、キューに積める件数、同時にproviderへ送っているin-flight数、ローカルで起動できるプロセス数は別の値です。本稿で100としているのは、適応型キューが取り得る同時実行windowの論理上限です。100件を同時に送信する設定ではありません。
実効並列度は、適応window、ローカルresource cap、固定上限の最小値で決まります。たとえば固定上限が100でも、利用可能なCPU、RAM、ファイル記述子から算出したresource capが20で、providerの応答を見た適応windowが6なら、実際の同時実行は6件までです。上限を大きくしても、他の制約を越えて実行しません。
この区別を曖昧にすると、『100件を一斉に起動した』『100倍速くなった』『100並列まで安定性を検証した』といった、実測が支えていない説明になります。100は安全弁の設定値であり、性能を示すには実際のpeak、成功率、timeout、処理時間、token数を別に計測します。
- queued tasks: 実行を待つ独立タスクの総数。
- in-flight calls: providerへ送信済みで応答待ちの呼び出し数。
- adaptive window: 成功と失敗のフィードバックから増減する現在の許容数。
- logical limit: どの条件でも越えない固定の天井。本稿では100。
effectiveConcurrency = min(
adaptiveWindow,
localResourceCap,
logicalLimit, // 100
)GLMへの経路をOpenCode CLIへ一本化します
大量処理だからといって、用途ごとに独自のHTTP clientを増やすと、認証、endpoint、model ID、timeout、再試行、利用量の計測が分散します。そこでGLM-5.2への実行経路はOpenCode CLIへ一本化し、キュー側はタスク分類、秘密境界、プロセス期限、投入制御、メトリクスだけを所有します。
OpenCodeにはread-onlyの監査用agentを用意し、write、edit、shell、subtask、web accessを拒否します。モデルには分析対象と成果物形式だけを渡し、実装、merge、デプロイを担当させません。CLIの終了コードとJSON eventを機械的に読み、最終textがない、JSONとして壊れている、provider error eventがある、といった状態を成功として扱わないことも重要です。
経路を一本化する目的は、特定のツールへ依存することではなく、providerとの通信契約を一箇所で検証できるようにすることです。model名を設定へ書いただけでは疎通確認になりません。実呼び出しのメトリクスでrouteとprovider modelを確認し、失敗時はprocess、format、429、5xx、timeoutを分けて記録します。
- OpenCode: provider protocol、認証ストア、model catalog、JSON eventを担当する。
- 適応キュー: 分類、admission、期限、再試行、並列度、メトリクスを担当する。
- 親エージェント: 採否、実変更、テスト、高影響判断、外部操作を担当する。
大量投入の前に、秘密境界でfail-closedします
並列度を上げるほど、誤った入力を一度に広く送る危険も増えます。そのため処理能力の調整より先に、送信可否を決めます。GLMへ送るのはPUBLICまたは、匿名化と内容検査を通したINTERNALのread-only分析だけです。CONFIDENTIAL、SECRET、分類不能、秘密値を必要とする作業は、自動的に安全側へ拒否します。
検査対象はprompt本文だけではありません。参照pathには相対pathだけを許可し、親directoryへの移動、Git管理情報、環境ファイル、credential、secret、秘密鍵、証明書、state fileなどを拒否します。本文では秘密鍵、Bearer token、key・token・passwordの代入形状などを検出し、既知形状を伏せた後でも疑わしい文字列が残れば送信しません。
redactionは安全の証明ではありません。固有のファイル名、業務用語、データ構造だけで対象を推測できることがあります。安全な要約を作れない入力は、文章を薄めて送るのではなく、親エージェントまたは承認済みの秘匿処理経路へ残します。分類拒否はprovider障害ではないため、他の安全なタスクのwindowを下げないよう、エラー種別も分けます。
- 送信可能: PUBLIC、検査済みINTERNAL、独立read-only分析。
- 送信不可: 分類不能、秘密値が必要、危険path、外部write、高影響判断。
- 拒否後: 同じ入力を形だけ変えて再送せず、安全な要約が作れるかを親側で再判断する。
同時実行できる単位まで、論点と成果物を分けます
適応型キューの前提は、タスク同士が独立していることです。大きな『全部レビューする』という依頼を複製しても、同じ文脈を何度も読み、同じ指摘を返すだけです。entrypointと依存を調べるinventory、例外とretryを見るerrors、resource解放を見るresources、境界値とraceを見るedge cases、設定と台帳を見るconfig、既存テストと不足分を見るtests、指摘を反証するcounterexampleのように、監査focusを分けます。
各タスクには一意のtask ID、対象範囲、監査focus、入力の分類、期待する成果物形式を付けます。同じファイルを複数の観点から読んでも構いませんが、同じ問いをそのまま重複投入しません。完了後のfindingも、triage、repair proposal、test proposal、counterexample、verification planへ分ければ、監査結果を次の実作業へ接続できます。
キューを空にしないことと、枠を埋めることは別です。安全で重複しない実作業が残る間は、完了イベントごとに次を補充します。一方、自然な作業が尽きたらidle stopとして終了します。上限へ近づけるためだけのno-op、同じpromptの再送、成果物を使わない水増しは、費用を増やして観測値を汚すため禁止します。
- 独立性: 同じ判断や同じwriteを複数タスクが所有しない。
- 一意性: task IDと根本原因fingerprintで重複を検出する。
- 接続性: findingを修正案、テスト案、反証、検証計画へつなぐ。
- 自然停止: 有益な作業が尽きたことをidle stopとして記録する。
初期4・1秒間隔から、成功時は加算し失敗時は半減します
providerの処理能力は固定ではなく、時刻、タスクの長さ、共有負荷によって変わります。開始時に許容上限まで一斉送信すると、最初の失敗信号が返る前に多数の呼び出しがin-flightになります。そこで初期windowを4とし、1秒ごとに1件だけadmissionします。先行応答を待ち切らずに次を送れますが、burstにはしません。
成功が3件続くたびにwindowを1増やし、provider由来の失敗が出たらwindowを半分へ下げます。これは空き容量を少しずつ探り、圧力を検出したら速く戻す加算増加・乗算減少の考え方です。分類拒否や危険path拒否はprovider圧力ではないため、window調整の信号から除きます。
論理上限100の手前には、CPU、利用可能メモリ、ファイル記述子から求めるresource capを置きます。OpenCodeの子プロセスはsocket、pipe、設定ファイル、標準出力を使うため、モデル側が応答できてもローカル資源が先に尽きる可能性があります。設定値、providerの健康度、端末資源の三つを別々に観測します。
window = min(initial_window, resource_cap, logical_limit)
for result in completion_stream:
if result.is_policy_refusal:
continue
if result.is_provider_failure:
success_streak = 0
window = max(1, window // 2)
else:
success_streak += 1
if success_streak >= 3:
window = min(window + 1, resource_cap, logical_limit)
success_streak = 0retry、deadline、circuit breakerを別の役割で組み合わせます
timeoutや429へ無制限にretryすると、古いタスクが新しいタスクの枠を占有し、同じcontextを何度も送り直します。retryは回数を制限し、短いjitterを入れます。各taskにはdeadlineを持たせ、run全体にも別のdeadlineを置きます。task deadlineは1件の停滞を止め、run deadlineは全体のwall-clockと外部呼び出し数を上から制限します。
連続したprovider失敗が一定数に達したらcircuit breakerを開き、冷却期間は新しい呼び出しを止めます。この状態では残りのタスクを無理に成功扱いせず、fallback理由を記録します。成功が戻ったら段階的に再開し、以前の高いwindowへ一度に戻しません。
補充元の探索にもdeadlineが必要です。次の作業を探す処理が遅いと、provider callが終わっているのにキューが『まだ作業があるかもしれない』状態で止まります。遅れた探索結果を捨てずに所有しながら、探索単位とrun全体の期限を守ると、空キューと探索停滞を区別できます。
- bounded retry: 一時的な429、5xx、timeout、process失敗だけを限定再試行する。
- task deadline: 一つの遅い呼び出しがslotを占有し続けるのを防ぐ。
- run deadline: 全体の停止時刻を決め、残件を未完了として記録する。
- circuit breaker: 連続失敗時に新規投入を止め、provider圧力を増幅しない。
呼び出し数だけでなく、並列度と採否まで計測します
大量処理で『何件呼んだか』だけを見ても、キューが健全かは分かりません。calls、success、failure、timeout、retry、prompt token、completion tokenに加え、initial・peak・final window、resource cap、provider error、fallback理由、補充数、重複拒否、探索期限、idle stopを記録します。
モデルの出力内容をmetricsへ保存しないことも重要です。ログにはroute、model、件数、token、並列度、エラー種別、採用・棄却数と理由だけを残します。prompt、raw response、秘密値を監査ログへ複製すると、キュー自体が新しい情報漏えい経路になります。
採用と成功も分けます。provider callが正常終了しても、内容が正しいとは限りません。successは通信と形式の結果、adoptedまたはrejectedは親エージェントが証拠とテストを確認した後の判断です。採否理由がなければ、GLMが何件成功したかと、実際の改善へ何件つながったかを比較できません。
{
"route": "opencode-cli",
"model": "glm-5.2",
"calls": 17,
"successes": 5,
"timeouts": 12,
"retries": 12,
"initialConcurrency": 4,
"peakConcurrency": 6,
"finalConcurrency": 5,
"resourceCap": 20,
"adopted": 0
}二つの実測は、最適値ではなく運転領域の違いを示します
ある安定運転では、実効3並列で302 calls、302 success、failureとtimeoutは0、合計217,844 tokensでした。別の負荷運転では、初期4、peak6、resource cap20で17 calls、5 success、12 timeout、12 retries、合計2,364,476 tokensでした。後者はpeak6であり、resource cap20にも論理上限100にも到達していません。
この二つから直接言えるのは、安定運転では多数の呼び出しをtimeoutなしで完了できたことと、別の運転ではtimeoutとretryが多く、少ない成功に対して大きなtoken量が計上されたことです。タスクの難易度、context長、provider状態、deadlineが同じ対照実験ではないため、『並列度を上げたことがtimeoutの原因』『3が常に最適』とは断定できません。
また、100に近い領域を計測した結果でもありません。100は設定上の天井であり、実測範囲は3からpeak6です。性能を比較するなら、同じtask set、同じdeadline、複数回のrunで並列度を変え、完了時間、成功率、p50・p95 latency、token、retry、provider errorを揃えて測る必要があります。
- 実測済み: 低い実効並列度での安定運転と、peak6までの負荷運転。
- 未実測: 100同時実行、100近傍の成功率、100倍の速度向上。
- 未分離: 並列度、task粒度、context長、provider状態、deadlineの因果。
stable run
calls=302, success=302, timeout=0
effective concurrency=3
total tokens=217,844
pressure run
calls=17, success=5, timeout=12, retries=12
initial=4, peak=6, resource cap=20
total tokens=2,364,476GLMの成功を、修正の完了と同じ意味にしません
GLMは探索、監査、反証、修正案、テスト案を広く担当できますが、出力は未信頼です。存在しないsymbolを前提にした指摘、すでに上位で防御されている誤検知、古い設定を読んだ提案も返ります。成功した応答をそのままpatch、merge、デプロイへ進めると、大量並列化した誤りも同じ速度で広がります。
親エージェントはfindingごとに実コード、正典、差分、決定的test、runtime proofを照合し、採用または棄却の理由を記録します。同一ファイル、同一symbol、生成物、DB、state、lockfileへのwriteは一つのownerへ固定します。独立したファイルを書ける場合でも、生成、整形、migration、デプロイは合流後の直列gateへ戻します。
監査でfindingが出たら、確認だけでキューを止めません。triage、repair proposal、test proposal、counterexample、verification planを独立したread-onlyタスクとして補充し、親側が一つの修正へ統合します。この接続があると、モデル利用量が問題発見だけで終わらず、検証可能な改善へつながります。
- GLM: 読み取り、候補生成、反証、検証計画。
- single write owner: 実装、競合解消、生成物、state変更。
- deterministic verifier: lint、typecheck、unit test、integration test、runtime proof。
- 高影響gate: 権限、migration、外部公開、merge、deploy、rollback。
独立性が低い仕事と、検証器がない仕事には向きません
この方式は、異なる対象または異なる監査focusへ分けられ、結果を機械的または独立に検証できる仕事に向きます。大量のファイルから未整合を探す、設定台帳を照合する、境界値や例外経路を列挙する、既存testの不足を考える、といった処理です。
反対に、一つの設計判断を共有し続ける必要がある仕事、同じファイルへ細かく書き込む仕事、migrationやstate変更、認証情報が必要な調査、正解を判定する方法がない創造的判断には向きません。分割できない仕事を無理に100枠へ広げると、統合作業と誤検知の確認が増え、直列実行より遅くなります。
上限を下げる判断も運用の一部です。timeout率、429・5xx、p95 latency、retry token、ローカルmemory、FD使用量が増え、windowを広げても完了時間が短くならない場合は、上限より先にtask粒度、context量、deadline、補充方法を見直します。providerの健全性が戻るまでcircuit breakerを維持する方が、呼び出しを続けるより早く復旧する場合があります。
- 向く仕事: 独立監査、設定照合、反証、テスト観点、公開情報の分類。
- 向かない仕事: 秘密依存、共有stateへのwrite、不可逆操作、採点不能な判断。
- 縮小条件: timeout・retry・p95・resource使用量が増え、throughputが改善しない。
持ち帰る判断軸は、上限よりフィードバックと検証です
論理上限100は、多数の独立作業を将来受け入れるための天井です。実際の運転は初期4件、1秒間隔、成功時の加算、失敗時の半減、resource cap、deadline、circuit breakerによって小さく始めます。100へ到達しなくても、完了ごとに意味のある作業を補充し、安定したthroughputを保てれば設計の目的は満たせます。
大量のモデル呼び出しを安全な開発工程に変える鍵は、送信前の秘密境界と、応答後の検証境界です。送ってよい独立read-only作業だけを通し、GLMの結果を未信頼として扱い、単一write ownerと決定的verifierで採否を決めます。並列度の数字より、何を拒否し、いつ縮小し、どう検証するかを先に設計することが重要です。


