如何提高搜索结果的相关性

搜索可以检索查询的有用记录,但广泛的搜索仍然可以返回比应用程序可以使用的更直接的结果,包括仅与问题松散相关的结果。

通过搜索后期处理,应用程序可以在检索后控制该结果集的大小和焦点。当将搜索结果插入到代理提示或空间有限的上下文卡中时,这尤其有用。

本指南介绍了如何为常规搜索和上下文卡检索配置搜索后行为。使用 TopKMemorySearchConfig 可返回固定的最大直接搜索结果数,并根据需要对其进行重新排序。使用 PruningMemorySearchConfig 还可以删除 LLM 中相关性较低的结果。

注:在构建上下文卡时,Oracle 代理内存将独立于当前线程中的消息搜索类似内存的记录。配置重新排序或修剪时,在组合这些集合之前,会分别将其应用于每组结果。组合结果受 max_relevant_results 和令牌预算限制。

使用 min_relevant_results_by_type 时,将单独搜索每个请求的记录类型。配置后,重新排序或修剪也会单独应用于每个搜索的结果。然后,对所有类似内存的记录类型进行其他搜索,即可使用保留的任何结果插槽。相比之下,如果为请求多个 record_types 的常规搜索配置了重新排序或修剪,则会对组合的搜索结果应用一次。

在本指南中,您将:

提示:有关软件包设置,请参见 Get Started with Agent Memory 。如果在此示例中需要本地 Oracle AI Database,请遵循在本地运行 Oracle AI Database 。

配置搜索组成部分

创建搜索配置使用的模型组件。重新排名者接收查询和原始文档文本,而修剪者使用 LLM 删除相关性较低的直接结果。


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"
API 参考:Reranker LLM

使用固定直接结果限制和重新排名

创建客户机或线程时传递 TopKMemorySearchConfig。搜索最先检索 max_results 个直接结果。然后,可选的 reranker 将仅接收这些结果并更改其顺序,而不会更改其身份。

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"
API 参考:TopKMemorySearchConfig OracleAgentMemory

使用基于 LLM 的修剪

在 OracleAgentMemory 上设置 pruner_llm 以使用缺省的 FAST 评估模式启用客户机范围的修剪。新线程会继承此设置,而已具有存储搜索配置的线程会在重新打开时保留此设置。当初始搜索包含太多不相关的结果并且您需要调整修剪行为时,请使用 PruningMemorySearchConfig。它保留分级的直接结果,并使用配置的 LLM 来标识应删除的其他结果。

直接结果限制在修剪之前应用,因此修剪程序仅评估由该限制选择的结果,并可能进一步减少结果计数。在常规搜索调用上提供 max_results。对于上下文卡检索,max_relevant_results 提供了相应的初始限制。

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,
)

修剪如何在坚果壳中工作

修剪程序会评估排名结果,以确定应保留多少文档。protected_fraction 确保始终包含最相关的文档。例如,使用 protected_fraction=0.1 时,排名前 10% 的文档会受到保护,使其免受修剪,并保留在搜索结果中。

将 evaluation_mode 设置为 PruningEvaluationMode,以控制计算工作的执行量:

num_probe_points 控制在 FAST 和 EXTENDED 模式中考虑的排名结果区域数。使用 EXHAUSTIVE 时将其省略。

注:清除使用 LLM,因此会使搜索速度变慢。在获得更专注的结果集时使用它比最小化搜索延迟更重要。

API 参考:PruningMemorySearchConfig 删除评估模式

应用令牌预算

使用 soft_token_budget 可确定格式化输出的估计大小。将按排名顺序考虑完成结果,并保留达到或超过目标的结果。当搜索找到匹配项时,这将至少保留第一个结果。

使用 token_budget 作为硬限制。省略了超过此限制的完整结果,因此当第一个结果太大时,硬限制不会产生任何输出。单个结果从不拆分。我们建议设置两个预算,硬限制大于软目标。大约三倍软目标的硬限制是一个有用的起点。

例如,如果 soft_token_budget=800 和结果估计为 420、300 和 250 个令牌,则将返回所有三个令牌。第三个结果将累积估计值从 720 到 970 个令牌,并完成软预算选择。如果还设置了 token_budget=900,则仅返回前两个,因为第三个将超过硬限制。

默认情况下应用配置的预算。正每调用值将覆盖其对应的已配置预算,而非正值将禁用它们。

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,
)
API 参考:MemorySearchConfig TopKMemorySearch 配置

结论

在本指南中,我们学习了如何配置直接结果限制、重新排名、基于 LLM 的修剪以及软格式化和硬格式化结果令牌预算。

→在了解如何自定义搜索结果选择后,您现在可以继续自定义上下文卡内容。

完整代码

本指南中包括了完整的示例,供您复制和运行。

#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,
)