Magasins et schéma

Cette page présente les abstractions de l'emplacement de stockage principal et les contrôles de schéma utilisés par le kit SDK de mémoire d'agent Oracle.

API de stockage

Stocker la sémantique d'écriture

Les écritures de stockage conservent une séparation claire entre le texte stocké par une application et la charge utile utilisée par le stockage pour l'extraction. La plupart des applications peuvent utiliser les API de niveau mémoire et de niveau thread et laisser le magasin préparer les lignes de recherche dont il a besoin pour la récupération de vecteur, de mot-clé ou hybride. Les API de stockage de niveau inférieur affichent index_texts, index_text, embeddings et embedding pour les intégrations avancées qui savent déjà quel texte ou vecteurs doivent être utilisés pour l'extraction.

Considérez chaque écriture comme deux éléments connexes :

update() accepte également text en tant que paramètre de compatibilité obsolète. Utilisez content dans le nouveau code ; le fait de fournir text émet un avertissement d'abandon.

Si aucun remplacement de recherche ou incorporation explicite n'est fourni, le magasin utilise le texte stocké résolu comme texte d'extraction. Le texte non vide est découpé par bloc par le magasin lors de la configuration du découpage par bloc. Le texte vide stocke le texte de l'enregistrement mais ne fournit aucun texte d'extraction.

Le tableau ci-dessous décrit comment le texte d'extraction est choisi avant la prise en compte des charges utiles vectorielles explicites.

Charge utile d'extraction au niveau du magasin

Entrée add() update()
index_texts ou index_text omis Chaque enregistrement utilise sa valeur contents résolue pour l'extraction. Une valeur content de remplacement est utilisée pour l'extraction. Si content est également omis, les mises à jour d'intégration uniquement réutilisent les lignes de texte d'extraction existantes de l'enregistrement.
Chaîne index_texts entrée ou chaîne index_text La chaîne remplace le texte d'extraction de cet enregistrement. Le magasin peut le fragmenter avant d'écrire des lignes d'extraction. La chaîne remplace le texte d'extraction de cet enregistrement. Le magasin peut le fragmenter avant d'écrire des lignes d'extraction.
Entrée list[str] index_texts ou list[str] index_text La liste est traitée comme des blocs appartenant à l'appelant. Chaque chaîne non vide est écrite sous la forme d'une ligne d'extraction, et le magasin ne la fragmente pas à nouveau. La liste est traitée comme des blocs appartenant à l'appelant. Chaque chaîne non vide est écrite sous la forme d'une ligne d'extraction, et le magasin ne la fragmente pas à nouveau.
Entrée None index_texts ou index_text=None None dans la liste externe index_texts signifie "utiliser le contenu stocké pour cet enregistrement". index_text=None efface les lignes d'extraction tout en laissant le contenu stocké inchangé, sauf si content est également fourni.
Chaîne vide ou liste de blocs vide Stocke le contenu de l'enregistrement et ne fournit aucun texte d'extraction pour cet enregistrement. Met à jour le contenu de l'enregistrement lorsque content est fourni et efface le texte d'extraction de cet enregistrement.

Les intégrations explicites sont facultatives. Lorsqu'ils sont omis, le magasin dérive des vecteurs locaux du texte de récupération lorsque le stockage vectoriel local est configuré ; les magasins de mots-clés ou hybrides peuvent également utiliser des lignes de récupération de texte uniquement. Lorsque des valeurs embeddings ou embedding explicites sont fournies, le magasin écrit ces vecteurs directement et n'appelle pas son intégrateur pour ces vecteurs.

Dans add(), embeddings=None se comporte comme l'omission de embeddings. Dans update(), embedding=None est explicite : le magasin conserve ou réécrit le texte d'extraction en fonction de content et index_text, mais stocke ces lignes sans vecteurs locaux. Si content et index_text sont tous deux omis, cela efface les vecteurs des lignes d'extraction existantes.

La forme du vecteur indique au magasin combien de parts de propriété l'appelant prend :

Certaines combinaisons sont rejetées de sorte que le texte stocké, le texte de récupération et les vecteurs ne s'écartent pas. La transmission de content=None efface le contenu stocké et les lignes d'extraction. Elle ne peut donc pas être combinée avec des valeurs index_text ou embedding non NULL ; les enregistrements de profil d'acteur ne prennent pas en charge content=None. Le paramètre text en phase d'abandon a le même comportement. La transmission de index_text=None dans update() signifie "effacer les lignes d'extraction", de sorte que les incorporations explicites non vides ne sont pas autorisées dans le même appel. Plusieurs vecteurs explicites nécessitent un texte de bloc explicite, sauf si la mise à jour est incorporée uniquement et que les lignes d'extraction existantes fournissent déjà le texte de bloc.

