Comment améliorer la pertinence des résultats de recherche

La recherche peut extraire des enregistrements utiles pour une requête, mais une recherche globale peut toujours renvoyer des résultats plus directs qu'une application ne peut utiliser, y compris des résultats qui ne sont que vaguement liés à la question.

Le post-traitement de recherche permet à une application de contrôler la taille et le focus de cet ensemble de résultats après l'extraction. Cela est particulièrement utile lorsque les résultats de recherche sont insérés dans une invite d'agent ou une carte de contexte avec un espace limité.

Ce guide explique comment configurer le comportement post-recherche pour les recherches régulières et l'extraction de cartes contextuelles. Utilisez TopKMemorySearchConfig pour renvoyer un nombre maximal fixe de résultats de recherche directe et éventuellement les reclasser. Utilisez PruningMemorySearchConfig pour enlever également les résultats moins pertinents avec un LLM.

Remarque : lors de la création d'une carte de contexte, la mémoire de l'agent Oracle recherche les enregistrements de type mémoire séparément des messages du thread en cours. Lorsque le reclassement ou l'élagage est configuré, il est appliqué séparément à chaque ensemble de résultats avant que les ensembles ne soient combinés. Les résultats combinés sont limités par max_relevant_results et le budget de jeton.

Lorsque min_relevant_results_by_type est utilisé, chaque type d'enregistrement demandé fait l'objet d'une recherche distincte. Le reclassement ou l'élagage, lorsqu'il est configuré, est également appliqué séparément aux résultats de chaque recherche. Une autre recherche sur tous les types d'enregistrements de type mémoire peut ensuite utiliser tous les emplacements de résultats restants. Par comparaison, si le reclassement ou l'élagage est configuré pour une recherche standard qui demande plusieurs éléments record_types, il est appliqué une seule fois aux résultats de la recherche combinée.

Dans ce guide, vous allez :

Conseil : pour la configuration des packages, reportez-vous à Introduction à la mémoire de l'agent. Si vous avez besoin d'une base de données Oracle AI Database locale pour cet exemple, suivez Exécuter Oracle AI Database localement.

Configurer les composants Search

Créez les composants de modèle utilisés par la configuration de recherche. Le reranker reçoit la requête et le texte brut du document, tandis que le pruner utilise le LLM pour supprimer les résultats directs moins pertinents.


import oracledb

from oracleagentmemory.core import (
    OracleAgentMemory,
    PruningEvaluationMode,
    PruningMemorySearchConfig,
    Reranker,
    SchemaPolicy,
    TopKMemorySearchConfig,
)
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm

embedder = Embedder(model="YOUR_EMBEDDING_MODEL")
search_llm = Llm(model="provider/search-llm-model")
reranker = Reranker(model="provider/reranker-model")
db_pool = oracledb.SessionPool(
    user="YOUR DB USER",
    password="YOUR DB PASSWORD",
    dsn="localhost:1521/...",
)
memory_store_id = "T_SEARCH_RESULTS"
Référence d'API : Reranker Llm

Utiliser une limite fixe de résultats directs et un nouveau classement

Transmettez TopKMemorySearchConfig lors de la création du client ou du thread. La recherche commence par extraire au maximum les résultats directs max_results. L'option facultative reranker reçoit alors uniquement ces résultats et modifie leur ordre sans modifier leur identité.

top_k_config = TopKMemorySearchConfig(
    max_results=5,
    reranker=reranker
)
memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=search_llm,
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    memory_store_id=memory_store_id,
    search_config=top_k_config,
)
user_id = "user_123"
Référence d'API : TopKMemorySearchConfig OracleAgentMemory

Utiliser l'élagage basé sur LLM

Définissez pruner_llm sur OracleAgentMemory pour activer l'élagage à l'échelle du client avec le mode d'évaluation FAST par défaut. Les nouveaux threads héritent de ce paramètre, tandis que les threads qui ont déjà une configuration de recherche stockée la conservent lorsqu'ils sont rouverts. Utilisez PruningMemorySearchConfig lorsque la recherche initiale contient trop de résultats moins pertinents et que vous devez régler le comportement d'élagage. Il conserve les résultats directs classés et utilise le LLM configuré pour identifier les résultats supplémentaires qui doivent être enlevés.

La limite de résultats directs est appliquée avant l'élagage, de sorte que l'élagateur évalue uniquement les résultats sélectionnés par cette limite et peut réduire davantage le nombre de résultats. Fournissez max_results lors d'un appel de recherche standard. Pour l'extraction de la carte de contexte, max_relevant_results fournit la limite initiale correspondante.

pruning_memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=search_llm,
    memory_store_id=memory_store_id,
    pruner_llm=search_llm,
)
thread = pruning_memory.create_thread(
    thread_id="search_result_pruning_demo",
    user_id=user_id,
)
pruned_results = thread.search(
    query="Which database does the service use?",
    max_results=50,
)
#Use PruningMemorySearchConfig for advanced modes and tuning.
extended_pruning_config = PruningMemorySearchConfig(
    pruner=search_llm,
    evaluation_mode=PruningEvaluationMode.EXTENDED,
    num_probe_points=3,
    protected_fraction=0.1,
)

Fonctionnement de l'élagage dans une coquille

