# 機能設計書 83-PostgreSQLツール

## 概要

本ドキュメントは、Giselleプラットフォームにおけるテキスト生成時のPostgreSQLツール連携機能の設計を定義する。この機能は、AIモデルがテキスト生成中にPostgreSQLデータベースに対してクエリを実行し、テーブル構造の取得やSQLクエリの実行を行えるようにする。

### 本機能の処理概要

**業務上の目的・背景**：AIワークフローにおいて、データベースとの連携は多くのユースケースで必要となる。レポート生成、データ分析、システム状態の確認など、データベースの情報を基にした意思決定や文書作成を自動化するために、AIモデルがPostgreSQLデータベースを直接参照できる機能が求められる。本機能は、Vercel AI SDKのツール機能を活用し、テキスト生成ノードからデータベース操作を可能にする。

**機能の利用シーン**：
- テキスト生成ノードでAIがデータベースのテーブル構造を理解し、適切なクエリを生成する場合
- 売上データや在庫情報を取得して分析レポートを自動生成する場合
- ユーザー情報やトランザクションデータを参照した自動応答を行う場合
- データベーススキーマを理解してドキュメントを生成する場合

**主要な処理内容**：
1. ユーザーがテキスト生成ノードでPostgreSQLツールを設定（接続文字列、使用ツール選択）
2. テキスト生成実行時にbuildToolSet関数でPostgreSQLツールセットを構築
3. シークレットから接続文字列を復号化
4. pg.Poolでデータベース接続プールを初期化
5. AIモデルがツールを呼び出すと、対応するSQLクエリが実行される
6. クエリ結果がAIモデルに返却され、応答生成に活用される
7. 生成完了後にコネクションプールをクリーンアップ

**関連システム・外部連携**：
- PostgreSQLデータベース
- node-postgres（pg）ライブラリ
- Vercel AI SDK（ツール機能）

**権限による制御**：PostgreSQL接続ユーザーの権限に依存。接続文字列で指定されたユーザーのアクセス権限内でのみ操作可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ワークフローエディタ画面 | 補助機能 | テキスト生成ノードでのPostgreSQLツール設定 |

## 機能種別

外部システム連携 / ツール実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tools | string[] | Yes | 使用するPostgreSQLツール名の配列 | 有効なツール名であること |
| secretId | SecretId | Yes | 接続文字列を格納したシークレットID | 有効なSecretId形式 |

### 入力データソース

- ノード設定: TextGenerationContent.tools.postgres
- シークレットストレージ: 暗号化されたPostgreSQL接続文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| toolSet | ToolSet | AI SDKで使用可能なツールセット |
| toolSet.postgres_getTableStructure | Tool | テーブル構造取得ツール |
| toolSet.postgres_query | Tool | SQLクエリ実行ツール |
| cleanup | function | コネクションプールのクリーンアップ関数 |

### 出力先

- テキスト生成処理: generateContent関数内でツールとして使用

## 処理フロー

### 処理シーケンス

```
1. テキスト生成リクエスト受信
   └─ TextGenerationContentにPostgreSQLツール設定を含む
2. ツールセット構築（buildToolSet）
   └─ ツール設定からPostgreSQLツールを識別
3. シークレット復号化
   └─ secretIdからPostgreSQL接続文字列を取得・復号
4. コネクションプール初期化
   └─ pg.Pool({connectionString})で接続プール生成
5. PostgreSQLツール生成（createPostgresTool）
   └─ 選択されたツールのみToolSetに追加
6. AI生成処理
   └─ AIモデルが必要に応じてツールを呼び出し
7. ツール実行
   └─ PostgreSQLクエリを実行し、結果を返却
8. クリーンアップ
   └─ pool.end()でコネクションプールを終了
```

### フローチャート