classe oracleagentmemory.core.OracleMemoryStore

Bases : IMemoryStore

Interface de banque commune utilisée par OracleAgentMemory.

Une implémentation de magasin est responsable de la persistance des enregistrements de texte et de l'exécution de recherches de similarité sur ces enregistrements. Les points d'entrée synchrones et asynchrones sont définis de sorte que les API de niveau supérieur peuvent afficher les surfaces synchrones/asynchrones correspondantes sans dupliquer la logique propre au magasin.

méthode add

Ajoutez des enregistrements au magasin.

Notes

Utilisez add_batches() lorsque l'appelant comporte déjà un ou plusieurs objets PendingRecordBatch.

method add_agent (résumé)

Ajoutez un enregistrement de profil d'agent.

method add_agent_async (async)

Ajoutez de manière asynchrone un enregistrement de profil d'agent.

method add_async (async)

Ajoutez de manière asynchrone des enregistrements orientés ligne au magasin.

accepte les mêmes arguments et renvoie les mêmes identificateurs que add().

méthode add_batches

Ajoutez des lots logiques préparés par l'appelant au magasin.

Exemples

store.add_batches(
    [
        PendingRecordBatch(
            contents=["pizza batch"],
            record_type="memory",
            record_ids="mem-batch-docs",
        )
    ]
)
['mem-batch-docs']

method add_batches_async (async)

Ajoutez de manière asynchrone des lots logiques préparés par l'appelant au magasin.

accepte les mêmes arguments et renvoie les mêmes identificateurs que add_batches().

method add_relations (résumé)

Stockez une ou plusieurs relations dirigées.

Les valeurs scalaires sont diffusées dans le batch d'enregistrement source. Les valeurs de liste doivent avoir la même longueur. Une seule orientation peut être stockée pour une paire d'adresses. Utilisez opposite_relation_types pour décrire la vue inverse plutôt que d'ajouter une seconde relation inverse. Les implémentations peuvent restreindre les types d'enregistrement d'adresse et les étiquettes de relation qu'elles conservent.

Exemples

store.add_relations(
    "new", "memory", "old", "memory", "supersedes"
)
['relation-id']

method add_relations_async (async)

Stockez de manière asynchrone une ou plusieurs relations dirigées.

Les valeurs scalaires sont diffusées dans le batch d'enregistrement source. Les valeurs de liste doivent avoir la même longueur. Une seule orientation peut être stockée pour une paire d'adresses. Utilisez opposite_relation_types pour décrire la vue inverse plutôt que d'ajouter une seconde relation inverse.

Exemples

await store.add_relations_async(
    "new", "memory", "old", "memory", "supersedes"
)
['relation-id']

method add_user (résumé)

Ajouter un enregistrement de profil utilisateur.

method add_user_async (async)

Ajouter un enregistrement de profil utilisateur de manière asynchrone.

method delete (résumé)

Supprimer un enregistrement stocké par identifiant.

method delete_async (async)

Supprimer de manière asynchrone un enregistrement stocké par identifiant.

method delete_relations (résumé)

Supprimer les relations par identifiant.

L'état de cycle de vie est recalculé à partir des relations restantes.

Exemples

store.delete_relations("relation-id")
1

method delete_relations_async (async)

Supprimer de manière asynchrone les relations par identificateur.

L'état de cycle de vie est recalculé à partir des relations restantes.

Exemples

await store.delete_relations_async("relation-id")
1

method delete_thread (résumé)

Supprimer un thread et les données stockées associées.

Notes

Il s'agit de l'opération de niveau magasin permettant de supprimer un thread et les enregistrements de niveau thread gérés par le magasin. Préférez la suppression de thread lorsque les exigences de conservation appellent la suppression des messages source et des données de mémoire dérivées de portée thread, car les suppressions au niveau message n'impliquent pas la suppression des enregistrements dérivés conservés séparément.

method delete_thread_async (async)

Supprimer de manière asynchrone un thread et les données stockées associées.

Notes

Il s'agit de l'opération de niveau magasin permettant de supprimer un thread et les enregistrements de niveau thread gérés par le magasin. Préférez la suppression de thread lorsque les exigences de conservation appellent la suppression des messages source et des données de mémoire dérivées de portée thread, car les suppressions au niveau message n'impliquent pas la suppression des enregistrements dérivés conservés séparément.

method get (résumé)

Extraire un enregistrement stocké par type et identifiant.

method get_async (async)

Extraire de manière asynchrone un enregistrement stocké par type et identifiant.

method get_relation (résumé)

Renvoyer une relation dans son orientation source-cible stockée.

