[v9.0/v8.18] Elasticsearchのsemantic_textフィールドでテキストのチャンクとEmbeddingを同時に行う

# はじめに
ベクトル検索がかなり一般的になりつつありますが、ベクトルのEmbeddingにはいろいろと面倒なこともあります。
- どこでEmbeddingするか
    - クラウドのサービス？オンプレ？
- 元のテキストも一緒に入れる
- チャンキング

ElasticsearchではIngest Pipelineを使用することで問題なく出来てはいましたが、Ingest Pipelineを作る手間は必要でした。
https://qiita.com/takeo-furukubo/items/e5d43fa734e4338b895f#ingest-pipeline%E3%81%AE%E4%BD%9C%E6%88%90

v8.15で`semantic_text`というフィールドがリリースされ、ingest pipelineを作成する手間が省けました。
https://qiita.com/daixque/items/570ec008e69099e663bf

`semantic_text`フィールドはv8.18/v9.0で少し仕様が変更となりました。
- チャンクとEmbedding(=ベクトル)が表示されなくなった
- `inner_hits`が`highlight`に変更
- multifieldで使用できるようなった

ドキュメントはこちらです。
https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html

:::note info
2025/04/16現在の最新バージョンであるv9.0.0をベースに記載
本記事の内容はEnterpriseライセンスが必要
:::

# 環境
Cloudを利用する場合はこちらの手順を行って機械学習ノードを追加してください。外部(OpenAI等)でEmbeddingする場合は必要ありません。
https://qiita.com/takeo-furukubo/items/e5d43fa734e4338b895f#%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%8E%E3%83%BC%E3%83%89%E3%81%AE%E8%BF%BD%E5%8A%A0
オンプレの場合はこちらが便利です。
https://qiita.com/takeo-furukubo/items/df17ca57203825a45da1

# 手順
## Embedding Model
### クラウドベース
OpenAI,Bedrock,Gemini等で必要な情報を作成してください。
### ElasticsearchでEmbedding
https://qiita.com/takeo-furukubo/items/51e40e0a059eb8d7aa90#e5%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E5%B1%95%E9%96%8B
こちらの手順でE5モデルを展開します。

## Inference Endpoint
Inference Endpointに対してテキストを投げるとEmbeddingが出来ます。
https://www.elastic.co/guide/en/elasticsearch/reference/current/inference-apis.html#infer-chunking-config
rerankやcompletionなども行えます。

![スクリーンショット 2025-03-21 10.08.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603229/5a37aafc-4bff-4fb7-aed2-d27ce08c42b9.png)

v8.18/v9.0からE5モデルとELSERモデルについては自動的にInference Endpointが作成されていますので、特に何もする必要はありません。

より詳しく知りたい方は弊社コンサルタントによるこちらの記事をご覧ください。
https://qiita.com/daixque/items/df699e8a2b318d593128#%E3%83%81%E3%83%A3%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0

### チャンキング
Inference Endpointでは`chunking_settings`でチャンキングを変更できます
- sentence
    - デフォルト設定
        - 250 words以内に収まるように文章単位で切り分け
        - 1文がオーバーラップ
- word
    - デフォルト設定
        -  250 words
        -  100 words overlap

ここでいう250 wordsは日本語で見た時の視覚的な250文字ではありません。
より詳しく知りたい方は弊社コンサルタントによる先ほどの記事の「チャンキング」の項目をご覧ください。
https://qiita.com/daixque/items/df699e8a2b318d593128#%E3%83%81%E3%83%A3%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0

分割は機械的に行っているので文章の意味は考慮されていません
デフォルトではsentenceになっています。
`max_chunk_size`と`sentence_overlap`を変更することで上記のデフォルト設定を変更できます。

### クラウドサービスのInference Endpoint
こちらに一覧があります。
https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html#put-inference-api-desc
１例としてGoogle Vertex AIを説明しておきます。
まずこのページを参考にservice accountのAPI Keyを作成します。
https://www.elastic.co/guide/en/serverless/current/security-connect-to-google-vertex.html
JSONファイルをダウンロードできるはずですので、それをDev Toolsで入力します。JSONをJSONの中にいれるのでちょっと工夫が必要です。
`service_account_json`に先ほどダウンロードしたJSONを貼り付けますが、`"""`で括ります。

