229 lines
7.9 KiB
Markdown
229 lines
7.9 KiB
Markdown
# TAKT 実行エンジン詳細
|
||
|
||
## サブエージェントの起動方法
|
||
|
||
全ての movement は `codex exec` でサブエージェントを起動して実行する。
|
||
**あなた(Team Lead)が直接作業することは禁止。**
|
||
|
||
### 実行フロー(Write + Bash)
|
||
|
||
1. プロンプト全文を一時ファイルへ保存する
|
||
2. Bash tool で `codex exec` を実行する
|
||
3. `stdout` を movement の出力として扱う
|
||
|
||
```bash
|
||
# 例
|
||
codex exec --full-auto - < "$tmp_prompt_file"
|
||
```
|
||
|
||
### permission_mode のマッピング
|
||
|
||
コマンド引数で解析された `permission_mode` を以下にマップして `codex exec` に渡す。
|
||
|
||
- `$takt coding --permit-full タスク`
|
||
- `permission_mode = "danger-full-access"`
|
||
- 実行: `codex exec --sandbox danger-full-access - < /tmp/...`
|
||
- `$takt coding --permit-edit タスク`
|
||
- `permission_mode = "full-auto"`
|
||
- 実行: `codex exec --full-auto - < /tmp/...`
|
||
- `$takt coding タスク`
|
||
- `permission_mode = "default"`
|
||
- 実行: `codex exec - < /tmp/...`
|
||
|
||
## 通常 Movement の実行
|
||
|
||
通常の movement(`parallel` フィールドなし)は、`codex exec` を1回実行する。
|
||
|
||
1. プロンプトを構築する(後述の「プロンプト構築」参照)
|
||
2. movement名を含めない安全なランダム名(例: `/tmp/takt-prompt-{timestamp}-{uuid}.md`)で保存する
|
||
3. `codex exec {権限オプション} - < /tmp/...` を実行する
|
||
4. `stdout` を受け取り Rule 評価で次 movement を決定する
|
||
|
||
## Parallel Movement の実行
|
||
|
||
`parallel` フィールドを持つ movement は、複数サブステップを並列実行する。
|
||
|
||
### 実行手順
|
||
|
||
1. parallel 配列の各サブステップごとにプロンプトを構築する
|
||
2. 各プロンプトを substep名を含めない安全なランダム名で保存する
|
||
3. **1つのメッセージで** サブステップ数分の Bash tool(`codex exec`)を並列実行する
|
||
4. 各 `stdout` を収集する
|
||
5. 各サブステップの `rules` で条件マッチを判定する
|
||
6. 親 movement の `rules` で aggregate 評価(`all()` / `any()`)を行う
|
||
|
||
### サブステップ条件マッチ判定
|
||
|
||
各サブステップ出力に対する判定優先順位:
|
||
|
||
1. `[STEP:N]` タグがあればインデックスで照合(最後のタグを採用)
|
||
2. タグがなければ出力全文と条件文の意味一致で判定
|
||
|
||
マッチした condition 文字列を記録し、親 movement の aggregate 評価に使う。
|
||
|
||
## セクションマップの解決
|
||
|
||
ピースYAMLトップレベルの `personas:`, `policies:`, `instructions:`, `output_contracts:`, `knowledge:` はキーとファイルパスの対応表。movement 内ではキー名で参照する。
|
||
|
||
### 解決手順
|
||
|
||
1. ピースYAMLを読み込む
|
||
2. 各セクションマップのパスを、**ピースYAMLファイルのディレクトリ基準**で絶対パスへ変換する
|
||
3. movement のキー参照(例: `persona: coder`)から実ファイルを Read で取得する
|
||
|
||
例: ピースが `~/.agents/skills/takt/pieces/default.yaml` の場合
|
||
- `personas.coder: ../facets/personas/coder.md` → `~/.agents/skills/takt/facets/personas/coder.md`
|
||
- `policies.coding: ../facets/policies/coding.md` → `~/.agents/skills/takt/facets/policies/coding.md`
|
||
- `instructions.plan: ../facets/instructions/plan.md` → `~/.agents/skills/takt/facets/instructions/plan.md`
|
||
|
||
## プロンプト構築
|
||
|
||
各 movement 実行時、以下を上から順に結合してプロンプトを作る。
|
||
|
||
1. ペルソナ(`persona:` 参照先 .md 全文)
|
||
2. 区切り線 `---`
|
||
3. ポリシー(`policy:` 参照先 .md。複数可)
|
||
4. 区切り線 `---`
|
||
5. 実行コンテキスト(cwd / piece / movement / iteration)
|
||
6. ナレッジ(`knowledge:` 参照先 .md)
|
||
7. インストラクション(`instruction:` または `instruction_template:`)
|
||
8. タスク(`{task}` 未使用時は末尾に自動追加)
|
||
9. 前回出力(`pass_previous_response: true` のとき)
|
||
10. レポート出力指示(`report` または `output_contracts.report` があるとき)
|
||
11. ステータスタグ出力指示(`rules` があるとき)
|
||
12. ポリシーリマインダー(ポリシーを末尾再掲)
|
||
|
||
### テンプレート変数展開
|
||
|
||
インストラクション内のプレースホルダーを置換する。
|
||
|
||
- `{task}`: ユーザー入力タスク
|
||
- `{previous_response}`: 前 movement 出力
|
||
- `{iteration}`: ピース全体イテレーション
|
||
- `{max_movements}`: 最大イテレーション数
|
||
- `{movement_iteration}`: 当該 movement 実行回数
|
||
- `{report_dir}`: `.takt/runs/{slug}/reports`
|
||
- `{report:ファイル名}`: 指定レポート内容(存在しない場合は `(レポート未作成)`)
|
||
|
||
## レポート出力指示と保存
|
||
|
||
movement がレポートを要求する場合、プロンプト末尾に必須指示を注入する。
|
||
|
||
### 形式1: name + format
|
||
|
||
```yaml
|
||
report:
|
||
name: 01-plan.md
|
||
format: plan
|
||
```
|
||
|
||
`output_contracts`(または `report_formats`)のキー参照先内容を読み込み、出力契約として渡す。
|
||
|
||
### 形式2: 複数レポート配列
|
||
|
||
```yaml
|
||
report:
|
||
- Summary: summary.md
|
||
- Scope: 01-scope.md
|
||
```
|
||
|
||
各レポートを見出し付き ` ```markdown ` ブロックで出力するよう指示する。
|
||
|
||
### 抽出と保存(Team Lead が実施)
|
||
|
||
`codex exec` 出力から ` ```markdown ` ブロックを抽出し、`{report_dir}/{ファイル名}` に Write で保存する。
|
||
|
||
- 実行ディレクトリ: `.takt/runs/{YYYYMMDD-HHmmss}-{slug}/`
|
||
- 保存先:
|
||
- `reports/`
|
||
- `context/knowledge/`
|
||
- `context/policy/`
|
||
- `context/previous_responses/`(`latest.md` を含む)
|
||
- `logs/`
|
||
- `meta.json`
|
||
|
||
## ステータスタグ出力指示
|
||
|
||
movement に `rules` がある場合、最後に1つだけタグを出力するよう指示する。
|
||
|
||
```text
|
||
[STEP:0] = {rules[0].condition}
|
||
[STEP:1] = {rules[1].condition}
|
||
...
|
||
```
|
||
|
||
- `ai("...")` は括弧を外した条件文を表示する
|
||
- parallel サブステップでも同様に適用する
|
||
|
||
## Rule 評価
|
||
|
||
### 通常 Movement
|
||
|
||
1. 出力中の `[STEP:N]` を検出(複数なら最後を採用)
|
||
2. 該当 index の rule を採用
|
||
3. タグがない場合は全文を読み condition と意味照合して最も近い rule を採用
|
||
|
||
### Parallel Movement(Aggregate)
|
||
|
||
- `all("X")`: 全サブステップが `X` に一致
|
||
- `any("X")`: いずれかが `X` に一致
|
||
- `all("X", "Y")`: サブステップ位置対応で一致
|
||
|
||
親 rules を上から順に評価し、最初の一致を採用する。
|
||
|
||
### 不一致時
|
||
|
||
どの rule にも一致しない場合は ABORT し、不一致理由をユーザーへ報告する。
|
||
|
||
## ループ検出
|
||
|
||
### 基本
|
||
|
||
- 同じ movement が連続3回以上なら警告
|
||
- `max_movements` 到達で ABORT
|
||
|
||
### カウンター
|
||
|
||
- `iteration`: 全体実行回数
|
||
- `movement_iteration[name]`: movement 別実行回数
|
||
- `consecutive_count[name]`: 連続実行回数
|
||
|
||
## Loop Monitors
|
||
|
||
`loop_monitors` がある場合、指定サイクルを監視する。
|
||
|
||
1. movement 遷移履歴を記録する
|
||
2. `cycle` が `threshold` 回以上連続出現したら judge を実行する
|
||
3. judge は `persona` + `instruction_template` + `rules` でプロンプト構築する
|
||
4. judge も同じく `codex exec` で起動する
|
||
5. judge の評価結果 `next` で遷移先を上書きする
|
||
|
||
## 状態遷移の全体像
|
||
|
||
```text
|
||
[開始]
|
||
↓
|
||
ピースYAML読み込み + セクションマップ解決
|
||
↓
|
||
実行ディレクトリ作成
|
||
↓
|
||
initial_movement 取得
|
||
↓
|
||
┌─→ codex exec で movement 実行(通常/parallel)
|
||
│ ↓
|
||
│ 出力受信
|
||
│ ↓
|
||
│ レポート抽出・保存
|
||
│ ↓
|
||
│ Loop Monitor チェック(必要時 judge を codex exec で実行)
|
||
│ ↓
|
||
│ Rule 評価(タグ優先、未タグ時は意味照合)
|
||
│ ↓
|
||
│ next 決定
|
||
│ ├── COMPLETE → 終了報告
|
||
│ ├── ABORT → エラー報告
|
||
│ └── movement名 → 次 movement
|
||
│ ↓
|
||
└──────────────────────┘
|
||
```
|