Oracle Agent Memory Hybrid Searchの使用

セマンティック検索は、問合せで異なる語が使用されている場合でも関連情報を検索するのに役立ちます。キーワード検索は、セマンティック検索で見逃す可能性のある正確な識別子、名前およびフレーズの検索に役立ちます。

この記事では、Oracle DatabaseでOracle Agent Memoryハイブリッド検索を使用する方法を説明します。

ハイブリッド検索は、Oracle Agent Memoryが意味と正確なテキストの両方でレコードを検索するのに役立ちます。Oracle管理のテキスト検索をベクトルベースのランキングと組み合せるため、問合せでは、問題コード、製品名、別名などの識別子を照合しながら、セマンティック取得のメリットを享受できます。

このガイドでは、次のことを行います。

ノート:セマンティック検索もキーワード検索のみでも信頼性の高い取得が提供されない場合は、ハイブリッド検索を使用します。ハイブリッド検索は、レコードに説明コンテンツとユーザーが検索する必要がある正確な用語の両方が含まれている場合に最も役立ちます。

ヒント:パッケージの設定については、エージェント・メモリーのスタート・ガイドを参照してください。この例にローカルOracleデータベースが必要な場合は、「Oracle AI Databaseのローカル実行」に従います。

Oracle Hybrid Searchクライアントの構成

ハイブリッド検索を有効にしたOracle Agent Memoryクライアントを作成します。クライアントはOracle Databaseにレコードを格納し、Oracleに検索に管理対象ハイブリッド・ベクトル索引を使用するように要求します。

ハイブリッド検索を最初に有効にする場合は、SchemaPolicy.CREATE_IF_NECESSARYを使用します。これにより、SDKは管理対象検索列を追加し、ハイブリッド索引がまだ存在しない場合は作成できます。

Oracleでキーワード・ランキングとベクトル・ランキングを組み合せる場合は、SearchStrategy.HYBRIDを使用します。ハイブリッド検索では、ストアのハイブリッド・ベクトル索引とOracle管理のハイブリッド・ベクトル索引が同じデータベース内モデルを共有するように、クライアントのメインembedderとしてOracleDBEmbedderが必要です。

テキスト一致のみが必要な場合は、かわりにSearchStrategy.KEYWORDを使用します。次のセクションでは、その設定を示します。

重要:このガイドでは、oracleagentmemory 26.6.0以降が必要です。管理対象スキーマが古いリリースで作成された場合は、SchemaPolicy.CREATE_IF_NECESSARYを使用してアプリケーションを1回起動します。これにより、サポートされている古いリリース済スキーマが適切にアップグレードされ、選択した戦略に必要な検索オブジェクトが追加されます。この最初のアップグレードでは、管理されたDDLおよびデータ・リライトが実行される可能性があるため、安価な通常の起動ではなく、計画された移行ステップとして扱います。スキーマの準備ができたら、通常の起動時にSchemaPolicy.REQUIRE_EXISTINGに切り替えることができます。

現在のリリース・シェイプをすでに要求している開発スキーマまたは部分的に更新されたスキーマは、所定の位置に完了せず、かわりに再作成します。

スキーマがアップグレードされる前にSchemaPolicy.REQUIRE_EXISTINGを使用すると、クライアントの作成が失敗し、欠落している管理対象検索オブジェクトが通知されます。

キーワード検索またはハイブリッド検索用にスキーマを初期化またはアップグレードした後は、スキーマを再作成するか埋込みバックフィルを実行しないかぎり、SearchStrategy.VECTORを使用してスキーマを再オープンしないでください。キーワードまたはハイブリッド・クライアントによって書き込まれる行にローカル埋込みが含まれないため、ベクトル検索ではレコードが欠落する可能性があります。

警告:既存のスキーマのハイブリッド索引の作成には時間がかかる場合があります。Oracleは、既存の格納済検索テキストをスキャンし、構成されたデータベース内モデルから管理対象ハイブリッド索引テキスト/ベクター状態を構築する必要があります。SchemaPolicy.CREATE_IF_NECESSARYは、クライアントの起動が戻る前にそのDDLが終了するまで待機するため、大規模なスキーマに対する計画移行またはメンテナンス操作として最初のハイブリッド・アップグレードを実行します。

ノート: SDKで管理対象ハイブリッド・ベクトル索引が作成されると、管理対象スキーマによって名前が付けられたDBMS_VECTOR_CHAINベクトル化プリファレンスも作成されます。このプリファレンスには、構成済のOracleDBEmbedderモデルからのベクトル化構成が格納され、軽量メタデータであることが想定されます。生成されたプリファレンス名は、管理対象スキーマに対して決定的であり、Oracle Textのpreference-name制限に適合する場合は、構成された表名の接頭辞に従います。CTX_USER_PREFERENCESCTX_USER_PREFERENCE_VALUESなどのOracle Textビューを使用してプリファレンスを検査できます。

