ducklab について
ducklabは、ソフトウェア開発向けのセルフホスト可能なハーネスです。複数のLLMが定められた役割で要件、仕様、計画、実装、レビューを進めます。テストゲートはコマンドの終了コードで判定し、モデルの呼び出しと判断を記録して、コミット前に承認を待ちます。
主な機能
- 01複数段階の開発サイクル
- 02役割を定めた複数LLMの協働
- 03コマンド終了コードによるテスト判定
- 04モデル呼び出しと判断の記録
- 05変更の受け入れ前にゲートを再実行
- 06CLI・デスクトップアプリ・MCPサーバー
活用シーン
- 01ローカルモデルでプロジェクト開発
- 02テストゲートで変更を確認・承認
- 03他のエージェントから開発ループを操作
- 04受け入れ済み変更の証跡を検証
MCP 対応
ducklabはMCPサーバーを提供し、他のモデルから開発ループを操作できます。操作と判断は記録され、実行主体も示されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Ducklab
複数のLLMを固定された役割で動かし、あなたが署名したテストゲートの下で、プロジェクトの開発サイクル全体を実行するセルフホスト可能なハーネスです。
ひとことで言うと: セルフホスト可能な開発ハーネス(Go エンジン+CLI+デスクトップアプリ、Linux を優先)· brief → requirements → spec → plan → build → review → release · 判定は終了コードで行い、モデルの意見は使いません · ローカルモデルを優先(llama.cpp、vLLM)しつつ、OpenAI 互換または Anthropic のエンドポイントも併用可能 · 記録され、誰の判断かが明確な決定を通じて、人間または他のエージェントが MCP 経由で操作可能 · Apache-2.0 · 自身を開発します(.ducklab/ に記録される実行ログが証拠です)。エージェントは AGENTS.md と llms.txt から始めてください。
概要を渡すと、要件、仕様、計画を作成します。1 つまたは複数のモデルで議論しながらタスクを組み立て、プロジェクトの実際のテストゲートを実行し、コミットの前に必ずあなたの確認を待ちます。すべてのモデル呼び出しが記録されます。モデルが判定を下すことは決してありません。
実際の評議会による受け入れをライブで記録し、早送りしています。アーキテクトが草案をストリーミングし、別のモデルがレビューし、予算がセント単位で更新されます。そして実行はあなたのゲートで停止します。ご覧いただいた内容の合計コストは $0.07 です。
ローカルモデルを優先するように構築されました。開発の大半を担った 2 つのモデルは、LAN 上の vLLM マシンと localhost 上の llama.cpp サーバーです。どちらもコストはゼロです。ホスト型モデルも同じロスターに加え、同じ証拠に基づいて評価できます。
これが存在する理由
多くのエージェント型コーディングツールは、優れたモデルを1つだけ想定し、それを信頼します。Ducklabは、安価なモデルを複数使い、そのどれも信頼しません。
- 判定するのはゲートであり、モデルではありません。 判定はコマンドの終了コードです。テストファーストの実行では、テストを書く前に成功するベースラインを測定し、テストを追加した後にその新しいテストで失敗することを確認します。また、すべての受け入れで、コミット済みの sha をクリーンなチェックアウトからゲートで再現します。再現できなかったものは何も取り込まれず、再現に失敗した受け入れは、その受け入れ自体のコミットを取り消します。
- あらゆる場面で相関を排除します。 レビューには別のモデルを使います。レビュアーには誰がコードを書いたかを知らせません(UI で隠すのではなく、ペイロードに含めません)。トーナメントの審査員はブラインドで選び、評議会の批評者は互いの意見ではなく草稿を読みます。
- 作業は契約です。 タスクの成果物は実装者が番号付きチェックリストにまとめ、番号ごとに報告します。レビュアーは差分と照らし合わせて各項目を確認します。未達の項目があれば、ラバーダックが呼び出されます。これは、測定された苦境(ブレーキによる拒否、失敗の連続、失敗するゲート)があるときだけ起動するアドバイザー席で、
none、実装者をすぐ作業に戻すメモ、またはstopのいずれかを返します。 - 席は証拠に基づいて選びます。 すべてのダックリングはスコアカードを持ちます。自分の実行における席ごとの合格率、実行あたりのコスト、コーディング指数が記録され、名簿ボードはその情報をもとに席を提案します。ランキング基準は自由に並べ替えられます。提案はまれで、根拠も明確です。合格率は Wilson の下限で順位付けし、最低3回実行する必要があり、無料だからといってローカルモデルが選ばれることはありません。
- 上限のないものはありません。 ターン数、トークン数、コスト、実行時間、ツール出力、シェルコマンドなど、すべての上限は見えており、実行中に引き上げることも、その記録を残すこともできます。
- ドキュメントはモデルのコンテキストウィンドウに制限されません。 ステージに Wiki を添付すれば、大きな席はすべてを読みます。小さな席には、各ドキュメントを読める分量に要約して渡し、全文は
ref_readを1回呼び出すだけで確認できます。また、誰も開かなかったドキュメントがあればゲートが示します。32k のローカルモデルにも、25万文字の参考資料を読み込ませられます。作業メモリはハーネスが担います。
記録に水増しはありません。判定とコスト、そして受け入れがクリーンなチェックアウトから成功を再現できたかどうかを、すべての実行について記録します。
Ducklab は Ducklab の中で開発されています。計画、バグ、リリース、受け入れられたタスクは、測定対象と同じローカルモデルおよびホスト型モデルを使い、Ducklab 自身のループを通じて進められました。最近の機能(実行ごとのワークツリー、マージ証明付きの受け入れ、受け入れレシート、ガバナンスの書き込みガード)は、Duck が構築し、人がゲートで確認しました。この主張を自分で確かめるには:
git clone https://github.com/jrullan/ducklab && cd ducklab
go build -o ducklab-cli ./cmd/ducklab
for r in .ducklab/runs/*/receipt.json; do ./ducklab-cli proof verify "$r"; done
v0.7.0 以降、すべての受け入れにレシートが付属します。コミット済みの sha、ゲートコマンド、その終了コード、クリーンなチェックアウトからの再現判定が記録されています。これらは第三者が再検証できる事実であり、評価ではありません。
ステータス
v0.7.0に加え、フェーズ3の作業も現在mainに反映されています。すべてのビルドとテストの実行は、それぞれ専用のgitワークツリー内で行われるため、チェックアウトが変更されることはありません。受け入れ時には実行ブランチをリベースし、リベース後のコミットでゲートを再実行して、早送りのみでマージします。また、作業がエンジン外でmainに反映された場合、オペレーターは完了済みの実行をlandedとして再度クローズできます。それ以前から備わっている機能は、7つのステージ、5つのモード、測定済みのスコアカードを備えたロスターボード、自動消化機能付きの参考ドキュメント、デスクトップから管理するスキル、着席型コンサルタントチャット(画像を送信する前にビジョン機能を検証)、スクリーンショットを証拠とするバグレポート、決定論的なカバレッジチェック付きの採用調査、実行が待機している理由を示すプロバイダー対応のキューイング、担当者が測定可能な限界に達した場合のエスカレーション提案、受け入れレシート(ducklab proof verify)、リリース、自動操縦、CLI、デスクトップアプリ、そしてMCP サーバーです。MCP サーバーは公式MCPレジストリにio.github.jrullan/ducklabとして登録されており、記録され、誰が行ったか明記された判断に基づいて、別のモデルがこのループを操作できます。
docs/status.mdではすべての受け入れ基準を追跡しており、達成数を切り上げていません。コードと仕様に差異がある場合は、docs/decisions/に記録されています。
インストール
Go 1.25以降、デスクトップにはNode 22以降、そしてgitが必要です。
Linux
CLIとエンジンは純粋なGoで実装されています。デスクトップアプリはWails v3アプリで、GTK/WebKitの開発用パッケージが必要です。
sudo apt install libgtk-3-dev libwebkit2gtk-4.1-dev # Debian/Ubuntu names
make desktop && make install
Ubuntu 24.04以降では、デスクトップアプリにAppArmorプロファイルも必要です。決定事項0003とpackaging/apparmor/を参照してください。
macOS
xcode-select --install # the desktop build links against WebKit
brew install go node
make desktop && make install
正直にお伝えすると、ducklabはLinux上で日々開発・実行されています。CLIとエンジンはmake crossのたびにdarwin/arm64向けのコンパイルチェックが行われますが、Macでのデスクトップアプリのビルドはまだ検証されていません。最初に試す人がその検証役になります。また、make installを実行すれば、いずれの場合もCLIとエンジンを利用できます。問題があれば、どんな内容でもご報告ください。
どちらのOSでも
make installは~/.local/binにインストールするため、このディレクトリがPATHに含まれていることを確認してください。デスクトップのバイナリがfrontend/srcより古い場合、古いバイナリをそのままインストールしてしまうため、警告が表示されます。
デスクトップアプリを使わないフロントエンド開発
ブラウザーでフロントエンドを動かすには、別々のターミナルでエンジンとViteを起動してから、接続情報を指定してブラウザーを開きます。最も手早いのはフェイクエンジンを使う方法です。同じ手順で、オプトインのCORSフラグを指定して実際のエンジンを使うこともできます。
# Fast, scripted data (recommended for UI work)
go run ./cmd/fake-engine --port 8787 --token fake-token
npm run dev --prefix frontend
# open http://localhost:5173/?engine=http://127.0.0.1:8787&token=fake-token
# Or use real engine data (development only; keep the origin explicit)
go run ./cmd/ducklab-engine --allow-origin http://localhost:5173
npm run dev --prefix frontend
# open http://localhost:5173/?engine=http://127.0.0.1:<engine-port>&token=<engine-token>
実際のエンジンは、デフォルトでは引き続き同一オリジンに制限されます。--allow-originを指定すると、ブラウザーのオリジンを1つだけ許可できます。このフラグはローカルでのフロントエンド開発やビジュアル監査を目的としたもので、認証やループバックへのバインドは変更しません。このフラグを指定しないと、ブラウザーのクロスオリジンエラーがセッションの停止のように見えることがあります。
engineとtokenのクエリパラメーターは、Viteの開発ビルドでのみ使用できます。環境変数VITE_DUCKLAB_ENGINEとVITE_DUCKLAB_TOKENで指定することもできます。デスクトップシェルは引き続き、注入された接続window.ducklabを使用します。
3つのバイナリ
| 概要 | |
|---|---|
ducklab-engine | デーモンです。すべての実行を管理します。バインド先は127.0.0.1のみで、起動のたびにベアラートークンをローテーションします。 |
ducklab | CLIクライアントです。状態を保持せず、エンジンに問い合わせます。 |
ducklab-desktop | デスクトップアプリです。クライアントでもあり、状態を保持しません。エンジンを自ら起動する(または既存のエンジンを引き継ぐ)ことができます。 |
プロバイダーキーは呼び出し時にエンジンの環境変数から取得されます。エンジンの起動前にキーをエクスポートするか、キーチェーンからキーを読み込むラッパーを通じてデスクトップアプリを起動してください。引き継いだエンジンに、このアプリが持つキーがない場合は、該当する説明の横に再起動ボタンが表示されます。
エンドツーエンドのサイクル
デスクトップから:初回起動時は Now → 最初のプロジェクトを作成、それ以降は Settings → Projects → New project を選び、続いて Work → Documents → Intent → Add intention → Draft it の順に進みます。ターミナルからは:
cd ~/dev/myproject
git init # ducklab needs a git repo
ducklab project init --name MyProject # auto-starts the engine if none is running
ducklab intake --from brief.txt # brief → requirements
ducklab intent # your briefs, verbatim, and what each one changed
ducklab spec # requirements → spec
ducklab plan # spec → milestones and tasks
ducklab run T-001 # build it
ducklab run accept r-20260729-... # commit it
ducklab review T-001 # read the commit
ducklab release plan --bump minor # what shipped
あなたの言葉は記録の一部です。すべてのブリーフは、モデルが読み取る前に INT-nnn エントリとして一字一句そのまま保存され、追加または変更された要件はそのブリーフを参照します。そのため、要件にはいつでも「誰が、どんな言葉で依頼したのか」を確認できます。
各ステージでは、まず .proposed ファイルを書き出して、あなたの判断を待ちます。accept すると反映され、reject すると実行による変更だけが正確に元に戻され、それ以外には手を加えません。「変更を依頼」すると、仕様書、計画、リリースノートなど、どのドラフトでもメモを添えて差し戻せます。あなたが明示的に付与した自律性レベルの範囲内でない限り、あなたの承認なしにコミットされることはありません。
参考ドキュメントは、どのステージにも追加できます。--ref ~/wiki/product/(またはデスクトップの添付機能)を使うと、ファイルやディレクトリ全体をアーキテクトの背景情報として読み込みます。プロンプトでは、次の2つのルールを明示して、参照情報の扱いを定めます。承認済みの要件がスコープを決め、参照情報とコードが食い違う場合はコードを正とします。コーパスがシートのコンテキスト上限を超えると、各ドキュメントは一度だけ要約され(コンテンツハッシュでキャッシュされます)、全文は ref_read ツールから引き続き参照できます。また、提案カードには、どのシートも一度も開かなかったドキュメントが一覧表示されます。
既存のコードベースの導入も同じ仕組みです。インテイクでコードを読み取り、現状を記述した要件を書き出します。仕様書では各セクションに as-built と明記し、計画は意図的に空のままにします。その後の新しい作業はバグ報告と計画の修正から始まります。ducklab 自体もこの方法で開発されています。
プロジェクトの正となる設定は、.ducklab/project.toml で宣言します。ゲート([verify]。クリーンチェックアウトに必要なものを指定する link_deps と setup を含みます)、アプリの起動方法(プリフライトを含む [run])、プロジェクト自身のバイナリの再ビルド方法([install])を定義すれば、ducklab を離れずに一連の作業を実行できます。スタック機能は、ビルドメタデータ(たとえば Meson の実行ファイル、Cargo のバイナリ、Go の main パッケージ、Node のスクリプト)から run.command の候補を提示しますが、採用するのは人が決めます。設定後は、ほかの点では成功しているすべてのビルドゲートで、run.smoke が宣言されていればそれを実行し、なければ run.command を実行します。これにより、インタラクティブなアプリケーションでも、各ゲートで実際の UI を開かずにヘッドレスのスモークテストを宣言できます。run.smoke_expect = "exit" | "live" で成功条件を定義します。exit は run.smoke_timeout_s の時間内にステータス 0 で終了することを求め、live は観測期間全体にわたってプロセスが存続することを求めます。省略した場合、明示的に設定された run.smoke はデフォルトで exit になります。一方、run.command にフォールバックする場合や、URL/ヘルスエンドポイントがあるアプリでは、デフォルトで live になります。ゲートと UI には有効な期待値が常に表示されるため、20 ミリ秒で正常終了するインタラクティブなプログラムが、起動済みの製品を装うことはできません。意図的な停止では、アプリのプロセスグループ全体に丁寧に終了を要求し、run.stop_grace_s 秒(デフォルトは3秒)待ってから強制終了します。同じ猶予期間は、live 製品のスモークテストが観測期間を終えたときにも適用されます。
ゲートとシェルのプロセスツリーには、常に DUCKLAB_RUN_ID と DUCKLAB_PROJECT_ID が渡されます。たとえば、excercise-tracker では [verify].tests に DATABASE_URL=test_db_${DUCKLAB_RUN_ID} を指定でき、compose のプリフライトでは ${DUCKLAB_PROJECT_ID} を実行ごとのプロジェクト名として使用できます。Ducklab が保証するのは識別情報のみです。プロビジョニングとティアダウンは、引き続きプロジェクト側の責任です。
モデルの追加
ducklab provider set openrouter --url https://openrouter.ai/api/v1 \
--key-env OPENROUTER_API_KEY
ducklab duckling set pato-sonnet --provider openrouter \
--model anthropic/claude-sonnet-4.5 \
--roles reviewer,judge --context 200000 \
--cost-in 3.0 --cost-out 15.0
ducklab duckling test pato-sonnet --prompt "say OK"
--key-env は環境変数の名前であり、キーそのものではありません。キーが設定ファイルに書き込まれたり、API 経由で送信されたり、シェルの履歴に残ったりすることはありません。
席の提案には根拠も示されます。実行結果に基づく合格率、実行ごとのコスト、コーディング指数です。選ぶのはあなたです。
デスクトップの名簿ビューで席を割り当てます。群れからモードの席へドラッグして、全体またはプロジェクトごとに設定できます。各アヒルのカードには根拠が表示され、席の横にはエンジンの提案が表示されます。アヒルが OpenRouter 上にある場合、コーディング/知能/エージェント能力の各指数は OpenRouter のベンチマークエンドポイントから取得され、それ以外はあなた自身の実行結果によって補われます。
このリポジトリを構築したモデル群
これはおすすめリストではありません。このリポジトリ独自の実行記録です(2026-08-24 時点で、記録された実行 454 件、席の割り当て約 2,300 件)。実際にどの席を誰が担当したかを確認できます。OpenAI 互換エンドポイントも同様に割り当てられます。
| アヒル | モデル | 提供元 | 担当した席 | 記録が示す内容 |
|---|---|---|---|---|
beelink-local | Qwen3.6-35B-A3B (Q4 GGUF) | Ryzen AI Max 395 上の llama.cpp (Vulkan)、デスク上 | 465 件(このリポジトリで最も多く席を担当したアヒル) | 判定、記録、レビュー担当。無料です。 |
luna | gpt-5.6-luna | OpenRouter | 455 件 | 実装担当の主力:測定合格率 77%、1 回の実行あたり約 $0.02。 |
atom-local | Qwen3.8-27B | LAN 上の DGX Spark で動作する vLLM | 352 件 | アーキテクトと記録担当。リリースノートも執筆しました。無料です。 |
k3 | Kimi K3 | OpenRouter | 348 件 | トリアージ、アーキテクチャの草案、質問アドバイザーを担当。 |
terra | gpt-5.6-terra | OpenRouter | 303 件 | より高性能な実装担当、1 回の実行あたり約 $0.28。 |
glm52 | GLM-5.2 | OpenRouter | 160 件 | レビュー担当:261 件のレビューで測定合格率 81%。 |
qwen38-max | Qwen3.8-Max | OpenRouter | 140 件 | アドバイザー(壁打ち相手)。測定合格率 88%。 |
pato-sonnet | Claude Sonnet 4.5 | OpenRouter | 7 件 | 高コストの席。より安価なモデルでは明確に限界が見られる場合に使用します。 |
正確さのため、2 点補足します。まず、ここでいう「ローカルモデルで構築」とは、ローカルのモデルが判定やドキュメント作成(判定、レビュー、記録、アーキテクチャ設計)を担当し、安価なホスト型モデルが主にコードを記述したことを意味します。席の割り当て全体の約 3 分の 1 は、この部屋のハードウェア上で実行されました。次に、上記の合格率は私の実行結果に基づいて測定したものです(ducklab duckling scorecard、Wilson 下限)。結果はそれぞれ異なります。それが重要なのです。名簿はリーダーボードではなく、あなたの記録を基に機能します。
実際の作業でも同じ仕組みを使えます。ducklab 独自の仕様書を council で改訂中。トークン数は 450 万、引き上げを求めた予算で一度停止しました。
5 つのモード
ducklab run T-001 --mode <mode>
| モード | 動作 |
|---|---|
solo | アヒル 1 羽です。他のすべてを測る基準になります。 |
pair | 実装担当とレビュー担当の組み合わせで、互いに相関しないようにします。その間にアドバイザーが入ります。いわば壁打ち相手です。 |
tournament | 参加者が隔離された worktree で同じタスクを実装し、判定役が内容を伏せた状態で選びます。 |
split | アーキテクトが作業を分解し、サブタスクを並行実行します。統合はファイルのコピーで行い、モデルは関与しません。 |
council | インテーク、仕様書、計画、レビューのために、複数のモデルが 1 つのドキュメントを扱います。1 つが草案を作成し、他のモデルが内容を伏せた状態で批評し、最初のモデルが修正します。 |
実行しないこと
コードで強制される不変条件:
- モデルが判定を決めることはありません。ゲートはコマンドの終了コードです。
- 合格した候補はバイト単位でそのまま適用され、合格後に再生成されることはありません。
- レビュー担当者がコードを書いた人物を知ることはありません。
- マージ対象のコミットをクリーンなチェックアウトから再現できないものが取り込まれることはありません。
- 拒否すると、その実行で書き込まれた内容だけが元に戻り、他の人の作業には影響しません。
- すべての予算(トークン、コスト、ターン数、経過時間)には、確認可能な上限があります。
- シークレットがプロジェクトの状態に触れることはありません。
- エンジンはループバック専用です。リモートモードはありません。
スキル
スキルは SKILL.md を含むディレクトリです。1 つのプロジェクト用なら
.ducklab/skills/ の下に、すべてのプロジェクトで使うならマシン全体の
スキルディレクトリに配置します(名前が重複した場合は、プロジェクト側の
スキルがグローバルのスキルより優先されます)。ドキュメントのみの形式には
スクリプトがなく、これがデフォルトです。モデルが読み、従うための手順書です。
アーキテクトは採用前に調査ガイドを読み(skill_list がプロンプトに含まれます)、
コンサルタントはチャット中に読み、実行可能なスキルで skill_run を使えるのは
実装担当者だけです。
スキルはデスクトップの 歯車 → Skills から管理します。スコープバッジと
検証上の問題を確認しながら一覧表示できるほか、読み取り、SKILL.md 全体の編集、
引数を指定した実行、削除ができます。実行中に duckling が作成したスキルは、
その実行が承認されるまで「承認待ち」としてグレー表示されます。スキルの提案にも、
コードの提案と同じゲートが適用されます。
ducklab skill new house-style
ducklab skill run changelog-entry --arg summary="..."
コンサルタント
すべてのプロジェクトには コンサルタント(ロスターボード上の Common 席)が あります。これは「これについてチャットする」ドアの向こう側にいるモデルであり、 ガイドレール内の自由形式チャットを担当します。コード、実行履歴、ボード、スキルを 読みますが、書き込みはしません。また、画像にも対応します。壊れた画面の スクリーンショットを貼り付けて質問できます。ビジョン機能は推測ではなく検証されます。 ビジョン対応を宣言した席には、実際の画像リクエストを一度送って確認します。 テキストのみ対応する席では、回答をでっち上げる代わりに、貼り付けを受け付けない旨を テキストで伝えます。
読み取ったリポジトリについての質問に答える、席に着いたコンサルタント。
別のモデルから ducklab を操作する
ducklab mcp serve は、ループ全体を stdio 経由の MCP サーバーとして公開します。
外部モデルは各結果を読み、ゲートを判断し(理由の記録が必須です。決定は
approved_by: mcp:<client> として記録され、「human」として記録されることは
ありません)、質問への回答、バグの登録、計画の修正、作業の開始を行います。
エンジンの next リストが規則です。オペレーターは、人が実行できない操作を
実行することはできません。
貢献
CONTRIBUTING.md を参照してください。ビルド方法、テストで アーキテクチャを保護する仕組み、ducklab 独自のループを通じた作業の流れ、 着手すべき場所について説明しています。要点は次のとおりです。
make # vet, test, build the frontend
go test ./... # 39 packages
cd frontend && npx vitest run
ライセンス: Apache-2.0。貢献は同じ条件で受け付けます (ライセンスの §5 に基づき、CLA は不要です)。Ducklab の名称とアヒルは メンテナーに帰属します(§6)。
仕様
このコードは、このリポジトリ内の文書化された仕様を実装しています。
docs/spec/(00-VISION から 08-DESKTOP-UI まで)は、
ビジョン、不変条件、プロトコル契約、受け入れ基準を定める規範レイヤーです。
システムの現在の姿は .ducklab/docs/ に記載されています。これは、ループ自体が
維持する、構築済みの要件、仕様、計画であり、それぞれのバージョンは人間が
承認するゲートで署名されます。両者の意図的な相違は
docs/decisions/ に記録されています。両者の差分が
ロードマップとなり、アラインメント段階でそれが算出されます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。