# 機能設計書 28-テキスト生成

## 概要

本ドキュメントは、Giselleシステムにおける「テキスト生成」機能の設計仕様を定義する。この機能は、AIモデル（Anthropic、Google、OpenAI、Perplexity）を使用してテキストコンテンツを生成するコア機能である。

### 本機能の処理概要

**業務上の目的・背景**：AIワークフローの中核機能として、各種LLM（Large Language Model）を活用したテキスト生成が必要である。この機能は、複数のAIプロバイダーに対応し、ツール連携（GitHub、PostgreSQL、Web検索等）や構造化出力にも対応する高度なテキスト生成エンジンである。

**機能の利用シーン**：
- ワークフロー内のテキスト生成ノードが実行される場合
- チャットインターフェースでユーザーの質問に回答する場合
- ドキュメント生成やコード生成などの自動化タスク
- GitHub Issueへの自動コメント生成
- 要約や翻訳などのテキスト変換タスク

**主要な処理内容**：
1. 生成コンテキストから入力メッセージを構築する
2. 使用するLLMプロバイダーとモデルを決定する
3. ツール連携の設定（GitHub、PostgreSQL、Web検索等）を準備する
4. AI SDK経由でストリーミングテキスト生成を実行する
5. 生成結果をチャンク単位でストレージに保存する
6. 完了時に生成出力（テキスト、推論、ソース）を保存する

**関連システム・外部連携**：
- AI Provider APIs: Anthropic Claude、Google Gemini、OpenAI GPT、Perplexity
- GitHub API: ツール連携時
- PostgreSQL: ツール連携時
- Storage: 生成結果の永続化

**権限による制御**：
- LLMプロバイダーのAPIキー認証
- ツール連携時は各サービスの認証情報が必要

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ワークフローエディタ画面 | 主画面 | テキスト生成ノードの実行 |
| 18 | プレイグラウンド画面 | 主画面 | アプリ実行テストでのテキスト生成 |

## 機能種別

AI処理 / ストリーミング生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | GiselleContext | Yes | Giselleコンテキスト | 有効なコンテキストオブジェクト |
| generation | RunningGeneration | Yes | 実行中の生成オブジェクト | status="running"であること |
| metadata | GenerationMetadata | No | 生成メタデータ | - |
| onComplete | function | No | 完了時コールバック | - |
| onError | function | No | エラー時コールバック | - |

### 入力データソース

- Generation: 生成コンテキスト（operationNode、sourceNodes、inputs）
- Storage: ファイル、過去の生成結果
- Vault: 暗号化されたAPIキーとシークレット

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| generatedText | string | 生成されたテキスト |
| reasoningText | string | 推論テキスト（Reasoningモデル使用時） |
| sources | Source[] | 参照ソース（Web検索使用時） |
| usage | GenerationUsage | トークン使用量 |
| messages | UIMessage[] | 生成メッセージ履歴 |

### 出力先

- Storage: `generations/{generationId}/ui-message-chunks.jsonl`
- Storage: 生成オブジェクト（CompletedGeneration）

## 処理フロー

### 処理シーケンス