Fournissez relation_id seul ou fournissez un tuple complet d'adresse source à cible.

Exemples

store.get_relation(relation_id="relation-id")
RecordRelation(...)
store.get_relation(
    "source-id", "memory", "target-id", "fact", "supports"
)
RecordRelation(...)

method get_relation_async (async)

Extraire de manière asynchrone une relation par ID ou tuple d'adresse.

Fournissez relation_id seul ou fournissez un tuple complet d'adresse source à cible.

Exemples

await store.get_relation_async(relation_id="relation-id")
RecordRelation(...)

method list (résumé)

Répertoriez les enregistrements stockés pour un type d'enregistrement.

method list_async (async)

Répertorie de manière asynchrone les enregistrements stockés pour un type d'enregistrement.

method list_relations (résumé)

Répertoriez les relations stockées dans leur orientation source-cible.

Exemples

store.list_relations(
    source_record_id="current-memory",
    relation_type="supports",
    metadata_filter={"source": "manual"},
)
[RecordRelation(...)]

method list_relations_async (async)

Répertorie de manière asynchrone les relations dans l'orientation source-cible.

Exemples

await store.list_relations_async(
    source_record_id="current-memory", relation_type="supports"
)
[RecordRelation(...)]

method list_thread_messages (résumé)

Répertoriez l'historique des messages stockés pour un thread.

method list_thread_messages_async (async)

Répertoriez de manière asynchrone l'historique des messages stockés pour un thread.

method search (résumé)

Rechercher des enregistrements par similarité.

Exemples

store.add(
    ["Searchable abstract memory"],
    record_type="memory",
    record_ids="mem-search-abstract-docs",
)
['mem-search-abstract-docs']
store.search("Searchable", 1, record_types={"memory"})[0][0].id
'mem-search-abstract-docs'

Filtrer sur une valeur de métadonnées scalaire :

store.add(
    ["pizza release"],
    record_type="memory",
    record_ids="mem-search-meta-source-docs2",
    metadata={"source": "slack"},
)
['mem-search-meta-source-docs2']
any(
    record.id == "mem-search-meta-source-docs2"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"source": "slack"},
    )
)
True

Filtrer sur les métadonnées imbriquées :

store.add(
    ["pizza review"],
    record_type="memory",
    record_ids="mem-search-meta-review-docs2",
    metadata={"review": {"status": "open"}},
)
['mem-search-meta-review-docs2']
any(
    record.id == "mem-search-meta-review-docs2"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"review": {"status": "open"}},
    )
)
True

Faites correspondre exactement une valeur de liste, y compris l'ordre :

store.add(
    ["pizza tags"],
    record_type="memory",
    record_ids="mem-search-meta-tags-docs2",
    metadata={"tags": ["prod", "urgent"]},
)
['mem-search-meta-tags-docs2']
any(
    record.id == "mem-search-meta-tags-docs2"
    for record, _ in store.search(
        "pizza",
        k=5,
        metadata_filter={"tags": ["prod", "urgent"]},
    )
)
True

Filtrer lorsqu'un tableau de métadonnées contient une valeur :

any(
    record.id == "mem-search-meta-tags-docs2"
    for record, _ in store.search(
        "pizza",
        k=5,
        metadata_filter={"tags": {"$array_contains": "prod"}},
    )
)
True

Combinez plusieurs conditions de métadonnées. Un enregistrement doit satisfaire toutes les clés :

store.add(
    ["pizza rollout"],
    record_type="memory",
    record_ids="mem-search-meta-combined-docs2",
    metadata={
        "source": "slack",
        "review": {"status": "open"},
        "tags": ["prod", "urgent"],
    },
)
['mem-search-meta-combined-docs2']
any(
    record.id == "mem-search-meta-combined-docs2"
    for record, _ in store.search(
        "pizza",
        k=5,
        metadata_filter={
            "source": "slack",
            "review": {"status": "open"},
            "tags": ["prod", "urgent"],
        },
    )
)
True

method search_async (async)

Rechercher des enregistrements de manière asynchrone par similarité sémantique.

method update (résumé)

Mettre à jour le contenu des enregistrements stockés, l'intégration des données, les métadonnées, l'horodatage ou l'expiration.

method update_async (async)

Mettre à jour de manière asynchrone le contenu des enregistrements stockés, l'intégration des données, les métadonnées, l'horodatage ou l'expiration.

method update_relations (résumé)

Mettez à jour les valeurs mutables sur les relations stockées.

Les champs omis restent inchangés, sauf que le passage à un type de relation mémoire intégré remplace son libellé inverse par l'inverse fixe. Une banque de mémoire soutenue par une base de données recalcule également les états de cycle de vie des adresses après une modification de type de relation.

Exemples

