2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI コーディングエージェントの1タスクが8時間かかる理由を、45日分のセッション履歴から測ってみた

2
Posted at

背景

最近、自分の作業ログを見ていて、どうにも腑に落ちないことがありました。

AI コーディングエージェントを使っているのに、1つのタスクが終わるまでに 8 時間、長いときは 24 時間を超えている。体感としては「ずっと動いている」のですが、成果物の量はそれに見合っていない。正直、生産性が上がっているのか下がっているのか、自分でもよく分からなくなっていました。

原因についての心当たりは、いくつかありました。

  • タスクが複雑すぎるのではないか
  • 検証まわりの Skill(手順書)が足りていないのではないか
  • 気づかないうちにオーバーエンジニアリングしているのではないか
  • そもそもマシンのリソースが足りていないのではないか
  • モデル選択や reasoning effort の設定が高すぎるのではないか

ただ、これらは全部「感想」です。感想をもとに対策を打っても、たいてい外します。

なので、45 日分のセッション履歴を実データとして引っ張り出して、SQL で集計してみました。この記事は、その測定結果と、そこから見えた「現実的な落としどころ」の話です。

結論だけ先に書くと、主因はタスクの難易度ではなく、1つのセッションに文脈を無限に積み上げる運用そのものでした。 そして、自分が立てた5つの仮説のうち、当たっていたのは1つ半くらいでした。


注意点 / 前提

先に、この記事の限界をはっきり書いておきます。ここを飛ばすと、数字だけが一人歩きしてしまうので。

  • これは私個人の1人分のログです。 n=1 です。組織全体の傾向でも、業界の平均でもありません。
  • 測定対象は VS Code のチャットセッションに限定しています。 同じ環境で動いている Coding Agent(2,706セッション)やコードレビュー(672セッション)、CLI(109セッション)はコスト特性が違うので除外しました。
  • 期間は2種類を使い分けています。 45日窓(318セッション)と14日窓(74セッション)です。表ごとにどちらかを明記します。
  • 「セッション所要時間」は最終更新時刻と作成時刻の差です。 つまり、私が席を外していた時間も、承認待ちの時間もそこに含まれます。エージェントが 8 時間働いた、という意味ではありません。
  • 測れなかったものがあります。 reasoning effort の設定値はイベントに記録列がなく、履歴からは検証できませんでした。文脈圧縮(compaction)の実施有無も、該当テーブルが全期間 0 行のため判定できません。ツール個別の実行時間も、開始イベントが記録されていないため直接は測れていません。
  • 推定が混じる箇所は「試算」と明記します。 前提条件も併記します。

そして、これは特定の製品や企業の批判ではありません。ツールは想定どおりに動いています。問題があるのは、私の使い方のほうです。


ここで一度、用語と前提を整理してみます

数字を見る前に、何が問題で何が問題ではないのかを切り分けておきます。

「遅い」には少なくとも3種類ある

種類 中身 誰の問題か
推論待ち モデルが考えている時間 コンテキストサイズとモデル選択の問題
ツール実行 テスト実行、ビルド、ファイル読み込み 回数の問題(1回あたりは速い)
アイドル 承認待ち、席外し、放置 運用と承認設計の問題

この3つは対策がまったく別物です。「遅い」とひとまとめにすると、どこを直せばいいのか永遠に分かりません。

コンテキストは「容量」ではなく「予算」

長文コンテキスト対応モデルを使っていると、入るなら入れておけばいい、と考えがちです。実際、私はそう考えていました。

ただ、Anthropic の context engineering に関する記事では、コンテキストは有限資源であり限界効用は逓減する、という整理がされています1。Chroma の "Context Rot" のレポートでは、18 モデルを対象に、タスクの難易度を一定に保ったまま入力長だけを増やしても性能が単調に劣化することが実証されています2。"Lost in the Middle" の研究では、関連情報が入力の中間にあると性能が大きく落ちることが示されています3

つまり「入るかどうか」と「効くかどうか」は別の話です。ここが今回の測定結果の背骨になります。

Prompt

実際に、調査レポートを作成するために、以下のPromptを投入しています!

私が`GitHub Copilot`で行っているタスク(チャットを開始してから、終了するまで) が8時間-24時間などかかるものもあり、全体の時間がかかりすぎています。1つのタスクは、1-2時間で終わるようにしたいです。
その長時間を要している根本原因をチャットのログなどから詳細に分析をして、緻密な分析レポートを作成してください。レポートは`/work/20260918-LongTimeTaskAnalytics.md`に作成をしてください。
分析をする際には、インターネットで公開されている論文や、インターネットで根拠のあるBest Practiceなども参考にしてくてください。
私の仮説は以下です。

- harness系のskillが不足している
- そもそもタスクが複雑なものばかり
- オーバーエンジニアリングが発生しているのに気づかない
- タスクを実行しているコンピューターのリソースが不足している
- タスクに対して使用しているモデルのReasoning Effortや、モデル選択が間違っている。高いものばかりになっている

