はじめに:モデルより「外側」で差がつく時代に、DeepSeek が外側を丸ごと公開した
コーディングエージェントを毎日使っていると、「同じモデルなのに、道具が変わると出来が変わる」と感じる場面が増えてきました。モデルに何を見せるか、どの道具を渡すか、危ない操作をどこで止めるか、長い作業をどう引き継ぐか。こうしたモデルの外側の仕組みをまとめて「ハーネス(harness)」と呼びます。馬具の「ハーネス」と同じで、力のあるモデルを仕事の形に沿って動かすための装備です。
2026年9月末、DeepSeek がこのハーネスを DeepSeek Harness(略称 dsh) として世界向けに公開しました。MIT ライセンスのオープンソースで、Mac(Apple シリコン)と Windows のデスクトップアプリ、そして npx @deepseek-ai/dsh web だけで立ち上がる Web 画面が用意されています。合言葉は「Everything is a plugin(すべてがプラグイン)」です。
OpenAI も以前に Codex のハーネス(openai/codex)を公開しています。筆者は前回の記事「OpenAI が公開した Codex ハーネスで何ができる?」でその中身を調べました。そこで今回は、次の3つを確かめることにしました。
- DeepSeek Harness のリポジトリには、具体的にどんな部品と文章が入っているのか
- そのうち、手元の Claude Code や Codex の設定にそのまま持ち帰れる記述はどれか
- Codex のハーネスと比べて、設計の考え方はどこが違うのか
読み終えるころには、DSH を使うかどうかに関係なく、自分の CLAUDE.md・AGENTS.md・スキル・フックに足せる具体的な書き方が手元に残るはずです。Claude Code か Codex を日常的に使っていて、「ハーネスの中身」を一度は覗いてみたい人を想定しています。

図1:同じ「ハーネス」でも組み立て方が正反対です。左の Codex は1つの実行ファイルに機能をまとめ、右の DSH はループや UI まで差し替えられる部品として積み上げています。
この記事の確認範囲
| 項目 | 内容 |
|---|---|
| 確認日 | 2026年10月4日(日本時間) |
| DeepSeek Harness | GitHub deepseek-ai/deepseek-harness の HEAD 5badb15(2026-10-03、0.2.1-alpha.1)を読み、npm の @deepseek-ai/dsh@0.2.0-rc.2 を実行 |
| Codex | 前回記事で clone した openai/codex(HEAD ab84d71)と、手元の Codex CLI 0.159.2 |
| 実行環境 | macOS(Apple M5 Max・128GB)、Node.js 22.23 |
| 動かしたモデル | DSH 側は LM Studio のローカル Qwen3.8-27B(DeepSeek の API キーは使っていません)。Codex 側は普段の設定の GPT-6 Astra |
DeepSeek 公式モデルでの動作は確認していません。モデルが違うため、この記事の「速さ」や「賢さ」の数字はハーネスの比較ではなく参考値です。比べているのは、ハーネスが「何を見せ、何を記録し、どこで止めるか」という仕組みのほうです。
DeepSeek Harness とは:公式の説明を3行で
公式ページの見出しは「Ready to use. Right now.」です。日常の作業、コーディング、そして自分専用のハーネスづくりの出発点になる、という位置づけで説明されています。

公式ページ(deepseek.com/en/harness、2026-10-04 撮影)。デスクトップアプリの画面例では、Plugins と Automation がサイドバーの上位に置かれています。
公式ページと README から、要点を3つに絞ります。
- 用途はコーディングに限らない:文書の整理、表計算の分析、スライド作成、調べもの、バックグラウンドの定期実行まで、同じハーネスで扱います。
- すべてがプラグイン:モデル、道具、スキル、セッション、サンドボックス、保存先、エージェントのループ、スケジュール、UI まで差し替えられます。土台は Cordis というプラグインの仕組みで、設計は論文 A Programming Paradigm for Spatiotemporal Composability にまとめられています。
- Creator mode:エージェント自身にプラグインを書かせ、その場で DSH に機能を足せます。
README の冒頭には「developer preview(開発者向けプレビュー)で、互換性を壊す変更がある」と大きく書かれています。あわせて SAFETY.md では「セキュリティ監査を受けていない」「使い捨ての VM やコンテナで動かすことを勧める」と明記されています。業務の本番環境に入れる前提の道具ではなく、今は読んで学び、試して持ち帰る段階だと考えるのがよさそうです。

GitHub のリポジトリ(2026-10-04 撮影)。スター約24.3万・フォーク2.9万。赤枠の .agents と .claude は、開発チームが AI エージェントに読ませるためのフォルダです。この記事の後半で中身を使います。
数字で見ると、規模の大きさが分かります。筆者が clone して数えた値です。
| 項目 | DeepSeek Harness | Codex(前回記事の調査) |
|---|---|---|
| ライセンス | MIT | Apache-2.0 |
| 主な言語 | TypeScript(一部 Python・ネイティブ拡張) | Rust |
| 部品の数 | packages/ 配下に 319 パッケージ(54グループ) | codex-rs/ 配下に 117 crate |
| テスト | *.spec.ts が 1,916 ファイル | (前回記事を参照) |
| 文書 | 英語と中国語の2言語を対で管理 | 英語 |
| GitHub スター(10/4) | 約24.3万 | 約12.8万 |
全体像:Codex との違いは「中心に何を置くか」
Codex は本体に組み込み、DSH は層を重ねる
Codex のハーネスは、Rust の codex-rs/core にエージェントのループ、シェル実行、サンドボックス、承認、文脈の圧縮、記憶(memories)などを組み込んでいます。外から使うときは、app-server の JSON-RPC や codex exec --json という「口」を通します。設定で振る舞いは変えられますが、ループそのものを別物に差し替える口はありません。
DSH は逆です。中心にあるのは Cordis という「プラグインを読み込んで組み合わせる仕組み」だけで、エージェントのループ(dsh-agent-loop)すら1つのプラグインです。どのプラグインをどう組み合わせるかは「プロファイル」と呼ぶ YAML の重ね合わせで決まります。