store.update_relations(
    "relation-id", relation_types="supports"
)
['relation-id']

method update_relations_async (async)

Mettre à jour de manière asynchrone les valeurs mutables sur les relations stockées.

Les champs omis restent inchangés, sauf que le passage à un type de relation mémoire intégré remplace son libellé inverse par l'inverse fixe. Une banque de mémoire soutenue par une base de données recalcule également les états de cycle de vie des adresses après une modification de type de relation.

Exemples

await store.update_relations_async(
    "relation-id", relation_types="supports"
)
['relation-id']

Banque Oracle DB

classe oracleagentmemory.core.OracleDBMemoryStore

Bases : OracleMemoryStore

Persistance basée sur la base de données pour les messages, documents, mémoires et profils d'acteur.

Créez une banque Oracle DB.

Avertissement : SchemaPolicy.CREATE_IF_NECESSARY peut être plus coûteux que le démarrage normal de l'emplacement de stockage car il peut réparer des objets de schéma gérés avant la réussite de l'initialisation. Planifier le travail de réparation en tant qu'opération de maintenance lorsqu'un schéma peut contenir de nombreuses lignes. Une banque sur une ancienne version de schéma nécessite une mise à niveau de schéma de package avant l'initialisation.

Si la configuration du schéma doit créer le travail de purge géré des enregistrements expirés mais que l'utilisateur de base de données ne dispose pas du privilège Scheduler-job, l'initialisation avertit et continue. Les messages et les mémoires expirés restent masqués lors des lectures et des recherches, mais ils ne sont pas purgés physiquement tant que le travail n'est pas créé par un utilisateur disposant du privilège CREATE JOB ou d'un planificateur équivalent.

Lorsque SchemaPolicy.CREATE_IF_NECESSARY crée pour la première fois un index hybride géré sur un schéma existant, Oracle analyse le texte de recherche stocké et crée l'état de l'index hybride géré à partir du modèle dans la base de données configuré. L'initialisation du stockage attend la fin de ce script LDD. Planifiez donc la première mise à niveau hybride en tant qu'opération de migration ou de maintenance pour les schémas volumineux. SearchIndexSyncMode contrôle la maintenance en cours après l'existence de l'index. Il ne rend pas le premier build d'index asynchrone.

La création de cet index hybride géré crée également une préférence de vecteur DBMS_VECTOR_CHAIN nommée par le schéma géré. La préférence stocke les métadonnées de configuration du vecteur léger à partir du modèle OracleDBEmbedder configuré. Il peut être inspecté à l'aide des vues de préférences Oracle Text telles que CTX_USER_PREFERENCES et CTX_USER_PREFERENCE_VALUES.

méthode add

Ajoutez des enregistrements à la banque Oracle DB.

Exemples

store.add(
    ["Index this stored text"],
    record_type="memory",
    record_ids="mem-db-add-docs",
)
['mem-db-add-docs']
store.add(
    ["Stored text"],
    record_type="memory",
    index_texts=["Search this text"],
    record_ids="mem-db-index-text-docs",
)
['mem-db-index-text-docs']
store.add(
    ["Short-lived event"],
    record_type="memory",
    record_ids="mem-db-ttl-docs",
    timestamps="2026-01-01T12:00:00+00:00",
    ttl_days=7,
    ttl_anchor=TimeToLiveAnchor.TIMESTAMP,
)
['mem-db-ttl-docs']

méthode add_agent

Ajoutez un enregistrement de profil d'agent.

Notes

La portée des enregistrements de profil d'agent n'est pas définie. L'identificateur d'enregistrement public inséré est la même valeur transmise que agent_id.

Exemples

store.add_agent("a-docs-agent", "Support assistant")
'a-docs-agent'

method add_agent_async (async)

Ajoutez de manière asynchrone un enregistrement de profil d'agent.

method add_async (async)

Ajoutez de manière asynchrone des enregistrements orientés ligne au magasin.

accepte les mêmes arguments et renvoie les mêmes identificateurs que add().

méthode add_batches

Ajoutez des lots logiques préparés par l'appelant au magasin.

Exemples

store.add_batches(
    [
        PendingRecordBatch(
            contents=["pizza batch"],
            record_type="memory",
            record_ids="mem-batch-docs",
        )
    ]
)
['mem-batch-docs']

method add_batches_async (async)

Ajoutez de manière asynchrone des lots logiques préparés par l'appelant au magasin.

accepte les mêmes arguments et renvoie les mêmes identificateurs que add_batches().

méthode add_relations

Stockez atomiquement une ou plusieurs relations mémoire-mémoire.