ノート:この例では、OracleDBEmbedderを使用します。Oracleでは、ハイブリッド索引の作成時にその埋込み者のデータベース内モデルが使用されるため、メイン・エンベダとハイブリッド索引は1つのDBモデルを共有します。

この例では、SearchIndexSyncMode.ON_COMMITも使用します。これにより、コミットされた書込みのたびにハイブリッド索引が最新の状態に保たれるため、新しく追加されたメモリーはすぐに検索可能になります。検索索引同期を自分で実行する場合はSearchIndexSyncMode.MANUALを使用し、バックグラウンドでハイブリッド索引をOracleでリフレッシュし、最近の書込みより遅れている検索結果を許容する場合はSearchIndexSyncMode.AUTOを使用します。この設定は、初期検索索引が存在した後の継続的なメンテナンスに適用されます。最初の索引ビルドを非同期にすることはありません。

import oracledb

from oracleagentmemory.core import (
    MemoryExtractionConfig,
    OracleAgentMemory,
    SchemaPolicy,
    SearchIndexSyncMode,
    SearchStrategy,
)
from oracleagentmemory.core.embedders import OracleDBEmbedder


db_pool = oracledb.SessionPool(
    user="YOUR DB USER",
    password="YOUR DB PASSWORD",
    dsn="YOUR DB CONNECT STRING",
)

db_embedder = OracleDBEmbedder(
    connection=db_pool,
    model="YOUR_DB_EMBEDDING_MODEL",
    embedding_dimension=384,
)

memory = OracleAgentMemory(
    connection=db_pool,
    embedder=db_embedder,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    search_strategy=SearchStrategy.HYBRID,
    search_index_sync=SearchIndexSyncMode.ON_COMMIT,
)
APIリファレンス: OracleAgentMemory OracleDBEmbedder スキーマ・ポリシー 検索戦略 検索インデックス同期モード

キーワード検索のみ使用

SearchStrategy.KEYWORDは、格納されている単語、識別子、別名、製品名または短いフレーズが検索で一致し、ベクトル・ランキングが不要な場合に使用します。キーワード検索では、ハイブリッド検索で使用されるものと同じストアド・サーチ・テキストが読み取られますが、ベクトル・フュージョンは使用されません。

キーワード検索にはPython埋込みは必要ありません。SDKが新しいキーワード・スキーマの検索オブジェクトを作成する必要がある場合は、格納された検索テキストに対してOracle Text索引を作成します。SearchIndexSyncMode.ON_COMMITおよびSearchIndexSyncMode.MANUAL制御キーワードのtext-indexリフレッシュ。

keyword_memory = OracleAgentMemory(
    connection=db_pool,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    search_strategy=SearchStrategy.KEYWORD,
)

次に示す同じadd_memory()およびsearch()コールは、SearchStrategy.KEYWORDで動作します。違いはランキングです。キーワード検索ではテキスト一致のみに基づいてレコードが返され、ハイブリッド検索ではテキスト一致とベクトル・ランキングが結合されます。

APIリファレンス: OracleAgentMemory 検索戦略

互換性のある検索戦略の使用

SDKは、管理対象スキーマを初めて作成またはアップグレードするときに、格納された取得データを検索用に準備する方法を記録します。記録されたモードは、DBクライアントが起動するたびにチェックされます。これにより、クライアントがレコードを見逃す可能性のある戦略を使用できなくなります。

要求されたストラテジはスキーマと互換性があるが、記録されたモードと一致しない場合、SDKは警告を出力します。クライアントは引き続き起動できますが、この警告は違いに気づき、意図的なものであることを確認するのに役立ちます。

警告: Oracleはストアド・サーチ・テキストからマネージド・ハイブリッド索引の状態を構築するため、既存のデータに対するハイブリッド索引の最初の作成は長時間実行される可能性があります。SearchIndexSyncModeは、索引が存在した後の進行中の索引メンテナンスを制御します。最初のビルドを非同期にすることはありません。

スキーマをベクトルからキーワードまたはハイブリッドへ、またはキーワードからハイブリッドへ意図的に移動する場合は、SchemaPolicy.CREATE_IF_NECESSARYを使用します。スキーマの準備ができた後、SchemaPolicy.REQUIRE_EXISTINGを使用して、データベース・オブジェクトを変更せずにスキーマを検証します。

APIリファレンス: SchemaPolicy 検索戦略

検索可能なメモリーの格納

通常のメモリから始めます。OracleAgentMemory.add_memory() APIでは、Oracleはメモリー・コンテンツ自体を検索可能なテキストとして使用します。これは最も単純なパスであり、通常、ユーザーがメモリーにすでに存在する単語またはフレーズを検索するときに十分です。

