内容纲要
这是一个典型 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"
}
怎么来?
三种方式(按成熟度)
- 规则 + 统计(最快落地)
- 小模型 / prompt 分类
- 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”。