```
1. 生成実行準備（useGenerationExecutor）
   ├─ 生成ステータスをrunningに更新
   └─ ファイルリゾルバー等の初期化

2. メッセージ構築
   └─ buildMessageObjectでコンテキストノードから入力メッセージを構築

3. ツールセット準備
   ├─ GitHubツールの設定（PAT/Secret認証）
   ├─ PostgreSQLツールの設定
   ├─ OpenAI Web検索ツールの設定
   ├─ Anthropic Web検索ツールの設定
   └─ Google検索・URLコンテキストの設定

4. AI Gateway設定
   └─ プロバイダー別のヘッダーとオプション設定

5. ストリーミング生成
   ├─ streamText呼び出し
   ├─ onChunkでキャンセルチェック
   ├─ smoothStreamで出力を平滑化
   └─ toUIMessageStreamでUI形式に変換

6. チャンク保存
   └─ batchWriterで定期的にストレージに書き込み

7. 完了処理
   ├─ ツールクリーンアップ
   ├─ テキスト、推論、ソースの抽出
   ├─ finishGenerationで結果保存
   └─ onCompleteコールバック呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ContentGenerationNode?}
    B -->|Yes| C[generateContentV2]
    B -->|No| D[useGenerationExecutor]
    D --> E[buildMessageObject]
    E --> F[ツールセット準備]
    F --> G{GitHubツール?}
    G -->|Yes| H[GitHub認証設定]
    G -->|No| I{PostgreSQLツール?}
    H --> I
    I -->|Yes| J[PostgreSQL接続設定]
    I -->|No| K{Web検索?}
    J --> K
    K -->|Yes| L[Web検索ツール設定]
    K -->|No| M[streamText呼び出し]
    L --> M
    M --> N[ストリーミング処理]
    N --> O{キャンセル?}
    O -->|Yes| P[abort]
    O -->|No| Q[チャンク保存]
    Q --> R{完了?}
    R -->|No| N
    R -->|Yes| S[ツールクリーンアップ]
    S --> T[出力抽出]
    T --> U[finishGeneration]
    U --> V[コールバック]
    V --> W[終了]
    C --> E
    P --> W
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-01 | プロバイダー選択 | LLMプロバイダーはノード設定に基づく | 常時 |
| BR-28-02 | ツール上限 | ツール使用時はstepCountでループを制限 | ツール使用時 |
| BR-28-03 | キャンセル対応 | 生成中にステータスがcancelledになったらabort | ストリーミング中 |
| BR-28-04 | エラー記録 | AI SDKエラーはFailedGenerationとして記録 | エラー発生時 |
| BR-28-05 | 平滑化 | smoothStreamで1秒遅延、行単位でチャンキング | ストリーミング時 |

### 計算ロジック

**トークン使用量**：
- inputTokens: 入力メッセージのトークン数
- outputTokens: 生成されたテキストのトークン数
- totalTokens: inputTokens + outputTokens

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 生成取得 | Storage (generations/) | SELECT | 現在の生成データ取得 |
| チャンク保存 | Storage (generations/{id}/ui-message-chunks.jsonl) | INSERT/APPEND | ストリーミングチャンク保存 |
| 生成更新 | Storage (generations/) | UPDATE | 完了/失敗ステータスと結果保存 |

### テーブル別操作詳細

#### Storage: generations/{generationId}

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | status | "running" → "completed"/"failed" | 完了時 |
| UPDATE | outputs | GenerationOutput[] | 完了時 |
| UPDATE | usage | inputTokens, outputTokens, totalTokens | 完了時 |
| UPDATE | messages | UIMessage[] | 完了時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| INVALID_MODEL | ValidationError | 指定されたモデルIDが不正 | 有効なモデルIDを指定 |
| API_ERROR | ExternalError | AI API呼び出しに失敗 | リトライまたはプロバイダ確認 |
| TOOL_ERROR | RuntimeError | ツール実行に失敗 | ツール設定を確認 |
| SECRET_ERROR | AuthError | シークレット復号に失敗 | シークレット設定を確認 |
| ABORT_ERROR | CancelError | 生成がキャンセルされた | 正常終了として扱う |

### リトライ仕様

- API呼び出しエラー: AI SDKの内部リトライに依存
- キャンセル: リトライなし（意図的な中断）

## トランザクション仕様

- チャンク保存はバッチライターで非同期実行
- 完了処理で全データを一括保存
- 部分的な失敗はFailedGenerationとして記録

## パフォーマンス要件

- ストリーミング開始: 1秒以内（First Token Time）
- チャンク保存間隔: バッチサイズに依存
- 全体完了: モデルとプロンプト長に依存

## セキュリティ考慮事項

- APIキーはVaultで暗号化管理
- シークレット（PAT、接続文字列）は復号後即使用
- ツールクリーンアップでリソースを確実に解放
- 生成結果に機密情報が含まれる可能性に注意

## 備考

- generateContentV2はContentGenerationNode用の新実装
- smoothStreamは1秒遅延で出力を平滑化（UX向上）
- Reasoningモデルはbudget tokensを設定（デフォルト4096）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

生成コンテキストと出力の構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/protocol/src/generation/index.ts` | Generation型とステータス |
| 1-2 | output.ts | `packages/protocol/src/generation/output.ts` | GenerationOutput型 |
| 1-3 | text-generation.ts | `packages/protocol/src/node/operations/text-generation.ts` | TextGenerationNode型 |