ドキュメント
https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-google-vertex-ai.html
一部情報を隠してあります。
```json
PUT _inference/text_embedding/google_vertex_ai_embeddings
{
    "service": "googlevertexai",
    "service_settings": {
        "service_account_json": """{
  "type": "service_account",
  "project_id": "hogehoge",
  "private_key_id": "<private key id>",
  "private_key": "-----BEGIN PRIVATE KEY----- hogehoge -----END PRIVATE KEY-----\n",
  "client_email": "hogehoge",
  "client_id": "<id>",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "<url>",
  "universe_domain": "googleapis.com"
}""",
        "model_id": "textembedding-gecko-multilingual@001",
        "location": "asia-northeast1",
        "project_id": "<project id>"
    }
}
```
## インデックス設定
以下をDev Toolsで実行します。
`.multilingual-e5-small-elasticsearch`はデフォルトで作成されているE5モデルのInference Endpointです。
```
PUT test-index-e5
{
  "mappings": {
    "properties": {
      "description": {
        "type": "text",
        "fields": {
          "semantic": {
            "type": "semantic_text",
            "inference_id": ".multilingual-e5-small-elasticsearch"
          }
        }
      }
    }
  }
}
```
## データ投入
長い文章を入れないと意味がないので、弊社の8.15リリースブログを日本語にしたものを投入します。
```
POST test-index-e5/_doc/
{
  "description": "Elastic 8.15を本日一般公開いたしました。新機能8.15リリースでは、数多くの機能が追加され、関連性を微調整するためのツールが増え、モデルの柔軟性が向上し、ベクトル検索が改善されています。さらに、AIを活用したセキュリティ分析が強化され、カスタムのSIEMデータの取り込みを数分でモダナイズできるようになっています。OpenTelemetry（OTel）プロジェクトへのElastic Common Schema（ECS）およびユニバーサルプロファイリングの供与に続いて、8.15には、OTel Collector Distributionを通じたOTelファーストのデータアーキテクチャーへの移行に向けた次の大きなマイルストーンも組み込まれています。このほかのハイライトをソリューション別にご紹介すると、以下のとおりです。Elastic Searchは、すぐに使えるセマンティック検索機能と生成AI機能を搭載した、業界で最も使用されているベクトルデータベースを基盤とするAI検索アプリを実装する開発者を支援します。セマンティックテキストとリランキングを通じてセマンティック検索を検索エクスペリエンスに組み込む簡単な方法、Learning to Rankとクエリルールの一般公開（GA）、追加のサードパーティプロバイダー（Google AI/Vertex AI、Mistral、Amazon Bedrock）に対応したElasticsearchの推論APIのテクニカルプレビューなどについては、Elastic Searchのハイライトに関するブログ記事または8.15リリースノートをお読みください。Elasticオブザーバビリティは、メトリックやログ、トレースをアクション可能なITインサイトへ変換し、デジタルエコシステムに一元的なオブザーバビリティを構築します。Elastic Distribution for OpenTelemetry Collectorのテクニカルプレビュー、OLTPプロファイリングのネイティブサポート、Elastic AI Assistantの機能強化（Gemini 1.5 Proモデルコネクターを使用したGoogle Vertexなど）のGA、Azure OpenAI向けLLMオブザーバビリティのGAなどについては、Elasticオブザーバビリティのハイライトに関するブログ記事または8.15のリリースノートをお読みください。Elastic Securityは、AIを活用したセキュリティ分析でSecOpsをモダナイズし、脅威の検知、調査、対応を加速させます。生成AIを使用してカスタムデータ統合の開発を自動化する自動インポートのテクニカルプレビュー、カスタムワークフローをまたいだ自動化と意思決定ガイダンスを容易にするElastic AI Assistantの新しいAPIのGA、GoogleのGemini 1.5 ProやFlash LLMを含めるよう拡張されたLLMオプションのGAなどについては、Elastic Securityのハイライトに関するブログ記事または8.15のリリースノートの詳細をお読みください。Elastic Search AI Platformでは、検索の精度とAIのインテリジェンスを組み合わせることで、ユースケースを問わず、すべてのユーザーがコア機能強化の恩恵を受けることができます。クラスター横断検索（CCS）の複数の機能強化のGA、Elasticsearch Query Language（ES|QL）内の追加機能のGA、Kibana内でのES|QL UXのさまざまな機能強化のGA、複数の新しい機械学習機能のGA、Logstash向けの各種機能のGAなどについては、Elasticsearchプラットフォームのハイライトに関するブログ記事または8.15リリースノートをお読みください。使用を開始する使用を開始する準備は良いですか？Elastic 8.15の新機能はすべて、Elasticが最新リリースを提供するマネージドサービス、Elastic Cloudで今すぐご利用いただけます。本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。"
}
```

