AIコーディングエージェントに長い作業を任せると、途中で指示を忘れ、レビューを飛ばし、同じ指摘を人間が何度も繰り返すことになる。TAKT(nrslib/takt・MIT・1,252★)はこの問題を「エージェントをもっと賢く指示する」方向ではなく、「工程そのものをエージェントの外に置く」方向で解こうとするCLIだ。計画・実装・レビュー・修正のループをYAMLの状態機械として定義し、次にどのステップへ進むかはエージェントの裁量ではなくTAKTのエンジンが決める。この記事では公式READMEの紹介にとどめず、v0.54.1のソースを実際に読み、takt workflow doctor を走らせて終了コードを確認しながら、遷移がどう決まるのかを具体的に確かめる。
/go で「タスクにつむ」を選び、キューから実行する流れ。出典: nrslib/takt docs/assets/tutorial-preview.ja.gif(MIT License・記事用にMP4へ変換)・何ができるか:計画→実装→レビュー→修正のループをYAMLで定義し、9種のコーディングエージェントに役割ごとに割り当てて実行する
・何を解決するか:「レビューを飛ばさないで」とプロンプトで頼む代わりに、遷移条件を満たさなければ次へ進めない構造にする
・何を代替できるか:CLAUDE.mdやスキルに書いた「守ってほしい手順」の一部。ただしエージェント本体は置き換えず、その外側に乗る
・実体:TypeScript・MIT・1,252★・npm週3,512ダウンロード・v0.54.1(2026-07-29公開)
①遷移の決め方はソース上で5種類あり、うち2つはLLMを呼ばない。②LLMが判定する場合も構造化出力→タグ検出→AI判定の3段でフォールバックし、全部外すと実行を止める。③YAMLは実行前に4層で検証され、条件式の文法・語彙・型・契約依存の違反はすべて終了コード1で弾かれる。
AIエージェントを動かす枠組み全体の中でTAKTがどの層に位置するかは、AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証と併せて読むと掴みやすい。LangGraphやCrewAIがアプリケーションのコードとしてエージェントを組み立てるのに対し、TAKTは既存のコーディングエージェントCLIを外から統制する層に立っている。
TAKTとは——AIコーディングエージェントの工程を外部から統制するCLI
TAKTは「TAKT Agent Koordination Topology」の頭字語で、名前の由来はドイツ語の「拍」、指揮者がオーケストラの時間を揃えるために振るタクトから来ている。この比喩は実装の役割分担にそのまま対応している。演奏するのはAIエージェントで、次に何を演奏するかを決めるのはエンジンだ。
docs/assets/description/04-engine.png(MIT License)まず実体を数値で押さえておく。以下はGitHub APIとnpmレジストリで2026-07-30(JST)に取得した値だ。
| 項目 | 実測値 |
|---|---|
| リポジトリ | nrslib/takt |
| ★ / fork | 1,252 / 83 |
| ライセンス | MIT(Copyright (c) 2026 Masanobu Naruse) |
| 主要言語 | TypeScript |
| 作成日 | 2026-01-25 |
| 最終push | 2026-07-29 |
| 最新バージョン | v0.54.1(npm公開 2026-07-29) |
| npm公開バージョン数 | 100 |
| npmダウンロード | 週3,512 / 月17,532 |
| GitHub Releases | 0件(gitタグのみ) |
| open issues | 60件 |
| コントリビューター | 20名(nrslibが1,342コミット) |
| Node要件 | >=24.15.0 |
作成から約半年で100バージョンをnpmに公開しており、単純平均で1.85日ごとに1リリースというペースになる。GitHubのReleasesページは0件だが、これはリリースを作っていないというだけで、gitタグ(v0.54.1まで)とnpm、そして202KBに達するCHANGELOG.mdで履歴は追える。バージョン履歴を追いたい場合はReleasesではなくCHANGELOGを見るのが正しい。
コード規模も見ておく。.ts ファイルは1,597本・合計430,956行で、そのうち src/__tests__/ 配下が714ファイル・284,385行を占める。実装側(テストディレクトリ外)は883ファイル・146,571行なので、テストディレクトリの行数は実装の約1.9倍にあたる。テストを厚く持つ構成で、E2E設定ファイルもプロバイダー別・並列/直列別に14種類が分かれている。
READMEには「TAKTはTAKT自身で作られている(dogfooding)」と書かれており、ビルトインワークフローの中に takt-default(TAKT自身の開発に使われているワークフロー)が実際に含まれている。
・読者の問い①「何ができるのか」への答え:計画・テスト作成・実装・レビュー・修正といった工程を、それぞれ別のペルソナと権限を持つステップとしてYAMLに書き、キューに積んだタスクを隔離環境で実行させられる
・問い②「何を解決するのか」:工程の順守がエージェントの気分に左右される問題。レビューを飛ばせない構造にし、指摘は修正ステップへ差し戻される
・問い③「何を代替できるのか」:CLAUDE.mdやスキルに書いた手順の強制部分。エージェント自体(Claude CodeやCodex)は代替せず、それらを部品として使う
遷移はどう決まるのか——5つの判定方法と3段フォールバック
ここが公式ドキュメントを読んでも分かりにくく、かつTAKTを理解する上で最も重要な部分だ。YAMLには次のような自然文の条件を書く。
name: plan-implement-review
initial_step: plan
max_steps: 10
steps:
- name: plan
persona: planner
edit: false
rules:
- condition: Planning complete
next: implement
- name: implement
persona: coder
edit: true
required_permission_mode: edit
rules:
- condition: Implementation complete
next: review
- name: review
persona: reviewer
edit: false
rules:
- condition: Approved
next: COMPLETE
- condition: Needs fix
next: implement # ← 修正ループ
「Planning complete」という自然文がどうやって機械的な遷移になるのか。ソースを読むと、src/core/models/status.ts に RuleMatchMethod という列挙型があり、判定方法が5つ定義されている。
重要なのは、5つのうち2つはLLMを呼ばないという点だ。src/core/workflow/phase-runner.ts の needsStatusJudgmentPhase() は、意味ラベルの候補が2つ以上あるときだけ判定フェーズが必要と返す。つまり選択肢が1つしかないステップでは判定のためのLLM呼び出しが発生せず、auto_select として確定する。並列サブステップを all() / any() で集計する aggregate も同様に機械的な処理だ。「工程を分けると呼び出しが増えてトークンが膨らむのでは」という懸念に対する、設計上の答えの一つになっている。
LLMに判定させる場合は、src/agents/judge-status-usecase.ts が3段のフォールバックを踏む。
意味ラベル候補が2つ以上"] --> B{"第1段
structured_output
JSONスキーマで回答"} B -->|成功| OK["次のステップを確定"] B -->|失敗| C{"第2段
phase3_tag
タグ検出で回答"} C -->|成功| OK C -->|失敗| D{"第3段
ai_judge
AI判定にフォールバック"} D -->|成功| OK D -->|失敗| E["RuleDetectionExhaustedError
実行を停止"] style OK fill:#19c2a8,color:#fff style E fill:#e5484d,color:#fff
3段すべてが判定に失敗した場合、TAKTは適当なステップへ進むのではなく RuleDetectionExhaustedError を投げて実行を止める。「判定できなかったのに何となく先へ進む」という曖昧な状態を作らない設計だ。
なお、公式のObservabilityガイドにはフェーズ単位のログラベルとして phase3_structured / phase3_tag / phase3_fallback が記載されている。内部の列挙型(structured_output / phase3_tag / ai_judge)とは名前が一部異なるため、ログを読むときとソースを読むときで対応を取り違えないよう注意したい。
条件式は4種類——自然文だけではない
src/core/models/workflow-rule-condition.ts を読むと、condition: に書けるものは4種類に分類されている。
| 種類 | 書き方 | 評価 |
|---|---|---|
| semantic(意味ラベル) | Planning complete |
LLMが候補から選ぶ |
| when(式) | when(findings.open.count > 0) |
状態を機械的に評価 |
| aggregate(集計) | all("...") / any("...") |
並列サブステップの結果を集計 |
| and(連結) | Approved && when(findings.open.count == 0) |
意味ラベルと式の両方を満たす |
when() が参照できる状態は context. / structured. / effect. / findings. の4つのルートに限られ、findings. 以下は型付きの閉じたスキーマになっている。findings.open.count(数値)、findings.open.bySeverity.critical(数値)、findings.provisional.fixpoint(真偽値)、findings.rounds.budgetExhausted(真偽値)などが定義済みのパスだ。
修正ループが止まらなくなったときの2つのブレーキ
レビュー→修正→再レビューのループを許す設計には、ループが終わらないリスクが付いてくる。TAKTには独立した2つの制動がある。
1つはYAMLの max_steps で、これはワークフロー全体のステップ実行回数の上限だ。ビルトインの default では30が設定されている。もう1つが src/core/workflow/engine/loop-detector.ts の LoopDetector で、同じステップが連続して何回実行されたかを数える。既定値は maxConsecutiveSameStep: 10、超過時の action は warn である。
ここは挙動を正確に把握しておきたいところで、既定の action は abort ではなく warn だ。つまり同一ステップが11回連続しても、既定設定では警告が出るだけで停止しない。実行を止めたい場合は action: abort を明示する必要がある(ignore で警告も抑制できる)。連続カウントは別のステップへ遷移した時点でリセットされるため、plan↔implementを交互に往復するようなパターンはこの検出器では捕まらず、その場合は max_steps 側の上限が効く。
なお takt exec(YAMLを書かずに始める即席モード)にはこれとは別に、Assistant・Worker・Review・Replanningの各エージェントとループ検出の閾値をまとめた設定があり、/setup から編集できる。
YAMLは実行前に4層で検証される——workflow doctorで実測した結果
上記の文法がどこまで本当に強制されるのかは、読むだけでは分からない。実際に takt をインストールし、意図的に壊した定義を takt workflow doctor に食わせて終了コードを確認した。
検証環境はmacOS(Darwin 23.5.0)・Node.js 25.2.1・takt 0.54.1、実施日は2026-07-30。まず正常な定義が通ることを確認し、そこから1箇所ずつ壊した。
# 正常な定義(意味ラベル2つ・修正ループあり)
$ takt workflow doctor t-ok
Workflow OK: .../.takt/workflows/t-ok.yaml # 終了コード 0
# ① 条件に ai() を書く
$ takt workflow doctor t-ai
[ERROR] ... steps.0.rules.0.condition: workflow rule conditions do not support ai()
[ERROR] Workflow validation failed # 終了コード 1
# ② 連結の順序を逆にする(when(...) && 意味ラベル)
$ takt workflow doctor b-rev
[ERROR] ... condition: Invalid workflow rule condition: when(findings.open.count > 0) && Planning complete
# 終了コード 1
# ③ 数値比較に文字列を渡す
$ takt workflow doctor c-typ
[ERROR] ... condition: Operator ">" requires numeric operands: "findings.open.bySeverity.critical > "high""
# 終了コード 1
# ④ findings.* を参照するが finding_contract を宣言しない
$ takt workflow doctor a-fwd
[ERROR] ... Configuration error: step "plan" uses findings.* rule but finding_contract is not configured
# 終了コード 1
4つの結果はそれぞれ別の層のバリデーションを示している。
・① 条件式のパーサ:ai() は条件式として明示的に拒否される。ソースにも「workflow rule conditions do not support ai()」という文字列がそのまま存在し、エラーメッセージと一致した
・② 連結の順序制約:and は「左が意味ラベル・右が when()」の順序しか受け付けない。逆順は文法エラーになる。実際にビルトインの merge-readiness-finding-contract-final-gate.yaml も approved && when(findings.open.count == 0 && ...) と正しい順序で書かれており、出荷されている定義がパーサの制約と一致している
・③ 静的な型検査:> のような順序比較に非数値を渡すと、実行時ではなくパース時に弾かれる。findings.open.items(配列)に > 0 を書いた場合も同じエラーになった
・④ 宣言の依存関係:findings.* を参照するには、その状態を生み出す finding_contract の宣言が必要。参照だけ書いて供給元がない定義は通らない
さらに、最初の試行では findings.total という存在しないパスを書いたところ Unsupported findings reference "findings.total" で拒否された。findings. の語彙が閉じており、綴り間違いも実行前に検出されることが確認できる。
まとめると、TAKTのYAMLは「文字列として読み込んで実行時に解釈する」タイプの設定ファイルではない。条件式は専用のパーサと型検査を通り、参照先の存在と依存関係まで実行前に検査される。1回の実行にAPIコストがかかるエージェント運用では、この事前検証の価値は小さくない。
default ワークフローの実際の抜粋。kind: workflow_call でサブワークフローを呼び、plan → write_tests → draft → peer-review → COMPLETE と遷移する。出典: nrslib/takt docs/assets/description/03-yaml-workflow.png(MIT License)インストールから隔離実行まで——takt・takt run・takt list の使い方
導入はnpmから。Nix flakesにも対応している。
# インストール(Node.js >=24.15.0 を宣言)
npm install -g takt
# Nix flakes を使う場合
nix run github:nrslib/takt
# 対話でタスクを詰めて /go →「タスクにつむ」でキューへ
takt
# キューに積んだタスクを隔離環境で実行
takt run
# 結果のブランチを管理(マージ・リトライ・再キュー・削除)
takt list
# ワークフロー定義の検証(CIに組み込める)
takt workflow doctor default
takt を引数なしで起動すると対話モードに入り、AIが要件を整理する。/go を打つとタスク案が提示され、「今すぐ実行」「GitHub Issueを作る」「タスクにつむ」「会話を続ける」から選ぶ。通常は「タスクにつむ」を選び、.takt/tasks/ に保存してから takt run でまとめて実行する流れになる。
docs/assets/description/06-isolated-tasks.png(MIT License)重要な注意点として、READMEは「今すぐ実行(Execute now)」について、worktreeによる隔離を行わず現在の作業ツリーに直接変更が入ると明記している。試したいだけのときは便利だが、既存の変更がある状態では選ばないほうがよい。
設定は ~/.takt/config.yaml に置く。最小構成は3行だ。
provider: claude # claude, claude-sdk, claude-terminal, codex, opencode, cursor, copilot, kiro, mock
model: sonnet # プロバイダーへそのまま渡される
language: en # en または ja
language: ja を指定すると日本語のビルトインが使われる。ビルトインは英語・日本語ともにワークフロー62本ずつが用意されており、この対訳の網羅性は日本語で運用する場合の実用的な差になる。
実行の痕跡は .takt/runs/ にレポート・ログ・コンテキストとして残る。observability.enabled と observability.usage_events_phase を有効にすると、フェーズ単位のトークン使用量が .jsonl で出力され、npm run analyze:usage でステップ×フェーズ×プロバイダー×モデルの表に集計できる。usageが取得できなかった呼び出しは0トークン扱いにせず usage_missing: true として区別される点は、集計の正確さを気にする運用では効いてくる。
主要コマンドは以下の通り。CLI以外に takt-acp(Agent Client Protocolエージェントとしてstdio JSON-RPCで動作)と takt-mcp(MCPサーバーとして動作し、MCPクライアントからタスクを積める)という2つのエントリポイントも同梱されている。
| コマンド | 役割 |
|---|---|
takt |
対話で要件を整理し、実行またはキューへ |
takt exec |
YAMLを書かずにAssistant/Worker/Reviewの即席モードで動かす |
takt run |
保留中のタスクをすべて実行 |
takt list |
タスクブランチの管理(マージ・リトライ・再キュー・削除) |
takt #N |
GitHub Issueをタスクとして実行 |
takt eject |
ビルトインのワークフロー・ファセットをコピーして改造 |
takt workflow init |
新しいワークフローの雛形を作る |
takt workflow doctor |
ワークフロー定義を検証(終了コードで判定可能) |
takt repertoire add |
GitHubからレパートリーパッケージを導入 |
CI向けには公式のGitHub Action(nrslib/takt-action)と、takt --pipeline --task "..." --auto-pr というパイプラインモードが用意されている。
ファセットとプロバイダー——文脈を分割し9種のAIエージェントへ配る
TAKTがステップごとに渡すプロンプトは、単一のテンプレートではなく「ファセット」と呼ばれる名前付きの部品から組み立てられる。
docs/assets/description/05-facets.png(MIT License)ビルトインとして同梱されているファセットの実数を数えると、この仕組みがどれだけ作り込まれているかが見える。
| ファセット種別 | 役割 | ビルトイン数(en) |
|---|---|---|
| personas | 誰として振る舞うか | 32 |
| instructions | いま何をするか | 83 |
| output-contracts | 何を返すか | 51 |
| knowledge | 何を知っておくべきか | 17 |
| policies | 従うべき規則 | 12 |
| workflows | 工程の定義そのもの | 62 |
takt eject default でビルトインを ~/.takt/workflows/ にコピーして改造でき、独自ペルソナは ~/.takt/personas/my-reviewer.md のようにMarkdownを置いて persona: my-reviewer と参照するだけで使える。プロンプト設計手法としての詳細は公式のFaceted Promptingにまとまっており、faceted-prompting という独立したnpmパッケージが依存に入っている。
プロバイダー(実際に動くエージェント)は src/infra/providers/ に9つのアダプタが実装されている。外部CLIが必要かどうかで導入コストが変わる点は事前に押さえておきたい。
| プロバイダー | 実行方式 | 外部CLIの要否 |
|---|---|---|
claude-sdk |
@anthropic-ai/claude-agent-sdk |
不要(Node + APIキー) |
codex |
@openai/codex-sdk |
不要(Node + APIキー) |
opencode |
@opencode-ai/sdk |
不要(Node + APIキー) |
claude |
Claude Code | 必要 |
claude-terminal |
Claude Codeを対話端末で駆動 | 必要(加えて tmux) |
copilot |
GitHub Copilot CLI | 必要 |
cursor |
Cursor Agent | 必要 |
kiro |
Kiro CLI | 必要 |
mock |
テスト用 | 不要 |
ステップごとにプロバイダーとモデルを自動選択させる auto_routing もあり、cost / balanced / performance の戦略と候補プール、ステップ名やタグによる振り分けルールを設定できる。ルーティングの判断は .takt/events/ にNDJSONとしてローカル記録され、READMEは「TAKTはルーティング判断をアップロードしない」と明記している。記録は takt telemetry status|enable|disable で確認・変更できる。
複数のエージェントに役割を割り当てて並列に走らせるという発想は、multi-agent-shogun徹底解説|将軍・家老・足軽で10AIを並列統制するOSSのような役職モデルとも重なる。TAKTの違いは、役割分担を人間が読む比喩で表現するのではなく、遷移条件・権限・出力契約という検証可能な形式に落としている点にある。またレビュー結果を構造化された findings として扱い、深刻度別の件数で遷移を決められるようにしている点は、Agent Governance Toolkit完全解説|Microsoft発のOWASP Agentic 10/10対応・本番AGガバナンス基盤が扱うようなガバナンス要件と地続きの発想だ。
類似ツールとの比較と、TAKT導入前に知っておく制約
TAKTと近い位置にあるものを、レイヤーの違いで整理する。各項目は2026-07-30時点の公式リポジトリ・公式ドキュメントの記述に基づく。
| TAKT | Claude Code単体(CLAUDE.md・スキル) | LangGraph等のフレームワーク | OpenHandsのような自律エージェント | |
|---|---|---|---|---|
| 工程の置き場所 | YAMLの状態機械(外部ファイル) | プロンプト・設定ファイルの記述 | アプリケーションのコード | エージェント内部の判断 |
| 遷移を決めるのは | TAKTのエンジン | エージェント自身 | 開発者が書いたグラフ | エージェント自身 |
| 実行前の検証 | takt workflow doctor(終了コード1で停止) |
なし | 言語の型検査に依存 | なし |
| エージェントの差し替え | 9プロバイダーを設定で切替 | Claude Codeに固定 | モデル層を差し替え | 実装に依存 |
| 主な利用形態 | 既存CLIエージェントの外付け統制 | 単体で使う | ライブラリとして組み込む | 単体で使う |
| 導入コスト | YAMLの学習+Node環境 | ほぼゼロ | コード実装が必要 | 環境構築 |
自律型エージェント側の実像はOpenHands完全ガイド:SWE-Bench 77.6%のOSS AIコーディングエージェント徹底解説で確認できる。TAKTはこの種のエージェントと競合するのではなく、工程の順序と検査を外側に持つかどうかという別の軸を扱っている。どちらが適するかは、守らせたい工程が既に決まっているか、それともタスクごとにエージェントに判断させたいかで分かれる。
導入前に把握しておくべき点も具体的に挙げておく。
・Node.js >=24.15.0 の宣言:これは比較的新しい下限で、既存のNode環境をそのまま使えない場合がある。なお筆者の環境ではNode 22.13.1でも takt --version と takt workflow doctor default は終了コード0で完了した。npmの engines は既定で助言的な指定であり実行を阻止しないためだが、宣言された下限を下回る構成は作者の想定外であり、プロバイダーSDKを含む全経路が動くことを意味しない。素直に24.15.0以上を用意するのが安全
・GitHub Releasesが0件:更新情報をReleasesの通知で追う運用は成立しない。CHANGELOG.mdかnpmを見る
・変更ペースが速い:約半年で100バージョン、open issuesは60件。CHANGELOGにはBREAKINGの表記が複数回登場する
・旧用語の情報が残っている:2026年春以前の解説記事では piece / movement という用語でTAKTが説明されていることがある。CHANGELOGによれば、v0.34.0(2026-04-03)で movements → steps、initial_movement → initial_step、max_movements → max_steps、piece_config → workflow_config へのリネームが互換エイリアス付きで入り、v0.36.0(2026-04-15)で旧用語が完全に廃止されて移行が必須になった(このとき84ファイルが一括リネームされている)。さらにv0.37.0(2026-04-20)で TAKT_PIECE_* 系のレガシー環境変数サポートが削除された。現在の用語は workflow と step で統一されているため、古い記事のYAMLをそのまま貼っても動かない
・OAuthの利用可否はプロバイダー次第:READMEはOAuthが許可されるかは提供元と用途で異なるとし、各プロバイダーの利用規約を確認するよう促している
コミュニティ側の広がりも記録しておく。Spec-Driven Development向けの実装として j5ik2o/takt-sdd が公開されており(npx create-takt-sdd で導入)、要件→ギャップ分析→設計→タスク→実装→検証の各段を部品として提供している。この作者はTAKT本体にも41コミットを入れている2番目のコントリビューターだ。開発はCodeRabbitのOSS支援プログラムのスポンサードを受けている。