建立並搜尋連結的記憶體圖表
記憶體連結可連接相關類似記憶體的記錄,同時保留歷史記錄。當較新的記憶體取代或縮小較舊的記憶體,或當兩個記憶體支援、複製或互相矛盾時,請使用這些選項。自動記憶體連結會將這些連結建立為自動記憶體擷取的一部分;當應用程式已經知道關係時,手動連結仍然可以使用。
此指南會自動建立小型的披薩偏好設定圖表,顯示如何在需要時明確管理連結,以及使用搜尋擷取圖表內容。
設定 Linked-Memory 用戶端
建立一般 OracleAgentMemory 從屬端。第一次執行時,請使用 SchemaPolicy.CREATE_IF_NECESSARY,讓 SDK 建立所有受管理資料庫物件,包括記憶體關聯存放區和特性圖表。
import oracledb
from oracleagentmemory.core import (
MemoryExtractionConfig,
OracleAgentMemory,
OracleSearchResultFormatConfig,
SchemaPolicy,
)
from oracleagentmemory.core.embedders.embedder import Embedder
embedder = Embedder(model="YOUR_EMBEDDING_MODEL")
db_pool = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="localhost:1521/...",
)
memory_store_id = "T_GRAPH_MEMORY"
memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
)
user_id = "graph-demo-user"
擷取時自動連結記憶體
對於大多數應用程式,啟用自動擷取功能,並讓 SDK 在從 add_messages() 擷取新記憶體時識別連結。預設連結模式 POST_EXTRACTION 會先擷取記憶體,為每個新記憶體擷取一組繫結的現有候選項目,並使用一個額外的 LLM 要求來決定是否應建立類型連結。這提供連結解析本身的內容,並且是連結品質很重要時的建議模式。
透過 MemoryExtractionConfig 在從屬端或繫線層次設定模式。下列執行緒會在每次新增訊息後擷取,並在擷取後解析連結。OracleAgentMemory 用戶端也必須設定擷取 LLM。
from oracleagentmemory.core import (
MemoryExtractionConfig,
MemoryLinkExtractionMode,
)
preference_thread = memory.create_thread(
thread_id="pizza-preferences",
user_id=user_id,
memory_extraction_config=MemoryExtractionConfig(
extract_memories=True,
memory_extraction_frequency=1,
memory_link_extraction_mode=MemoryLinkExtractionMode.POST_EXTRACTION,
),
)
preference_thread.add_messages(
[{"role": "user", "content": "I now prefer sourdough pizza."}]
)
例如,當執行緒已包含使用者偏好精簡地殼的記憶體時,連結器可以擷取新的來源偏好設定,並建立舊記憶體的 supersedes 連結。生命週期連結類型 (例如 supersedes、refines 和 duplicates) 會保留較舊的記憶體作為歷史記錄,並將其標示為無效;圖表搜尋仍可傳回為連結的相關資訊環境。
DURING_EXTRACTION 會要求擷取 LLM 在擷取記憶體的相同要求中識別連結,以避免額外的連結解析要求。其候選人受擷取搜尋約束。設定 memory_link_extraction_mode=MemoryLinkExtractionMode.DISABLED 以關閉自動連結。自動模式都不會嘗試尋找商店中每個可能的關係,因此請針對必須記錄的關係使用明確的連結。
手動建立連結的記憶體
正常建立記憶體,然後使用 link_records() 連線。關係會導向:它的來源指向其目標。supersedes、refines 和 duplicates 會使目標無效;supports 和 contradicts 會讓兩個端點記憶體都有效。
選取一個連結類型
對於記憶體發展,來源通常是較新的記憶體,而目標則是現有的記憶體。選取描述該關係的連結類型。
| 連結類型 | 當原始碼記憶體使用… | 對目標記憶體的影響 |
|---|---|---|
supersedes |
將目標取代為目前的資訊。例如,新的偏好設定會取代先前的偏好設定。 | 變成無效,但仍可作為歷史記錄使用。 |
refines |
在新增詳細資料或精確度時保留目標資訊。例如,特定的健行偏好設定會縮小一般的範圍。 | 變成無效,但仍可作為歷史記錄使用。 |
duplicates |
具有與目標相同的意義。來源為偏好的複本。 | 變成無效以避免重複的直接結果。 |
supports |
提供目標的證明。例如,避免肉類與魚類支援素食偏好。 | 維持不變。 |
contradicts |
與目標衝突,但 SDK 無法判斷哪一個記憶體是正確的。 | 維持不變。 |
圖形搜尋會依照任一方向的每個連結進行。當它從目標周遊至來源時,會顯示對應的反向標籤,例如 is_superseded_by 或 is_refined_by。
thin_crust_id = memory.add_memory(
"The user's preferred pizza style is thin crust.",
memory_id="pizza-thin-crust",
memory_type="preference",
user_id=user_id,
)
sourdough_id = memory.add_memory(
"The user now prefers sourdough pizza.",
memory_id="pizza-sourdough",
memory_type="preference",
user_id=user_id,
)
neapolitan_id = memory.add_memory(
"The user's preferred pizza style is sourdough, especially Neapolitan sourdough.",
memory_id="pizza-neapolitan-sourdough",
memory_type="preference",
user_id=user_id,
)
supersedes_link_id = memory.link_records(
source_record_id=sourdough_id,
source_record_type="preference",
target_record_id=thin_crust_id,
target_record_type="preference",
relation_type="supersedes",
)
memory.link_records(
source_record_id=neapolitan_id,
source_record_type="preference",
target_record_id=sourdough_id,
target_record_type="preference",
relation_type="refines",
)
搜尋會依循任一方向的連結,同時在結果中保留其儲存的方向。
編輯與刪除連結
使用 link_records() 傳回的關係 ID 來更新關係。省略的欄位則維持不變。更新關係類型會重新計算端點狀態,因此先前生命週期連結在其取代類型沒有生命週期效果時,不會讓記憶體失效。
依其關係 ID 或完整導向端點元組刪除關係:來源 ID 和類型、目標 ID 和類型,以及關係類型。刪除也會重新計算受影響的端點狀態。
#Changing a lifecycle link recalculates the status of both endpoint memories.
memory.update_record_link(
supersedes_link_id,
relation_type="supports",
metadata={"reviewed_by": "preference-service"},
)
#Delete by the stable relation ID.
memory.delete_record_link(relation_id=supersedes_link_id)
#Or delete by the complete directed relation triple.
memory.delete_record_link(
source_record_id=neapolitan_id,
source_record_type="preference",
target_record_id=sourdough_id,
target_record_type="preference",
relation_type="refines",
)
透過連結的記憶體搜尋
設定 num_hops,將連結的相關資訊環境附加至每個直接記憶體結果。0 是預設值,且僅傳回直接結果;1 到 5 的值會跟隨該許多連結。max_linked_results 會限制所有躍點連附至每個直接結果的連結記憶體總計。它預設為 100;將其設為 0 以傳回不含連結內容的直接結果。
範圍、描述資料、記錄類型以及到期篩選會套用至連結的記憶體。include_invalid_results 只適用於最上層直接結果。連結的記憶體相關資訊環境可包含無效的歷史記錄,無論該選項為何。若為正值 num_hops,SDK 會依循兩個方向的連結,並將連結的環境定義傳回為下節所述的確定性最短路徑樹狀結構。
results = memory.search(
"What pizza should I recommend?",
user_id=user_id,
max_results=5,
num_hops=2,
max_linked_results=20,
include_invalid_results=False,
)
每個結果都包含一個遞迴的連結結果樹狀結構。使用每個連結記憶體之最短可用路徑的 SDK 格式。遍歷可防止路徑中重複的記憶體,並在替代路徑到達相同記憶體時,選取一個確定的最短路徑。
提示的格式圖表內容
每個 SearchResult 都會顯示 format_content(),以顯示直接結果及其連結的記憶體作為結構化提示文字。依預設,它會使用產生結果之搜尋的 include_invalid_results 設定。提供的格式設定組態會覆寫其明確設定的選項。停用無效的內容時,無效的連結記憶庫會省略其內容。導致有效連結記憶體的記錄無效,會保留其狀態與連結內容;只會省略無效的分支。
使用 OracleSearchResultFormatConfig 可修改轉譯的樹狀結構。此範例包含無效的歷史內容,同時移除時間戳記、角色以及更精簡提示的狀態。您也可以包含中繼資料、執行緒、使用者或代理程式識別碼,以及預估的相關性。每個彩現的關係標籤都會描述顯示的父對子方向,即使 RecordRelation 會保留其儲存的方向。
format_config = OracleSearchResultFormatConfig(
include_invalid_results=True,
show_timestamp=False,
show_role=False,
show_status=False,
)
for result in results:
print(result.format_content(format_config))
完整代碼
本指南中包含完整的範例,可供您複製和執行。
#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 - Create and Search Linked Memory Graphs
#-------------------------------------------------------------------------
##Create a graph memory client
import oracledb
from oracleagentmemory.core import (
MemoryExtractionConfig,
OracleAgentMemory,
OracleSearchResultFormatConfig,
SchemaPolicy,
)
from oracleagentmemory.core.embedders.embedder import Embedder
embedder = Embedder(model="YOUR_EMBEDDING_MODEL")
db_pool = oracledb.SessionPool(
user="YOUR DB USER",
password="YOUR DB PASSWORD",
dsn="localhost:1521/...",
)
memory_store_id = "T_GRAPH_MEMORY"
memory = OracleAgentMemory(
connection=db_pool,
embedder=embedder,
schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
memory_store_id=memory_store_id,
memory_extraction_config=MemoryExtractionConfig(extract_memories=False),
)
user_id = "graph-demo-user"
##Create linked memories
thin_crust_id = memory.add_memory(
"The user's preferred pizza style is thin crust.",
memory_id="pizza-thin-crust",
memory_type="preference",
user_id=user_id,
)
sourdough_id = memory.add_memory(
"The user now prefers sourdough pizza.",
memory_id="pizza-sourdough",
memory_type="preference",
user_id=user_id,
)
neapolitan_id = memory.add_memory(
"The user's preferred pizza style is sourdough, especially Neapolitan sourdough.",
memory_id="pizza-neapolitan-sourdough",
memory_type="preference",
user_id=user_id,
)
supersedes_link_id = memory.link_records(
source_record_id=sourdough_id,
source_record_type="preference",
target_record_id=thin_crust_id,
target_record_type="preference",
relation_type="supersedes",
)
memory.link_records(
source_record_id=neapolitan_id,
source_record_type="preference",
target_record_id=sourdough_id,
target_record_type="preference",
relation_type="refines",
)
##Edit and delete links
#Changing a lifecycle link recalculates the status of both endpoint memories.
memory.update_record_link(
supersedes_link_id,
relation_type="supports",
metadata={"reviewed_by": "preference-service"},
)
#Delete by the stable relation ID.
memory.delete_record_link(relation_id=supersedes_link_id)
#Or delete by the complete directed relation triple.
memory.delete_record_link(
source_record_id=neapolitan_id,
source_record_type="preference",
target_record_id=sourdough_id,
target_record_type="preference",
relation_type="refines",
)
#Recreate the example links for the search example.
memory.link_records(sourdough_id, "preference", thin_crust_id, "preference", "supersedes")
memory.link_records(neapolitan_id, "preference", sourdough_id, "preference", "refines")
##Search linked memories
results = memory.search(
"What pizza should I recommend?",
user_id=user_id,
max_results=5,
num_hops=2,
max_linked_results=20,
include_invalid_results=False,
)
##Format graph context for a prompt
format_config = OracleSearchResultFormatConfig(
include_invalid_results=True,
show_timestamp=False,
show_role=False,
show_status=False,
)
for result in results:
print(result.format_content(format_config))