takt/docs/faceted-prompting.ja.md
2026-02-09 10:43:08 +09:00

399 lines
18 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.

# Faceted Prompting: AIプロンプトへの関心の分離
## 問題
マルチエージェントシステムが複雑になるにつれ、プロンプトはモリシックになる。1つのプロンプトファイルにエージェントの役割、行動規範、タスク固有の指示、ドメイン知識、出力形式がすべて混在する。これは3つの問題を生む。
1. **再利用できない** — 2つのステップが同じレビュアーのペルソナを必要としつつ指示が異なる場合、プロンプト全体を複製するしかない
2. **暗黙的な結合** — コーディング規約を変更すると、それを参照するすべてのプロンプトを編集する必要がある
3. **責任の不明確さ** — プロンプトのどの部分がエージェントの「役割」を定義し、どの部分が「やるべきこと」を定義しているのか区別がつかない
## アイデア
ソフトウェア工学の基本原則である**関心の分離Separation of Concerns**をプロンプト設計に適用する。
エージェントごとに1つのモリシックなプロンプトを書く代わりに、「何の関心を扱っているか」で独立した再利用可能なファイルに分解する。そしてワークフローのステップごとに宣言的に合成する。
## 5つの関心
Faceted Promptingはプロンプトを5つの直交する関心に分解する。
| 関心 | 答える問い | 例 |
|------|-----------|-----|
| **Persona** | *誰*として判断するか? | 役割定義、専門性 |
| **Policy** | *何を*守るか? | 禁止事項、品質基準、優先順位 |
| **Instruction** | *何を*するか? | 目標、ステップ固有の手順 |
| **Knowledge** | *何を*参照するか? | 前提知識、ドメイン資料、API仕様 |
| **Output Contract** | *どう*出すか? | 出力構造、レポートテンプレート |
各関心はそれぞれのディレクトリに独立したファイルMarkdownまたはテンプレートとして格納される。
```
workflows/ # ワークフロー定義
personas/ # WHO — 役割定義
policies/ # RULES — 禁止事項・品質基準
instructions/ # WHAT — ステップ手順
knowledge/ # CONTEXT — 前提知識・参照資料
output-contracts/ # OUTPUT — 出力契約テンプレート
```
### 配置と各ファセットの典型例
LLMに渡せるスロットは **system prompt****user message** の2つだけである。5つの関心はこの2つに配置される。
```
System Prompt:
┌─────────────────────────────────────────────┐
│ Persona — エージェントの役割・専門性・行動姿勢 │
└─────────────────────────────────────────────┘
User Message:
┌─────────────────────────────────────────────┐
│ Knowledge — 判断の前提となる参照資料 │
│ Instruction — このステップでやるべき手順 │
│ Output Contract — 出力の構造定義 │
│ Policy — 守るべきルール・禁止事項・品質基準 │
└─────────────────────────────────────────────┘
```
Personaはエージェントの**identity**であり、タスクによって変わらない。system promptに置くことでLLMの応答全体を方向付ける。残りの4つはステップごとに変わるため、user messageに合成する。
Policyをuser messageの末尾に配置するのは意図的な設計判断である。LLMは直前に読んだ内容に強く影響されるrecency効果。禁止事項やREJECT基準といった制約は、出力生成の直前にあることで遵守されやすくなる。Knowledge → Instruction → Policyという流れは「文脈を理解 → 作業を理解 → 制約を確認」という自然な認知順序にもなっている。
以下に各ファセットの典型的なファイル例を示す。
#### Persona — `personas/architecture-reviewer.md`
system promptに配置される。役割の定義、境界、行動姿勢のみを含む。
```markdown
# Architecture Reviewer
あなたはソフトウェアアーキテクチャの専門家です。
コードの構造・設計・保守性を評価します。
## 役割の境界
**やること:**
- 構造・設計の妥当性検証
- コード品質の評価
- 変更スコープの適切性確認
**やらないこと:**
- セキュリティ脆弱性のレビューSecurity Reviewerの仕事
- 自分でコードを書く
## 行動姿勢
- 完璧な設計を求めない。現状の制約下で最善かを判断する
- 既存コードベースの規約を尊重する
```
以下の4つはすべてuser messageに配置される。
#### Policy — `policies/coding.md`
タスクをまたがって適用される共有ルール。規範的(「こうすべき」)。
```markdown
# コーディングポリシー
## 原則
| 原則 | 基準 |
|------|------|
| DRY | 3回以上の重複はREJECT |
| Fail Fast | 不正状態は早期にエラー |
| 最小権限 | 必要最小限のスコープ |
## 禁止事項
- **未使用コード** - 「念のため」のメソッド、将来用フィールド
- **オブジェクトの直接変更** - スプレッド演算子で新規作成
- **フォールバックの濫用** - `?? 'default'` で不確実性を隠さない
```
#### Knowledge — `knowledge/architecture.md`
判断の前提となる参照情報。記述的(「こうなっている」)。
```markdown
# アーキテクチャ知識
## レイヤー構造
依存の方向: 上位層 → 下位層(逆方向禁止)
| レイヤー | 責務 | 依存先 |
|---------|------|--------|
| Controller | HTTPリクエスト処理 | Service |
| Service | ビジネスロジック | Repository |
| Repository | データアクセス | なし |
## ファイル構成
| 基準 | 判定 |
|------|------|
| 1ファイル300行超 | 分割を検討 |
| 1ファイルに複数の責務 | REJECT |
| 循環依存 | REJECT |
```
#### Instruction — `instructions/implement.md`
このステップ固有の手順。命令形で記述する。
```markdown
計画に基づいてタスクを実装してください。
**やること:**
1. 変更スコープを宣言する
2. コードを実装する
3. テストを書いて実行する
4. 判断ログを記録する
**注意:** Previous Response がある場合は差し戻しです。
指摘事項を踏まえて修正してください。
```
#### Output Contract — `output-contracts/review.md`
出力の構造を定義する。エージェントはこの形式に従って出力する。
````markdown
```markdown
# アーキテクチャレビュー
## 結果: APPROVE / REJECT
## サマリー
{1-2文で結果を要約}
## 確認した観点
| 観点 | 結果 | 備考 |
|------|------|------|
| 構造・設計 | ✅ | - |
| コード品質 | ✅ | - |
| テストカバレッジ | ✅ | - |
## 問題点REJECTの場合
| # | 場所 | 問題 | 修正案 |
|---|------|------|--------|
| 1 | `src/file.ts:42` | 問題の説明 | 修正方法 |
```
````
#### 合成後の完全なプロンプト
上記5つのファイルがエンジンによって合成され、最終的にLLMに渡される形を示す。
**System Prompt:**
```markdown
# Architecture Reviewer
あなたはソフトウェアアーキテクチャの専門家です。
コードの構造・設計・保守性を評価します。
## 役割の境界
**やること:**
- 構造・設計の妥当性検証
- コード品質の評価
- 変更スコープの適切性確認
**やらないこと:**
- セキュリティ脆弱性のレビューSecurity Reviewerの仕事
- 自分でコードを書く
## 行動姿勢
- 完璧な設計を求めない。現状の制約下で最善かを判断する
- 既存コードベースの規約を尊重する
```
**User Message:**
```markdown
## Knowledge
### レイヤー構造
依存の方向: 上位層 → 下位層(逆方向禁止)
| レイヤー | 責務 | 依存先 |
|---------|------|--------|
| Controller | HTTPリクエスト処理 | Service |
| Service | ビジネスロジック | Repository |
| Repository | データアクセス | なし |
### ファイル構成
| 基準 | 判定 |
|------|------|
| 1ファイル300行超 | 分割を検討 |
| 1ファイルに複数の責務 | REJECT |
| 循環依存 | REJECT |
---
## User Request
ユーザー認証モジュールにJWTトークンの検証機能を追加してください。
---
## Instructions
計画に基づいてタスクを実装してください。
**やること:**
1. 変更スコープを宣言する
2. コードを実装する
3. テストを書いて実行する
4. 判断ログを記録する
**注意:** Previous Response がある場合は差し戻しです。
指摘事項を踏まえて修正してください。
---
## Output Contract
以下のフォーマットでレポートを出力してください。
\```markdown
# アーキテクチャレビュー
## 結果: APPROVE / REJECT
## サマリー
{1-2文で結果を要約}
## 確認した観点
| 観点 | 結果 | 備考 |
|------|------|------|
| 構造・設計 | ✅ | - |
| コード品質 | ✅ | - |
| テストカバレッジ | ✅ | - |
## 問題点REJECTの場合
| # | 場所 | 問題 | 修正案 |
|---|------|------|--------|
| 1 | `src/file.ts:42` | 問題の説明 | 修正方法 |
\```
---
## Policy
### 原則
| 原則 | 基準 |
|------|------|
| DRY | 3回以上の重複はREJECT |
| Fail Fast | 不正状態は早期にエラー |
| 最小権限 | 必要最小限のスコープ |
### 禁止事項
- **未使用コード** - 「念のため」のメソッド、将来用フィールド
- **オブジェクトの直接変更** - スプレッド演算子で新規作成
- **フォールバックの濫用** - `?? 'default'` で不確実性を隠さない
```
このように、独立したファイルがランタイムで1つのプロンプトに組み立てられる。ファイルの内容を変えればプロンプトが変わり、別のファイルを指せば別の組み合わせになる。
### なぜこの5つか
**Persona** と **Instruction** は最低限必要なもの — エージェントが誰で、何をすべきかを定義する必要がある。しかし実際には、さらに3つの関心が独立した軸として現れる。
- **Policy** はタスクをまたがって適用される規約・基準を捉える。「何を守るか」を定義する関心であり、禁止事項フォールバック濫用の禁止、未使用コードの禁止、品質基準REJECT/APPROVE判定、優先順位正確性 > 速度)を含む。コーディングポリシーは機能実装でもバグ修正でも同じように適用される。ポリシーは「横断的関心事」であり、作業内容に関係なく守るべきルールを規定する。
- **Knowledge** はエージェントが判断の前提として参照する情報を捉える。アーキテクチャ文書はプランナーにもレビュアーにも関係がある。ナレッジをインストラクションから分離することで重複を防ぎ、インストラクションを手順に集中させる。ナレッジは記述的「このドメインはこうなっている」であり、規範的「こうすべき」なルールはPolicyに属する。
- **Output Contract** は作業そのものとは独立した出力構造を捉える。同じレビューフォーマットをアーキテクチャレビュアーとセキュリティレビュアーの両方で使える。出力形式の変更がエージェントの振る舞いに影響しない。
## 宣言的な合成
Faceted Promptingの中核メカニズムは**宣言的な合成**である。ワークフロー定義が各ステップでプロンプトの内容を直接埋め込むのではなく、*どの*関心を組み合わせるかを宣言する。
主要な特性は次の通り。
- **各ファイルは1つの関心だけを持つ。** ペルソナファイルには役割と専門性のみを記述し、ステップ固有の手順は書かない。
- **合成は宣言的。** ワークフローは*どの*関心を組み合わせるかを記述し、プロンプトを*どう*組み立てるかは記述しない。
- **自由に組み合わせ可能。** 同じ `coder` ペルソナを異なるポリシーとインストラクションで異なるステップに使える。
- **ファイルが再利用の単位。** 同じファイルを指すことでポリシーをワークフロー間で共有する。
### TAKTでの実装例
[TAKT](https://github.com/nrslib/takt) はFaceted PromptingをYAMLベースのワークフロー定義「ピース」と呼ぶで実装している。builtinの各ファセットは、各ステップTAKTでは「ムーブメント」と呼ぶから bare name で直接参照できる。セクションマップは「名前とファイル名が異なる」場合のカスタムエイリアス用途でのみ任意で使う。
```yaml
name: my-workflow
max_iterations: 10
initial_movement: plan
movements:
- name: implement
persona: coder # WHO — builtins/{lang}/personas/coder.md
policy: coding # RULES — builtins/{lang}/policies/coding.md
instruction: implement # WHAT — builtins/{lang}/instructions/implement.md
knowledge: architecture # CONTEXT — builtins/{lang}/knowledge/architecture.md
edit: true
rules:
- condition: Implementation complete
next: review
- name: review
persona: architecture-reviewer # 異なる WHO
policy: review # 異なる RULES
instruction: review # 異なる WHAT共有も可能
knowledge: architecture # 同じ CONTEXT — 再利用
output_contracts:
report:
- name: review.md
format: architecture-review # OUTPUT — builtins/{lang}/output-contracts/architecture-review.md
edit: false
rules:
- condition: Approved
next: COMPLETE
- condition: Needs fix
next: implement
```
エンジンは各キーをファイルに解決し、内容を読み込み、実行時に最終的なプロンプトを組み立てる。ワークフローの作者がモノリシックなプロンプトを書くことはない — どのファセットを組み合わせるかを選択するだけである。
## 既存手法との違い
| 手法 | 内容 | 本手法との違い |
|------|------|--------------|
| **Decomposed Prompting** (Khot et al.) | *タスク*をサブタスクに分解して異なるLLMに委任 | 分解するのはタスクではなく*プロンプトの構造* |
| **Modular Prompting** | XML/HTMLタグを使った単一プロンプト内のセクション分け | 関心を*独立ファイル*に分離し、宣言的に合成する |
| **Prompt Layering** (Airia) | エンタープライズ向けのスタック可能なプロンプトセグメント | 管理ツールであり、プロンプト設計のデザインパターンではない |
| **PDL** (IBM) | データパイプライン向けのYAMLベースプロンプトプログラミング言語 | 制御フローif/for/model呼び出しが焦点で、関心の分離ではない |
| **Role/Persona Prompting** | 役割を割り当ててレスポンスを方向付ける | ペルソナは5つの関心の1つにすぎない — ポリシー、インストラクション、ナレッジ、出力契約も分離する |
核心的な違いは次の点にある。既存手法は*タスク*(何をするか)を分解するか、*プロンプトの構造*どう書式化するかを整理する。Faceted Promptingは*プロンプトの関心*(各部分がなぜ存在するか)を独立した再利用可能な単位に分解する。
## 実用上の利点
**ワークフロー作者にとって:**
- コーディングポリシーを1つのファイルで変更すれば、それを使うすべてのワークフローに反映される
- 既存のペルソナ、ポリシー、インストラクションを組み合わせて新しいワークフローを作れる
- 各ファイルを単一の責務に集中させられる
**チームにとって:**
- プロンプトを複製せずにプロジェクト間でポリシー(品質基準・禁止事項)を標準化できる
- ドメイン専門家がナレッジファイルを管理し、ワークフロー設計者がインストラクションを管理する分業ができる
- 個々の関心を独立してレビューできる
**エンジンにとって:**
- プロンプト組み立ては決定的 — 同じワークフロー定義とファイルからは同じプロンプトが構築される
- ポリシーの配置を最適化できる(例: recency効果を活用して末尾に配置し、制約遵守を強化
- 各関心を他の部分に影響を与えずにステップごとに注入・省略・上書きできる
## まとめ
Faceted Promptingは、関心の分離Separation of ConcernsをAIプロンプト工学に適用するデザインパターンである。プロンプトを5つの独立した関心 — Persona、Policy、Instruction、Knowledge、Output Contract — に分解し、宣言的に合成することで、再利用可能で保守しやすく透明なマルチエージェントワークフローを実現する。