Vertex AI Searchの作成でハマった点

# Vertex AI Searchの作成でハマった点

### はじめに

Vertex AI Searchは、Agent Builderで作成できるアプリケーションの1つです。

※ 本記事の内容は、リソースのアップデートにより変更されている可能性があります。

### 1. データストアの構造化/非構造化の選択

- データストア作成時に構造化/非構造化を指定する必要がある
- 誤った設定でデータをインポートするとエラーが発生

#### エラー例
1. 非構造化データストアに構造化データをインポートした場合：
`
To create document without content, content config of data store must be NO_CONTENT.`

2. 構造化データストアにBQからメタデータをインポートした場合：
`To create document with content, the content config of data store must be CONTENT_REQUIRED.`

#### データストア作成時の設定
- 構造化データ：`contentConfig`を`NO_CONTENT`または省略
- 非構造化データ：`contentConfig`を`CONTENT_REQUIRED`

```bash
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-H "X-Goog-User-Project: $PROJECT_ID" \
"https://discoveryengine.googleapis.com/v1/projects/$PROJECT_ID/locations/global/collections/default_collection/dataStores?dataStoreId=$DATA_STORE_ID" \
-d "{
  \"displayName\": \"$DATA_STORE_DISPLAY_NAME\",
  \"industryVertical\": \"GENERIC\",
  \"solutionTypes\": [\"SOLUTION_TYPE_SEARCH\"],
  \"contentConfig\": \"CONTENT_REQUIRED\"
}"
```

### 2. メタデータの要件

#### BigQueryの非構造化データストアの場合
- 必須のメタデータフィールドが必要
- メタデータなしではエラーが発生

エラー例：
```json
{
  "error": {
    "code": 400,
    "message": "BQ table (project_id: xx, dataset_id: xx, table_id: xx) \nMissing field id with type STRING and is in REQUIRED mode\n",
    "status": "INVALID_ARGUMENT"
  }
}
```

#### 必要なBigQueryテーブル構造
```json
[
  {
    "name": "id",
    "mode": "REQUIRED",
    "type": "STRING",
    "fields": []
  },
  {
    "name": "jsonData",
    "mode": "NULLABLE",
    "type": "STRING",
    "fields": []
  },
  {
    "name": "content",
    "type": "RECORD",
    "mode": "NULLABLE",
    "fields": [
      {
        "name": "mimeType",
        "type": "STRING",
        "mode": "NULLABLE"
      },
      {
        "name": "uri",
        "type": "STRING",
        "mode": "NULLABLE"
      }
    ]
  }
]
```

### 3. Terraformでの制限事項

#### 現在の制限
- 空のデータストアとアプリの作成までしかできない
- データの追加はAPIまたはコンソールから行う必要がある


#### エラー対応

```
エラー：│ Error: Error creating DataStore: googleapi: Error 403: Your application is authenticating by using local Application Default Credentials. The discoveryengine.googleapis.com API requires a quota project, which is not set by default. To learn how to set your quota project, see https://cloud.google.com/docs/authentication/adc-troubleshooting/user-creds .
```

- 下記を参考に対処した
  https://medium.com/google-cloud/vertex-search-and-conversation-364cdc591167

```hcl
provider "google" {
  project = <PROJECT ID>
  region  = var.region
  user_project_override = true 
  billing_project = var.project_id
}
```

#### Terrafrom コード
```hcl
# データソースの作成
resource "google_discovery_engine_data_store" "default" {
  location                    = "global"
  data_store_id               = "test"
  display_name                = "test"
  industry_vertical           = "GENERIC"
  content_config              = "CONTENT_REQUIRED"
  solution_types              = ["SOLUTION_TYPE_SEARCH"]
  create_advanced_site_search = true
  document_processing_config {
    default_parsing_config  {
      digital_parsing_config {}
    }
  }
}

# APPの作成
resource "google_discovery_engine_search_engine" "default" {
  engine_id = "test"
  collection_id = "default_collection"
  location = google_discovery_engine_data_store.default.location
  display_name = "test"
  data_store_ids = [google_discovery_engine_data_store.default.data_store_id]
  common_config {
    company_name = "Test Company"
  }
  search_engine_config {
    search_add_ons = ["SEARCH_ADD_ON_LLM"]
    search_tier    = "SEARCH_TIER_ENTERPRISE" 
  }
}
```

### 4. データソースの違い

#### BigQueryとCloud Storageの比較
- データストアやアプリの作成は共通のAPI/Terraformコード
- データインポート時のパラメータが異なる

#### インポートコマンド例

1. BigQueryの場合：
    ```bash
    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    "https://discoveryengine.googleapis.com/v1/projects/$PROJECT_ID/locations/global/collections/default_collection/dataStores/$DATA_STORE_ID/branches/0/documents:import" \
    -d "{
      \"bigquerySource\": {
        \"projectId\": \"$PROJECT_ID\",
        \"datasetId\":\"$DATASET_ID\",
        \"tableId\": \"$TABLE_ID\",
        \"dataSchema\": \"document\"
      },
     \"reconciliationMode\": \"INCREMENTAL\"
    }"
    ```

2. Cloud Storageの場合：
    ```bash
    curl -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      -H "X-Goog-User-Project: $PROJECT_ID" \
      "https://discoveryengine.googleapis.com/v1alpha/projects/$PROJECT_ID/locations/global/collections/default_collection/dataStores/$DATA_STORE_ID/branches/0/documents:import" \
      -d "{
        \"gcsSource\": {
          \"inputUris\": [\"${INPUT_FILE_PATTERN}\"],
          \"dataSchema\": \"document\",
        },
        \"reconciliationMode\": \"INCREMENTAL\"
      }"
    ```

### 5. その他の注意点

1. Cloud Storageの制限
   - パス指定：`gs://bucket/folder/*`の形式が可能
   - 再帰的なインポートは不可
   - フォルダ直下のオブジェクトのみ読み込み可能

2. リソース削除後の再作成
   - 削除後2-3時間待つ必要がある
   - 同じIDでの再作成時にエラーが発生