Azure AI サービス

このセクションでは、AzureVectorStore をセットアップしてドキュメントの埋め込みを保存し、Azure AI 検索サービスを使用して類似性検索を実行する手順を説明します。

Azure AI 検索 (英語) は、Microsoft の大規模な AI プラットフォームの一部である、多用途のクラウドホスト型クラウド情報検索システムです。他の機能の中でも特に、ユーザーはベクトルベースのストレージと検索を使用して情報をクエリできます。

前提条件

  1. Azure サブスクリプション: Azure サービスを使用するには、Azure サブスクリプション (英語) が必要です。

  2. Azure AI 検索サービス: AI 検索サービス (英語) を作成します。サービスが作成されたら、Settings の Keys セクションから管理者 apiKey を取得し、Overview セクションの Url フィールドからエンドポイントを取得します。

  3. (オプション) Azure OpenAI サービス: Azure OpenAI サービス (英語) を作成します。NOTE: Azure Open AI サービスにアクセスするには、別のフォームに記入する必要がある場合があります。サービスが作成されたら、Resource Management の Keys and Endpoint セクションからエンドポイントと apiKey を取得します。

構成

起動時に、コンストラクターで関連する initialize-schema boolean プロパティを true に設定するか、Spring Boot を使用している場合は application.properties ファイルで …​initialize-schema=true を設定することでオプトインしている場合、AzureVectorStore は AI 検索サービスインスタンス内に新しいインデックスを作成しようとします。

これは互換性を損なう変更です! 以前のバージョンの Spring AI では、このスキーマ初期化はデフォルトで行われていました。

あるいは、手動でインデックスを作成することもできます。

AzureVectorStore をセットアップするには、インデックス名とともに上記の前提条件から取得した設定が必要です。

  • Azure AI 検索エンドポイント

  • Azure AI 検索キー

  • (オプション) Azure OpenAI API エンドポイント

  • (オプション) Azure OpenAI API キー

これらの値は OS 環境変数として指定できます。

export AZURE_AI_SEARCH_API_KEY=<My AI Search API Key>
export AZURE_AI_SEARCH_ENDPOINT=<My AI Search Index>
export OPENAI_API_KEY=<My Azure AI API Key> (Optional)

Azure および Open AI の実装は、Embeddings インターフェースをサポートする有効な OpenAI の実装に置き換えることができます。たとえば、Azure の実装の代わりに、Spring AI の Open AI または TransformersEmbedding の実装を埋め込みに使用できます。

依存関係

Spring AI の自動構成およびスターターモジュールのアーティファクト名に大幅な変更がありました。詳細については、アップグレードノートを参照してください。

これらの依存関係をプロジェクトに追加します。

1. 埋め込みインターフェースの実装を選択します。次の中から選択できます。

  • OpenAI 埋め込み

  • Azure AI 埋め込み

  • ローカルセンテンス Transformers の埋め込み

<dependency>
   <groupId>org.springframework.ai</groupId>
   <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.ai</groupId>
 <artifactId>spring-ai-starter-model-azure-openai</artifactId>
</dependency>
<dependency>
 <groupId>org.springframework.ai</groupId>
 <artifactId>spring-ai-starter-model-transformers</artifactId>
</dependency>

2. Azure (AI 検索) ベクトルストア

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-azure-store</artifactId>
</dependency>
依存関係管理のセクションを参照して、Spring AI の部品表をビルドファイルに追加してください。

プロパティの構成

Spring Boot 構成で次のプロパティを使用して、Azure ベクトルストアをカスタマイズできます。

プロパティ デフォルト値

spring.ai.vectorstore.azure.url

spring.ai.vectorstore.azure.api-key

spring.ai.vectorstore.azure.use-keyless-auth

false

spring.ai.vectorstore.azure.initialize-schema

false

spring.ai.vectorstore.azure.index-name

spring_ai_azure_vector_store

spring.ai.vectorstore.azure.default-top-k

4

spring.ai.vectorstore.azure.default-similarity-threshold

0.0

spring.ai.vectorstore.azure.content-field-name

コンテンツ

spring.ai.vectorstore.azure.embedding-field-name

埋め込み

spring.ai.vectorstore.azure.metadata-field-name

メタデータ

サンプルコード

アプリケーションで Azure SearchIndexClient を構成するには、次のコードを使用できます。

