检索器的优化,动态检索策略,怎么基于用户问题动态调整检索参数?

内容纲要

这是一个典型 RAG / Agent 工程里的核心问题,你已经问到“检索器从静态工具 → 智能组件”这一步了。

下面我不讲泛泛而谈的“可以用 LLM 判断”,而是给你一套可落地、可编码、可扩展动态检索策略体系


一、先给一句话总纲(非常重要)

动态检索策略 = 把“用户问题”先当成一个“信号源”,
再根据这个信号,动态配置检索器的参数组合。

换句话说:
不是所有问题都配同一套检索参数。


二、检索器里「真正可动态调的参数」有哪些?

你先要明确:你能调什么

1️⃣ 向量检索层参数(Embedding / Vector DB)

参数 作用
top_k 返回多少条候选文档
score_threshold 相似度最低阈值
embedding_model 使用哪种 embedding
chunk_size 文档切分粒度
chunk_overlap 切片重叠
search_type dense(稠密向量) / sparse(稀疏向量) / hybrid(混合)

2️⃣ 混合检索 / 重排层参数

参数 作用
BM25 权重 关键词精确度
向量权重 语义相似度
rerank_top_n 进入重排的文档数
reranker_model 是否启用重排

3️⃣ 上下文构建层参数(Context Builder)

参数 作用
max_tokens 最大上下文
去重策略 是否合并相似 chunk
来源优先级 权威文档 / 最新文档
多轮记忆 是否引入历史问题

三、动态调整的第一步:问题画像(Query Profiling)

核心思想

先不要急着检索,先“看清楚问题是什么类型”

一个工程可用的问题画像维度

{
  "intent": "fact / howto / analysis / opinion",
  "domain": "tech / finance / medical / internal",
  "specificity": "high / medium / low",
  "ambiguity": "low / high",
  "temporal": "yes / no",
  "length": "short / long",
  "structure": "keyword / natural_language"
}

怎么来?

三种方式(按成熟度)

  1. 规则 + 统计(最快落地)
  2. 小模型 / prompt 分类
  3. LLM 自我分析(工业常用)

示例 Prompt(可直接用):

请分析用户问题的检索特征,输出 JSON:
- intent
- specificity
- 是否需要精确匹配
- 是否适合语义扩展
- 建议的 top_k 范围

四、核心:基于问题画像 → 动态调参策略

下面是真正能直接抄的策略表


① 问题非常具体 / 强关键词(如报错、参数、字段)

特征

  • 问题短
  • 专有名词多
  • 一问一答

策略

search_type = hybrid(BM25 权重大)
top_k = 5 ~ 10
score_threshold = 高
chunk_size = 小
rerank = 可选

原因

不需要“联想”,要“命中”。


② 问题模糊 / 宽泛(如“怎么设计一个…”)

特征

  • 抽象
  • 无明显关键词
  • 需要组合知识

策略

search_type = dense
top_k = 20 ~ 50
score_threshold = 低
chunk_size = 大
rerank = 开

原因

要覆盖面,而不是精准一刀。


③ 问题是“分析 / 对比 / 总结”

特征

  • 多条件
  • 多角度
  • 输出长

策略

top_k = 30+
rerank_top_n = 10 ~ 20
context 合并去重
优先长文档

④ 问题涉及时间 / 最新信息

特征

  • “最近”
  • “最新”
  • “现在”

策略

过滤旧文档
提高新文档权重
降低相似度阈值

⑤ 用户连续追问(多轮对话)

特征

  • “那这个呢?”
  • “继续”
  • “详细说说”

策略

引入上一轮 context
缩小 top_k
提高 rerank 权重

五、一个「动态检索策略」完整伪代码(重点)

profile = analyze_query(user_query)

params = {}

if profile.specificity == "high":
    params["top_k"] = 8
    params["search_type"] = "hybrid"
elif profile.intent == "analysis":
    params["top_k"] = 30
    params["rerank"] = True
else:
    params["top_k"] = 20

if profile.ambiguity == "high":
    params["score_threshold"] = 0.3
else:
    params["score_threshold"] = 0.6

docs = retriever.search(user_query, **params)

这就是动态检索器的最小工程闭环


六、进阶:让检索器“自己学会调参”

如果你再往前走一步:

1️⃣ 检索失败自反馈

  • 命中文档太少 → 提高 top_k
  • 生成答非所问 → 收紧 threshold
  • LLM 给低置信回答 → 重新检索

2️⃣ 多路检索并行

  • keyword 路
  • semantic 路
  • history 路
  • tool 路

再由一个 Retriever Agent 决策。


七、一句话工程总结(送你)

静态检索解决“能不能查到”,
动态检索解决“该怎么查”。

当你开始根据问题本身调检索参数
你已经在做真正的 RAG 系统,而不是“向量库 + Prompt”

close
arrow_upward