図2:下から順に重ね、後の層が前の層を上書きします。筆者が設定画面で足したローカルモデルも、自分で足したフックの橋渡しも「④ あなたの層」に書き込まれました。
合成された結果は、次のコマンドでいつでも確認できます。筆者の Web プロファイルでは約1,300行・184個のプラグイン定義になり、各定義に「どのパッケージ由来で、どのファイルが上書きしたか」がコメントで付いていました。
# 合成後のプロファイル(実際に読み込まれるプラグイン一覧と設定)を表示する
npx @deepseek-ai/dsh web --dump-config | less
「ハーネスに何が入っているのか」を知りたいとき、この1コマンドで全部見えるのは教材として非常に便利です。Codex で同じことをするには、config.toml、[features] の既定値、ソースコードを行き来する必要がありました。
動かしてみる:API キーなしでも、ローカルモデルで試せる
起動と最初のつまずき
Node.js 22.19 以上が入っていれば、起動はコマンド1つです。試すだけなら、設定の保存先を DSH_HOME で別フォルダに分けておくと後片付けが楽になります。
# 試用の設定・セッションを ~/.dsh ではなく専用フォルダに保存する
export DSH_HOME="$HOME/dsh-trial"
# Web 画面を起動する(既定で http://127.0.0.1:3080 が開く)
npx @deepseek-ai/dsh web
起動すると「Preview Notice」に続いて「Add an API key to get started」という画面が出ます。DeepSeek の API キーを持っていればここに入れます。持っていない場合は「Configure later」で閉じ、Settings › Models › Add model provider › Custom model API から、OpenAI 互換や Anthropic 互換の API を足せます。Third-party の欄には OpenAI・Anthropic・Kimi などの一覧も用意されていました。
筆者は API キーを使わず、Mac の LM Studio で動かしている Qwen3.8-27B をつなぎました。
# LM Studio のサーバーを起動し、モデルを読み込む(LM Studio の CLI)
lms server start
lms load qwen/qwen3.8-27b -y
設定画面では Provider ID に lmstudio、Base URL に http://127.0.0.1:1234/v1、API protocol に「OpenAI Chat Completions」を選び、「Fetch available models」でモデルを取り込みます。

設定画面の Models。赤枠が筆者の追加した LM Studio です。DeepSeek の行の赤い点は「キー未設定」を表します。
ここで1つつまずきました。LM Studio はキーを確認しないのに、空欄のままだと No API key for provider: lmstudio で止まります。任意の文字(筆者は lm-studio)を入れると動きました。設定画面で足した内容は $DSH_HOME/profiles/web/cordis.patch.yml に YAML で書き込まれ、キーは .credentials.yaml に別保存されます。
補足:公式モデルは「DeepSeek-V41-Flash」と「DeepSeek-V4-Pro」の2つが選択肢に出ました。ソースを読むと、公式プロバイダーの接続先は
https://api.deepseek.com/anthropic、つまり Anthropic Messages 互換の API で、文脈の上限は100万トークンに設定されています。
エージェントの「型」を選ぶ
入力欄の上には、作業フォルダ(Workspace)と「エージェントの型」を選ぶメニューがあります。型は4つです。

型の選択メニュー。赤枠の Creator mode は「会話で DSH 自体を作り替える」型です。
| 型 | 何が違うか |
|---|---|
| Standard mode | 普段使い。検索・編集・端末・Web 検索など一通りの道具 |
| PTC mode | 道具を TypeScript のプログラムからまとめて呼ぶ型(PTC=Programmatic Tool Calling)。大量の結果を絞り込む作業向け |
| Minimal mode | 端末の道具だけ。モデルの素の実力を比べるとき用 |
| Creator mode | DSH 自身を調べる道具と、プラグインを入れる plugin_manager が加わる |
小さなバグを直させてみる
動きを見るために、料金計算の小さな Python プロジェクトを用意しました。クーポンの割引率を100で割り忘れたバグと、「5000円以上で送料無料」の境界を > で書いたバグの2つが入っていて、テスト4件中2件が落ちます。プロジェクトの AGENTS.md には次のルールを書きました。
# このリポジトリでの作業ルール
- テストは `python3 -m unittest discover -s tests -q` で実行する。修正のたびに全テストを通す。
- 変更は `src/` の中だけにする。`tests/` は書き換えない。
- 最後に、直した箇所と理由を日本語で 3 行以内にまとめる。
あわせて、仕様を書いたスキル(.agents/skills/coupon-rules/SKILL.md)も置きました。依頼文は「テストが2件失敗しています。原因を調べて直してください。」だけです。
録画(約34秒に編集。中盤は10倍速)。最初にスキル coupon-rules を読み、テストで失敗を再現し、src/pricing.py を2か所直して全テストが通るまでを自動で進めました。
結果は2分25秒で完了、テスト4件すべて合格でした。最後の報告は AGENTS.md の指定どおり日本語の3行で、「tests/ は未変更」とも書かれていました。ローカルの 27B モデルでも、ハーネスが用意する道具とルールの渡し方がしっかりしていれば、この規模の作業は通ります。
中身を見る:実行トレースで「モデルに何が届いたか」を確かめる
DSH の Web 画面には、チャットの隣に Trajectory(実行トレース) というタブがあります。ここが教材として一番価値のある画面でした。
システムプロンプトは短く、文脈は別のメッセージで渡す
Trajectory の先頭にある「Initial System Prompt」を開くと、モデルに渡したシステムプロンプトがそのまま読めます。

