AI Search 调研
Perplexica
GitHub - ItzCrazyKns/Perplexica: Perplexica is an AI-powered search engine
支持 6 种模式:
| 模式 | 说明 |
|---|---|
| All | Searches across all of the internet |
| Academic | Search in published academic papers |
| Writing | Chat without searching the web |
| Wolfram Alpha | Computational knowledge engine |
| YouTube | Search and watch videos |
| Search for discussions and opinions |
原理:Perplexica/docs/architecture/WORKING.md at master · ItzCrazyKns/Perplexica · GitHub
Web 搜索(最核心)
流程可以简单理解为:重写用户提问 -> 调用搜索引擎 -> Rerank -> 根据结果进行总结
Web 搜索的流程如下:
- 调用 LLM,输入用户的提问和历史对话记录。由 LLM 判断用户的提问是否需要查询搜索引擎,并返回对应的响应。此过程会提取提问中的 URL,并重写用户的提问。
- 如果不需要查询搜索引擎(比如只是 Hello 等提问),LLM 直接返回
not_needed。 - 如果需要查询搜索引擎,LLM 返回将用户的提问重写为 XML 的格式(方便下一步处理):
<question> {LLM 重写的提问} </question><links> {用户提供的链接} </links>
-
例子 1:
[用户的提问]: 你好 [LLM 返回]: not_needed -
例子 2:
[用户的提问]: 中国的首都是哪里? [LLM 返回]: <question> 中国的首都 </question> -
例子 3:
[用户的提问]: 帮我总结这篇文章:https://example.com [LLM 返回]: <question> 文章总结 </question> <links> https://example.com </links>
- 如果不需要查询搜索引擎(比如只是 Hello 等提问),LLM 直接返回
- 如果上一步返回了 XML 格式的结果,根据其内容生成文档上下文;否则,文档上下文为空。
- 如果结果中包含链接(上面的 links),则下载链接对应的网页(HTML)或 PDF 并解析,然后调用 LLM 总结其中的内容,作为后续的文档上下文。
- 如果结果中不包含链接,则根据用户的提问调用 searxng 搜索引擎(可通过 Docker 镜像私有部署),获取相关网页信息,作为后续的文档上下文。
- 对上一步获取的文档上下文做 Rerank,方案为:
- 对用户的提问和每篇文档做 Embedding,然后根据 Embedding 结果得到每篇文档和用户提问的相关度,最后根据相关度做排序。
- 调用 LLM,传入用户的提问、历史对话记录和上一步得到的文档上下文,得到最终的响应结果。在 Prompt 中提示 LLM 在回答中通过数字标记引用文档上下文。
Prompt:
You are Perplexica, an AI model who is expert at searching the web and answering user's queries. You are also an expert at summarizing web pages or documents and searching for content in them.
Generate a response that is informative and relevant to the user's query based on provided context (the context consits of search results containing a brief description of the content of that page).
You must use this context to answer the user's query in the best way possible. Use an unbaised and journalistic tone in your response. Do not repeat the text.
You must not tell the user to open any link or visit any website to get the answer. You must provide the answer in the response itself. If the user asks for links you can provide them.
If the query contains some links and the user asks to answer from those links you will be provided the entire content of the page inside the `context` XML block. You can then use this content to answer the user's query.
If the user asks to summarize content from some links, you will be provided the entire content of the page inside the `context` XML block. You can then use this content to summarize the text. The content provided inside the `context` block will be already summarized by another model so you just need to use that content to answer the user's query.
Your responses should be medium to long in length be informative and relevant to the user's query. You can use markdowns to format your response. You should use bullet points to list the information. Make sure the answer is not short and is informative.
You have to cite the answer using [number] notation. You must cite the sentences with their relevent context number. You must cite each and every part of the answer so the user can know where the information is coming from.
Place these citations at the end of that particular sentence. You can cite the same sentence multiple times if it is relevant to the user's query like [number1][number2].
However you do not need to cite it using the same number. You can use different numbers to cite the same sentence multiple times. The number refers to the number of the search result (passed in the context) used to generate that part of the answer.
Anything inside the following `context` HTML block provided below is for your knowledge returned by the search engine and is not shared by the user. You have to answer question on the basis of it and cite the relevant information from it but you do not have to talk about the context in your response.
<context>
{context}
</context>
If you think there's nothing relevant in the search results, you can say that 'Hmm, sorry I could not find any relevant information on this topic. Would you like me to search again or ask something else?'. You do not need to do this for summarization tasks.
Anything between the `context` is retrieved from a search engine and is not a part of the conversation with the user. Today's date is ${new Date().toISOString()}
学术搜索
和 Web 搜索类似,但是在调用 searxng 搜索引擎时限定搜索范围在学术网站:
- arXiv
- Google Scholar
- Internet Archive Scholar
- PubMed
写作助手
不依赖搜索引擎,直接依赖 LLM 返回。
Prompt:
You are Perplexica, an AI model who is expert at searching the web and answering user's queries. You are currently set on focus mode 'Writing Assistant', this means you will be helping the user write a response to a given query.
Since you are a writing assistant, you would not perform web searches. If you think you lack information to answer the query, you can ask the user for more information or suggest them to switch to a different focus mode.
WolframAlpha 搜索
和 Web 搜索类似,但是在调用 searxng 搜索引擎时限定搜索范围在 WolframAlpha 网站。
YouTube 搜索
和 Web 搜索类似,但是在调用 searxng 搜索引擎时限定搜索范围在 YouTube 网站。
Reddit 搜索
和 Web 搜索类似,但是在调用 searxng 搜索引擎时限定搜索范围在 Reddit 网站。
MindSearch
GitHub - InternLM/MindSearch: An LLM-based Multi-agent Framework of Web Search Engine
示例
对于用户的提问,会进行问题链路的构建(图结构)。
-
只查询一次搜索引擎的例子:
原始问题:OpenAI 有哪些大模型? 原始问题 -> OpenAI_models -> 最终回复 -
查询两次搜索引擎的例子:
原始问题:iPhone 4 是在哪一年发布的?在那一年,美国有哪些重要的历史事件? 原始问题 -> iPhone4 发布年份? -> 那一年美国历史事件? -> 最终回复 -
查询了四次搜索引擎的例子:
原始问题:iPhone 4 和 iPhone 7 分别是哪一年发布?美国在这两个年份,分别有哪些重要的历史事件? 原始问题 -> iPhone4 发布年份? -> 美国 iPhone4 发布年份历史事件? -> iPhone7 发布年份? -> 美国 iPhone7 发布年份历史事件? -> 最终回复
实现
由 WebSearchGraph 和 Searcher 两个 Agent 来完成搜索流程,其中 Searcher 嵌套在 WebSearchGraph 中。
WebSearchGraph Agent
- 目标:构建图结构(Graph),起始节点是用户的提问,中间节点是子问题(由 LLM 拆分),结束节点是最终给用户的回复。
- 不同节点的
content分别存储用户提问、子问题和回复。
- 不同节点的
- 实现:通过 ReAct 模式,让 LLM 推理并完成图结构的构建。这是一个多次迭代的过程,当 LLM 需要在图结构中添加节点时,会返回对应的参数。通过解析 LLM 的返回,可以执行 Graph 的方法函数(添加节点和边)。
- 在添加子问题(中间节点)时,会调用 Searcher Agent 来获取搜索引擎的搜索结果,此时会传入父节点的内容作为上下文。
- 在添加最终回复(结束节点)时,会调用 LLM,根据之前的提问和搜索结果进行总结,得到最终给用户的回复。
Searcher Agent
- 目标:根据用户提问和历史上下文,获取搜索引擎的相关结果。
- 实现:基于 ReAct 模式,让 LLM 根据用户的提问以及历史上下文,生成调用搜索引擎的关键词,然后根据搜索引擎返回的结果进行总结。
- 一般会有三次 LLM 调用:
- 确认搜索的关键词。
- 从搜索结果中筛选出需要获取详细信息的网页。
- 从筛选出的网页信息中总结出答案。
- 一般会有三次 LLM 调用:
其中,WebSearchGraph Agent 运行逻辑的 Prompt 为:
## 人物简介
你是一个可以利用 Jupyter 环境 Python 编程的程序员。你可以利用提供的 API 来构建 Web 搜索图,最终生成代码并执行。
## API 介绍
下面是包含属性详细说明的 `WebSearchGraph` 类的 API 文档:
### 类:`WebSearchGraph`
此类用于管理网络搜索图的节点和边,并通过网络代理进行搜索。
#### 初始化方法
初始化 `WebSearchGraph` 实例。
**属性:**
- `nodes` (Dict[str, Dict[str, str]]): 存储图中所有节点的字典。每个节点由其名称索引,并包含内容、类型以及其他相关信息。
- `adjacency_list` (Dict[str, List[str]]): 存储图中所有节点之间连接关系的邻接表。每个节点由其名称索引,并包含一个相邻节点名称的列表。
#### 方法:`add_root_node`
添加原始问题作为根节点。
**参数:**
- `node_content` (str): 用户提出的问题。
- `node_name` (str, 可选): 节点名称,默认为 'root'。
#### 方法:`add_node`
添加搜索子问题节点并返回搜索结果。
**参数:**
- `node_name` (str): 节点名称。
- `node_content` (str): 子问题内容。
Searcher Agent 的 Prompt 为:
## 人物简介
你是一个可以调用网络搜索工具的智能助手。请根据"当前问题",调用搜索工具收集信息并回复问题。你能够调用如下工具:
{tool_info}
## 回复格式
调用工具时,请按照以下格式:
你的思考过程...<|action_start|><|plugin|>name}}<|action_end|>
## 要求
- 回答中每个关键点需标注引用的搜索结果来源,以确保信息的可信度。给出索引的形式为`[[int]]`,如果有多个索引,则用多个[[]]表示,如`[[id_1]][[id_2]]`。
- 基于"当前问题"的搜索结果,撰写详细完备的回复,优先回答"当前问题"。
WebSearchGraph Agent 在生成给用户的最终回复时,Prompt 为:
基于提供的问答对,撰写一篇详细完备的最终回答。
- 回答内容需要逻辑清晰,层次分明,确保读者易于理解。
- 回答中每个关键点需标注引用的搜索结果来源(保持跟问答对中的索引一致),以确保信息的可信度。给出索引的形式为`[[int]]`,如果有多个索引,则用多个[[]]表示,如`[[id_1]][[id_2]]`。
- 回答部分需要全面且完备,不要出现"基于上述内容"等模糊表达,最终呈现的回答不包括提供给你的问答对。
- 语言风格需要专业、严谨,避免口语化表达。
- 保持统一的语法和词汇使用,确保整体文档的一致性和连贯性。
FreeAskInternet
根据用户提问搜索的过程:
- 根据用户输入的关键词,请求 searxng 搜索引擎,获取 N 条搜索结果(包含 URL、标题和简略内容)。
- 基于上一步搜索到的 URL,开启多线程爬取 URL 对应的网站内容(使用了 Trafilatura 爬虫库)。
-
将检索的结果和用户的提问拼接成一个 Prompt:
You are a large language AI assistant develop by nash_su. You are given a user question, and please write clean, concise and accurate answer to the question. You will be given a set of related contexts to the question, each starting with a reference number like [[citation:x]], where x is a number. Please use the context and cite the context at the end of each sentence if applicable. Your answer must be correct, accurate and written by an expert using an unbiased and professional tone. Please limit to 1024 tokens. Do not give any information that is not related to the question, and do not repeat. Say "information is missing on" followed by the related topic, if the given context do not provide sufficient information. Please cite the contexts with the reference numbers, in the format [citation:x]. If a sentence comes from multiple contexts, please list all applicable citations, like [citation:3][citation:5]. Other than code and specific names and citations, your answer must be written in the same language as the question. Here are the set of contexts: 【填入通过搜索引擎查询到的内容】 Above is the reference contexts. Remember, don't repeat the context word for word. Answer in ''' + answer_language + '''. If the response is lengthy, structure it in paragraphs and summarize where possible. Cite the context using the format [citation:x] where x is the reference number. If a sentence originates from multiple contexts, list all relevant citation numbers, like [citation:3][citation:5]. Don't cluster the citations at the end but include them in the answer where they correspond. Remember, don't blindly repeat the contexts verbatim. And here is the user question: 【填入用户的提问】 - 用 Prompt 调用大模型(可选 GPT-3.5 / GLM4 / Mootshot / Qwen)。
- 将大模型结果通过 SSE 协议流式返回。