@Bean
public SearchIndexClient searchIndexClient() {
  return new SearchIndexClientBuilder().endpoint(System.getenv("AZURE_AI_SEARCH_ENDPOINT"))
    .credential(new AzureKeyCredential(System.getenv("AZURE_AI_SEARCH_API_KEY")))
    .buildClient();
}

To create a vector store, you can use the following code by injecting the SearchIndexClient bean created in the above sample along with an EmbeddingModel provided by the Spring AI library that implements the desired Embeddings interface.

@Bean
public VectorStore vectorStore(SearchIndexClient searchIndexClient, EmbeddingModel embeddingModel) {

  return AzureVectorStore.builder(searchIndexClient, embeddingModel)
    .initializeSchema(true)
    // Define the metadata fields to be used
    // in the similarity search filters.
    .filterMetadataFields(List.of(MetadataField.text("country"), MetadataField.int64("year"),
            MetadataField.date("activationDate")))
    .defaultTopK(5)
    .defaultSimilarityThreshold(0.7)
    .indexName("spring-ai-document-index")
    .build();
}

フィルター式で使用されるメタデータキーのすべてのメタデータフィールド名と型を明示的にリストする必要があります。上記のリストには、フィルター可能なメタデータフィールド (型 TEXT の country、型 INT64 の year、および型 BOOLEAN の active ) が登録されています。

フィルタリング可能なメタデータフィールドが新しいエントリで拡張された場合は、このメタデータを含むドキュメントを (再) アップロード / 更新する必要があります。

メインコードで、いくつかのドキュメントを作成します。

List<Document> documents = List.of(
	new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("country", "BG", "year", 2020)),
	new Document("The World is Big and Salvation Lurks Around the Corner"),
	new Document("You walk forward facing the past and you turn back toward the future.", Map.of("country", "NL", "year", 2023)));

ドキュメントをベクトルストアに追加します。

vectorStore.add(documents);

最後に、クエリに似たドキュメントを取得します。

List<Document> results = vectorStore.similaritySearch(
    SearchRequest.builder()
      .query("Spring")
      .topK(5).build());

すべてが順調に進めば、"Spring AI rocks!!" というテキストを含むドキュメントを取得できるはずです。

メタデータのフィルタリング

AzureVectorStore では、汎用の移植可能なメタデータフィルターを利用することもできます。

例: 次のいずれかのテキスト式言語を使用できます。

vectorStore.similaritySearch(
   SearchRequest.builder()
      .query("The World")
      .topK(TOP_K)
      .similarityThreshold(SIMILARITY_THRESHOLD)
      .filterExpression("country in ['UK', 'NL'] && year >= 2020").build());

または、プログラムで DSL という式を使用します。

FilterExpressionBuilder b = new FilterExpressionBuilder();

vectorStore.similaritySearch(
    SearchRequest.builder()
      .query("The World")
      .topK(TOP_K)
      .similarityThreshold(SIMILARITY_THRESHOLD)
      .filterExpression(b.and(
         b.in("country", "UK", "NL"),
         b.gte("year", 2020)).build()).build());

移植可能なフィルター式は、独自の Azure Search OData フィルター (英語) に自動的に変換されます。例: 次のポータブルフィルター式:

country in ['UK', 'NL'] && year >= 2020

は、次の Azure OData フィルター式 (英語) に変換されます。

$filter search.in(meta_country, 'UK,NL', ',') and meta_year ge 2020

カスタムフィールド名

デフォルトでは、Azure ベクトルストアは、Azure AI 検索インデックスで次のフィールド名を使用します。

  • content - ドキュメントテキスト用

  • embedding - ベクトル埋め込みの場合

  • metadata - ドキュメントメタデータ用

However, when working with existing Azure AI Search indexes that use different field names, you can configure custom field names to match your index schema. This allows you to integrate Spring AI with pre-existing indexes without needing to modify them.

ユースケース

カスタムフィールド名は、次のような場合に特に役立ちます。

  • 既存のインデックスとの統合 : 組織には、フィールド命名規則が確立された Azure AI 検索インデックスがすでに存在します (例: chunk_textvectormeta_data)。

  • 命名規則に従う : チームはデフォルトとは異なる特定の命名規則に従います。

  • 他のシステムからの移行 : 別のベクトルデータベースまたは検索システムから移行していて、一貫したフィールド名を維持したいと考えています。

プロパティによる設定

Spring Boot アプリケーションプロパティを使用してカスタムフィールド名を構成できます。