Les valeurs scalaires sont diffusées dans le lot d'ID source ; les listes doivent être alignées. Une seule orientation de relation peut être stockée pour une paire d'adresses. Les étiquettes de liaison de mémoire intégrées reçoivent leur étiquette inversée fixe et les étiquettes de cycle de vie mettent à jour l'état de l'adresse dans la même transaction.

Exemples

store.add_relations(
    "new-memory", "memory", "old-memory", "memory", "supersedes"
)
['relation-id']

method add_relations_async (async)

Stockez de manière asynchrone une ou plusieurs relations dirigées.

Les valeurs scalaires sont diffusées dans le batch d'enregistrement source. Les valeurs de liste doivent avoir la même longueur. Une seule orientation peut être stockée pour une paire d'adresses. Utilisez opposite_relation_types pour décrire la vue inverse plutôt que d'ajouter une seconde relation inverse.

Exemples

await store.add_relations_async(
    "new", "memory", "old", "memory", "supersedes"
)
['relation-id']

méthode add_user

Ajouter un enregistrement de profil utilisateur.

Notes

Les enregistrements de profil utilisateur n'ont pas de portée. L'identificateur d'enregistrement public inséré est le fichier user_id explicite ou inféré.

Exemples

store.add_user("u-docs-profile", "Prefers concise answers.")
'u-docs-profile'

method add_user_async (async)

Ajouter un enregistrement de profil utilisateur de manière asynchrone.

méthode delete

Supprimez une ligne gérée et ses lignes de bloc par identificateur.

Notes

L'opération s'exécute dans une transaction. Lorsque cascade est activé pour une cible de niveau supérieur prise en charge, la suppression de profil et toutes les suppressions enfant ciblées sont validées ou annulées ensemble.

Exemples

store.add(["Delete me"], record_type="memory", record_ids="mem-delete-docs")
['mem-delete-docs']
store.delete("memory", "mem-delete-docs")
1

method delete_async (async)

Supprimer de manière asynchrone un enregistrement stocké par identifiant.

méthode delete_relations

Supprimer les relations par identifiant et recalculer l'état du cycle de vie.

Exemples

store.delete_relations("relation-id")
1

method delete_relations_async (async)

Supprimer de manière asynchrone les relations par identificateur.

L'état de cycle de vie est recalculé à partir des relations restantes.

Exemples

await store.delete_relations_async("relation-id")
1

méthode delete_thread

Supprimer un thread et ses lignes stockées associées.

Notes

Utilisez cette opération lorsque vous avez besoin d'un nettoyage en cascade de niveau thread. Dans la banque de données adossée à une base de données, la suppression du thread enlève la ligne de thread géré ainsi que les lignes de message et de mémoire associées, ainsi que les données de recherche gérées pour extraction. Elle est plus large qu'une suppression de niveau message, qui supprime uniquement la ligne de message brut. La suppression de thread enlève les lignes de message et de mémoire dépendantes ainsi que les données d'extraction associées dans la même transaction.

Exemples

store.delete_thread("c1")
0

method delete_thread_async (async)

Supprimer de manière asynchrone un thread et les données stockées associées.

Notes

Il s'agit de l'opération de niveau magasin permettant de supprimer un thread et les enregistrements de niveau thread gérés par le magasin. Préférez la suppression de thread lorsque les exigences de conservation appellent la suppression des messages source et des données de mémoire dérivées de portée thread, car les suppressions au niveau message n'impliquent pas la suppression des enregistrements dérivés conservés séparément.

method get

Extraire un enregistrement stocké par identifiant.

Exemples

store.add(["Remember this"], record_type="memory", record_ids="mem-get-docs")
['mem-get-docs']
store.get("memory", "mem-get-docs").id
'mem-get-docs'

method get_async (async)

Extraire de manière asynchrone un enregistrement stocké par type et identifiant.

méthode get_relation

Renvoyer une relation identifiée par un ID ou un tuple d'adresse complet.

Fournissez relation_id seul ou fournissez un tuple complet d'adresse source à cible.

Exemples

store.get_relation(relation_id="relation-id")
RecordRelation(...)
store.get_relation(
    "source-id", "memory", "target-id", "fact", "supports"
)
RecordRelation(...)

method get_relation_async (async)

Extraire de manière asynchrone une relation par ID ou tuple d'adresse.

Fournissez relation_id seul ou fournissez un tuple complet d'adresse source à cible.

Exemples

await store.get_relation_async(relation_id="relation-id")
RecordRelation(...)

méthode list

Enumérer les enregistrements persistants pour un type d'enregistrement.

Notes

"user_profile" et "agent_profile" sont des types d'enregistrement non ciblés. Pour ces types d'enregistrement, thread_id, user_id et agent_id sont ignorés et l'identité de l'acteur reste dans record.id. Les enregistrements "thread" affichent l'identificateur de thread en tant que record.id et record.thread_id.