### データ確認
以下を実行してみます。

```
GET test-index-e5/_search
```
以下のような結果が得られます。
```
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "test-index-e5",
        "_id": "8UREtpUBqwkeZIyI1eFg",
        "_score": 1,
        "_source": {
          "description": "Elastic 8.15を本日一般公開いたしました。新機能8.15リリースでは、数多くの機能が追加され、関連性を微調整するためのツールが増え、モデルの柔軟性が向上し、ベクトル検索が改善されています。さらに、AIを活用したセキュリティ分析が強化され、カスタムのSIEMデータの取り込みを数分でモダナイズできるようになっています。OpenTelemetry（OTel）プロジェクトへのElastic Common Schema（ECS）およびユニバーサルプロファイリングの供与に続いて、8.15には、OTel Collector Distributionを通じたOTelファーストのデータアーキテクチャーへの移行に向けた次の大きなマイルストーンも組み込まれています。このほかのハイライトをソリューション別にご紹介すると、以下のとおりです。Elastic Searchは、すぐに使えるセマンティック検索機能と生成AI機能を搭載した、業界で最も使用されているベクトルデータベースを基盤とするAI検索アプリを実装する開発者を支援します。セマンティックテキストとリランキングを通じてセマンティック検索を検索エクスペリエンスに組み込む簡単な方法、Learning to Rankとクエリルールの一般公開（GA）、追加のサードパーティプロバイダー（Google AI/Vertex AI、Mistral、Amazon Bedrock）に対応したElasticsearchの推論APIのテクニカルプレビューなどについては、Elastic Searchのハイライトに関するブログ記事または8.15リリースノートをお読みください。Elasticオブザーバビリティは、メトリックやログ、トレースをアクション可能なITインサイトへ変換し、デジタルエコシステムに一元的なオブザーバビリティを構築します。Elastic Distribution for OpenTelemetry Collectorのテクニカルプレビュー、OLTPプロファイリングのネイティブサポート、Elastic AI Assistantの機能強化（Gemini 1.5 Proモデルコネクターを使用したGoogle Vertexなど）のGA、Azure OpenAI向けLLMオブザーバビリティのGAなどについては、Elasticオブザーバビリティのハイライトに関するブログ記事または8.15のリリースノートをお読みください。Elastic Securityは、AIを活用したセキュリティ分析でSecOpsをモダナイズし、脅威の検知、調査、対応を加速させます。生成AIを使用してカスタムデータ統合の開発を自動化する自動インポートのテクニカルプレビュー、カスタムワークフローをまたいだ自動化と意思決定ガイダンスを容易にするElastic AI Assistantの新しいAPIのGA、GoogleのGemini 1.5 ProやFlash LLMを含めるよう拡張されたLLMオプションのGAなどについては、Elastic Securityのハイライトに関するブログ記事または8.15のリリースノートの詳細をお読みください。Elastic Search AI Platformでは、検索の精度とAIのインテリジェンスを組み合わせることで、ユースケースを問わず、すべてのユーザーがコア機能強化の恩恵を受けることができます。クラスター横断検索（CCS）の複数の機能強化のGA、Elasticsearch Query Language（ES|QL）内の追加機能のGA、Kibana内でのES|QL UXのさまざまな機能強化のGA、複数の新しい機械学習機能のGA、Logstash向けの各種機能のGAなどについては、Elasticsearchプラットフォームのハイライトに関するブログ記事または8.15リリースノートをお読みください。使用を開始する使用を開始する準備は良いですか？Elastic 8.15の新機能はすべて、Elasticが最新リリースを提供するマネージドサービス、Elastic Cloudで今すぐご利用いただけます。本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。"
        }
      }
    ]
  }
}
```

どのようにチャンクされているか、ベクトルの値がどうなっているのかが全く見えません。
これはわざとやっています（＝隠しています）