spring.ai.vectorstore.azure.url=${AZURE_AI_SEARCH_ENDPOINT}
spring.ai.vectorstore.azure.api-key=${AZURE_AI_SEARCH_API_KEY}
spring.ai.vectorstore.azure.index-name=my-existing-index
spring.ai.vectorstore.azure.initialize-schema=false

# Custom field names to match existing index schema
spring.ai.vectorstore.azure.content-field-name=chunk_text
spring.ai.vectorstore.azure.embedding-field-name=vector
spring.ai.vectorstore.azure.metadata-field-name=meta_data
When using an existing index with custom field names, set initialize-schema=false to prevent Spring AI from trying to create a new index with the default schema.

ビルダー API 経由の構成

あるいは、ビルダー API を使用してプログラムでカスタムフィールド名を構成することもできます。

@Bean
public VectorStore vectorStore(SearchIndexClient searchIndexClient, EmbeddingModel embeddingModel) {

	return AzureVectorStore.builder(searchIndexClient, embeddingModel)
		.indexName("my-existing-index")
		.initializeSchema(false) // Don't create schema - use existing index
		// Configure custom field names to match existing index
		.contentFieldName("chunk_text")
		.embeddingFieldName("vector")
		.metadataFieldName("meta_data")
		.filterMetadataFields(List.of(
			MetadataField.text("category"),
			MetadataField.text("source")))
		.build();
}

完全な例: 既存のインデックスの操作

Here’s a complete example showing how to use Spring AI with an existing Azure AI Search index that has custom field names:

@Configuration
public class VectorStoreConfig {

	@Bean
	public SearchIndexClient searchIndexClient() {
		return new SearchIndexClientBuilder()
			.endpoint(System.getenv("AZURE_AI_SEARCH_ENDPOINT"))
			.credential(new AzureKeyCredential(System.getenv("AZURE_AI_SEARCH_API_KEY")))
			.buildClient();
	}

	@Bean
	public VectorStore vectorStore(SearchIndexClient searchIndexClient,
			EmbeddingModel embeddingModel) {

		return AzureVectorStore.builder(searchIndexClient, embeddingModel)
			.indexName("production-documents-index")
			.initializeSchema(false) // Use existing index
			// Map to existing index field names
			.contentFieldName("document_text")
			.embeddingFieldName("text_vector")
			.metadataFieldName("document_metadata")
			// Define filterable metadata fields from existing schema
			.filterMetadataFields(List.of(
				MetadataField.text("department"),
				MetadataField.int64("year"),
				MetadataField.date("created_date")))
			.defaultTopK(10)
			.defaultSimilarityThreshold(0.75)
			.build();
	}
}

その後は、通常どおりベクトルストアを使用できます。

// Search using the existing index with custom field names
List<Document> results = vectorStore.similaritySearch(
	SearchRequest.builder()
		.query("artificial intelligence")
		.topK(5)
		.filterExpression("department == 'Engineering' && year >= 2023")
		.build());

// The results contain documents with text from the 'document_text' field
results.forEach(doc -> System.out.println(doc.getText()));

カスタムフィールド名を使用した新しいインデックスの作成

initializeSchema=true を設定することで、カスタムフィールド名を持つ新しいインデックスを作成することもできます。

@Bean
public VectorStore vectorStore(SearchIndexClient searchIndexClient,
		EmbeddingModel embeddingModel) {

	return AzureVectorStore.builder(searchIndexClient, embeddingModel)
		.indexName("new-custom-index")
		.initializeSchema(true) // Create new index with custom field names
		.contentFieldName("text_content")
		.embeddingFieldName("content_vector")
		.metadataFieldName("doc_metadata")
		.filterMetadataFields(List.of(
			MetadataField.text("category"),
			MetadataField.text("author")))
		.build();
}

これにより、カスタムフィールド名を使用した新しい Azure AI 検索インデックスが作成され、最初から独自の命名規則を確立できるようになります。

ネイティブクライアントへのアクセス

Azure ベクトルストアの実装は、getNativeClient() メソッドを通じて、基盤となるネイティブ Azure 検索クライアント (SearchClient) へのアクセスを提供します。

AzureVectorStore vectorStore = context.getBean(AzureVectorStore.class);
Optional<SearchClient> nativeClient = vectorStore.getNativeClient();

if (nativeClient.isPresent()) {
    SearchClient client = nativeClient.get();
    // Use the native client for Azure Search-specific operations
}

ネイティブクライアントを使用すると、VectorStore インターフェースでは公開されない可能性のある Azure 検索固有の機能と操作にアクセスできます。