Exemples

store.add(
    ["First listed", "Second listed"],
    record_type="memory",
    record_ids=["mem-list-docs-1", "mem-list-docs-2"],
)
['mem-list-docs-1', 'mem-list-docs-2']
[record.id for record in store.list("memory", limit=2)]
['mem-list-docs-1', 'mem-list-docs-2']
store.add_user("u-list-docs", "Prefers concise answers.")
'u-list-docs'
any(
    record.id == "u-list-docs"
    for record in store.list("user_profile", user_id=None, limit=10)
)
True

method list_async (async)

Répertorie de manière asynchrone les enregistrements stockés pour un type d'enregistrement.

méthode list_relations

Répertoriez les relations dans leur orientation source-cible.

Exemples

store.list_relations(
    source_record_id="current-memory",
    relation_type="supports",
    metadata_filter={"source": "manual"},
)
[RecordRelation(...)]

method list_relations_async (async)

Répertorie de manière asynchrone les relations dans l'orientation source-cible.

Exemples

await store.list_relations_async(
    source_record_id="current-memory", relation_type="supports"
)
[RecordRelation(...)]

méthode list_thread_messages

Renvoyer les messages persistants pour un thread.

Exemples

store.list_thread_messages("c1")
[]

method list_thread_messages_async (async)

Répertoriez de manière asynchrone l'historique des messages stockés pour un thread.

Rechercher des enregistrements par similarité.

Le back-end de recherche actif dépend de l'adresse SearchStrategy configurée de la banque. SearchStrategy.VECTOR classe le vecteur de requête par rapport aux vecteurs d'enregistrement stockés. SearchStrategy.HYBRID interroge l'index hybride géré d'Oracle sur le texte de recherche stocké et son état d'index géré. SearchStrategy.KEYWORD se classe uniquement par le texte correspondant au texte de recherche stocké.

Exemples

store.add(
    ["pizza preference"],
    record_type="memory",
    record_ids="mem-search-docs",
    thread_ids="c-search-docs",
)
['mem-search-docs']
results = store.search(
    "pizza",
    1,
    thread_id="c-search-docs",
    exact_thread_match=True,
    record_types={"memory"},
)
results[0][0].id
'mem-search-docs'

Filtrer sur une valeur de métadonnées scalaire :

store.add(
    ["pizza release"],
    record_type="memory",
    record_ids="mem-search-meta-source-docs",
    metadata={"source": "slack"},
)
['mem-search-meta-source-docs']
any(
    record.id == "mem-search-meta-source-docs"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"source": "slack"},
    )
)
True

Filtrer sur les métadonnées imbriquées :

store.add(
    ["pizza review"],
    record_type="memory",
    record_ids="mem-search-meta-review-docs",
    metadata={"review": {"status": "open"}},
)
['mem-search-meta-review-docs']
any(
    record.id == "mem-search-meta-review-docs"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"review": {"status": "open"}},
    )
)
True

Faites correspondre exactement une valeur de liste, y compris l'ordre :

store.add(
    ["pizza tags"],
    record_type="memory",
    record_ids="mem-search-meta-tags-docs",
    metadata={"tags": ["prod", "urgent"]},
)
['mem-search-meta-tags-docs']
any(
    record.id == "mem-search-meta-tags-docs"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"tags": ["prod", "urgent"]},
    )
)
True

Filtrer lorsqu'un tableau de métadonnées contient une valeur :

any(
    record.id == "mem-search-meta-tags-docs"
    for record, _ in store.search(
        "pizza",
        k=3,
        metadata_filter={"tags": {"$array_contains": "prod"}},
    )
)
True

Combinez plusieurs conditions de métadonnées. Un enregistrement doit satisfaire toutes les clés :

store.add(
    ["pizza rollout"],
    record_type="memory",
    record_ids="mem-search-meta-combined-docs",
    metadata={
        "source": "slack",
        "review": {"status": "open"},
        "tags": ["prod", "urgent"],
    },
)
['mem-search-meta-combined-docs']
any(
    record.id == "mem-search-meta-combined-docs"
    for record, _ in store.search(
        "pizza",
        k=5,
        metadata_filter={
            "source": "slack",
            "review": {"status": "open"},
            "tags": ["prod", "urgent"],
        },
    )
)
True

method search_async (async)

Rechercher des enregistrements de manière asynchrone par similarité sémantique.

méthode update

Mettre à jour le contenu des enregistrements stockés, l'état de la recherche, les métadonnées et les valeurs d'horodatage.

Exemples