### チャンクとベクトルの確認
とはいえ、確認したいとは思います。以下のコマンドを実行します。
```
GET test-index-e5/_search
{
  "query": {
    "match_all": {}
  },
  "fields": [ "_inference_fields" ]
}
```

`_inference_fields`に情報が隠されています。

```
"_inference_fields": {
            "description.semantic": {
              "inference": {
                "inference_id": ".multilingual-e5-small-elasticsearch",
                "model_settings": {
                  "task_type": "text_embedding",
                  "dimensions": 384,
                  "similarity": "cosine",
                  "element_type": "float"
                },
                "chunks": {
                  "description": [
                    {
                      "start_offset": 0,
                      "end_offset": 463,
                      "embeddings": [
                        0.05764432,
                        -0.041604187,
                        -0.0827228,
                        -0.006668131,
                        0.035910662,
```

`start_offset`と`end_offset`がチャンクの場所を示しています。最初のチャンクは463文字目までということになります。
これは以下のようなチャンクになっています。
250文字ではなく463文字あります。これが文字数とトークン数の違いです。
LLMに送ったときはトークンのカウント方法が変わって、違うトークン数になることもあります。
```
Elastic 8.15を本日一般公開いたしました。新機能8.15リリースでは、数多くの機能が追加され、関連性を微調整するためのツールが増え、モデルの柔軟性が向上し、ベクトル検索が改善されています。さらに、AIを活用したセキュリティ分析が強化され、カスタムのSIEMデータの取り込みを数分でモダナイズできるようになっています。OpenTelemetry（OTel）プロジェクトへのElastic Common Schema（ECS）およびユニバーサルプロファイリングの供与に続いて、8.15には、OTel Collector Distributionを通じたOTelファーストのデータアーキテクチャーへの移行に向けた次の大きなマイルストーンも組み込まれています。このほかのハイライトをソリューション別にご紹介すると、以下のとおりです。Elastic Searchは、すぐに使えるセマンティック検索機能と生成AI機能を搭載した、業界で最も使用されているベクトルデータベースを基盤とするAI検索アプリを実装する開発者を支援します。
```

ちなみに2番めはどうでしょうか？
```
                    {
                      "start_offset": 367,
                      "end_offset": 1102,
                      "embeddings": [
                        0.060885683,
                        -0.010370333,
                        -0.05912814,
                        0.01564187,
```
367文字目から始まっているのでオーバーラップしているのがわかります。
以下の部分がオーバーラップ部分です。
```
Elastic Searchは、すぐに使えるセマンティック検索機能と生成AI機能を搭載した、業界で最も使用されているベクトルデータベースを基盤とするAI検索アプリを実装する開発者を支援します。
```

# 検索
`semantic_text`フィールドに対する検索では、何も指定しないとどのチャンクがヒットしているのかがわかりません。`highlight`を使用してチャンクを表示するようにします。

以下を実行します。
```
GET test-index-e5/_search
{
  "query": {
    "semantic": {
      "field": "description.semantic",
      "query": "セキュリティ機能について"
    }
  },
  "highlight": {
    "fields": {
      "description.semantic": {
        "order": "score",
        "number_of_fragments": 1
      }
    }
  }
}
```