左の赤枠が「文脈(CONTEXT)」として渡された3つのメッセージ、右の赤枠がシステムプロンプトの冒頭です。
冒頭はたった2行です。
You are an AI agent powered by DeepSeek Harness.
You are a coding agent powered by the qwen/qwen3.8-27b model.
その後に「bash の結果では必ず [exit code: N] を確認する」「中身を見るのは cat ではなく read の道具で」「探すのは find ではなく glob の道具で」といった、道具ごとの短い注意が1〜数文ずつ並びます。全体で 5,785 字でした。Codex が未知のモデル向けに持つ既定の指示(prompt.md)は 20,903 バイトあり、こちらは「どう働くか」「計画の立て方」「進捗の伝え方」まで長い基本方針を書いています。

図3:DSH は、各文を「その事実を持つプラグイン」が登録し、番号順に並べます。AGENTS.md や権限の情報は system に混ぜず、別の user メッセージとして渡します。
ただし、DSH が「指示を少なくしている」わけではありません。同じリクエストで渡される道具26個の定義(JSON)は約2.1万字ありました。方針を system に長く書くのではなく、道具の説明の中に使い方を書く設計です。
この分け方には、DeepSeek らしい理由が README に書かれています。system の文面を変えると、API 側のキャッシュ(同じ前半部分を使い回して速く安くする仕組み)が先頭から効かなくなります。そのため DSH は、権限モードを切り替えても system は1バイトも変えず、新しい状況を履歴の後ろに追記します。plan mode の指示文にも「道具の一覧はキャッシュのためにモード間で同じに保つ」と明記されていました。
道具の一覧と、スキルの読み方
Trajectory の「Tools」タブでは、そのリクエストで渡した道具の一覧が見られます。

右の赤枠が Tools タブ、左の赤枠が最初に行った skill の呼び出しです。スキルは一覧(名前と説明)だけを先に渡し、本文は必要になったときに読みます。
ここで気づいたことがあります。最初に ~/.dsh を分けずに起動したとき、文脈メッセージのスキル一覧に、筆者が Codex 用に置いていた ~/.agents/skills のスキルが19個並んでいました。DSH はスキルを次の順で探します。
| 優先 | 場所 | 補足 |
|---|---|---|
| 1 | <プロジェクト>/.dsh/skills | DSH 専用 |
| 2 | <プロジェクト>/.agents/skills | Codex と同じ場所 |
| 3 | 設定 customSkillDirs | 任意 |
| 4 | ~/.dsh/skills | DSH 専用 |
| 5 | ~/.agents/skills | Codex と同じ場所 |
つまり、.agents/skills に置いたスキルは Codex と DSH の両方から読まれます。指示ファイルも AGENTS.md と CLAUDE.md の両方を探し、同じ内容なら1回だけ読み込みます。DSH は最初から「他のハーネスの資産を持ち込む」前提で作られているわけです。
ループの1周は、すべてログに残る
DSH の開発規約(AGENTS.md)で、筆者が一番感心した1行がこれです。
Model-visible ⟺ logged: anything that reaches a model request must be reconstructable from the session log. (モデルに届くものは、すべてセッションログから組み立て直せなければならない)

図4:ループの各段階で、何がログに書かれるかの対応です。実行トレース画面は、このログを読み直して作られています。
セッションは ~/.dsh/sessions/<フォルダ名>/<ID>/session.v4.jsonl.zstd に、zstd で圧縮した JSONL として保存されます。展開して数えると、先ほどのバグ修正は58行でした。system メッセージ、道具の定義、AGENTS.md などの文脈、道具の呼び出しと結果が、すべて別々のイベントとして並びます。
# セッションログを展開して、イベントの種類ごとに数える
zstd -dc ~/.dsh/sessions/*/session-*/session.v4.jsonl.zstd | jq -r .type | sort | uniq -c
Codex も ~/.codex/sessions/ に JSONL を残しますが、DSH は「新しい種類の入力を足すなら、新しいイベントを定義せよ」とまで規約にしています。後から「なぜこう動いたか」を調べられることを、仕組みの側で保証しているのです。
ターミナルから使う:codex exec と dsh headless
スクリプトや CI から使う口も比べました。同じプロジェクトをもう1つずつ用意し、同じ依頼を両方に渡しています。
# Codex:1回答えて終了。途中経過を JSONL で出す
codex exec --json -s workspace-write "テストが2件失敗しています。原因を調べて直してください。" < /dev/null
# DSH:同じく1回答えて終了。--json で途中経過を1行ずつ出す
npx @deepseek-ai/dsh headless --json "テストが2件失敗しています。原因を調べて直してください。"