store.add(["Original note"], record_type="memory", record_ids="mem-update-docs")
['mem-update-docs']
store.update("memory", "mem-update-docs", content="Updated note")
1
store.get("memory", "mem-update-docs").content
'Updated note'

method update_async (async)

Mettre à jour de manière asynchrone le contenu des enregistrements stockés, l'intégration des données, les métadonnées, l'horodatage ou l'expiration.

méthode update_relations

Mettez à jour les champs de relation mutables et recalculez l'état de cycle de vie de l'adresse.

Les champs omis restent inchangés. Les étiquettes de liaison de mémoire intégrées conservent toujours leur étiquette inverse dérivée.

Exemples

store.update_relations("relation-id", relation_types="supports")
['relation-id']

method update_relations_async (async)

Mettre à jour de manière asynchrone les valeurs mutables sur les relations stockées.

Les champs omis restent inchangés, sauf que le passage à un type de relation mémoire intégré remplace son libellé inverse par l'inverse fixe. Une banque de mémoire soutenue par une base de données recalcule également les états de cycle de vie des adresses après une modification de type de relation.

Exemples

await store.update_relations_async(
    "relation-id", relation_types="supports"
)
['relation-id']

Relations

OracleDBMemoryStore peut stocker des relations dirigées entre des enregistrements de type mémoire (memory, fact, guideline et preference). Utilisez add_relations(), get_relation(), list_relations(), update_relations() et delete_relations() lorsqu'une intégration a besoin de l'API de relation de niveau inférieur. Les API client et thread fournissent link_records(), update_record_link() et delete_record_link() pour les types de relation de mémoire pris en charge.

Pour extraire une relation, indiquez relation_id seul ou le tuple d'adresse stocké complet : ID et type d'enregistrement source, ID et type d'enregistrement cible, et type de relation. Un tuple partiel et un ID de relation associés à un champ de tuple ne sont pas valides car aucun des deux n'identifie la relation demandée sans ambiguïté.

Utilisez list_relations() pour énumérer les relations dans l'ordre de création. Filtrer par ID et type d'enregistrement source ou cible, ou par libellé de relation dirigée. Il utilise la limite de liste de sécurité normale du magasin, sauf si vous transmettez limit=None. Son élément metadata_filter utilise la même sémantique de correspondance exacte, d'objet imbriqué, d'appartenance à un tableau et de négation que list(). Transmettez metadata_filter=None pour renvoyer uniquement les relations sans métadonnées.

Les types de relation de cycle de vie (supersedes, refines et duplicates) marquent la mémoire cible non valide tant que le lien existe. La suppression ou la modification du dernier lien de ce type rétablit le statut valide de la cible. Les API de recherche peuvent exclure les enregistrements non valides avec include_invalid_results=False.

classe oracleagentmemory.apis.relations.RecordRelation

Bases : object

Décrivez une relation dirigée et stockée entre deux enregistrements.

Stratégie de recherche

classe oracleagentmemory.core.dbsearch.SearchStrategy

Bases : Enum

Comportement de recherche pour les banques Oracle DB.

L'initialisation de la banque de données utilise la stratégie sélectionnée pour choisir la fonction de recherche de schéma géré. La recherche VECTOR stocke les incorporations locales. La recherche KEYWORD stocke le texte recherchable et un index de texte. La recherche HYBRID stocke le texte recherchable plus l'état d'index vectoriel hybride géré par Oracle. La banque de base de données valide cette fonctionnalité de schéma au démarrage afin qu'une stratégie incompatible ne renvoie pas de résultats incomplets en mode silencieux.

VECTOR
Recherche par similarité vectorielle uniquement. Le magasin intègre la requête avec l'intégrateur configuré, ou utilise un query_vector fourni par l'appelant, et classe les enregistrements en fonction de la distance par rapport aux vecteurs stockés. Utilisez-le avec un schéma de base de données configuré pour la recherche vectorielle.
HYBRID
Recherchez avec l'index hybride géré d'Oracle. Oracle combine la correspondance de texte sur le texte de recherche stocké avec le classement vectoriel à partir de l'index hybride dans la base de données. Utilisez cette option lorsque les utilisateurs peuvent effectuer une recherche par langage naturel, ainsi que par identifiants, alias ou noms de produit exacts. Cette stratégie exige que l'intégrateur principal du magasin soit un OracleDBEmbedder afin que l'index géré et le magasin partagent un modèle dans la base de données.
KEYWORD
Effectuez une recherche uniquement par mot-clé/texte sur le texte de recherche stocké. Ce mode ne crée pas d'intégrations de requête locale et n'a pas besoin d'un intégrateur Oracle DB. Lorsqu'il est ouvert sur un schéma hybride existant, il peut utiliser la branche de texte de cet index hybride sans créer de nouvel index hybride. Utilisez-le lorsque les identificateurs exacts, les alias, les noms de produit ou les expressions courtes doivent conduire à la récupération sans fusion vectorielle.