user_id = "user_123"

memory.add_memory(
    "The user calls the Milan outage the renewal blocker.",
    user_id=user_id,
)

APIリファレンス: OracleAgentMemory

ユーザーが検索できるストア識別子

ユーザーが正確な問題コード、請求書番号、製品名または別名で検索できる場合は、そのテキストを格納するメモリーに含めます。ハイブリッド検索では、正確なテキストを照合し、自然言語の問合せにベクトル・ランキングを使用できます。

メモリーを読取り可能にします。多くの場合、重要な識別子を含む短い文で十分です。この例では、記憶に、ユーザーが後で入力する可能性のある問題識別子と要求識別子が含まれています。

memory.add_memory(
    "The follow-up fix for the Milan outage is the edge-cluster retry patch, "
    "tracked as ORA-27102.",
    user_id=user_id,
)

memory.add_memory(
    "The renewal request INV-48291 stays attached to the Milan blocker ORA-27102.",
    user_id=user_id,
)

APIリファレンス: OracleAgentMemory

識別子またはフレーズで検索

通常のsearch() APIを使用します。ハイブリッド検索は、同じOracle Agent Memory検索インタフェースの後ろで実行されるため、スコープ、結果制限およびレコード・タイプ・フィルタを通常どおり使用し続けることができます。

最初の問合せでは、メモリー・テキストに格納されている正確な問題コードが検索されます。2番目の問合せでは、同じ記憶セットから自然言語句が検索されます。

for query in ["ORA-27102", "renewal blocker"]:
    print(f"\nSearch results for {query!r}:")
    results = memory.search(
        query=query,
        user_id=user_id,
        max_results=5,
        record_types=["memory"],
    )
    print_search_results(results)

ノート:検索結果の順序は、格納されたデータ、ハイブリッド索引構成およびOracleスコアリング動作によって異なる場合があります。テストまたはデモでは、1つの正確なランキングに依存するのではなく、予想されるレコードが返されることを確認します。

APIリファレンス: OracleAgentMemory OracleSearch結果

まとめ

このガイドでは、Oracle管理のハイブリッド検索を有効にし、キーワードのみの検索、通常のメモリーの格納、メモリー・テキスト内の検索可能な識別子、正確な識別子と自然言語句の両方による問合せ済メモリーをいつ使用するかを確認しました。

Oracle DBでハイブリッド検索を有効にする方法を学習した後、「ストアとスキーマ」に進むことができます。

完全コード

#Copyright © 2026 Oracle and/or its affiliates.
#This software is under the Apache License 2.0
#(LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
#(UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.

#Oracle Agent Memory Code Example - Oracle Hybrid Search
#-------------------------------------------------------

##Configure an Oracle hybrid search client

import oracledb

from oracleagentmemory.core import (
    MemoryExtractionConfig,
    OracleAgentMemory,
    SchemaPolicy,
    SearchIndexSyncMode,
    SearchStrategy,
)
from oracleagentmemory.core.embedders import OracleDBEmbedder


db_pool = oracledb.SessionPool(
    user="YOUR DB USER",
    password="YOUR DB PASSWORD",
    dsn="YOUR DB CONNECT STRING",
)

db_embedder = OracleDBEmbedder(
    connection=db_pool,
    model="YOUR_DB_EMBEDDING_MODEL",
    embedding_dimension=384,
)

memory = OracleAgentMemory(
    connection=db_pool,
    embedder=db_embedder,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    search_strategy=SearchStrategy.HYBRID,
    search_index_sync=SearchIndexSyncMode.ON_COMMIT,
)



##Configure an Oracle keyword search client

keyword_memory = OracleAgentMemory(
    connection=db_pool,
    memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    search_strategy=SearchStrategy.KEYWORD,
)


def print_search_results(results: list) -> None:
    for result in results:
        print(f"- [{result.record.record_type}] {result.content}")



##Store a basic hybrid search memory

user_id = "user_123"

memory.add_memory(
    "The user calls the Milan outage the renewal blocker.",
    user_id=user_id,
)



##Store identifiers users may search for

memory.add_memory(
    "The follow-up fix for the Milan outage is the edge-cluster retry patch, "
    "tracked as ORA-27102.",
    user_id=user_id,
)

memory.add_memory(
    "The renewal request INV-48291 stays attached to the Milan blocker ORA-27102.",
    user_id=user_id,
)



##Search hybrid records by identifier or phrase

for query in ["ORA-27102", "renewal blocker"]:
    print(f"\nSearch results for {query!r}:")
    results = memory.search(
        query=query,
        user_id=user_id,
        max_results=5,
        record_types=["memory"],
    )
    print_search_results(results)