建立並搜尋連結的記憶體圖表

記憶體連結可連接相關類似記憶體的記錄,同時保留歷史記錄。當較新的記憶體取代或縮小較舊的記憶體,或當兩個記憶體支援、複製或互相矛盾時,請使用這些選項。自動記憶體連結會將這些連結建立為自動記憶體擷取的一部分;當應用程式已經知道關係時,手動連結仍然可以使用。

此指南會自動建立小型的披薩偏好設定圖表,顯示如何在需要時明確管理連結,以及使用搜尋擷取圖表內容。

設定 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))