```mermaid
flowchart TD
    A[テキスト生成リクエスト] --> B{PostgreSQLツール設定あり?}
    B -->|No| Z[通常の生成処理]
    B -->|Yes| C[シークレットID取得]
    C --> D[接続文字列復号化]
    D --> E{復号化成功?}
    E -->|No| F[警告ログ出力]
    F --> Z
    E -->|Yes| G[pg.Pool初期化]
    G --> H[使用ツール取得]
    H --> I[createPostgresTool実行]
    I --> J[ToolSetに追加]
    J --> K[AI生成処理]
    K --> L{ツール呼び出し?}
    L -->|No| M[cleanup実行]
    L -->|Yes| N[PostgreSQLクエリ実行]
    N --> O[結果返却]
    O --> K
    M --> P[生成完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-83-01 | ツール選択制限 | useToolsに含まれるツールのみ生成 | 常時 |
| BR-83-02 | ツール名プレフィックス | ツール名には"postgres_"プレフィックスを付与 | 常時 |
| BR-83-03 | クエリ長制限 | SQLクエリは1000文字以内 | queryツール使用時 |
| BR-83-04 | 接続プールクリーンアップ | 生成完了後にpool.end()を実行 | 常時 |
| BR-83-05 | エラーハンドリング | クエリエラー時はエラー情報を返却 | クエリ失敗時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| getTableStructure | information_schema.columns | SELECT | publicスキーマのテーブル構造を取得 |
| query | 任意 | 任意 | ユーザー指定のSQLクエリを実行 |

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

#### getTableStructureの場合

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | table_name, column_name, data_type, is_nullable | table_schema = 'public' | ordinal_positionでソート |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | シークレットID未定義 | ツールをスキップしてログ出力 |
| - | 警告 | 接続文字列復号化失敗 | ツールをスキップしてログ出力 |
| - | 警告 | useToolsが配列でない | ツールをスキップしてログ出力 |
| - | エラー | SQLクエリ実行エラー | エラー情報をツール結果として返却 |
| - | エラー | 未知のツール名 | Error throw |

### リトライ仕様

データベース接続エラーに対するリトライは、pg.Poolのデフォルト動作に従う。

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

各クエリは自動コミットで実行。明示的なトランザクション管理は行わない。

## パフォーマンス要件

- ツールセット構築時間: < 100ms
- コネクションプール: デフォルト設定（pg.Poolのデフォルト）
- クエリタイムアウト: pg.Poolのデフォルト設定

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

- 接続文字列は暗号化してシークレットストレージに保存
- 接続文字列はログに出力しない
- SQLインジェクションリスク: AIモデルが生成するクエリに対する直接的な防御なし（ユーザーの責任で適切な権限設定を推奨）
- 最小権限の原則に基づく接続ユーザー設定を推奨
- 読み取り専用ユーザーの使用を推奨

## 備考

- 対応するPostgreSQLツールは2種類（getTableStructure、query）
- AIモデルがツールを自律的に選択して呼び出す
- 生成完了後のクリーンアップが重要（コネクションリーク防止）

---

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

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

### 推奨読解順序

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

PostgreSQLツールの型定義とスキーマを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | text-generation.ts | `packages/protocol/src/node/operations/text-generation.ts` | PostgresTool型定義（85-89行目） |
| 1-2 | postgres.ts | `packages/language-model-registry/src/tools/postgres.ts` | 2種類のツール定義とスキーマ |

**読解のコツ**: defineTool関数でname、title、description、schemaを定義。queryツールにはZodスキーマあり、getTableStructureにはなし。

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

ツールセット構築の起点を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | build-tool-set.ts | `packages/giselle/src/generations/v2/tools/build-tool-set.ts` | postgresケース（137-180行目） |

**主要処理フロー**:
1. **137-148行目**: シークレットID取得と検証
2. **149-158行目**: 接続文字列復号化
3. **159-169行目**: useTools配列検証
4. **170-178行目**: createPostgresTool呼び出しとcleanup関数登録

#### Step 3: PostgreSQLツール生成を理解する

createPostgresTool関数の詳細を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | postgres.ts | `packages/giselle/src/generations/v2/tools/postgres.ts` | createPostgresTool関数（7-76行目） |

**主要処理フロー**:
- **7-17行目**: 関数シグネチャ（connectionString、toolDefs、useTools、contextを受け取る）
- **18行目**: pg.Poolでコネクションプール初期化
- **22-25行目**: useToolsに含まれるツールのみをフィルタリング
- **27-45行目**: getTableStructure実装
- **47-61行目**: query実装
- **69-74行目**: cleanup関数（pool.end()）

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

```
generateContent (generate-content.ts)
    │
    ├─ buildToolSet (build-tool-set.ts)
    │      │
    │      ├─ getLanguageModelTool("postgres")
    │      │
    │      ├─ decryptSecret (secrets/index.ts)
    │      │
    │      └─ createPostgresTool (postgres.ts)
    │             │
    │             ├─ pg.Pool({connectionString})
    │             │
    │             └─ tool (ai SDK)
    │                    │
    │                    └─ execute: pool.query()
    │
    ├─ streamText / generateText (AI SDK)
    │      │
    │      └─ ツール呼び出し → PostgreSQLクエリ実行
    │
    └─ cleanup()
           │
           └─ pool.end()
```

### データフロー図

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

TextGenerationContent ───▶ buildToolSet ───▶ ToolSet + cleanup
        │                       │
        ▼                       ▼
    tools.postgres        createPostgresTool
        │                       │
        ▼                       ▼
    secretId ───▶ decryptSecret ───▶ connectionString
                                │
                                ▼
                            pg.Pool
                                │
                                ▼
                    [AI生成中のツール呼び出し]
                                │
                    ┌───────────┴───────────┐
                    ▼                       ▼
            getTableStructure           query
                    │                       │
                    ▼                       ▼
        information_schema.columns    ユーザー指定SQL
                    │                       │
                    └───────────┬───────────┘
                                ▼
                          Query Results
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| text-generation.ts | `packages/protocol/src/node/operations/text-generation.ts` | ソース | PostgresTool型定義 |
| postgres.ts | `packages/language-model-registry/src/tools/postgres.ts` | ソース | ツール定義とスキーマ |
| build-tool-set.ts | `packages/giselle/src/generations/v2/tools/build-tool-set.ts` | ソース | ツールセット構築のエントリーポイント |
| postgres.ts | `packages/giselle/src/generations/v2/tools/postgres.ts` | ソース | createPostgresTool実装 |
| generate-content.ts | `packages/giselle/src/generations/generate-content.ts` | ソース | テキスト生成処理（ツール使用） |