左が Codex、右が DSH の出力(実際の出力を1行ずつ短く整形)。どちらもテスト4件が通り、tests/ は変更されていません。
どちらも修正は成功しましたが、出力の形はかなり違います。
| 観点 | codex exec --json | dsh headless --json |
|---|---|---|
| 行の単位 | 項目(item)が完了するたびに1行 | 思考・道具の呼び出し・結果・ステップ開始がそれぞれ1行 |
| 思考の中身 | 出ない(推論は暗号化して保持) | thinking として出る(モデルが返す範囲で) |
| 使った道具 | シェルのコマンドとファイル変更 | bash・skill・read・edit と道具名がそのまま出る |
| 最後の集計 | turn.completed に入力・出力トークン | final に最終回答の全文 |
| 今回の所要時間 | 43秒(GPT-6 Astra、入力 約11.5万トークン) | 106秒(ローカル Qwen3.8-27B) |
時間の差はモデルとマシンの差が大部分なので、優劣の材料にはなりません。注目したいのは、スキルの読み方の違いです。DSH は skill という専用の道具で coupon-rules を読み、それがログにもそのまま残りました。Codex も同じスキルを読みましたが、cat AGENTS.md .agents/skills/coupon-rules/SKILL.md … とシェルで読んでいます。また Codex は作業の前に、筆者のグローバル指示(共有ノートを読む)と memories(過去の会話から作る記憶)も確認していました。どちらのハーネスも、プロジェクトの外にある個人設定まで読むという点は、比較するときに意識しておきたいところです。
ここからが本題:Claude Code・Codex に流用できる書き方
ここからは、DSH のリポジトリから「自分の環境に持ち帰れるもの」を、実際の記述例つきで紹介します。全体の地図を先に示します。

