takt/docs/spec-aggregate-conditions.md
nrslib 70651f8dd8 feat: ai() 条件式によるAI遷移判断とパラレルステップ実行を実装 (#9, #20)
- rules の condition に ai("...") 式を追加し、別AIが遷移先を判断する仕組みを導入
- ワークフローステップに parallel フィールドを追加し、サブステップの並列実行を実装
- all()/any() 集約条件の仕様書を追加
2026-01-30 14:53:25 +09:00

105 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 集約条件 `all()` / `any()` 仕様
## 背景
パラレルステップでは複数のサブステップが並列実行される。各サブステップは自身のルールで結果approved, rejected 等)を判定するが、親ステップが「全体としてどう遷移するか」を決定する必要がある。
現状、親ステップの遷移判定は結合テキストに対する `ai()` 評価かタグ検出しかない。しかし、「全員が承認したら次へ」「1人でも却下したらやり直し」といった集約判定はルールベースで十分であり、AI呼び出しは不要。
## 目的
パラレルステップの親ルールに `all("condition")` / `any("condition")` 構文を追加し、サブステップの判定結果をルールベースで集約する。
## YAML 構文
```yaml
- name: parallel-review
parallel:
- name: arch-review
agent: ~/.takt/agents/default/architect.md
rules:
- condition: approved
next: _
- condition: rejected
next: _
- name: security-review
agent: ~/.takt/agents/default/security-reviewer.md
rules:
- condition: approved
next: _
- condition: rejected
next: _
rules:
- condition: all("approved")
next: COMPLETE
- condition: any("rejected")
next: implement
```
## 式のセマンティクス
| 式 | 意味 |
|---|------|
| `all("X")` | 全サブステップの判定結果が `X` のとき真 |
| `any("X")` | 1つ以上のサブステップの判定結果が `X` のとき真 |
「判定結果」とは、サブステップのルール評価でマッチしたルールの `condition` 値を指す。
## エッジケースの定義
| ケース | `all("X")` | `any("X")` |
|--------|-----------|-----------|
| 全サブステップが X | true | true |
| 一部が X | false | true |
| いずれも X でない | false | false |
| 判定結果なし(ルール未定義 or マッチなし) | false | そのサブステップは判定対象外 |
| サブステップ 0 件 | false | false |
| 非パラレルステップで使用 | false | false |
`all()` は「全員が確実に X」を要求するため、判定不能なサブステップがあれば false。
`any()` は「誰か1人でも X」を探すため、判定不能なサブステップは無視する。
## 評価の優先順位
親ステップの `rules` 配列は先頭から順に評価される。各ルールの種類に応じた評価方式が適用される。
| 順位 | 種類 | 評価方式 | コスト |
|------|------|---------|--------|
| 1 | `all()` / `any()` | サブステップの判定結果を集計 | なし |
| 2 | 通常条件(`done` 等) | 結合テキストで `[STEP:N]` タグ検出 | なし |
| 3 | `ai("...")` | AI judge 呼び出し | API 1回 |
最初にマッチしたルールで遷移が確定する。`all()` / `any()` を先に書けば、マッチした時点で `ai()` は呼ばれない。
## 他の条件式との混在
同一の `rules` 配列内で自由に混在できる。
```yaml
rules:
- condition: all("approved") # 集約(高速)
next: COMPLETE
- condition: any("rejected") # 集約(高速)
next: implement
- condition: ai("判断が難しい場合") # AI フォールバック
next: manual-review
```
## サブステップのルール
サブステップの `rules` はサブステップ自身の判定結果を決めるために使う。`next` フィールドはパラレル文脈では使用されない(親の `rules` が遷移を決定する)。スキーマ互換性のため `next` は必須のまま残し、値は任意とする。
## ステータスタグの注入
親ステップの全ルールが `all()` / `any()` / `ai()` のいずれかである場合、ステータスタグ(`[STEP:N]` 系)の注入をスキップする。タグ検出が不要なため。
## 変更対象
| ファイル | 変更内容 |
|---------|---------|
| `src/models/types.ts` | `WorkflowRule` に集約条件フラグを追加 |
| `src/config/workflowLoader.ts` | `all()` / `any()` パターンの検出と正規化 |
| `src/workflow/engine.ts` | 集約条件の評価ロジックを追加 |
| `src/workflow/instruction-builder.ts` | ステータスタグスキップ条件を拡張 |
| テスト | パース、評価、エッジケース、混在ルール |