「ローカルAIでエージェントを動かす」と決めたあと、実際に効いてくるのはループの作り込みです。エージェントとは要するに、AIが自分でツールを選び→実行し→結果を見て→次を決める——という多段ループ(足場)を回し続ける仕組み。この「ループをどう設計・運用するか」をループエンジニアリングと呼び、ローカルでは特有の勘所があります。この記事は、その勘所を同じループを3機種(RTX A6000 48GB / RTX4060ノート 8GB / Mac mini M4 16GB)で実測しながら、一次データで整理します。

結論(先に要点)

  • ループの「成否」は機材に依存しない——同じモデルなら、速い機材でも遅い機材でも到達できる答えは同じ。3機種すべて連鎖3/3成功・同一7ターンでした。
  • 機材で変わるのは「総実時間(レイテンシ×ステップ)」だけ。同じ7BループがA6000で11秒、Mac mini M4で26秒。2.4倍の差。
  • tok/s(単発速度)は総実時間を予測しない。多弁なモデルは1トークンが速くても、トークンを吐きすぎてループ完了は遅くなる(実測でA6000・Mac両方再現)。
  • 安いゲーミングノート(RTX4060 8GB)がMac mini M4を逆転——7BがVRAMに収まれば専用GPUが効く。ただしVRAMに収まる範囲だけ
  • だからローカルのループ設計は、**「手数を減らす」「暴走を止める」「文脈を太らせない」「モデルを常駐させVRAMに収める」**が核になります。

「ループを誰が回すのか(人間か、コードか)」という大前提はエージェント能力はチャット能力と別物で論じています。本記事はその実装・運用編です。

ループエンジニアリングとは

エージェントのループは、ざっくり4工程の繰り返しです。

  1. 観測(observe): いまの状態・前のツール結果を読む
  2. 計画(plan): 次に何をするか決める(どのツールを呼ぶか/もう答えるか)
  3. 実行(act): ツールを呼ぶ(ファイル操作・検索・計算など)
  4. 検証(verify): 結果が妥当か確かめ、ダメなら別手を試す
ループエンジニアリング ― AIが回す4工程を、足場(コード)で制御する

観測

状態・前の結果を読む

計画

次の一手を決める

実行

ツールを呼ぶ

検証

妥当か確かめる

④検証 → ①観測 へ繰り返し、ゴールに達したら終了(↺ ループ)

この4工程を回す「足場(コード)」の制御点

  • 停止条件(暴走ガード)
  • リトライ(エラー回復)
  • 文脈管理(刈り込み)
  • 承認ゲート(重要操作)

チャットは②〜④を人間が毎ターン手で回す。エージェントは足場+モデルで自動化する。足場の出来が、モデル選びと同じくらい結果を左右する。

チャットは工程2〜4を人間が毎ターン手で回すのに対し、エージェントはコード(足場)+モデルで自動化します。つまりループエンジニアリングとは、この足場(停止条件・リトライ・文脈管理・承認ゲート)をどう書くかの技術です。モデル選びと同じくらい、足場の出来が結果を左右します。

【実測】同じループの総実時間を3機種で測る

「ローカルでエージェントを回すと、機材でどれだけ違うのか」を確かめるため、前の結果を次に使う依存連鎖タスク3本(天気2件→合算/検索→メール/加算→乗算)を、ツール結果を戻して次を呼ぶ本物のループで回し、最後までやり切るのにかかった壁時計時間を測りました。3機種とも同じqwen2.5:7b・同じ温度0です(計測コードは後述)。

マシンVRAM/メモリ総実時間ターン数生成tok/s連鎖成否
RTX A6000 ワークステーション48GB11.0s7110.63/3
RTX 4060 ゲーミングノート8GB19.9s752.23/3
Mac mini M416GB26.4s722.33/3

計測: 各機 ollama・temperature=0・依存連鎖3タスク。総実時間は自前のストップウォッチ(perf_counter)実測。生成tok/sはollamaの計測値(Mac版ollamaは稀に異常値を返すため、横断比較は壁時計を主指標にしています・要検証)。

