dsh agent loop とは?1ターンの流れを解説

入力の受け付けから turn/end まで:ターンのライフサイクル、プラグインのフックポイント、loop と subagent・Agent Teams の違い、そして暴走を防ぐ loop guard。

最終更新: 2026-10-03

ターミナルでも、Web UI でも、デスクトップアプリでも、dsh の会話を動かしているのは同じエンジン:agent loop です。あなたのメッセージを受け取り、モデルに次の一手を問い合わせ、モデルが選んだツールを実行し、このターンに「貸し」がなくなるまで繰り返す——それがループの正体です。モードやプラグイン、サブエージェントの解説を読んだあとで「入力と応答の間で実際に何が起きているのか」を知りたい人向けの、その仕組みを解説するページです。

このページの内容はすべて公式アーキテクチャドキュメントと公開ディスカッションに基づきます。出典は本文とページ末尾にリンクしてあり、ドキュメントが使うイベント名はそのまま使っています。バージョンに関わる挙動は公式 changelog を優先してください。

要点だけ

  • ▸step はモデルへの 1 回のリクエストと、それが呼ぶツール。turn は 0 個以上の step で、入力を受け取るときに開き、やるべき処理が尽きた時点で閉じます。
  • ▸agent loop 自体もプラグインです(既定のドライバーは core/agent-loop)。すべての段階がイベントであり、ほかのプラグインから割り込めます。
  • ▸ウォーターフォール型イベント(agent/pre-step、agent/request、llm/stream、tools/*)ではリスナーが next() を呼ぶ必要があります。agent/turn-stopping は turn を止められます。
  • ▸subagent と Agent Teams は loop の中ではなく上にあります。loop の暴走はほぼプラグイン設計の問題で、コミュニティに確立した guard パターンがあります。

agent loop とは何か、何でないか

DeepSeek Harness は Cordis というプラグインフレームワークの上に立っています。サービス、型付きイベント、巻き戻し可能な副作用が、ひとつの共有コンテキストに集約される構造です。公式ドキュメントははっきり言います——このプロダクトのすべての部分がプラグインであり、モデルアダプタ、ツールレジストリ、セッションログ、そして agent loop 自体も例外ではない、と。core/agent-loop は Agent インターフェースを実装する既定のドライバーで、設定から差し替え可能です。

このページで覚えるべき定義は 2 つだけ。どちらも公式の turn flow ドキュメントからの引用です:

Turn(ターン)

0 個以上の step。turn は最初の入力が受け取られる前に開き、やるべき処理が尽きたところで閉じます。

Step(ステップ)

モデルへの 1 回のリクエストと、それが呼ぶツール。ツールの往復が 3 回あれば、1 つの turn の中に 3 つの step があるだけです。

Agent loop

step のサイクルを繰り返すドライバー:入力を受け取り、プロンプトを組み立て、モデルを呼び、ツールを実行し、次の step が必要か判断します。

1 つのターンのライフサイクル

公式ドキュメントは turn のイベント列をそのまま公開しています。下の図を上から順にたどってください。等幅ラベルはすべてドキュメント上の実際のイベント名、つまりプラグインを書くときにリッスンする名前です。

  1. 1

    turn の開始

    永続化
    turn/start

    turn/start が発火し、ループは inbox から次のステップ入力とキューされたメッセージを 1 つ受け取ります。注入されたコンテキストは、次の入力メッセージが来てはじめて効力を持ちます。

  2. 2

    プロンプトとツールの組み立て

    プロンプトセクションとツールスキーマを組み立て、ランタイムコンテキストを投影します。モデルが見る履歴の源はセッションログであり、メモリ上の一時的な配列ではありません。

  3. 3

    入力のゲート

    agent/pre-step

    agent/pre-step のリスナーは、受け取ったメッセージを書き換えたり拒否したりできます。ここが最初のウォーターフォールです。全リスナーが next() を呼んでチェーンを続ける必要があります。

  4. ↳

    拒否されれば turn は閉じる

    turn/end

    メッセージが拒否された場合、または最初の enter が空に書き換えられた場合、turn は step ゼロのまま永続化されて閉じます。

  5. 4

    1 つの step:モデルリクエスト

    step/start · llm/stream

    step/start のあと、agent/request が実際のルートを解決し、リクエストはログから導出・凍結され、応答は llm/stream を通じてストリーミングされます。

  6. 5

    ツールパイプライン

    永続化
    tools/pre-execute → execute → post-execute

    各ツール呼び出しは tool/call → tools/pre-execute → tools/execute → tools/post-execute → tool/result というガード付きのチェーンを通ります。失敗した step は欠けたツール結果を記録します。

  7. 6

    次の step はあるか

    step/end

    step/end のあとループは判断します。ツールがもう 1 回のリクエストを必要とするか、新しい入力が届いていれば、次の step を受け取りサイクルを続けます。

  8. 7

    停止チェック

    agent/turn-stopping

    agent/turn-stopping は next() を持たない逐次イベントです。ここでリスナーは turn を止められます——公式ドキュメントに明記された turn への割り込み機構です。

  9. 8

    turn の終了

    永続化
    turn/end

    やるべき処理が尽きたところで turn/end が発火します。turn/*、step/*、メッセージイベント、tool/* は永続的なセッションイベントで、再起動後も残ります。それ以外はライブな拡張ポイントです。

覚えておきたい点が 2 つ:step 内のリトライはプロンプト組み立てと agent/pre-step をやり直しません。「モデルに見えるものはログに残る」(model-visible means logged)が硬いルールです——すべてのモデルリクエストはセッションログから完全に再構成できなければなりません。

プラグインはどこで loop にフックするか

公式ドキュメントに「hook」という言葉は出てきません。公式の用語はイベントで、その大半はウォーターフォール型です。リスナーはコンテキストを受け取り、next() を呼んで委譲する義務を負い、委譲前にペイロードを書き換えることもできます。重要なのは 4 系統で、agent.inject() が loop の外からモデルに見えるコンテキストを注入する公式の入口です:

入力を検査する:agent/pre-step

ループが受け取ったばかりのメッセージを書き換え・拒否します。この step がどの入力を受け入れるかをここで決めます。

モデル呼び出しに割り込む:agent/request、llm/stream

モデル呼び出しのストリーミング前に観察・改変できます。この段階でのキャンセルは、システムプロンプトもユーザーメッセージもコミットしません。

すべてのツールを包む:tools/pre-execute、tools/execute、tools/post-execute

各ツール呼び出しを囲むガード付き実行パイプライン。承認・ログ・ポリシー系プラグインの標準的な設置場所です。

turn を止める:agent/turn-stopping

逐次実行、next() なし。ここで停止判定を返せば turn は終わります。loop guard 系プラグインが頼るのがこのイベントです。

プラグイン開発ガイド.

agent loop・subagent・Agent Teams の違い

「dsh agent swarm」系の検索語は、異なる 3 つのレイヤーを混ぜがちです。それぞれを loop に紐づければ、もう混同しません:

agent loop

1 エージェントのエンジン。このページの turn・step・イベントの話は、1 つの loop が 1 つのセッションを駆動する話です。

Subagent(サブエージェント)

あなたのエージェントが生み出す第 2 層のエージェント実体。公式は subagent プロバイダを 1 つのインターフェースの背後に定義します——「まっさらな子エージェントから、別製品に委譲された turn まで」。各 subagent は自分自身の loop を回します。

Agent Teams(実験的)

公式のオプトイン調整シーム:永続ロスター、タスクボード、メールボックスを、継続可能な subagent の上に重ねたもの。個々の loop の上にある調整レイヤーです。

「Swarm」

多エージェント構成を指すコミュニティの通称で、dsh の公式機能名ではありません。協調がアドホックか構造化かで、それぞれ subagent と Agent Teams に対応付けて読みましょう。

サブエージェントガイド.

loop の暴走と loop guard

loop は終わるように設計されています。turn はやるべき処理が尽きたところで閉じ、agent/turn-stopping はリスナーが止められるために存在します。だから暴走の原因はほぼ常に「loop に流れ込むもの」側、つまり入力を注入し続けるプラグインにあります。

最も丁寧に記録された事例が公式ディスカッション #4819 です。コミュニティプラグインの dsh-agent-loop は、モデルが推論だけを出して可視テキストを返さないとき、notice メッセージを注入してループを続行させていました。ところが注入されたメッセージに message id がなく、コールドリストア時にセッションログの検証が失敗(「session event lacks an identified message」)、セッション全体が開けなくなったのです。そこで議論された修復方針がそのまま標準の guard セットです。合成メッセージは通常の createUserMessage 経由で流し、しかも append の時点でイベント形状を検証する——リストア時の検証だけに頼らない、ということです。

  • ▸周回数の上限——ターンごとのラウンド制限は、あらゆる loop guard 設定の最初の不変量です。
  • ▸無進展の検出——連続 2 step で何も変わっていなければ、続けずに止めます。
  • ▸同エラーで遮断——同じエラーが 2 回出たらサーキットブレーカーを落とす。トークンを燃やすリトライ嵐より安く済みます。
  • ▸明示的な出口を残す——loop には、いつでも人間から見える退出方法が必要です。

コンテキスト圧縮ガイド.

よくある質問

dsh agent loop についての短い回答です。詳細は本文にあります。

dsh の agent loop とは、ひとことで何ですか?

既定のドライバー core/agent-loop のことです。入力をモデルリクエストとツール呼び出しに変換し、turn に残った処理がなくなるまで step を繰り返します。

turn と step の違いは何ですか?

step はモデルへの 1 リクエストと、それが呼ぶツールです。turn は 0 個以上の step——入力を受け取るときに開き、やるべき処理が尽きたところで閉じます。1 つの turn に多数の step が入ることもあります。

プラグインはどうやって agent loop にフックしますか?

イベント経由です。agent/pre-step が入力のゲートを務め、agent/request と llm/stream がモデル呼び出しの前後で働き、3 つの tools/* イベントがツール実行を包み、agent/turn-stopping が turn を止めます。ウォーターフォール型リスナーは next() を呼ぶ必要があります。

agent loop・subagent・Agent Teams、どれが必要ですか?

1 セッション分の仕事には loop だけで足ります。独立したコンテキストが要るタスクなら subagent(自分の loop を持ちます)。複数エージェントでロスター・タスクボード・メールボックスを共有したくなったら Agent Teams です。

agent loop が暴走することはありますか?どう防ぎますか?

loop 自体はやるべき処理が尽きれば終わりますが、入力を注入し続けるプラグインが生かし続けることはあります。公式ディスカッション #4819 が実例です。標準の guard は、ラウンド制限・無進展の検出・同エラー遮断・明示的な出口の 4 点です。

loop を理解する前に Cordis を学ぶ必要はありますか?

ありません。turn フローはそれだけで読めます。イベント名と順序が分かれば大半のプラグインは書けます。Cordis が本当に要るのは、loop ドライバー自体の差し替えのようなサービス置き換えです。

続きを読む

loop と同レイヤー、あるいは loop を使うガイド:サブエージェント、モード、プリセット、コンテキスト圧縮。

出典と根拠

このページの仕組みは、公式アーキテクチャドキュメント・ディスカッション #4819・v0.2.1-alpha.1 リリースノートに基づきます。バージョンに関わる挙動は公式 changelog を優先してください。Loop Guard の不変量はコミュニティのプロトコルです。

DSH Plugins は DeepSeek Harness プラグインの独立したコミュニティ ディレクトリです。DeepSeek との提携・公認はありません。サードパーティ製プラグインはセキュリティ監査を受けていません。インストール前にソースコードをご確認ください。

DeepSeek Harnessの新着プラグインを毎週お届け。スパムはありません。