以下のような結果になります。正しくセキュリティに関するチャンクが取り出されています。
```
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.9173356,
    "hits": [
      {
        "_index": "test-index-e5",
        "_id": "8UREtpUBqwkeZIyI1eFg",
        "_score": 0.9173356,
        "_source": {
          "description": "Elastic 8.15を本日一般公開いたしました。新機能8.15リリースでは、数多くの機能が追加され、関連性を微調整するためのツールが増え、モデルの柔軟性が向上し、ベクトル検索が改善されています。さらに、AIを活用したセキュリティ分析が強化され、カスタムのSIEMデータの取り込みを数分でモダナイズできるようになっています。OpenTelemetry（OTel）プロジェクトへのElastic Common Schema（ECS）およびユニバーサルプロファイリングの供与に続いて、8.15には、OTel Collector Distributionを通じたOTelファーストのデータアーキテクチャーへの移行に向けた次の大きなマイルストーンも組み込まれています。このほかのハイライトをソリューション別にご紹介すると、以下のとおりです。Elastic Searchは、すぐに使えるセマンティック検索機能と生成AI機能を搭載した、業界で最も使用されているベクトルデータベースを基盤とするAI検索アプリを実装する開発者を支援します。セマンティックテキストとリランキングを通じてセマンティック検索を検索エクスペリエンスに組み込む簡単な方法、Learning to Rankとクエリルールの一般公開（GA）、追加のサードパーティプロバイダー（Google AI/Vertex AI、Mistral、Amazon Bedrock）に対応したElasticsearchの推論APIのテクニカルプレビューなどについては、Elastic Searchのハイライトに関するブログ記事または8.15リリースノートをお読みください。Elasticオブザーバビリティは、メトリックやログ、トレースをアクション可能なITインサイトへ変換し、デジタルエコシステムに一元的なオブザーバビリティを構築します。Elastic Distribution for OpenTelemetry Collectorのテクニカルプレビュー、OLTPプロファイリングのネイティブサポート、Elastic AI Assistantの機能強化（Gemini 1.5 Proモデルコネクターを使用したGoogle Vertexなど）のGA、Azure OpenAI向けLLMオブザーバビリティのGAなどについては、Elasticオブザーバビリティのハイライトに関するブログ記事または8.15のリリースノートをお読みください。Elastic Securityは、AIを活用したセキュリティ分析でSecOpsをモダナイズし、脅威の検知、調査、対応を加速させます。生成AIを使用してカスタムデータ統合の開発を自動化する自動インポートのテクニカルプレビュー、カスタムワークフローをまたいだ自動化と意思決定ガイダンスを容易にするElastic AI Assistantの新しいAPIのGA、GoogleのGemini 1.5 ProやFlash LLMを含めるよう拡張されたLLMオプションのGAなどについては、Elastic Securityのハイライトに関するブログ記事または8.15のリリースノートの詳細をお読みください。Elastic Search AI Platformでは、検索の精度とAIのインテリジェンスを組み合わせることで、ユースケースを問わず、すべてのユーザーがコア機能強化の恩恵を受けることができます。クラスター横断検索（CCS）の複数の機能強化のGA、Elasticsearch Query Language（ES|QL）内の追加機能のGA、Kibana内でのES|QL UXのさまざまな機能強化のGA、複数の新しい機械学習機能のGA、Logstash向けの各種機能のGAなどについては、Elasticsearchプラットフォームのハイライトに関するブログ記事または8.15リリースノートをお読みください。使用を開始する使用を開始する準備は良いですか？Elastic 8.15の新機能はすべて、Elasticが最新リリースを提供するマネージドサービス、Elastic Cloudで今すぐご利用いただけます。本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。"
        },
        "highlight": {
          "description.semantic": [
            "Elastic Securityは、AIを活用したセキュリティ分析でSecOpsをモダナイズし、脅威の検知、調査、対応を加速させます。生成AIを使用してカスタムデータ統合の開発を自動化する自動インポートのテクニカルプレビュー、カスタムワークフローをまたいだ自動化と意思決定ガイダンスを容易にするElastic AI Assistantの新しいAPIのGA、GoogleのGemini 1.5 ProやFlash LLMを含めるよう拡張されたLLMオプションのGAなどについては、Elastic Securityのハイライトに関するブログ記事または8.15のリリースノートの詳細をお読みください。Elastic Search AI Platformでは、検索の精度とAIのインテリジェンスを組み合わせることで、ユースケースを問わず、すべてのユーザーがコア機能強化の恩恵を受けることができます。クラスター横断検索（CCS）の複数の機能強化のGA、Elasticsearch Query Language（ES|QL）内の追加機能のGA、Kibana内でのES|QL UXのさまざまな機能強化のGA、複数の新しい機械学習機能のGA、Logstash向けの各種機能のGAなどについては、Elasticsearchプラットフォームのハイライトに関するブログ記事または8.15リリースノートをお読みください。使用を開始する使用を開始する準備は良いですか？"
          ]
        }
      }
    ]
  }
}
```

# まとめ
`semantic_text`フィールドを使うと非常に簡単にベクトル検索ができるようになります。
チャンキングを自分で制御したいという要望にも勿論応えられます（これまで通り外部でチャンキングしてベクトルを保存する）。
また、multi fieldに対応するようになったので、わざわざ`copy_to`などで別のフィールドにテキスト検索用に作る必要がなくなりました。

より便利になったElasticsearchのベクトル検索をぜひご利用ください。