同じ7Bループの総実時間(秒・依存連鎖3タスク・qwen2.5:7b・temp0・自前実測/短いほど速い)
  • RTX A6000 48GB11.0s
  • RTX 4060 ノート 8GB19.9s
  • Mac mini M4 16GB26.4s

成否は3機種とも同じ(連鎖3/3・同一7ターン)。変わるのは総実時間だけで、A6000とMac mini M4で約2.4倍差。初回モデル読込(コールドスタート)を含む。

ここから4つ、実測でしか見えないことが出ます。

発見1:成否は機材に依存しない。変わるのは時間だけ

3機種すべてが3/3成功・同一7ターン。これは当然で、同じ重み(モデル)なら、どのツールをどう呼ぶかは機材で変わらないからです。CPUが速かろうが遅かろうが、出てくる判断は同じ。機材選びは「賢さ」ではなく「速さ・容量」の問題——この切り分けがローカルのループ設計の出発点です(能力と実行性を分けて測る考え方は測定プロトコルに)。

発見2:tok/s(単発速度)は総実時間を予測しない

同じ3タスクを、より小さいqwen3.5:2bでも測ると——

モデルA6000 総実時間Mac 総実時間
qwen2.5 7B11.0s(7ターン)26.4s(7ターン)
qwen3.5 2B15.9s(9ターン)34.5s(9ターン)
① 単発の生成速度 tok/s(A6000・大きいほど“1トークンが速い”)
  • qwen3.5 2B171
  • qwen2.5 7B110.6
② 同じループの総実時間(A6000・短いほど速い)
  • qwen3.5 2B15.9s(9ターン)
  • qwen2.5 7B11.0s(7ターン)

2Bは1トークンこそ速い(①で長い)のに、多弁で約1,200トークン吐きターンも増え、ループ完了は7Bより遅い(②でも長い=低速)。総実時間=トークン量×ターン数×1トークンの時間。

小さい2Bの方が、ループ完了は遅いのです(A6000で1.4倍、Macで1.3倍)。2Bは1トークンこそ速い(A6000で171 tok/s)のに、多弁で1,200トークンも吐き、ターンも増えたから。総実時間を決めるのは単発のtok/sではなく、「トークン量 × ターン数 × 1トークンの時間」です。「小さい=速い」はチャットの直感で、ループでは逆転しうる。だからループ用のモデル選びは、単発ベンチではなく連鎖で測るべきです(function calling&連鎖の実測)。

発見3:安いノートGPUがMacを逆転する——ただしVRAMに収まる範囲で

総実時間の順は A6000(11秒)→ RTX4060ノート(20秒)→ Mac mini M4(26秒)7万円台のゲーミングノートのGPUが、Mac mini M4より速いのです。理由は単純で、7B(Q4=約4.7GB)が8GB VRAMに収まれば、NVIDIAの専用GPUが帯域で効く(52 tok/s)から。Mac mini M4のユニファイドメモリ(約22 tok/s)を上回ります。

ただし、これは「収まる範囲」だけの勝利です。8GBには14B級は載らず、はみ出した分はCPUにオフロードされて大幅に低速化します(経験則・要検証)。一方Macの16GBユニファイドメモリは、遅くてもより大きなモデルを載せられる。A6000の48GBは何でも常駐できます。「速いGPU」と「大きく載るメモリ」は別の軸で、ループに載せたいモデルサイズで最適解が変わります。手元の機材で「何が載るか・どのくらいの速さか」は動くか診断(用途を「AIエージェント」にすると総実時間とコストも)で即わかります。

発見4:コールドロードは毎ループの“税”

各機の内訳を見ると、最初のタスクだけ突出します(A6000: 8.2s vs 残り1.2〜1.7s/ノート: 11.6s vs 残り3.4〜4.9s)。これは初回のモデル読み込み(コールドスタート)。48GBのA6000は一度載せれば常駐できますが、メモリが小さい機材ほど、モデル切替や再読み込みのロード税が毎回効く。ループを頻繁に止めて別モデルに切り替える設計は、非力な機材ほど割に合いません。

