如何提高搜索结果的相关性
搜索可以检索查询的有用记录,但广泛的搜索仍然可以返回比应用程序可以使用的更直接的结果,包括仅与问题松散相关的结果。
通过搜索后期处理,应用程序可以在检索后控制该结果集的大小和焦点。当将搜索结果插入到代理提示或空间有限的上下文卡中时,这尤其有用。
本指南介绍了如何为常规搜索和上下文卡检索配置搜索后行为。使用 TopKMemorySearchConfig 可返回固定的最大直接搜索结果数,并根据需要对其进行重新排序。使用 PruningMemorySearchConfig 还可以删除 LLM 中相关性较低的结果。
注:在构建上下文卡时,Oracle 代理内存将独立于当前线程中的消息搜索类似内存的记录。配置重新排序或修剪时,在组合这些集合之前,会分别将其应用于每组结果。组合结果受 max_relevant_results 和令牌预算限制。
使用 min_relevant_results_by_type 时,将单独搜索每个请求的记录类型。配置后,重新排序或修剪也会单独应用于每个搜索的结果。然后,对所有类似内存的记录类型进行其他搜索,即可使用保留的任何结果插槽。相比之下,如果为请求多个 record_types 的常规搜索配置了重新排序或修剪,则会对组合的搜索结果应用一次。
在本指南中,您将:
- 配置固定的最大直接搜索结果数
- 使用重新排序
- 使用基于 LLM 的修剪
- 使用已配置和按呼叫的令牌预算
提示:有关软件包设置,请参见 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,以控制计算工作的执行量:
FAST是默认值。它优先考虑低延迟,并可能提前停止评估。EXTENDED会评估更广泛的结果部分,并增加延迟和 LLM 使用。EXHAUSTIVE单独评估每个求职者结果,并具有最高的延迟和 LLM 使用率。
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,
)