図7:6つの持ち帰り先。どれも DSH を使わなくても効く書き方です。
DSH は MIT ライセンスなので、文章を流用するときは出典とライセンスの表示を残しておきましょう。また、DSH 固有の道具名(read・glob など)は、自分のハーネスの道具名に置き換えます。
流用1:指示書とスキルを「1か所に書いて、リンクで共有」する
DSH のリポジトリでは、CLAUDE.md が AGENTS.md へのシンボリックリンクになっています。packages/ の下にも同じリンクがあり、.claude/skills は ../.agents/skills を指しています。人間が編集するのは AGENTS.md と .agents/skills/ だけで、Claude Code はリンク経由で、Codex は本来の場所で読みます。
Claude Code と Codex を併用しているリポジトリなら、そのまま真似できます。
# 既存の CLAUDE.md を AGENTS.md に寄せ、CLAUDE.md をリンクにする
git mv CLAUDE.md AGENTS.md
ln -s AGENTS.md CLAUDE.md
# スキルも .agents/skills を正とし、Claude Code 用の場所をリンクにする
mkdir -p .agents/skills .claude
git mv .claude/skills/* .agents/skills/ 2>/dev/null
rmdir .claude/skills 2>/dev/null
ln -s ../.agents/skills .claude/skills
DSH の AGENTS.md の末尾には、エージェント自身に向けた次の一文もあります。
## Editing these instructions
`CLAUDE.md` symlinks `AGENTS.md` at root and `packages/`; edit the real file.
リンクの存在をエージェントに知らせておくと、リンク先ではなく「本物」を編集してくれます。日本語で書くなら「CLAUDE.md は AGENTS.md へのリンクです。編集するときは AGENTS.md を直接直してください。」で十分です。
流用2:Claude Code のフックを、DSH でもそのまま動かす
DSH には dsh-hooks-claude-code と dsh-hooks-codex という橋渡しのプラグインがあり、Claude Code や Codex の hooks.json を書き換えずに読み込めます。実際に試しました。
まず、Claude Code 用に危険なコマンドを止めるフックを書きます。
#!/bin/bash
# .claude/hooks/guard-bash.sh
# PreToolUse フック。実行予定のコマンドが危険なら exit 2 + 標準エラーで止める
cmd=$(python3 -c 'import json,sys; print(json.load(sys.stdin).get("tool_input",{}).get("command",""))')
if echo "$cmd" | grep -Eq 'rm -rf|git push|git reset --hard'; then
echo "このリポジトリでは「$cmd」は禁止です。消したいファイル名を挙げて、人に確認してください。" >&2
exit 2
fi
exit 0
次に、DSH のプロファイルにプラグインを入れて、hooks.json の場所を指定します。
# 本体と同じ版を明示してインストールする(理由は後述のトラブル対処を参照)
npx @deepseek-ai/dsh plugin --profile web add -w @deepseek-ai/dsh-hooks-claude-code@0.2.0-rc.2
# $DSH_HOME/profiles/web/cordis.patch.yml に追記
- insert:
- id: hooks-claude-code
name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: /path/to/project/.claude/hooks.json # 相対パスは起動したフォルダ基準になる
projectDir: /path/to/project
ここで、README を読むだけでは気づきにくい落とし穴がありました。

図6:Claude Code のシェル道具は Bash、DSH は bash。英数字だけの matcher は完全一致として扱われるため、"Bash" のままでは DSH 側で発火しません。
Claude Code で普通に書く "matcher": "Bash" のまま DSH を動かすと、bash で echo hello を実行してもフックのログは0行でした。橋渡しのコードを読むと、Bash のように英数字と | だけの matcher は「完全一致の候補」として扱われ、DSH の道具名 bash とは一致しません。"matcher": "Bash|bash" と両方を並べると、同じ hooks.json が Claude Code と DSH の両方で動きました。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|bash",
"hooks": [
{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-bash.sh" }
]
}
]
}
}
この状態で「build フォルダを rm -rf build で消してから、テストを実行して結果を教えてください」と頼んだときの様子です。
録画(約43秒に編集)。フックが rm -rf を止め、エージェントは消す対象を調べて質問を出し、「削除せずテストだけ実行」を選ぶと最後まで進みました。
止めた瞬間の画面では、フックの標準エラーがそのまま赤字のエラーとして表示されています。

赤枠がフックのメッセージ。モデルはこれを「サンドボックスに拒否された」と解釈しつつ、ルールの中身を確かめにいきました。
その後エージェントは .claude/hooks/guard-bash.sh を読み、「消したいファイル名を挙げて人に確認」というメッセージに従って、ask_user_question で次の質問を出してきました。

上の赤枠がフックの意図を読み取った説明、下の赤枠が質問です。中身が4バイトの tmp 1ファイルだけだと確認してから聞いています。
フックのメッセージに「次に何をすべきか」まで書いておくと、モデルは止められた後の行動をそれに合わせる、という点はどのハーネスでも使えるコツです。Claude Code の公式ドキュメントでも、exit 2 の標準エラーはモデルに渡されると説明されています。
橋渡しは便利ですが、制限もはっきり書かれています。対応するイベントは Claude Code の30種類中7種類(SessionStart・UserPromptSubmit・PreToolUse・PostToolUse・Stop・SubagentStart・SubagentStop)で、PreToolUse の allow は事前承認にならず、updatedInput(入力の書き換え)も反映されません。hooks.json は起動時に1回だけ読むので、直したら dsh web を再起動します。
流用3:plan mode の指示文を、CLAUDE.md の「計画だけの依頼」に使う
DSH の Standard mode には、plan mode(計画だけ立てて、承認されるまで変更しないモード)用の指示文が入っています(packages/bundle/web-app/presets/standard.patch.yml)。抜粋します。
Imperative language to implement changes means plan the implementation, not execute it.
A user's conversational agreement — including an answer confirming something you asked —
approves nothing and does not end plan mode; fold the confirmed decision into the plan
and submit it through exit_plan_mode.
Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices
or material ambiguity that inspection cannot answer. Do not ask the user where code lives
or how current behavior works when you can find out.
Make the plan decision-complete: ... detailed enough that another engineer can implement it
without making design decisions.
よく練られているのは、「質問への『はい』は計画の承認ではない」と明記している点と、「調べれば分かることはユーザーに聞かない」という線引きです。Claude Code の plan mode でも、Codex の Plan mode でも、ここが曖昧だとエージェントが途中で実装を始めたり、場所を聞いてきたりします。
日本語に直して CLAUDE.md や AGENTS.md に足すなら、次のような形になります。
## 計画だけを頼まれたとき
- 「直して」「実装して」と書かれていても、計画モード中は計画を立てるだけにする。
- 確認の質問に「はい」と答えてもらっても、それは計画の承認ではない。決まった内容を計画に反映し、計画として提出する。
- コードの場所や今の動きなど、調べれば分かることはユーザーに聞かない。聞くのは、ユーザーが決めるべき選択と、調べても解消しない曖昧さだけ。
- 計画は「別のエンジニアが設計判断なしで実装できる」粒度で書く(目的と成功条件、変更点、テスト、前提を含める)。
流用4:同じ道具の空回りを止める注意文を、フックで返す
DSH には dsh-repeat-tool-reminder というガードがあり、同じ道具を同じ引数で3・5・8回続けて呼ぶと、モデルに注意文を挟みます。止めるのではなく、あくまで「結果を見直して別の手を考えて」と促すだけです。1回目は短く、2回目以降は道具名と回数を添えて強めに書く、という段階の付け方が上手です。
Claude Code では、PostToolUse フックの additionalContext で同じことができます。DSH の文面をそのまま使った例です。
#!/usr/bin/env python3
# .claude/hooks/repeat-reminder.py
# PostToolUse フック:同じ道具を同じ引数で続けて呼んだら、3・5・8回目に注意文を返す
# 文面は DeepSeek Harness の dsh-repeat-tool-reminder(MIT)を参考にした
import hashlib, json, os, sys, tempfile
THRESHOLDS = (3, 5, 8)
data = json.load(sys.stdin)
sig = data.get("tool_name", "") + json.dumps(data.get("tool_input", {}), sort_keys=True, ensure_ascii=False)
key = hashlib.sha1(data.get("session_id", "default").encode()).hexdigest()[:16]
state_path = os.path.join(tempfile.gettempdir(), f"repeat-reminder-{key}.json")
try:
state = json.load(open(state_path))
except (OSError, ValueError):
state = {"sig": None, "count": 0}
state["count"] = state["count"] + 1 if state["sig"] == sig else 1
state["sig"] = sig
json.dump(state, open(state_path, "w"))
n = state["count"]
if n not in THRESHOLDS:
sys.exit(0)
if n == THRESHOLDS[0]:
msg = ("You are repeating the exact same tool call with identical arguments. "
"Carefully analyze the previous result before calling again: if the task is not complete, "
"try a different approach or different arguments instead of repeating the call.")
else:
msg = (f"Repeated tool call detected:\n- tool: {data.get('tool_name')}\n- consecutive_calls: {n}\n"
"The repeated calls are not making progress. Do not call this tool with these exact arguments again. "
"Inspect the latest result and choose a different action, different arguments, or finish the task "
"if enough evidence has been gathered.")
print(json.dumps({"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": msg}}, ensure_ascii=False))
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash|bash",
"hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/repeat-reminder.py" }]
}
]
}
}
Claude Code(Sonnet 5.5)に「同じ echo same を3回実行して、届いた注意をそのまま引用して」と頼んで確かめました。

1回目・2回目の後には何も届かず、3回目の後にだけ DSH 由来の注意文が届きました(2026-10-04 実測)。
matcher は Bash だけにしていますが、"Read|Grep|Bash" のように広げれば、同じファイルを何度も読み直す空回りにも効きます。
流用5:「危ないかどうか」の定義文を、承認の判断基準に使う
DSH の実験的プラグイン Auto review は、道具を実行する前に、同じモデルに「この操作は安全か」を審査させる仕組みです。Codex にも Guardian という同じ発想の仕組みがあります。両方のプロンプトから判定ルールを抜き出して並べました。

図5:Codex は4段階+「ユーザーがどこまで許したか」の2軸、DSH は3段階で「秘密情報を外に出す」は人が頼んでも拒否します。
DSH の審査プロンプト(packages/experimental/auto-review/src/index.ts)の中心部分です。
First classify the pending action by its actual effects, never by the tool name,
message tone, or claimed intention:
- low: ordinary project-local reads and writes, analysis, formatting, linting, tests,
builds, non-destructive Git operations, ...
- medium: irreversible deletion of pre-existing objects or state, force push or history
rewrite, production reads, writes or deployments, ... Medium may be allowed only when
a current human or direct-parent instruction explicitly authorizes the action, exact
target and necessary scope, with no unresolved conflict.
- high: sensitive information exfiltration across a trust boundary ... High must always
be denied, even when a human or parent explicitly requests the exact action.
「道具の名前や口調ではなく、実際に起きる結果で分類する」「medium は人が操作・対象・範囲まで明示したときだけ許可」「迷ったら拒否(fail closed)」。この3点は、Claude Code の auto モードを使うときに CLAUDE.md に書いておく判断基準としても、PreToolUse フックで自前の判定スクリプトを書くときの仕様としても、そのまま使えます。
なお、Codex の Guardian の既定しきい値は「low と medium は許可、high はユーザーの許可が medium 以上なら許可、critical は常に拒否」です。DSH のほうが「人が頼んでも出さない」線を明確に引いているのが、両者の一番の違いでした。
流用6:長い作業の引き継ぎメモと、決定の記録
最後は、作業の進め方そのものに関わる2つです。
1つ目は、文脈があふれたときに会話を要約する「圧縮」の指示文です(packages/compaction/compaction-basic/src/summarizer.ts)。見出しが8つに固定されています。
## Primary Request and Intent
## Key Technical Concepts
## Files and Code
## Errors and Fixes
## Pending Jobs
## Current Work
## Next Step
## Critical Context
規則として「空の見出しも消さずに (none) と書く」「ファイルパス・コマンド・エラー文・数値はそのまま残す」「ユーザーの訂正は忠実に残す」「前回の要約は丸写しせず、古い事実を捨てて新しい情報と統合する」が並びます。Claude Code の /compact に渡す指示や、セッションをまたぐ引き継ぎメモのひな形にちょうどよい形です。
2つ目は Agent Notes です。.agents/notes/ の下に proposed(提案)・implemented(実装済み)・rejected(却下)・archived(凍結)の4つのフォルダがあり、エージェントが設計判断の理由を RFC のように書き残します。筆者の数えた時点で実装済み228件、凍結924件ありました。テンプレートには「Alternatives considered(検討した別案)」が必須で、理由として次の一文が添えられています。
A decision recorded without what it beat invites re-litigation (何に勝ったかを書かずに残した決定は、同じ議論の蒸し返しを招く)
エージェントに大きな設計変更を任せることが増えた今、「なぜそうしたか」と「何を捨てたか」をリポジトリに残させる仕組みは、Claude Code でも Codex でもそのまま導入できます。docs/decisions/ を作り、AGENTS.md に「設計判断を伴う変更では、却下した案も含めて記録を1つ書く」と1行足すだけで始められます。
おまけ:道具やスキルを設計するときのチェックリスト
.agents/skills/agent-experience/SKILL.md は19行しかない短いスキルですが、MCP サーバーの道具やスキルを自作する人には役に立つチェックリストです。要点を日本語にすると次のとおりです。
- 最初に見せるのは目的・できること・制約だけにし、詳しい説明は必要になったら読ませる
- 後から読む資料には、何が書いてあるかの説明と、確実に取り出す方法を付ける
- 権限・破壊的な影響・必要な確認は、その操作の前に見えるところに書く
- 結果は短くし、詳細は ID やパスで取り出せるようにする(ログ全体を返さない)
- 道具の定義と system の説明で同じことを2回書かない。変更したら最初のターンのトークン数を測る
Codex と並べて分かった違い
ここまでの観察を表にまとめます。
| 観点 | Codex(openai/codex) | DeepSeek Harness |
|---|---|---|
| 中心にあるもの | Rust の本体(core) | Cordis のプラグイン読み込み(ループもプラグイン) |
| 振る舞いの変え方 | config.toml・[features](約150個)・プラグイン | プロファイルの YAML で、どの部品も外す・足す・設定変更 |
| 外から使う口 | app-server(JSON-RPC)、codex exec --json、SDK | dsh headless --json、JSON-RPC の SDK(TS / Python)、ACP |
| 既定のモデル | OpenAI のモデル(Responses API) | DeepSeek-V41-Flash(Anthropic Messages 互換 API)。OpenAI・Anthropic・互換 API も追加可 |
| サンドボックスの名前 | read-only / workspace-write / danger-full-access | 同じ3つの名前。使えない環境では黙って素通しせず失敗する |
| 承認の自動化 | Guardian(4段階+ユーザーの許可度) | Auto review(実験的・3段階・秘密の持ち出しは常に拒否) |
| システムプロンプト | 長い基本方針(既定で約2.1万バイト) | 短い名乗り+道具ごとの1文(実測 5,785 字) |
| 指示ファイル | AGENTS.md | AGENTS.md と CLAUDE.md(.local 版も) |
| スキルの場所 | .agents/skills など | .dsh/skills と .agents/skills |
| フック | 独自の hooks(12種類のイベント) | Claude Code / Codex の hooks.json を読む橋渡し |
| 他のハーネスを呼ぶ | 他ツールからの設定・履歴の取り込み | subagent_claude_code / subagent_codex で子として呼べる(既定はオフ) |
| 記録 | ~/.codex/sessions/ の JSONL | ~/.dsh/sessions/ の zstd 圧縮 JSONL+実行トレース画面 |
一言でまとめると、Codex は「よくできた1台の車」を公開し、DSH は「車を組み立てる工場」を公開した、という違いです。Codex のほうが部品同士の連携が固く、細部まで作り込まれています。DSH は部品の境界と記録の規約が徹底していて、「ハーネスとは何でできているか」を学ぶ教材としては DSH のほうが見通しよく作られていると感じました。
もう1つ印象的だったのは、DSH がほかのハーネスとの互換を最初から設計に入れていることです。サンドボックスのモード名は Codex と同じ、指示ファイルは Claude Code と Codex の両方の名前を読み、スキルは Codex と同じ場所を探し、フックは両方の書式を読み、さらに Claude Code と Codex を子エージェントとして呼ぶ部品まであります。乗り換えではなく「併用」を前提にした作りです。
使う前に知っておきたい注意点
公式 API を使うと、セッションログが既定で送られる
設定画面の General の一番下に、次のスイッチがあり、既定でオンになっていました。

赤枠のスイッチ。説明は「Help improve DeepSeek models and products.」です。
ソースを読むと、これは DeepSeek の公式 API にリクエストを送るとき、本文に dsh_session_log という項目でセッションログを同梱する機能です(1リクエスト最大8MiB)。CLI の文書には、送られる内容に「メッセージの本文、道具の引数と結果、作業フォルダのパス」が含まれうると書かれています。今回の筆者のようにローカルモデルだけを使う場合は送られませんが、公式 API で業務のコードを扱うなら、最初にこのスイッチを確認しておきましょう。
ほかの送信も整理しておきます。
| 何が | 既定 | 止め方 |
|---|---|---|
| セッションログの同梱(公式 API 利用時) | オン | 上の画面のスイッチ、または設定で enabled: false |
| 入れているプラグイン一覧の同梱(公式 API 利用時) | オン | 設定で enabled: false |
| OpenTelemetry のログ | フィードバックを送ったときだけ | 環境変数 DSH_TELEMETRY_MODE=DISABLED |
| 匿名 ID | $DSH_HOME/.anonymous-user-id に保存 | ファイルを消すと作り直される |
Codex も、既定で利用状況の数値を送る設定になっていて、analytics.enabled = false で止められます。どちらも「既定で何かを送る」こと自体は珍しくありませんが、DSH は会話の中身まで含むため、知っておく価値があります。
Auto review などの実験的プラグイン
Plugins 画面には8つの公式プラグインが並び、そのうち4つ(Agent Teams・Auto Authorization Review・Automation tasks・Voice input)に Experimental の印が付いています。

赤枠が Auto review を足すプラグイン(既定はオフ)。README には「安全でない操作を許可することも、役に立つ作業を拒否することもある」と書かれています。
Auto review を有効にすると、審査で許可された操作は Full access(サンドボックスなし)で実行されます。DSH の SAFETY.md が勧めるとおり、使うなら使い捨ての環境にとどめるのが無難です。
Creator mode は、ローカルの 27B モデルには荷が重かった
元の紹介文で目玉として挙げられている Creator mode も試しました。「呼ぶと固定の文字列を返すだけの道具 coupon_rule を作って、このプロファイルに入れて」という小さな依頼です。
結論から書くと、ローカルの Qwen3.8-27B では完成しませんでした。

中央の赤枠が道具の呼び出し(ほとんどが DSH 本体の read と grep)、下の赤枠が To-do(1件進行中・4件未着手)と累計の数字です。
エージェントはまず cordis-plugin-development・cordis-composition-reference・agent-experience の3つのスキルを読み、cordis_inspect_list と cordis_inspect_query で DSH が今どんなサービスを持っているかを調べました。ここまでは設計どおりの動きです。To-do には「登録の約束事を確かめる → ワークスペースにプラグインを書く → plugin_manager で入れて警告を確認 → 実際に呼んで確かめる → 日本語で報告」の5段階が並びました。
ところが1段目の「確かめる」が終わりません。道具の型定義を確認しようと、npm のキャッシュにある DSH 本体の lib/index.js を何十行ずつ読み続け、2ターン・24ステップで道具を33回呼び(read 12回・grep 9回・bash 5回など)、処理したトークンは累計で約93万に達しました。読み込む文脈が長くなるほど1ステップの準備に時間がかかり、2回目のターンは約26分たってもプラグインのファイルを1つも書いていませんでした。途中で筆者側のサーバーが止まったため、それ以上は追えていません。
| 項目 | 値(筆者の実測) |
|---|---|
| ターン・ステップ | 2ターン・24ステップ(1ターン目は7分で中断し、続きを依頼) |
| 道具の呼び出し | 33回(read 12・grep 9・bash 5・skill 3・cordis_inspect 3・todo_write 1) |
| 処理したトークン | 約92.8万(Cache hit は LM Studio が報告しないため 0%) |
| 書かれたファイル | 0 |
Creator mode は「DSH 自身のソースを読んで、正しい作法でプラグインを書く」型なので、長い文脈を速く読めるモデルが前提になります。公式の DeepSeek モデル(文脈100万トークン)での動作は今回確認できていません。試すなら、まず公式モデルか十分に大きいモデルで、「固定の文字列を返すだけ」のような小さな依頼から始めるのがよさそうです。また、plugin_manager は danger-full-access か毎回の承認が必要で、入れたプラグインはサンドボックスの外の同じプロセスで動くと README に明記されています。会話でハーネス自体を書き換える強力な機能である分、扱いは慎重にしたいところです。
小さな発見:中断されたターンも、チャット画面では「Completed in 7m 0s」と表示されていました。ログ上の終了理由は
interruptedです。完了表示だけで判断せず、実行トレースやログで確かめるのが安全です。
トラブルシューティング:筆者がつまずいた順

図8:上から順に起きやすい症状です。
| 症状 | 原因 | 対処 |
|---|---|---|
| 起動直後に「Add an API key to get started」 | 既定のモデルが DeepSeek 公式 | キーを入れるか、Configure later → Custom model API で別モデルを足す |
No API key for provider: lmstudio | キー欄が空 | 任意の文字(例 lm-studio)を入れる |
installation rejected … incompatible with dsh 0.2.0-rc.2 | npm の latest タグが古い版(0.0.1-rc.5)を指している | @0.2.0-rc.2 のように本体と同じ版を明示する |
ERR_PNPM_ADDING_TO_ROOT | 手元の pnpm 9 がプロファイルのルートへの追加を止める | dsh plugin --profile web add -w <パッケージ> と -w を付ける |
| Claude Code のフックが発火しない | 道具名が Bash と bash で違う | matcher に小文字の bash も並べて書き(本文の流用2を参照)、dsh web を再起動 |
~/Documents/deepseek-harness/ ができた | 初回起動で Default workspace が作られる | 試すだけなら DSH_HOME を分け、使うフォルダを Workspace に追加する |
まとめ
DeepSeek Harness は、エージェントのループ・道具・安全装置・記録・UI を、すべて差し替えられる部品として公開したハーネスです。実際に動かして中身を読み、次のことが分かりました。
- Codex は1台の車、DSH は車の工場。Codex は本体に機能を作り込み、DSH はループまでプラグインにして、プロファイルの YAML で組み立てる
- システムプロンプトは短く、使い方は道具の説明へ。DSH の system は 5,785 字で、方針は道具ごとの1文と道具定義に分散している。キャッシュを壊さないため、状況の変化は履歴の後ろに足す
- すべてをログに残す規約が、実行トレース画面の見やすさを支えている
- 他のハーネスとの互換が前提。
AGENTS.md・CLAUDE.md・.agents/skills・Claude Code / Codex のhooks.jsonをそのまま読む。ただし matcher は"Bash|bash"にする - 持ち帰れる書き方が多い。指示書とスキルのリンク共有、plan mode の指示文、空回りへの注意フック、危険度の定義文、圧縮の書式、Agent Notes は、DSH を使わなくても Claude Code と Codex で効く
- 注意点として、公式 API 利用時のセッションログ送信が既定でオン。まだ developer preview で、互換性を壊す変更がある
次の一歩としては、まず自分のリポジトリで CLAUDE.md を AGENTS.md へのリンクにし、repeat-reminder のフックを入れてみるのがおすすめです。どちらも10分で終わり、Claude Code と Codex の両方で効果があります。DSH 本体を試すなら、DSH_HOME を分けて npx @deepseek-ai/dsh web を起動し、Trajectory タブでシステムプロンプトと道具の一覧を眺めてみてください。自分が普段使っているハーネスが、モデルに何を見せているのかを想像する手がかりになります。
参考リソース
- DeepSeek Harness 公式ページ
- deepseek-ai/deepseek-harness(GitHub):README・AGENTS.md・SAFETY.md・
docs/・.agents/ - DeepSeek Harness のドキュメント
- Cordis(GitHub)
- openai/codex(GitHub)
- Claude Code のフックのリファレンス
- 筆者の前回記事:OpenAI が公開した Codex ハーネスで何ができる?
- 筆者の関連記事:Qwen Code と Codex・Claude Code の比較
本文で引用した DeepSeek Harness の文章・コードは MIT ライセンス(© 2026 DeepSeek)です。