Le pruner évalue les résultats classés pour déterminer le nombre de documents à conserver. protected_fraction garantit que les documents les plus pertinents sont toujours inclus. Par exemple, avec protected_fraction=0.1, les 10 % premiers des documents classés sont protégés contre l'élagage et restent dans les résultats de la recherche.

Définissez evaluation_mode avec PruningEvaluationMode pour contrôler la taille du travail d'évaluation :

num_probe_points contrôle le nombre de régions à résultats classés prises en compte en modes FAST et EXTENDED. Omettez-le lorsque vous utilisez EXHAUSTIVE.

Remarque : l'élagage utilise un LLM, de sorte qu'il peut ralentir les recherches. L'utiliser lors de l'obtention d'un ensemble de résultats plus ciblé est plus important que de minimiser la latence de recherche.

Référence d'API : PruningMemorySearchConfig Mode évaluation élagage

Appliquer des budgets par jeton

Utilisez soft_token_budget pour cibler la taille estimée de la sortie formatée. Les résultats complets sont pris en compte dans l'ordre et le résultat qui atteint ou traverse la cible est conservé. Cela conserve au moins le premier résultat lorsque la recherche trouve une correspondance.

Utilisez token_budget comme limite stricte. Un résultat complet qui dépasserait cette limite est omis, de sorte qu'une limite stricte ne peut produire aucune sortie lorsque le premier résultat est trop volumineux. Les résultats individuels ne sont jamais fractionnés. Nous vous recommandons de définir les deux budgets, avec une limite stricte supérieure à la cible souple. Une limite stricte environ trois fois la cible souple est un point de départ utile.

Par exemple, avec soft_token_budget=800 et des résultats estimés à 420, 300 et 250 jetons, les trois sont renvoyés. Le troisième résultat prend l'estimation cumulée de 720 à 970 jetons et complète la sélection du budget logiciel. Si token_budget=900 est également défini, seuls les deux premiers sont renvoyés car le troisième dépasserait la limite stricte.

Les budgets configurés s'appliquent par défaut. Les valeurs positives par appel remplacent les budgets configurés correspondants, tandis que les valeurs non positives les désactivent.

results = memory.search(
    query="Which database does the service use?",
    user_id=user_id,
    soft_token_budget=1_000,
    token_budget=3_000,
)

#Per-call values override the configured budgets.
larger_results = memory.search(
    query="Which database does the service use?",
    user_id=user_id,
    soft_token_budget=4_000,
    token_budget=12_000,
)
Référence d'API : MemorySearchConfig TopKMemorySearchConfig

Conclusion

Dans ce guide, nous avons appris à configurer les limites de résultats directs, le reclassement, l'élagage basé sur le LLM et les budgets de jetons de résultats au format souple et fixe.

→ Après avoir appris à personnaliser la sélection des résultats de recherche, vous pouvez maintenant passer à Personnaliser le contenu de la carte contextuelle.

Code complet

L'exemple complet est inclus dans ce guide pour que vous puissiez le copier et l'exécuter.

#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 - Improve Search Result Relevance
#------------------------------------------------------------------

##Configure search components


import oracledb

from oracleagentmemory.core import (
    OracleAgentMemory,
    PruningEvaluationMode,
    PruningMemorySearchConfig,
    Reranker,
    SchemaPolicy,
    TopKMemorySearchConfig,
)
from oracleagentmemory.core.embedders.embedder import Embedder
from oracleagentmemory.core.llms.llm import Llm

embedder = Embedder(model="YOUR_EMBEDDING_MODEL")
search_llm = Llm(model="provider/search-llm-model")
reranker = Reranker(model="provider/reranker-model")
db_pool = oracledb.SessionPool(
    user="YOUR DB USER",
    password="YOUR DB PASSWORD",
    dsn="localhost:1521/...",
)
memory_store_id = "T_SEARCH_RESULTS"



##Configure top k search

top_k_config = TopKMemorySearchConfig(
    max_results=5,
    reranker=reranker
)
memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=search_llm,
    schema_policy=SchemaPolicy.CREATE_IF_NECESSARY,
    memory_store_id=memory_store_id,
    search_config=top_k_config,
)
user_id = "user_123"



##Configure pruned search

pruning_memory = OracleAgentMemory(
    connection=db_pool,
    embedder=embedder,
    llm=search_llm,
    memory_store_id=memory_store_id,
    pruner_llm=search_llm,
)
thread = pruning_memory.create_thread(
    thread_id="search_result_pruning_demo",
    user_id=user_id,
)
pruned_results = thread.search(
    query="Which database does the service use?",
    max_results=50,
)
#Use PruningMemorySearchConfig for advanced modes and tuning.
extended_pruning_config = PruningMemorySearchConfig(
    pruner=search_llm,
    evaluation_mode=PruningEvaluationMode.EXTENDED,
    num_probe_points=3,
    protected_fraction=0.1,
)



##Apply search token budgets

results = memory.search(
    query="Which database does the service use?",
    user_id=user_id,
    soft_token_budget=1_000,
    token_budget=3_000,
)

#Per-call values override the configured budgets.
larger_results = memory.search(
    query="Which database does the service use?",
    user_id=user_id,
    soft_token_budget=4_000,
    token_budget=12_000,
)