Agentic search/RAG pipeline
这个 blog 是复现 ZeroSearch 的副产物。拿来和 function call search 对比时搭的 pipeline。
Search-O1, Search-R1, ReSearch, DeepResearcher, ZeroSearch 之类都是采用整体上类似的 agentic search 结构, i.e., think, search, infomation 交叉生成,直到生成了 answer.
以下示意图出自 Search-O1。

接下来先构建搜索引擎,Bing 和 Google 之类的个人申请好麻烦,国内提供 api 服务的有博查。
1 | import os, json, time, requests, transformers, torch, re |
搜索引擎函数定义
1 | import serpapi |
bocha
1 | def retrieve_from_bocha(query, topk, retry_attempt=3): |
1 | Doc 1: 正面观点:2025年金价会越来越高!不少机构及分析师预测2025年金价均价达到2800-2900美元区间,并可能突破3000美元关口。当然手里有黄金的朋友也不建议卖的太早了,未来金价有望达到700元/克。 |
agentic search
这是 zero search 的提示词,实际测试时还是有点问题,例如:
- tag 部分不生成,例如非第一次think只会生成
</think>,已修改 - 没有搜索上限,复杂问题或者单纯没有搜索到内容的情况就会重复好久,我记得 search-o1 有搜索次数上限: “You can repeat the search process multiple times if necessary. The maximum number of search attempts is limited to {MAX_SEARCH_LIMIT}.\n\n”,我没有修改提示词,直接break。
- 答案过于简洁,不大友善
整体推理流程是 loop,每个 loop 内:
- 以 prompt 为输入 think,可能会直接回答或者生成 search
- model.generate 检测到
</search>中断 - 检查是否是 eos 导致,是则退出 loop
- 抽取新生成的内容
<search>去搜索 - 将本轮新生成的内容和搜索结果拼入 prompt 中
1 | # 搜索结果的模板,最后的 `<think>` 最好还是加下,可能会出现非第一次think只会生成 </think> 的情况 |
1 | model_path = 'Alibaba-NLP/ZeroSearch_google_V2_Qwen2.5_7B_Instruct' |
1 | <|im_start|>system |
国内搜索引擎结果真是让人无语
text 拆分
以下函数是将 已经是 chat template 化的 str,重新组织为 messages。
1 | pattern_pairs_qwen = [ |
1 | [{'role': 'system', |
以上是完整的 messages,以下是仅模型生成部分。
1 | <think> The question is about the capital of France. I need to search for the capital of France. </think> |
1 | # 提取 answer |
Paris
Comments