**読解のコツ**: TextGenerationNodeのcontentにはllm、tools、outputの設定が含まれる。

#### Step 2: エントリーポイントを理解する

generateContent関数の全体構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | generate-content.ts | `packages/giselle/src/generations/generate-content.ts` | 関数シグネチャと分岐 |

**主要処理フロー**:
1. **69-81行目**: generateContent関数シグネチャ
2. **87-95行目**: ContentGenerationNode判定とV2への分岐
3. **97-506行目**: V1実装（useGenerationExecutor使用）
4. **577-861行目**: V2実装（generateContentV2関数）

#### Step 3: メッセージ構築を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | utils.ts | `packages/giselle/src/generations/utils.ts` | buildMessageObject関数 |

#### Step 4: ツール連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | tools.ts | `packages/giselle/src/generations/v2/tools.ts` | buildToolSet関数 |
| 4-2 | postgres.ts | `packages/giselle/src/generations/tools/postgres.ts` | PostgreSQLツール |

#### Step 5: 生成実行ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | use-generation-executor.ts | `packages/giselle/src/generations/internal/use-generation-executor.ts` | 生成実行の共通処理 |

### プログラム呼び出し階層図

```
generateContent (generate-content.ts)
    │
    ├─ isContentGenerationNode判定
    │      │
    │      ├─ Yes → generateContentV2
    │      │
    │      └─ No → useGenerationExecutor
    │
    └─ useGenerationExecutor
           │
           ├─ setGeneration (status: running)
           │
           ├─ buildMessageObject
           │      └─ ファイル、生成結果、画像等のリゾルブ
           │
           ├─ ツールセット準備
           │      ├─ GitHubツール
           │      ├─ PostgreSQLツール
           │      └─ Web検索ツール
           │
           ├─ streamText (AI SDK)
           │      │
           │      ├─ model (AI Gateway経由)
           │      ├─ messages
           │      ├─ tools
           │      └─ callbacks (onChunk, onError, onFinish)
           │
           ├─ toUIMessageStream
           │
           ├─ batchWriter
           │      └─ storage.setBlob (チャンク保存)
           │
           └─ finishGeneration
                  │
                  ├─ outputs構築
                  ├─ usage取得
                  └─ setGeneration (status: completed)
```

### データフロー図

```
[入力]                      [処理]                           [出力]

generation ─────────────▶ buildMessageObject
                              │
                              ▼
                         ModelMessage[]
                              │
                              ▼
                         streamText ─────────▶ AI Provider API
                              │
                              ▼
                         UIMessageStream
                              │
                              ├─▶ チャンク ──────▶ ui-message-chunks.jsonl
                              │
                              └─▶ 完了時
                                    │
                                    ├─▶ text
                                    ├─▶ reasoningText
                                    ├─▶ sources
                                    └─▶ usage
                                          │
                                          ▼
                                    finishGeneration
                                          │
                                          ▼
                                    CompletedGeneration ────▶ Storage
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| generate-content.ts | `packages/giselle/src/generations/generate-content.ts` | ソース | メイン実装 |
| use-generation-executor.ts | `packages/giselle/src/generations/internal/use-generation-executor.ts` | ソース | 実行ユーティリティ |
| utils.ts | `packages/giselle/src/generations/utils.ts` | ソース | メッセージ構築 |
| tools.ts | `packages/giselle/src/generations/v2/tools.ts` | ソース | ツールセット構築 |
| postgres.ts | `packages/giselle/src/generations/tools/postgres.ts` | ソース | PostgreSQLツール |
| index.ts | `packages/protocol/src/generation/index.ts` | ソース | Generation型 |
| text-generation.ts | `packages/protocol/src/node/operations/text-generation.ts` | ソース | TextGenerationNode型 |
| giselle.ts | `packages/giselle/src/giselle.ts` | ソース | Giselleクラス（メソッド公開） |
