
关联代码:
data/课程练习/RAG技术与应用/query_rewrite.py目标:在进入 RAG 检索/联网搜索前,把用户 Query 做“结构化处理”——先识别类型,再选择策略改写/拆分/触发搜索,输出更“检索友好”的输入,并让回答可追溯(带来源)。

我把 Query Rewrite 当成 RAG 的“前置意图校准”:
换句话说:Rewrite 负责把门开对(搜得全),Rerank 才有发挥空间去“排得准”。
下面是我对 case1~case6(以及对应方法)的总结。
场景类型 | 典型痛点 | 我在 Demo 里的处理方式 | 期望收益 |
|---|---|---|---|
上下文依赖型 | “还有/其他/继续/那它呢”这类追问,需要历史才能自洽 | 传入 conversation_history,让模型补全必要上下文 | 避免检索“无主语/无对象” |
模糊指代型 | “这个/它/都/那里”指代不清 | 强约束“只输出一行改写问句”,要求结合历史做指代消解 | 提升召回精度(Precision) |
对比型 | “哪个更好/更刺激”但缺少对比对象或对比维度 | 传入 context_info(候选对比对象),让模型显式把对象写进问题 | 确保上下文覆盖对比双方 |
多意图型 | 一句话多个需求(票价 + 必玩 + 交通) | rewrite_multi_intent_query() 输出 JSON 数组,拆成多个子问题 | 触发多路检索,减少信息丢失 |
反问/情绪型 | “难道就没有更快的办法吗?”容易被模型输出“分析” | 明确规则:只输出一行中立问句,不要分析 | 保持可检索性与对话连贯性 |
其他/已清晰 | Query 本身足够明确 | 尽量原样输出或轻改写 | 避免“画蛇添足” |
这次最大的坑也是最大的收获:不能用同一套清洗逻辑处理所有输出。
one_line_text(清洗为单行)json_object(完整 JSON,不允许被截断)json_array所以我把调用统一收敛到 _call_rewrite_model(..., output_format=...),并加了:
_extract_first_json_object():容错解析 JSON 对象_extract_first_json_array():容错解析 JSON 数组我对提示词的重点变成了两类约束:
结论:Rewrite 是“把检索入口对齐意图”,Rerank 是“在候选里做精排”。
今天把 Query Rewrite 往前推进了一步:不止改写/拆分 query,而是把 联网搜索(Web Search) 接进 demo,形成可闭环的:
我把它理解为给 LLM 增加一个“可查证的外部知识入口”,用于弥补:
但联网搜索不是越多越好:它会带来 延迟 和 成本,还会引入“网页噪声”,所以需要一套“何时搜/怎么搜/搜完怎么用”的工程约束。
对应代码(核心在 query_rewrite.py):
auto_web_search_rewrite()identify_web_search_needs():先判断是否需要联网(need_web_search + reason)rewrite_for_web_search():把 query 改成更适合搜索引擎的 query,并给出关键词/意图/建议来源generate_search_strategy():输出搜索策略(关键词拆分、平台、时间范围)web_search.search_web() → TavilyClient.search(...)format_web_search_context() → call_dashscope_chat() → chat_answer_text()优点:
缺点:
对应代码:
dashscope_generation.call_generation_can_search()web_search 作为 tools 传给模型function_call 或 tool_calls 后,代码执行搜索并以 role=function 回填结果auto_web_search_rewrite_demo_with_search_function_call()这条链路跑通后,我的最大收获是:工具调用发生与否,必须可观测,否则很容易“以为搜了,其实没搜”。
logging.basicConfig(level=logging.INFO, ...),这样能看到:tool_call web_search ...web_search ok ... results=...done (no tool call)(代表第二轮模型已拿到搜索结果,不再调用工具)function_call一开始只解析 function_call,结果 DashScope 返回 tool_calls 时就会“误判无工具调用”,导致助手 message 没 content。
修复:
call_generation_can_search() 同时兼容 function_call 和 tool_callschat_answer_text() 增强兜底:支持 content 为 list、多块拼接,必要时尝试 output.text课程练习 RAG技术与应用 目录(含 query_rewrite.py 等):
Cyning12/auto-gpt-work-demo · data/课程练习/RAG技术与应用