HYBRIDE = 'hybride'

MOT-clé = 'mot-clé'

VECTEUR = 'vecteur'

Mode de synchronisation d'index de recherche

classe oracleagentmemory.core.dbsearch.SearchIndexSyncMode

Bases : Enum

Comportement d'actualisation des index de recherche de base de données gérée.

Ce paramètre détermine quand Oracle rend le texte de recherche nouveau ou modifié visible pour la recherche en mode texte adossée à une base de données. SearchStrategy.HYBRID utilise l'index vectoriel hybride géré d'Oracle. SearchStrategy.KEYWORD utilise un index Oracle Text. SearchStrategy.VECTOR n'utilise pas ce paramètre.

ON_COMMIT
Actualisez l'index lors de la validation de la transaction d'écriture. Il s'agit du choix par défaut et du plus simple pour la plupart des applications, car les enregistrements peuvent faire l'objet d'une recherche immédiatement après une écriture réussie. Il peut ajouter du travail pour écrire des transactions car l'index est immédiatement mis à jour.
MANUAL
N'actualisez pas l'index automatiquement. Les enregistrements nouveaux ou mis à jour peuvent ne pas apparaître dans la recherche par mot clé ou hybride tant que vous n'avez pas exécuté vous-même l'opération de synchronisation d'index côté base de données. Cela est utile pour les chargements en masse ou les fenêtres de maintenance dans lesquelles vous souhaitez contrôler l'actualisation des exécutions de travail.
AUTO
Laissez Oracle actualiser l'index hybride géré de manière asynchrone. Les écritures peuvent éviter le coût d'actualisation immédiat, mais les résultats de la recherche peuvent différer des écritures récentes jusqu'à ce qu'Oracle termine l'actualisation en arrière-plan. Ce mode est pris en charge uniquement avec SearchStrategy.HYBRID.

Avertissement : ce paramètre contrôle la maintenance continue après l'existence de l'index de recherche géré. Il ne rend pas le premier build d'index asynchrone. La création d'un index hybride géré sur du texte de recherche stocké existant peut être longue car Oracle construit l'état de l'index hybride géré à partir de ce texte.

AUTO = 'AUTO'

MANUEL = 'manuel'

ON_COMMIT = 'ON_COMMIT'

Durée de vie

classe oracleagentmemory.core.retention.MemoryRetentionConfig

Bases : object

Paramètres de conservation de niveau schéma pour les enregistrements sauvegardés par Oracle DB.

classe oracleagentmemory.apis.ttl.TimeToLiveAnchor

Bases : Enum

Ancrage utilisé pour calculer un horodatage d'expiration à partir d'une durée de vie.

CREATED_AT
Calculer l'expiration à partir de l'horodatage de création de la base de données de l'enregistrement. Il s'agit de la valeur par défaut lorsque les appelants omettent ttl_anchor.
TIMESTAMP
Calculer l'expiration à partir de l'horodatage de l'événement stocké de l'enregistrement. Utilisez cette option lorsqu'un message ou une mémoire représente un événement plus ancien et doit expirer par rapport à l'heure de l'événement au lieu de l'heure d'insertion.

CREATED_AT = 'CREATED_AT'

TIMESTAMP = 'TIMESTAMP'

Stratégie de schéma

classe oracleagentmemory.core.SchemaPolicy

Bases : str, Enum

Stratégie de création de schéma pour les banques Oracle DB.

EXIGER_EXISTANT

Vérifiez que le schéma géré complet existe déjà et qu'il est à jour. Ne créez ni ne modifiez des objets de base de données.

CREATE_IF_EMPTY

S'il n'existe aucun objet géré, initialisez le schéma. Si des objets existent déjà, vous devez disposer d'un schéma géré complet et à jour.

CRÉER_SI_NÉCESSAIRE

Créez les objets gérés manquants et appliquez les mises à niveau de schéma géré prises en charge.

RECRÉER

Supprimez et recréez tous les objets de schéma gérés. C'est destructeur.

NO_CHECK

Ignorer la validation et la création de schéma géré. Utilisez cette stratégie pour un emplacement de stockage protégé par la sécurité des données profondes existant tant qu'un contexte de sécurité de l'utilisateur final est actif. Un emplacement de stockage ouvert sous un contexte d'utilisateur final nécessite un contexte actif pour chaque opération de base de données suivante. D'autres stratégies de schéma rejettent les contextes de l'utilisateur final car le travail du cycle de vie du schéma doit être exécuté via une identité de base de données administrative.