タスク別の所要時間(秒・初回はモデル読込=コールドスタートを含む)
  • A6000 タスク1(初回ロード込)8.2s
  • A6000 タスク2・31.2〜1.7s
  • ノート タスク1(初回ロード込)11.6s
  • ノート タスク2・33.4〜4.9s

初回だけ突出するのはモデル読込(コールドスタート)。48GBのA6000は一度載せれば常駐できるが、メモリが小さい機材ほど再読込の“ロード税”が毎回効く。タスク2・3のバー幅は範囲の代表値で表示(数値は範囲を併記)。

実測から導く、ループ設計の7原則

上の数字は、そのまま足場(コード)の設計指針になります。

① 最大ステップ数の上限ガード(暴走を必ず止める)

ローカルは「課金ゼロ」でも、暴走ループは時間と電力を無限に食います。実際、別モデル(Qwen2.5 7B)は10都市を集計するタスクで平均206回もツールを呼び続けて終了不能になりました(深い連鎖の実測)。遅い機材ほど暴走の被害は深刻(1ステップが重い)。だからMAX_TURNSのような上限ガードは必須で、これはモデル選びと同じくらい効きます。

② 手数とトークンを最小化する

総実時間を支配するのはステップ数 × 1ステップの生成量(発見2)。だから——プロンプトで「まず計画を立ててから動け」と促して無駄なツール往復を減らす、ツールの説明文を明確にして一発で正しく呼ばせる、多弁なモデルには簡潔に答えるよう指示する。1ステップ削るのが、速いGPUを買うのと同じくらい効くこともあります。

③ 文脈(コンテキスト)を太らせない

ループはターンごとに観測結果が積み上がります。放置すると文脈窓を食いつぶし、低速化・破綻を招く。古い観測を要約・刈り込みする、ツール結果は必要な部分だけ戻す、長期記憶は外部(ファイル/DB)に逃がす——といったコンテキスト管理がループの安定性を決めます。

④ 検証ゲートと「重要操作の承認」

エージェントはファイル削除・送信・課金など強い操作を呼べてしまう。だから足場側で実行前の検証(引数のバリデーション)と、重要操作の人間承認ゲートを挟む。壊れたJSONより怖いのは「呼ぶべきでない時に呼ぶ」判断ミスで、これはスキーマ拘束よりツール説明の明確化+承認ゲートで効きます(構造化出力の実測)。

⑤ モデルを常駐させ、VRAMに収める

発見3・4の通り、オフロード(VRAM超過)とコールドロードは総実時間を激しく悪化させます。だから——ループに使うモデルはVRAMに収まるサイズを選ぶkeep_aliveで常駐させて再ロードを避ける、複数モデルの切替を最小化する。**「賢い大きいモデル」より「収まって常駐できるモデル」**がループでは速いことが多い。

⑥ エラー回復(諦めずに別手)

1ステップの失敗でループ全体を止めない。壊れたJSONはリトライ、ツール失敗は別手、を足場に組み込む。小型モデルでも、スキーマで縛り・バリデータで検査し・リトライを設計すれば信頼性は相当カバーできます。

⑦ 計測して回す(pNで考える)

1ステップの成功率が95%でも、20ステップ連鎖すれば 0.95²⁰ ≈ 0.36 まで落ちる——信頼性は掛け算で効きます(掛け算の効果)。だから手数を短く保ち、本番投入前に自分のタスクで連鎖を実測する。本記事の計測コードはそのまま流用できます。

再現手順(最短)

エージェントループは、ollamaの/api/chatツール結果をtoolロールで戻して次を呼ぶだけで作れます。骨子はこれだけです。

import json, urllib.request
OLLAMA = "http://127.0.0.1:11434"

def chat(model, messages, tools):
    payload = {"model": model, "messages": messages, "tools": tools,
               "stream": False, "options": {"temperature": 0}}
    req = urllib.request.Request(f"{OLLAMA}/api/chat",
            data=json.dumps(payload).encode(),
            headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req) as r:
        return json.load(r)