捏造は絶対に禁止です。
全ての情報源には必ず出典を提示してください。

測ってみた: 時間はどこへ消えているのか

8時間超のセッションが、全体の18%で時間の74%を食っている

まず、セッション所要時間の分布です(45日窓 / 318セッション)。

所要時間 セッション数 構成比 合計時間 時間構成比
30分未満 91 28.6% 7 h 0.3%
30分〜2時間 66 20.8% 75 h 3.4%
2〜4時間 38 11.9% 108 h 4.9%
4〜8時間 65 20.4% 393 h 17.8%
8〜24時間 43 13.5% 552 h 25.0%
24時間超 15 4.7% 1,069 h 48.5%
合計 318 100% 2,204 h 100%
  • 8時間以上は 58セッション(18.2%)で、総時間の 73.6%
  • 4時間以上は 123セッション(38.7%)で、総時間の 91.4%

ここが最初の発見でした。「全部のタスクが長い」のではありません。 28.6%、つまり3割近くは 30 分未満で終わっています。少数の巨大セッションが時間を食い尽くしているだけです。

「そもそもタスクが複雑なものばかりだから」という自分の仮説は、この分布を見た時点で怪しくなりました。

最長セッションの実態

上位を抜粋します(リポジトリ名とセッションIDは匿名化しています)。

セッション リポジトリ 所要 モデル呼び出し数 入力トークン累計
S-01 リポジトリA 5,691分(94.9h) 15,980 26.8億
S-02 リポジトリA 1,313分 8,384 12.3億
S-03 リポジトリA 1,276分 8,297 11.9億
S-04 リポジトリB 3,829分(63.8h) 2,128 5.7億
S-05 リポジトリC 2,130分(35.5h) 2,750 5.4億

S-01 は、1つのチャットで 15,980 回のモデル呼び出し、ターン番号は最大 17,508 に達しています。

これはもう、1つのチャットが1プロジェクト全体の容器になっている状態です。書いていて恥ずかしいのですが、私は「文脈が残っているほうが説明が省けて効率的」だと思っていました。

指示1件あたりのコストに換算する

14日窓(74セッション)で単位あたりに落とすと、こうなります。

