使用 Oracle 代理程式記憶體混合搜尋
即使查詢使用不同的字詞,語意搜尋也有助於尋找相關資訊。關鍵字搜尋有助於尋找語意搜尋可能遺漏的精確識別碼、名稱及詞句。
本文將說明如何在 Oracle Database 中使用 Oracle Agent Memory 混合式搜尋。
混合搜尋可協助 Oracle Agent Memory 依意義與確切的文字尋找記錄。它將 Oracle 管理的文字搜尋與向量式排名結合,因此查詢可以比對識別碼 (例如問題代碼、產品名稱及別名),同時仍受益於語意擷取。
在本指南中,您將:
- 將 Oracle 備份的用戶端設定為使用
SearchStrategy.HYBRID - 使用
SearchStrategy.KEYWORD設定僅關鍵字搜尋 - 瞭解哪些搜尋策略可以共用相同的受管理綱要
- 新增記憶體,使用自己的文字進行搜尋
- 將識別碼與別名儲存在記憶體文字中,以便使用者稍後搜尋
- 以完全符合的識別符或自然語詞來搜尋那些記憶庫
注意:當語意搜尋與關鍵字搜尋都未單獨提供可靠的擷取時,請使用混合搜尋。當記錄同時包含描述性內容與使用者需要尋找的確切詞彙時,混合搜尋最有用。
提示:如需設定套裝程式,請參閱開始使用代理程式記憶體。如果此範例需要本機 Oracle 資料庫,請遵循在本機執行 Oracle AI Database 。
設定 Oracle Hybrid Search 從屬端
建立啟用混合搜尋的「Oracle 代理程式記憶體」從屬端。用戶端會將記錄儲存在 Oracle Database 中,並要求 Oracle 使用受管理的混合向量索引進行搜尋。
第一次啟用混合搜尋時,請使用 SchemaPolicy.CREATE_IF_NECESSARY。這可讓 SDK 新增受管理搜尋資料欄,並且建立混合索引 (如果還沒有的話)。
當您希望 Oracle 結合關鍵字和向量排名時,請使用 SearchStrategy.HYBRID。混合搜尋需要 OracleDBEmbedder 作為從屬端的主要 embedder,因此儲存和 Oracle 管理的混合向量索引會共用相同的資料庫內模型。
如果您只想要文字比對,請改用 SearchStrategy.KEYWORD。下一個區段顯示該設定。
重要事項:本指南需要 oracleagentmemory 26.6.0 或更新版本。如果您的受管理綱要是由舊版建立,請使用 SchemaPolicy.CREATE_IF_NECESSARY 啟動應用程式一次。這項升級會就地支援較舊的已發行綱要,並新增所選策略所需的搜尋物件。首次升級可能會執行受管理的 DDL 和資料重寫,因此請將其視為規劃的移轉步驟,而不是便宜的正常啟動。綱要就緒之後,您可以切換回 SchemaPolicy.REQUIRE_EXISTING 以正常啟動。
已宣告目前版本資源配置的開發或部分更新綱要未就地完成;請改為重新建立它們。
如果您在升級綱要之前使用 SchemaPolicy.REQUIRE_EXISTING,從屬端建立會失敗,並告訴您遺漏哪些受管理搜尋物件。
初始化或升級關鍵字或混合搜尋的綱要之後,除非您重新建立綱要或執行內嵌回填,否則請勿使用 SearchStrategy.VECTOR 重新開啟綱要。由關鍵字或混合用戶端寫入的資料列可能不包含本機內嵌,因此向量搜尋可能會遺漏記錄。
警告:為現有綱要建立混合索引可能需要一些時間。Oracle 必須掃描現有的預存搜尋文字,並從設定的資料庫內模型建立受管理的混合索引文字 / 向量狀態。SchemaPolicy.CREATE_IF_NECESSARY 會在從屬端啟動傳回之前等待該 DDL 完成,因此針對大型綱要,以計劃的移轉或維護作業執行第一個混合式升級。
注意:當 SDK 建立受管理的混合向量索引時,也會建立一個由受管理綱要命名的 DBMS_VECTOR_CHAIN 向量設定程式偏好設定。此偏好設定會儲存已設定 OracleDBEmbedder 模型的向量化程式組態,且預期為輕量型中繼資料。產生的偏好設定名稱是受管理綱要的確定名稱,而且符合 Oracle Text 的 preference-name 限制時,會依照設定的 table-name 前置碼進行。您可以使用 Oracle Text 檢視 (例如 CTX_USER_PREFERENCES 和 CTX_USER_PREFERENCE_VALUES) 來檢查偏好設定。
注意:此範例使用 OracleDBEmbedder。Oracle 在建立混合索引時,會使用內嵌器的資料庫內模型,因此主要內嵌程式和混合索引會共用一個資料庫模型。
此範例也會使用 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 | OracleDB 內嵌程式 | 綱要原則 | 搜尋策略 | 搜尋索引同步模式 |
僅使用關鍵字搜尋
當您要搜尋符合已儲存的字詞、識別碼、別名、產品名稱或短詞時,而且不希望向量排名時,請使用 SearchStrategy.KEYWORD。關鍵字搜尋會讀取混合搜尋所使用的相同預存搜尋文字,但不會使用向量融合。
關鍵字搜尋不需要 Python 內嵌器。如果 SDK 需要為新的關鍵字綱要建立搜尋物件,就會在儲存的搜尋文字上建立 Oracle Text 索引。SearchIndexSyncMode.ON_COMMIT 和 SearchIndexSyncMode.MANUAL 控制關鍵字文字索引重新整理。
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 第一次建立或升級受管理綱要時,會記錄儲存的擷取資料如何準備進行搜尋。每次啟動資料庫從屬端時都會檢查記錄的模式。這樣可以防止客戶使用可能會無訊息遺漏記錄的策略。
如果要求的策略與綱要相容,但不符合記錄的模式,SDK 就會發出警告。用戶端仍然可以啟動,但警告可以幫助您注意差異,並確認其為刻意。
SearchStrategy.VECTOR使用本機儲存的內嵌。除非您重新建立綱要或執行內嵌式回填,否則請勿使用SearchStrategy.VECTOR開啟關鍵字或混合式綱要,因為文字型從屬端可能有沒有本機內嵌的寫入資料列。SearchStrategy.KEYWORD僅使用預存搜尋文字。它可以建立或使用關鍵字綱要。它也可以開啟現有的混合綱要,並使用混合索引的純文字分支。它不會將混合式綱要變更回關鍵字模式。SearchStrategy.HYBRID使用預存搜尋文字與 Oracle 管理的混合向量索引。它可以在使用SchemaPolicy.CREATE_IF_NECESSARY時建立混合式綱要、開啟現有的混合式綱要或升級關鍵字綱要。混合模式要求用戶端使用OracleDBEmbedder作為其主要嵌入程式。
警告:第一次對現有資料建立混合索引可能會長時間執行,因為 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 代理程式記憶體」搜尋介面後執行,因此您可以照常使用範圍、結果限制以及記錄類型篩選。
第一個查詢會搜尋儲存在記憶體文字中的確切問題程式碼。第二個查詢會搜尋同一組記憶庫中的自然語言詞語。
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 評分行為而異。在測試或示範中,檢查是否傳回預期的記錄,而不是依賴一個精確的排名。
| 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)