Dify Agent で OCI ADB Select AI を活用したSQL生成・実行するフローの構築


## 初めに

本記事では、Dify Agent を用いて **Oracle Autonomous Database (ADB) のSelect AI機能**を連携させ、自然言語からSQL生成→実行→結果出力を自動化するワークフローの構築方法を解説します。AIを活用した業務効率化の具体例として、技術者向けの実装手順と設計思想を分かりやすく説明します。

---


## 1. カスタムツールの登録手順

### ステップ1：APIスキーマの定義
```yaml
openapi: 3.1.0
info:
  title: AI SQL Query API
  version: 1.0.0
  description: API for generating and executing SQL queries via Oracle AI integration
servers:
  - url: http://127.0.0.1:9999
    description: Local development server
paths:
  /health:
    get:
      summary: System health and database connectivity check
      operationId: healthCheck
      responses:
        '200':
          description: System status information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
        '503':
          description: Critical health issue detected
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Unexpected error during health check
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /selectai/{action}:
    post:
      summary: Execute AI-driven SQL operations
      operationId: executeAiQuery
      parameters:
        - in: path
          name: action
          required: true
          schema:
            type: string
            enum: [showsql, runsql]
            description: Operation type - showsql generates SQL, runsql executes it
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - query
              properties:
                query:
                  type: string
                  description: Input query/prompt for the requested action
                  example: "List all active users with their account balances"

      responses:
        '200':
          description: Success response varies by action
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/SqlGenerationResponse'
                  - $ref: '#/components/schemas/QueryExecutionResponse'
        '400':
          description: Invalid request parameters or syntax errors
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No SQL generated (only for showsql action)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Database operation failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          example: "Invalid action specified"
        message:
          type: string
          example: "Supported actions: showsql, runsql"
      required: [error]

    HealthResponse:
      type: object
      properties:
        status:
          type: string
          enum: [ok, degraded, critical]
        database:
          type: boolean
        pool_stats:
          type: object
          properties:
            busy:
              type: integer
            opened:
              type: integer
            max:
              type: integer
        response_time_ms:
          type: integer
        timestamp:
          type: integer
        error:
          type: string

    SqlGenerationResponse:
      type: object
      properties:
        sql:
          type: string
          description: Generated SQL statement
          example: "SELECT * FROM users WHERE status = 'active'"

    QueryExecutionResponse:
      type: object
      properties:
        columns:
          type: array
          items:
            type: string
          example: ["USER_ID", "BALANCE"]
        data:
          type: array
          items:
            type: array
            items:
              type: string
          example: [[1, "1000.00"], [2, "500.00"]]
        row_count:
          type: integer
          example: 2
```
> **ポイント**：`showsql`と`runsql`の2ステップ構造は、SQL注入リスク軽減と処理の可視性向上に有効です。

![API設定画面の例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/e3e436f3-de3f-4a7a-9cee-0a086c937973.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/3617c82f-ec8d-4906-8a57-ab3d62321e94.png)

*Difyでのカスタムツールの設定画面*

---

## 2. AIエージェントの構成方法


#### 実装ルール（必須要件）
| 項目 | 内容 |
|------|------|
| 処理フロー | 2段階プロセス厳守（生成→実行の分離） |
| 出力形式 | 最終結果を**Markdownテーブル**で返却 |


![エージェントフロー例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/58e0dc25-df71-493c-aa1a-fbd81fedb386.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/8766d6aa-a33e-4057-9d30-c84eafad2bcd.png)

手順のプロンプト：

```
# 自然言語からOracle SQLへの変換アシスタント

## ロールと目的
あなたは`executeAiQuery`ツールを通じて自然言語をOracle SQLに変換し実行する専門家です。**最終的にMarkdownテーブルを出力する必要があります**。

## 実行フロー（厳密な順序）
1. **SQL生成**  
   - **必ず**`executeAiQuery(action="showsql", query=ユーザー入力)`を呼び出す  
   - Oracle構文に準拠したSQL文を生成し`{"sql": "生成されたSQL"}`形式で返却

2. **SQL実行とテーブル変換**  
   - **必ず**`executeAiQuery(action="runsql", query=前工程SQL)`でJSON結果を取得  
   - JSONを直接Markdownテーブルに変換（このフォーマット変換を省略禁止）

## 強制ルール
- **ユーザー入力を直接SQLに変換しない**
- `action`パラメータ値を厳密に区別：`showsql`はSQL生成、`runsql`はSQL実行  
- 中間出力一切禁止。唯一許可される最終出力はMarkdownテーブル  
- 全ての操作を`executeAiQuery`ツール経由で実行

## 例
ユーザー入力：`how many regions`  
出力：
```markdown
|REGIONS_COUNT|
|-------------|
|5            |
```



---

## 3. 実行例


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/8ea6c93b-37e1-4a6d-b06c-1bd043d8e45c.png)

`executeAiQuery(action="showsql", query=ユーザー入力)`の実行ログ：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/37c3f7a6-58d7-46b1-af01-6da1a0671368.png)

`executeAiQuery(action="runsql", query=前工程SQL)`の実行ログ：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/e70dd73a-5fcc-48ad-a5d9-8af6db353156.png)

最終結果：


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3932781/485fb113-eeb2-4f0f-a584-db2fafb7cd6c.png)



---

## 4. 拡張可能性
この基盤を応用して実現可能な機能例：
1. ビジネス用ダッシュボード連携（Tableau/PowerBI）
2. チャットボット統合（Oracle ADBのAIクエリ機能を会話型UIで提供）
3. データガバナンス強化（生成SQLの自動チェックリスト適用）

---

## 参考リンク
- [OCI の Autonomous Database (ADB) に搭載された Select AI を Python で REST API を公開](https://qiita.com/engchina/items/784ff1a2fabb3ab3cd2c) 
- Dify公式ドキュメント：[カスタムツール登録ガイド](https://docs.dify.ai/)

---

## 結論
本アプローチにより、非技術者でも自然言語でデータ分析を実行可能となり、OCI ADBのAI機能とDifyの連携は、データ駆動型組織構築の有力なソリューションと言えます。