指標 実測値
セッション実時間合計 728 時間
LLM 推論時間合計 310 時間(42.6%
LLM 呼び出し数 49,288
ツール実行完了数 99,082
人間の指示ターン数 437

ここから割り算すると、

  • 指示1件あたり LLM 呼び出し 112.8 回
  • 指示1件あたりツール呼び出し 226.7 回
  • 指示1件あたり純粋な推論待ち 42.6 分

1回指示を出すと、モデルが 113 回考えて、ツールを 227 回叩いて、推論だけで 43 分待つ。ここにツール実行時間と承認待ちを足せば、1指示で1〜2時間が溶けます。

残りの 57% はアイドルだった

イベント間に5分以上の無記録区間がある時間を「アイドル」として集計しました(長時間のターミナルコマンドもここに混じる点は注意してください)。

セッション 所要(分) アイドル(分) アイドル比率 最大ギャップ(分)
S-06 4,329 4,273 98.7% 3,683
S-07 3,940 3,373 85.6% 1,754
S-08 3,046 2,582 84.8% 885
S-09 1,890 1,418 75.0% 559
S-01 5,691 1,508 26.5% 260

最大ギャップが 3,683 分、つまり 61 時間のセッションが実在します。

「8時間かかった」の多くは、エージェントが8時間働いていたのではなく、8時間分の壁時計が経過していただけでした。 これは正直、自分でもちょっとショックでした。


なぜ1回の推論が遅いのか

コンテキストサイズと遅延の関係

14日窓 / 50,325 call / 312.6時間 の集計です。

入力トークン帯 call数 平均遅延 遅延合計
25k 未満 4,833 3.5 秒 4.7 h
25–50k 1,490 6.1 秒 2.5 h
50–100k 12,548 13.0 秒 45.3 h
100–200k 15,747 26.9 秒 117.6 h
200–400k 9,560 34.8 秒 92.3 h
400k 超 6,147 29.4 秒 50.2 h
  • 100k トークン超の call が 31,454件(62.5%)で、LLM 総遅延の 83.2%(260.1時間)を消費
  • 25k 未満(3.5秒)と 200–400k(34.8秒)で 約10倍 の差

この差は、体感ではほとんど意識できません。1回 3.5 秒が 35 秒になっても、待っている側は「まあこんなものか」と思ってしまう。それが 3 万回積み上がると 260 時間になる、という話です。

コンテキストの「床」がすでに高い

45日窓で 20 call 以上のセッション 275 件について、セッション内で最も軽かった call の入力トークン数を取りました。

  • 最小値の中央値: 50,245 トークン
  • 第1四分位の中央値: 108,169 トークン

つまり 会話が始まった瞬間から 5 万トークン、平常運転で 10 万トークンを毎 call 再送しているということです。

これはシステムプロンプト+instructions+Skill の description+ツールスキーマの固定費です。実測した資産の量はこうでした。

資産 ファイル数 サイズ
プロジェクトSkill 114 約 899 KB
プロンプト資産 323 約 1.44 MB
ユーザーレベルSkill(複数スコープ合計) SKILL.md 128件

Skill の本体は progressive disclosure で遅延読み込みされます4。ただし 128 件分の namedescription(最大1,024文字)は常時システムプロンプトに載ります。 加えて、このセッションのシステムプロンプトには 250 件超の deferred tool 名が列挙されていました。

Anthropic も「肥大したツールセットは、どのツールを使うか曖昧にする最も一般的な失敗モード」と書いています1。心当たりがありすぎます。

入力と出力の比率が異常

45日窓のモデル別です。

モデル call数 入力トークン 出力トークン 入力/出力比
モデルα(高速) 52,635 123.4億 5,607万 220.2
モデルβ(高性能) 24,998 88.7億 2,927万 302.9
モデルγ 17,596 52.4億 1,914万 273.5
モデルδ(最新世代) 21,320 51.1億 3,314万 154.0
モデルε(軽量) 39,913 28.3億 3,363万 84.1

1トークン出力するために 150〜300 トークン読み込んでいます。これは「毎ターン、肥大した文脈全体を読み直している」ことの、かなり直接的な証拠だと思っています。


個別の増悪要因

1. 検証系 Skill が1件もロードされていなかった

これが今回いちばん効いた発見でした。

プロジェクトの Skill ディレクトリを実測したところ、SKILL.md は 33 件ありました。ただし、ディレクトリ階層が2種類に分かれていました。

階層 件数 システムプロンプトへの掲載
skills/<name>/SKILL.md 20 20件すべて掲載
skills/<category>/<name>/SKILL.md 13 0件。1件も掲載されていない

ロードされていなかった 13 件には、検証ループ、敵対的レビュー、エラーリカバリ、TDD の red/green 判定、大量出力の分割といった、まさに今回の問題に直結する手順書が全部入っていました。

13 件すべて、frontmatter の name はディレクトリ名と一致していました。つまり原因は命名ではなく配置階層です。VS Code のドキュメントでは、プロジェクト Skill の保存場所が定義されており、name は親ディレクトリ名と一致する必要がある、とされています4。カテゴリ分け用の中間フォルダは想定されていません。整理整頓のつもりで切ったフォルダが、そのまま無効化のスイッチになっていました。

さらにまずいのは、プロジェクトの共通指示ファイルが、この存在しない Skill を参照していたことです。

通常の自動検証は harness-verification-loop、敵対的レビューは adversarial-review の発動規則に従う。

エージェントは「検証ループを使え」と指示されるけれど、その中身にアクセスできない。結果として、毎回その場で検証ループを再発明していたわけです。これが「同じ確認を何度も繰り返す」「テスト実行→失敗→再試行が発散する」挙動の構造的な原因になっていたと考えています。

自分の仮説「harness 系の Skill が不足している」は、正確には 「不足」ではなく「存在するが到達不能」 でした。そして修正はフォルダを 13 個動かすだけです。

2. ターミナル出力が文脈を汚染している

ユーザー側の発話を種別で分類しました(45日窓)。

種別 ターン数 総文字数 平均 最大
ターミナル完了通知 428 11,700,356 27,337 82,201
人間の指示 1,548 598,218 386 31,532
Try Again 81 729 9 9

ユーザー側入力文字数の 95.1% がターミナル出力です。

しかも、これが会話履歴に残り続けるので、以降の全 call で再送され続けます。 あるセッションでは、turn 180 で 64,236 文字、turn 978 で 56,857 文字、turn 2554 で 74,898 文字のターミナル通知が注入されていました。

これはまさに、Chroma が示した「irrelevant content の追加によって、タスク難易度が一定でも性能が単調に劣化する」条件そのものです2。Anthropic が「最も安全で軽量な compaction は tool result clearing」と述べている対象でもあります1

3. 指示のスコープが有界でない

非ターミナルの発話 1,629 件に対するキーワード出現です。

パターン 件数 比率
「全て」「すべて」 749 46.0%
「捏造」(禁止の定型句) 577 35.4%
「並列」 443 27.2%
「プラン」「計画」 436 26.8%
「残タスク」「残作業」 353 21.7%
「敵対的レビュー」 247 15.2%
Try Again 81 5.0%

同一セッション内の実際の発話を並べると、なかなか厳しいものがあります。

turn  673: 全ての残タスクを実行してください。
turn  678: 全ての残タスクを実行してください。
turn  769: 全ての残タスクを実行してください。
turn  907: 全ての残タスクをリストアップして、残タスクがあれば、全ての残タスクを実行してください。
turn 2397: 全ての残タスクを実行してください。
turn 2895: このアプリケーションを実装するための残タスクをリストアップしてください。
turn 3401: (同上、一字一句同じ)
turn 7934: Try Again
turn 7936: Try Again

「残タスクを列挙する → 実行する → 残タスクを列挙する」というループが、完了条件が定義されていないために停止しない。 列挙自体が毎回フルスキャンを伴うので、1ループが数十分から数時間になります。

別のセッションでは、同じ質問が3回連続していました。

turn 1556: 最終版のシステムテストの結果のレポートの場所を教えてください。
turn 1557: 最終版のシステムテストの結果のレポートの場所を教えてください。
turn 1567: 最終版のシステムテストの結果のレポートの場所を教えてください。

これは「エージェントが応答を返さない/見失った」ときの、私自身のリトライです。長大コンテキストでの指示追従性の劣化23が、実地で現れた形だと解釈しています。

4. モデル選択が遅延を支配している

14日窓のモデル別です。

モデル call数 平均遅延 遅延合計 平均入力 平均出力
モデルδ(最新世代) 21,320 36.9 秒 218.5 h 239,456 1,554
モデルα(高速) 9,015 14.4 秒 36.0 h 238,063 1,244
モデルε(軽量) 7,922 10.7 秒 23.5 h 71,305 858
モデルβ(高性能) 2,976 18.8 秒 15.5 h 292,952 1,430
モデルζ(小型) 2,881 1.4 秒 1.1 h 3,805 87

ここで見るべきは、モデルδ(平均入力 239,456)とモデルα(平均入力 238,063)が、ほぼ同一のコンテキストサイズなのに、平均遅延が 36.9秒 対 14.4秒=2.56倍の差があることです。

  • モデルδ単独で、14日間の LLM 遅延 312.6 時間のうち 218.5 時間(69.9%) を消費
  • 平均出力は全モデルで 87〜2,006 トークンと小さい。出力が小さいのに遅いのは、入力処理と推論に時間を使っているということ

reasoning effort については、イベントに記録列がないため履歴からは検証できませんでした。ただ、ワークスペースのタスク定義に --reasoning-effort xhigh かつ --context-tier long_context を指定するものがあり、高 effort を常用していた運用実態は確認できます。ここは未検証項目として残します。

5. ツール自体は壊れていない

結果 件数 比率
成功 300,929 98.1%
失敗 5,946 1.9%

306,875 回のツール実行のうち、失敗は 1.9% です。ツールが壊れているわけではありません。 問題は失敗率ではなく、「1指示あたり 227 回も叩いている」という回数そのものです。


自分の仮説はどれだけ当たっていたか

仮説 判定 根拠
検証系 Skill が不足している 支持(ただし「不足」ではなく「未ロード」) 13 Skill が階層の問題でロードされず、共通指示はそれを参照していた
そもそもタスクが複雑なものばかり 部分的に否定 28.6% は30分未満で完結。長時間化は少数セッションに集中
オーバーエンジニアリングに気づいていない 部分的に支持(間接証拠のみ) 指示の46.0%が「全て」、15.2%が「敵対的レビュー」。ただし「不要だった」ことは履歴からは判定不能
マシンのリソースが不足している 否定 14コア/20論理、RAM 63.8GB(空き32GB)、C: 空き382GB。加えて時間の42.6%はサーバー側の推論待ち
モデル選択・reasoning effort が高すぎる モデル選択は支持。effort は判定不能 同一コンテキストで2.56倍の差、総遅延の69.9%を占める

5つのうち、明確に当たっていたのは1つ、部分的が2つ、外れが1つ、判定不能が1つ。まあ、こんなものだと思います。仮説を測らずに対策を打たなくてよかった、というのが正直な感想です。 リソース不足だと思ってマシンを買い替えていたら、何も解決しませんでした。


因果構造として整理する

要点は B → D → H → J → L の正のフィードバックです。

セッションが長くなるほどコンテキストが太り、太るほど1 call が遅く、指示追従性も落ちる。追従性が落ちるとこちらが再指示し、セッションがさらに長くなる。

ここを断ち切らない限り、個別の最適化はあまり意味を持ちません。


完了条件(Definition of Done)の話

ここからは、測定単位を「セッション」から「指示1件」へ落とした話です。個人的には、この節がいちばん実務に効くと思っています。

時間を食っているのは「止まり方を書かなかった十数件」

45日窓・有効セグメント 1,328 件・LLM 推論時間合計 650 時間で集計しました。

1指示あたりモデル呼び出し 指示数 構成比 LLM時間合計 時間構成比
10未満 308 23.2% 6 h 0.9%
10–49 490 36.9% 63 h 9.7%
50–199 355 26.7% 153 h 23.5%
200–499 115 8.7% 150 h 23.1%
500–999 38 2.9% 131 h 20.2%
1000以上 22 1.7% 147 h 22.6%
  • 200 呼び出し以上の指示は 13.2%(175件)で、推論時間の 65.8%(428時間)
  • 50 呼び出し未満の指示は 60.1%(798件)あるが、時間はわずか 10.6%

つまり 全指示を改善する必要はありません。暴走した十数件を止めるだけでいい。 これは実務的にかなり重要な話だと思います。

最も高くついた指示(実際の文言)

実際の指示 呼び出し LLM時間 経過時間
「全ての残作業を実行してください。」 4,560 710.4分 666分
「残作業をリストアップしてください。」 3,920 668.5分 372分
「作業状況を教えてください。」 3,670 552.4分 561分
「不明点はデフォルトのプランを採用…全てのタスクを実行…敵対的レビューを行って…」 3,192 779.3分 413分
「作業を再開してください。」 1,621 344.2分 155分

3行目が象徴的です。読み取りだけのはずの状況確認が、3,670 回の推論・9.2 時間になっています。「教えてください」に停止規則がないので、エージェントはプロジェクト全体の状態を再導出しにいきました。

これ、エージェントは悪くありません。私が「どこまで調べるか」を書いていないだけです。

欠けていたのは、毎回ほぼ同じ4要素だった

自分の指示を類型化すると、抜けているものは 出力の形/判定の手段/上限/やらないこと の4つでした。

実際に使った指示 欠けていたもの 書き換え例
「残作業をリストアップしてください」 出力先/粒度/情報源/件数上限/実行しないこと 「タスク管理ファイルの未完了行だけを列挙し、作業ディレクトリに表で保存。ID・1行要約・依存のみ。最大30件。コード変更と実行は行わない。10分で終わらなければ途中経過を保存して停止」
「全ての残作業を実行してください」 対象ID範囲/1件の合格判定/時間上限と停止時の報告 「T-011〜T-013 の3件のみ実行。各件の完了は該当テストが exit 0 になること。3件終わったら停止し、残りは実行しない。60分超過時は完了済みIDと未着手IDを報告して停止」
「作業を再開してください」 再開地点の定義/読むファイル/最初の1手だけ 「計画ファイルの未チェック先頭1件だけを実行し、結果を報告して停止。2件目に進まない」
「作業状況を教えてください」 読み取り専用の明示/参照先/出力形式/探索の上限 「読み取り専用。git status --short と計画ファイルの2つだけを見て、完了数/残数/直近の失敗を10行以内で報告。ファイル読み取りは5件まで。テスト実行・コード変更は禁止」
「根本原因を調査してください」 仮説の数/証拠の形式/1つ特定したら停止 「仮説を最大3つ立て、各仮説に再現コマンドと実出力を対応させる。1つが確証できた時点で停止し、修正は行わない」

共通して抜けているのは、「やらないことリスト」と「超過時に停止して報告する」の2行でした。この2行がないと、エージェントは「まだ改善できる」方向へ進み続けます。

合格条件を書いた指示は、実際に安い(ただし相関です)

指示文の内容で4分類して比較しました(45日窓 / 1,328セグメント)。

類型 件数 呼び出し中央値 平均 LLM時間合計 プロンプト長中央値
A. 検証コマンド/合格条件あり 58 21 101 29 h 1,346字
B. 成果物パス指定あり 353 55 153 210 h 620字
C. 無限定スコープ(「全て」「残作業」) 465 36 131 248 h 42字
D. その他 452 21 79 163 h 27字

A はプロンプトが最も長い(1,346字)のに、呼び出し中央値が最小(21回)で合計時間も最小。C は42文字しか書いていないのに合計 248 時間です。

ただし正直に書くと、これは相関であって因果の証明ではありません。 平均では A=101、C=131 と差は小さく、A の最大値も 1,787 に達します。A は検証中心のタスク、C は実装中心のタスクという交絡が分離できていません。因果を言うには、同一タスクを完了条件あり/なしで実行する A/B が必要です。

自然実験: 時間制約を書いた区間と、撤回した後

もう少し因果に近い材料として、あるセッション内で同じ作業文脈のまま時間制約が付き、直後に撤回されている区間がありました。

区間 指示(抜粋) 呼び出し 経過時間
9 「…承認します。30分以内に終わらないと、このジョブの意味がありません。 90 49分
10 30分で終わらなくていいです。 有料のクラウド配備を許可します」 5 11分
18 「全ての残タスクをリストアップして、実装プランを作成して保存」 246 171分
25 「残タスクをリストアップ…全ての残タスクを実装してください」 167 348分
31 「…7日で終了でOKです。 全ての残タスクを実…」 728 244分
32 (区間25と同一文言の再送) 322 236分
  • 時間制約を書いた区間9は 49分で決着
  • 撤回した直後から、区間あたり 171〜348 分へ拡大
  • 時間枠を「7日」へ広げた直後(区間31)が最大の 728 呼び出し

ただしここにも交絡があります。 撤回と同時に「有料の配備を許可」しており、作業内容そのものが重くなっています。単独では因果の証明になりません。

とはいえ、上限値の宣言が消費量を規定していることの傍証にはなると思っています。ちなみに同じセッションで、私は turn 1024 に「30分以内に終わらないと意味がありません」と書き、turn 1214 で「30分で終わらなくていいです」と撤回しています。時間超過は当時から体感でも問題になっていた、という記録でもあります。

削ってはいけないものもある

時間短縮のために品質ゲートを外したくなりますが、データはそれを支持しませんでした。

件数 呼び出し中央値 LLM時間合計
敵対的レビュー指示あり 209 35 99 h(全体の15.2%)
なし 1,119 35 551 h

中央値はどちらも 35 回で、まったく同じです。 敵対的レビューは時間の主因ではありません。削るべきは「無限定スコープ」のほうです。

3つ目の欠落: 「完了が観測できない」

完了条件がないと、スコープだけでなく完了の可視性も壊れます。

あるセッションでの私の発話です。

「現在の作業状況を教えてください。処理が止まっているように見えるので、知りたいのです。

同じターンでのエージェントの応答。

「処理はハングしていません。統合検証が完了し、main への反映直前の安全な停止地点です。

エージェントは正しく停止していました。停止したことが私に伝わっていなかっただけです。

完了条件がないと「終わった」が宣言できない。だから私は待ち続けて、確認のための新しい指示を出し、それがまた数百呼び出しを起こす。「作業状況を教えてください=3,670 呼び出し」は、この構造の産物でした。

対照的に、完了条件を書いたときの報告はこうでした。

「指定ファイルに保存 / 658行・49,577 bytes / SHA-256 取得済み / 160/203完了、43 task 残り」

検証可能な単一の事実に着地しています。 成功パターンは既に自分の履歴の中にありました。再現できていなかっただけです。

完了条件は、誰が設計すべきか

「完了条件をエージェントに考えさせるのは合理的か」という論点があります。ここは3つに分解すると整理できます。

構成要素 内容 決定主体 理由
① 受入基準 何をもって価値があるとするか 人間 要求そのもの。エージェントが持っていない情報
② 停止規則 時間上限・試行回数・スコープ上限 人間が確定/エージェントが既定値を提案 上限値自体が価値判断
③ 判定手順 どのコマンドの exit code を見るか エージェントに委譲するのが合理的 コードベース固有の知識が必要で、人間が書くと時間がかかる

決定的なのは、基準を作る主体と、合否を判定する主体を分離することです。

これは抽象論ではなく、自分のデータに根拠があります。非ターミナル発話 1,629 件のうち 577件(35.4%)に「捏造は絶対に禁止」 が入っていました。つまり、完了申告がすでに信用されていない。 しかもこのリポジトリには、偽 PASS を防ぐための資産が既に存在します。過去に実際に起きているということです。

エージェントに①②③すべてを作らせ、合否も判定させる設計は、この不信の原因を制度化することになります。正しい分離は「人間でもエージェントでもなく、コマンドの exit code が判定する」です。そうすると「捏造は絶対に禁止」を毎回書く必要自体がなくなります。

コスト面でも明快です。完了条件の提案は「10呼び出し未満」の作業で、実測平均は 1.2 分。対して 1,000 呼び出し超の指示は平均およそ 400 分。提案と承認に2分払って 400 分の暴走を防ぐ比率なので、ここは迷う余地がありません。

目的と衝突していた、自分の定型文

最後に、複数セッションで繰り返し使っていた一文を晒しておきます。

「タスクの粒度は、各タスクの実施時に成果物の品質を最大限高めるために、タスクを詳細に分析して、タスクを分割します。」

これは目的関数が「品質の最大化」になっていて、停止点を持っていません。 1〜2時間で終わらせたいなら、完了条件は「品質の上限」ではなく 「品質の下限+時間の上限」 として書く必要があります。

書き換えるならこうです。

「タスクの粒度は、各タスクが60分以内に、定義された検証コマンドで PASS を確認できるように分割します。品質はその検証を満たす最小限で足り、超過分は backlog に回します。」

この一行の置換が、単体でいちばん効く可能性があると思っています。


ここまでの整理

長くなったので、一度まとめます。

良い点(測ってみて分かった、明確に効くこと)

  • 時間を食っているのは少数のセッションと少数の指示。 8時間超の18.2%が総時間の73.6%、200呼び出し超の13.2%が推論時間の65.8%。全部を直す必要はない
  • フォルダ階層の修正だけで、検証系 Skill 13件が有効になる。 数分の作業で、共通指示が前提としていた手順が初めて機能する
  • 完了条件の2行(判定コマンドと上限)は、提案1.2分で400分の暴走を防ぐ比率
  • 成功パターンは既に自分の履歴の中にある。 完了条件を書いたときの報告は、実際に検証可能な事実に着地していた

注意点(そのまま一般化してはいけないこと)

  • n=1 の個人ログです。 組織の平均でも業界の傾向でもありません
  • 「合格条件を書いた指示は安い」は相関であって因果ではない。 タスク内容の交絡を分離できていません
  • 時間制約を書いた区間が短く済んだ自然実験にも交絡があります。 撤回と同時に作業内容自体が重くなっていました
  • アイドル時間には、長時間コマンドと人間の離席が混在しています。 分解できていません
  • 承認は安全機構です。 時間短縮のために無差別な自動承認をするのは、方向として違います

限界(今回測れなかったこと)

  • reasoning effort 別の遅延比較(記録列がない。A/B が必要)
  • compaction の実施有無(「されていない」のか「記録されていない」のか判定不能)
  • サブエージェントの計装(イベント0件だが、計装欠落の可能性を排除できない)
  • ツール個別の実行時間(開始イベントがないため、227回の内訳を時間で分解できない)
  • オーバーエンジニアリングの直接測定。 「その作業が不要だった」ことは履歴からは判定できません。成果物のうち最終的に破棄された割合を別途追跡する必要があります

まとめ: まず何をするか

万能の解決策はありませんし、この記事の内容も私の環境での測定結果にすぎません。実務では、リポジトリの構成やチームの承認フロー次第で話が変わることが多いと思います。

そのうえで、私が明日から変えるのは次の3つです。

1. Skill のフォルダ階層をフラット化する

数分で終わります。共通指示が前提としている検証手順が、初めて実際に機能するようになります。効果測定として、同種タスクの1指示あたり呼び出し数(現状112.8回)を再測定するつもりです。

2. 「90分ルール」と「完了条件必須」を適用する

  • 90分経過した/成果物が1つ完成した/同じ質問を2回した、のいずれかで新しいチャットを開く
  • 引き継ぎは会話ではなくファイルで行う(完了したこと/残タスク/次の一手だけ)
  • 「全ての残タスクを実行してください」は使わない

「同じ質問を2回した」を条件に入れているのは、それがエージェントが文脈を見失った兆候だからです。実測で Try Again が81件ありました。

METR の研究では、AI の成功率は人間所要時間の長いタスクほど下がることが示されています51セッションを短く切ることは、成功率が高い領域に留まる操作だと理解しています。

3. 長い出力のコマンドをファイル経由にする/実行を委譲する

ユーザー側入力の95%を占めるターミナル通知を、会話から追い出します。長い出力は必ずファイルへリダイレクトして必要行だけ読む。テストは最小 verbosity を既定にする。実行は専用のサブエージェントへ委譲して、要約だけを本文脈へ戻す。

Anthropic は「サブエージェントは数万トークンを使って探索し、1,000〜2,000トークンの要約だけを返す」設計を推奨しています6。ただし同社は「マルチエージェントはチャットの約15倍のトークンを使う」「コーディングタスクは調査タスクほど並列化できない」とも書いています。無条件の並列化ではなく、「調査と実行の隔離」が目的です。私の指示の27.2%が「並列」を要求していましたが、あれは時間短縮の意図でした。設計し直す必要があります。

そのあとに効いてきそうなこと

上の3つが片付いたら、次はこのあたりだと考えています。いずれも効果は試算なので、前提を併記します。

モデルのルーティングを決める。 同一コンテキストで 2.56 倍の遅延差がある以上、用途で切り替えるべきでした。

用途 目安 実測平均遅延(14日窓)
調査・要約・ファイル読み 軽量/小型モデル 10.7秒 / 1.4秒
通常の実装・編集 高速モデル 14.4秒
難所の設計判断・根本原因分析 高性能/最新世代 18.8秒 / 36.9秒

最新世代モデルを既定にしない、というだけの話です。試算として、最新世代の call の半分を高速モデルへ置き換えると、14日窓で 218.5h → 約151.9h。およそ66時間(全体の21%)の短縮になります。前提は「call 数と成功率が変わらないこと」で、ここは当然検証が必要です。

コンテキスト予算を 100k トークンに設定する。 100k 超の call が 62.5%、遅延の 83.2% を占めている以上、ここが本丸です。仮に全 call を 50–100k 帯(平均13.0秒)に収められたとすると、14日窓で 181.7 時間。実測 312.6 時間に対し 41.9% 削減の計算になります。手段は上の1〜3とほぼ同じです。

承認待ちを減らす。 アイドル比率が 26〜98%、最大ギャップ 61 時間という実測がある以上、ここは無視できません。ただし承認は安全機構です。 読み取り系(git status、テスト実行、ファイル一覧など)だけを auto-approve の allow-list に入れて、破壊的操作や課金を伴う操作は明示承認のまま残します。無差別な自動承認は、方向として違うと思っています。

固定オーバーヘッドの棚卸し。 SKILL.md 128件、プロンプト資産 323ファイル。本体は遅延読み込みでも、description は全件が常時載ります。使っていないものを整理する。1トークンの削減が全 call に効くので、レバレッジとしてはここが最も高い場所です。

目標値

全部やったときに、どこまで戻したいか。

指標 現状(実測) 目標
セッション実時間の中央値帯 2〜4時間 30分〜2時間
8時間超セッションの比率 18.2% 0%
1指示あたり LLM call 112.8回 30回以下
1指示あたりツール call 226.7回 60回以下
平均入力トークン/call 100k〜240k 100k未満
平均 call 遅延 22.4秒 13秒以下

達成できるかは分かりません。ただ、目標を数値で置いておかないと、改善したかどうかも測れないので。

人間が毎回書くのは、この2行だけにする

完了条件: <検証コマンド> が exit 0 / または <ファイル> に <何> が存在すること
上限: 60分・タスク3件まで。超えたら停止して、完了分と未着手分を報告

検証コマンドを具体的に何にするかは、エージェントに提案させます。人間は承認するだけです。


最後に。今回いちばん効いたのは、新しいツールでも新しいモデルでもなく、自分の作業ログを SQL で叩いたことでした。

心当たりが5つあって、当たっていたのは1つ半。外れていた仮説(マシンのリソース)に投資していたら、何も改善しなかったはずです。

同じような「なんか遅い気がする」を抱えている方は、まず自分のログを1回集計してみるのが早いと思います。まずはそこまでで十分です。


出典

一次データ(本記事で実行した測定)

# 内容 取得方法
D1 セッション時間分布・所要時間・ターン数 セッションストアの sessions テーブルへの SQL 集計(45日窓)
D2 LLM 呼び出し回数・遅延・トークン events テーブルの usage 系イベント
D3 ツール実行成否 events テーブルのツール完了イベント
D4 発話種別・プロンプトパターン turns テーブルの分類と文字数集計
D5 compaction / subagent の有無 該当テーブル全件カウント(0行)、イベント種別の全種集計
D6 Skill 配置とロード状況 ローカルの再帰検索と、システムプロンプト掲載一覧との突合
D7 ローカルマシン資源 Get-CimInstance / Get-Process / Get-PSDrive
D8 reasoning effort の運用実態 ワークスペースのタスク定義
D9 指示1件あたりのコスト events を指示メッセージ位置で区切ってセグメント化し、セグメントごとに集計(1,328セグメント・650時間)

外部文献

  1. Anthropic Applied AI Team, "Effective context engineering for AI agents", 2025-09-29. https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents (閲覧 2026-09-18)— context は有限資源で限界効用は逓減する/compaction・structured note-taking・sub-agent の3手法/tool result clearing は最も安全で軽量な compaction/肥大したツールセットは最も一般的な失敗モード 2 3

  2. Hong, K., Troynikov, A., Huber, J., "Context Rot: How Increasing Input Tokens Impacts LLM Performance", Chroma Technical Report, 2025-07-14. https://www.trychroma.com/research/context-rot (閲覧 2026-09-18)— 18モデルで、タスク難易度を一定に保ったまま入力長のみを変化させても性能が単調に劣化することを実証 2 3

  3. Liu, N. F. ほか, "Lost in the Middle: How Language Models Use Long Contexts", TACL 2023, arXiv:2307.03172v3. https://arxiv.org/abs/2307.03172 (閲覧 2026-09-18)— 関連情報が中間にあると性能が大きく劣化する 2

  4. Visual Studio Code Documentation, "Use Agent Skills in VS Code"(更新日 2026-09-16). https://code.visualstudio.com/docs/agent-customization/agent-skills (閲覧 2026-09-18)— プロジェクトSkillの保存場所/name は親ディレクトリ名と一致する必要がある/3段階の progressive disclosure/context: fork によるサブエージェント実行 2

  5. Kwa, T., West, B., Becker, J. ほか, "Measuring AI Ability to Complete Long Software Tasks", NeurIPS 2025, arXiv:2503.14499v4. https://arxiv.org/abs/2503.14499 (閲覧 2026-09-18)— 50%-task-completion time horizon の提案

  6. Hadfield, J. ほか, "How we built our multi-agent research system", Anthropic, 2025-06-13. https://www.anthropic.com/engineering/multi-agent-research-system (閲覧 2026-09-18)— スケーリング規則のプロンプト埋め込み/サブエージェントの要約返却/マルチエージェントは約15倍のトークン消費/コーディングは調査ほど並列化できない

2
1
1

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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?