def run_agent(model, prompt, tools, exec_tool, max_turns=8):  # ← 上限ガード必須(原則①)
    messages = [{"role": "user", "content": prompt}]
    for _ in range(max_turns):
        msg = chat(model, messages, tools)["message"]
        calls = msg.get("tool_calls") or []
        if not calls:                       # ツールを呼ばなくなったら終了
            return msg.get("content", "")
        messages.append(msg)
        for tc in calls:                    # 観測→実行→結果を戻す
            name = tc["function"]["name"]
            args = tc["function"]["arguments"]
            result = exec_tool(name, args)
            messages.append({"role": "tool", "tool_name": name,
                             "content": json.dumps(result, ensure_ascii=False)})
    return ""                               # 上限到達=暴走を止める

本記事の3機種計測は、この骨子に総実時間とトークン数の記録を足した scripts/bench_loop_walltime.py(当リポジトリ)で行いました。python scripts/bench_loop_walltime.py qwen2.5:7b のように実行すると、総実時間 / ターン数 / 生成tok/s がJSONで出ます。まず手元の機材で、自分のタスクのループ時間を測ってみてください。

機材の選び方(ループ視点)

ループでは「単発の速さ」より「載るサイズ × 常駐 × 1ループの総実時間」で選びます。

最速・大容量で何でも常駐(開発・重い多段)— RTX A6000 48GB 48GBで32B級まで常駐でき、ループも最速。当サイトの基準GPUです。

Amazonで見る広告・Amazon 楽天で見る広告・楽天

効率と容量のバランス(16GBで余裕の常駐)— Mac mini M4 7BループはノートGPUに速度で譲りますが、16GBで大きめモデルも載り、SoCは省電力。常時稼働の開発機として有力(効率の実測)。

Amazonで見る広告・Amazon 楽天で見る広告・楽天

コスパよく始める(7B級が収まればMacより速い)— RTX4060クラスのGPU 8GB VRAMに収まる7B級なら、専用GPUが効いて総実時間で有利。ただし14B級は載らずオフロードで失速するので、用途のモデルサイズを先に決めてから。GPUの選び方はローカルAI向けGPUの選び方に、中古を含む価格帯ごとの整理があります。

Amazonで見る広告・Amazon 楽天で見る広告・楽天

機材×モデルの全実測値は検証DB(tok/s・電力・tok/s/Wでソート可)、手元で動くかは動くか診断で確認できます。

よくある質問

Q. ローカルでエージェント(ループ)は実用になりますか? A. なります。ツールを正しく呼ぶ土台は現代モデルなら十分で、成否は機材に依存しません(発見1)。実用性を決めるのは「総実時間が許容範囲か」と「足場(暴走ガード等)が組めているか」です。

Q. 速いGPUを買えばループは速くなりますか? A. 部分的にYes。ただし手数を1つ減らす方が効くこともあり(発見2・原則②)、モデルがVRAMに載るかで結果が逆転します(発見3)。まず自分のタスクで総実時間を測るのが先です。

Q. どのモデルがループ(エージェント)に向きますか? A. 単発の賢さではなく連鎖の安定性で選びます。総合比較はエージェント実用度スコアカード、作り方の全体像はローカルでAIエージェントを動かすへ。

まとめ

  • ループエンジニアリング=足場(停止条件・文脈管理・検証・常駐)の設計。モデル選びと同じくらい効く。
  • 実測では、成否は機材非依存/総実時間は機材で2〜3倍違う/tok/sは総実時間を予測しない/安いノートGPUがMacを逆転(収まる範囲で)
  • 設計の核は上限ガード・手数削減・文脈管理・VRAM適合・常駐。まず動くか診断と本記事のコードで、自分のループ時間を測ることから。

※ 本記事は機材の購入リンク(アフィリエイト)を含みます。掲載の総実時間・tok/s は当サイトの自前実測(各機 ollama・temperature=0・依存連鎖3タスク・各1回)。サンプルは小さく、温度・プロンプト・ollamaのバージョンで変動します(要検証)。総実時間には初回のモデル読み込み(コールドスタート)を含みます。モデルのライセンス・商用可否は一次情報での確認を推奨します。