DeepSeek Harness 能力の3つの役割:Definition / Provider / Consumer
公式ドキュメントには Service Definition、Service Provider、Consumer という3つの用語が頻繁に登場します。これらが合わさって、ある能力の seam、つまり置き換え可能な能力インターフェースを構成します。
この章では、3つがそれぞれ何であるか、そしてなぜ1つの能力を3つの役割に分けるのかを明確に説明します。
完全な能力がその seam を構成します。どの単一の役割も seam ではありません。
3つの役割はそれぞれ何か
ある能力が十分に汎用的で、置き換え可能な提供者(Provider)をサポートする必要がある場合(例:Bash 実行)、harness はその能力を3つの役割に分けます。
| 役割 | 担当内容 | Bash を例に |
|---|---|---|
| Service Definition インターフェース + 型 | Cordis サービス、およびリクエスト Request と結果 Result の型を定義する | dsh-shell(ctx.shell として登録) |
| Service Provider 実装 | その能力を実際に実装する。通常は1つの実行環境に特化する | dsh-bash-local(ローカル実行) |
| Consumer モデル向けツール | 能力をモデルが呼び出せるツールとして公開する | dsh-tool-bash(bash ツール) |
Service Definition は「どんな能力があり、どんな形か」を宣言するだけで、実装方法には関心を持ちません。
Service Provider は Definition の抽象クラスを継承し、具体的な振る舞いを実装します。
Consumer はモデル向けで、能力をツールスキーマに包み、モデルが呼び出せるようにします。
3つの役割は同じパッケージに置くことも、別々のパッケージに分けることもできます。
判断基準はただ1つ:これらの役割が独立して進化または置き換えられる必要があるかどうかです。
1枚の図でわかる seam の3つの役割
3つの役割はすべて Definition に依存しますが、Provider と Consumer は互いに依存しません。
図の点線枠が完全な能力、つまり seam です。
Definition は中央にあり、Provider と Consumer はどちらもそれにのみ依存します。
Provider は Definition を継承して実装し、Consumer はinject: ['shell']それを介して依存します。
Provider と Consumer の間には依存関係は一切ありません。
したがって Provider を交換するとき、Definition と Consumer は1行も変更する必要がありません。
Bash を例に:ctx.shell の3つの役割
Bash 実行は dsh の中で最も典型的な seam であり、3つの役割はそれぞれ専用のパッケージを持っています。
Service Definition は dsh-shell パッケージで、ctx.shell サービスとして登録されます。
それは Bash のリクエスト型を定義し、ShellExecRequest結果型も定義します。ShellRunResult。
Service Provider は dsh-bash-local で、ローカルコンピューター上でコマンドを実行します。
同じ Definition には他の Provider もあります。例えば dsh-bash-sandbox はサンドボックス内で実行し、dsh-pwsh-local は PowerShell を実行します。
Consumer は dsh-tool-bash で、能力をモデルが呼び出せる bash ツールとして包みます。
tool-bash は inject で ctx.shell への依存を宣言し、execute 内で ctx.shell.run(...) を呼び出します。
公式リファレンス「能力 Seam とコアサービス」は、ctx.shell の3つの役割の所在を1つの表で管理しています。
| ctx キー | 役割 | 所属パッケージ(Definition) | 実装(Provider) | 直接の消費者(Consumer) |
|---|---|---|---|---|
| ctx.shell | seam | shell | bash-local / bash-sandbox / pwsh-local | tool-bash / tool-pwsh / hooks-claude-code / hooks-codex |
消費者には、フックブリッジプラグインである hooks-claude-code と hooks-codex も含まれます。
それらは tool-bash と同じく、ctx.shell というインターフェースのみを認識し、背後でどの実行器が使われているかには関心を持ちません。
Bash seam では、モデル向けのリクエスト ShellExecRequest(workdir、timeoutMs は任意)と、実行器が実際に使用する完全に解決された仕様 ShellExecSpec(フィールドは必須)は分離されています。
ツール層はこの2つの間で ctx.shell.resolve(request) を呼び出します。これが「パッケージ境界では暗黙よりも明示を優先する」という原則です。
なぜ3つの役割に分けるのか
分割する最初の利点は、提供者(Provider)を交換できることです。
同じ Service Definition に複数の提供者を持たせることができ、cordis.yml で選択します。
実例
# ローカル実行
- name: '@deepseek-ai/dsh-bash-local'
# 提供者を変更したいときは、上の行を置き換えるだけでよい。
# 下の行に置き換えると、サンドボックス実行器に変更される:
# - name: '@deepseek-ai/dsh-bash-sandbox'
提供者を変更しても、Service Definition と Consumer はどちらも変更されません。
分割する2番目の利点は、3つの役割が独立して進化できることです。
| 役割 | 独立して進化する自由度 |
|---|---|
| Service Definition | 呼び出し側がその約束事に依存し始めると、ほとんど変更されない |
| Service Provider | パフォーマンスと安全性を独立して最適化できる |
| Consumer | 能力がモデルに提示される方法を調整できる |
分割する3番目の利点は、依存関係の分離(デカップリング)です。
Service Provider は Service Definition に依存します。
Consumer は Service Definition に依存します。
Service Provider と Consumer互いに依存しない。
| 依存関係 | 成立するか |
|---|---|
| Provider → Definition | である |
| Consumer → Definition | である |
| Provider → Consumer | 否 |
| Consumer → Provider | 否 |
実際に整理する:使用中の seam の3つの役割を特定する
公式リファレンス「能力 Seam とコアサービス」は、完全なサービス一覧を管理しています。
馴染みのある seam を1つ選んでください。例えば ctx.fs や ctx.llm など。3つのステップで整理できます。
最初のステップ:その Definition パッケージを特定します。つまり表の「所属パッケージ」列です。
2番目のステップ:その Provider パッケージを特定します。つまり表の「実装」列です。
3番目のステップ:その Consumer を特定します。つまり表の「直接の消費者」列です。
例えば ctx.llm の Definition は llm パッケージ、実装は llm-deepseek と llm-pi-ai、直接の消費者は agent-loop と compaction-basic です。
また、ctx.fs の Definition は fs パッケージ、実装は fs-local、fs-sandbox と fs-e2b、直接の消費者は tool-fs です。
この考え方に慣れれば、組み込みサービスを見たときに、それがどの役割に属するかを一目で見分けられるようになります。
まとめと自習テスト
一言でまとめると:能力は Definition(インターフェースと型)、Provider(実装)、Consumer(モデル向けツール)の3つの役割に分けられ、この3つが合わさって初めて seam になる、ということです。
自習テスト1:Bash 能力の Definition、Provider、Consumer はそれぞれどのパッケージに対応しますか?
自習テスト2:Bash の Provider を交換するとき、どのパッケージを変更せずに維持できますか?
自習テスト3:「どの単一の役割も seam ではない」のはなぜですか?
その他の拡張