Tanya Barrow / Unsplash文章
Perplexity 架构解析:如何实现有依据的 LLM 输出#
Perplexity AI 是目前最知名的"答案引擎"之一,它将大语言模型(LLM)与实时网页搜索相结合,提供带引用的回答。这篇文章将探讨 Perplexity 背后的架构,并调研商业和开源领域的替代方案。
Perplexity 是什么?#
Perplexity AI 是一个 AI 驱动的搜索引擎,它直接生成答案而不是返回链接列表。与传统搜索引擎不同,Perplexity 会综合多个来源的信息,并提供内联引用,让用户可以验证信息的准确性。
核心价值#
- 有依据的输出:每个观点都有可追溯的来源。
- 实时信息:访问最新的网页内容,而不仅仅依赖训练数据。
- 透明度:内联引用支持事实核查。
- 对话式交互:自然语言查询和追问。
Perplexity 的历史定位#
Perplexity 的核心技术是稠密检索(Dense Retrieval)——将文本转换为向量,在语义空间中匹配相关内容。但 Perplexity 并非第一个大规模应用稠密检索的产品(Google 2019 年就已引入 BERT,Neeva、You.com 等 AI 搜索也早于 Perplexity)。它的创新在于产品形态——将检索与 LLM 生成完美结合,创造了"答案引擎"这一新品类。
Perplexity 的真正创新#
之前的 AI 搜索产品仍然是"搜索引擎"思路:检索、排序、展示链接列表,用户需要自己点击阅读和总结。Perplexity 则将流程改为:检索 → LLM 综合 → 直接给出带内联引用 [1][2] 的综合答案,成为真正的"答案引擎"。Perplexity 站在了正确的时间点:LLM 能力成熟(GPT-3.5/4)+ 检索技术成熟(向量数据库生态),将两者结合成了杀手级产品。
技术演进路径#
- 2017:FAISS 开源(高效向量搜索)
- 2019:BERT 应用于 Google 搜索
- 2020:DPR 论文(Dense Passage Retrieval)的学术突破;RAG 论文(Facebook)带来检索 + 生成的范式
- 2021:向量数据库生态成熟(Pinecone、Milvus、Weaviate 等)
- 2022:ChatGPT 爆发 + Perplexity 成立
- 2023:RAG 成为主流架构
Perplexity 的架构#
检索增强生成(RAG)#
Perplexity 的核心是 RAG(Retrieval-Augmented Generation,检索增强生成)架构。RAG 通过在生成过程中引入外部知识检索来增强 LLM 的输出质量。整个流程如下:
- 用户查询:接收用户的自然语言问题。
- 查询处理层:查询理解和意图识别、查询改写和扩展、复杂问题的子查询分解。
- 检索系统:网页搜索(实时抓取)、索引搜索(预索引知识库)、多源聚合。
- 上下文处理层:相关性排序和过滤、分块提取和摘要、来源去重。
- LLM 生成层:构建带上下文的 prompt、引用感知的生成、带内联引用的回答合成。
- 输出:带引用的有依据回答。
核心组件#
1. 查询处理层#
查询处理层将用户输入转换为优化的搜索查询:
- 意图识别:判断查询是需要事实信息、观点还是实时数据。
- 查询扩展:添加相关词汇以提高检索覆盖率。
- 查询分解:将复杂问题拆分为子查询以获得全面的答案。
意图识别的实现#
意图识别(Intent Classification)是查询处理的第一步,目的是让系统"理解"用户想要什么类型的答案,从而优化后续的检索和生成策略。
常见的意图类型:
| 意图类型 | 说明 | 示例 |
|---|---|---|
| factual(事实信息) | 需要客观、可验证的答案 | "什么是 RAG?" |
| comparison(对比) | 需要多对象比较,结合事实参数与主观分析 | "GPT-4 和 Claude 3 的区别" |
| realtime(实时数据) | 需要最新的动态信息 | "今天的股价是多少?" |
| howto(操作指南) | 需要步骤化的指导 | "如何部署 Next.js 应用?" |
实现方式:
- 基于 LLM 的分类:用 LLM 本身做意图分类,灵活但延迟较高。
def classify_intent(query: str) -> str:
response = llm.chat([
{
"role": "system",
"content": """判断用户查询的意图类型,只返回以下之一:
- factual: 事实信息查询
- realtime: 实时数据查询
- comparison: 对比分析查询
- howto: 操作指南查询"""
},
{"role": "user", "content": query}
])
return response.strip().lower()
- 微调的小模型:专门训练的分类模型,速度快、成本低。
from transformers import pipeline
# 使用微调的 BERT 分类器
classifier = pipeline("text-classification", model="intent-classifier")
def classify_intent(query: str) -> str:
result = classifier(query)[0]
return result["label"] # 如 "factual"
- 规则 + 模型混合:关键词规则快速筛选,模型兜底处理复杂情况。
def classify_intent(query: str) -> str:
# 规则快速匹配
realtime_keywords = ["今天", "现在", "最新", "实时", "当前"]
if any(kw in query for kw in realtime_keywords):
return "realtime"
comparison_patterns = ["和.*比", "与.*区别", "哪个更"]
if any(re.search(p, query) for p in comparison_patterns):
return "comparison"
# 兜底用 LLM 分类
return llm_classify(query)
意图如何影响后续处理:
| 意图类型 | 检索策略 | 生成策略 |
|---|---|---|
| factual | 优先索引库,高权威性来源 | 精确引用,低 temperature |
| opinion | 多源聚合,包含论坛/评论 | 多角度呈现,承认主观性 |
| realtime | 强制网页搜索,时间加权 | 标注数据时效性 |
| comparison | 并行检索多个对象 | 结构化对比,表格输出 |
| howto | 优先官方文档/教程 | 步骤化输出,代码示例 |
2. 检索系统#
Perplexity 的检索系统结合了多种数据源:
- 实时网页搜索:获取最新的网页内容。
- 预索引知识库:之前抓取并索引的内容。
- 专业来源:学术论文、新闻、论坛等。
检索过程通常采用混合检索策略,结合稠密检索(基于 embedding 的语义搜索)和稀疏检索(BM25 等关键词方法)。稠密检索擅长语义理解和同义词匹配,稀疏检索擅长精确匹配专有名词,两者互补可获得最佳效果。
3. 上下文处理#
检索到文档后,需要进行处理:
# 上下文处理示意
def process_context(documents: list[Document], query: str) -> list[Chunk]:
# 按相关性排序
ranked = rerank_documents(documents, query)
# 提取相关片段
chunks = extract_relevant_chunks(ranked, query)
# 去除重复
unique_chunks = deduplicate(chunks)
# 适配上下文窗口
return truncate_to_fit(unique_chunks, max_tokens=8000)
4. 引用感知的生成#
生成阶段是 Perplexity 的差异化所在:
- Prompt 工程:结构化的 prompt 指导模型引用来源。
- 内联引用格式:
[1]、[2]标记链接到来源。 - 事实约束:模型被限制只能使用检索到的上下文中的信息。
# Prompt 模板示意
PROMPT_TEMPLATE = """
根据以下来源回答用户的问题。
对每个观点使用内联引用 [1]、[2] 等。
只使用提供的来源中的信息。
来源:
{formatted_sources}
问题:{user_query}
带引用的回答:
"""
技术基础设施#
模型栈#
据报道,Perplexity 使用:
- 多个 LLM 提供商(OpenAI、Anthropic、自研模型)。
- 针对特定任务微调的模型(引用生成、摘要)。
- 高速推理基础设施以实现低延迟响应。
搜索基础设施#
- 自研网页爬虫用于实时索引。
- 向量数据库用于语义搜索(可能使用 embedding)。
- 传统搜索索引用于关键词匹配。
如何实现有依据的输出#
幻觉问题#
LLM 容易产生"幻觉"——生成看似合理但实际错误的信息。有依据的输出通过以下方式解决这个问题:
- 限制知识来源:模型只能引用检索到的文档。
- 要求引用:每个观点都必须有可验证的来源。
- 生成后验证:对照来源检查生成的内容。
Perplexity 的方法#
1. 检索优先的设计#
与主要依赖参数化知识的 ChatGPT 不同,Perplexity 会先检索:
- 传统 LLM 的流程是 "查询 → LLM → 回答",
- 而 Perplexity 是 "查询 → 搜索 → 检索 → LLM + 上下文 → 回答"。
2. 引用约束的生成#
模型被指导:
- 只做有检索来源支持的陈述。
- 用来源引用标记每个观点。
- 当来源冲突时承认不确定性。
3. 来源质量过滤#
并非所有检索到的内容都是等价的:
- 域名权威性评分。
- 内容新鲜度加权。
- 跨来源验证。
局限性#
- 检索质量:检索不好会导致回答不好。
- 引用准确性:模型可能错误引用或错误归因。
- 延迟:实时搜索增加了响应时间。
- 覆盖缺口:并非所有信息都可索引。
开源替代方案#
以下是两个开箱即用、内置网页搜索和引用功能的开源产品。
RAGFlow#
类型:开源 RAG 引擎
架构:带 UI 的完整 RAG 解决方案。
特点:
- 文档解析和分块。
- 多模型支持。
- 包含 Web UI。
- 引用提取。
优点:
- 开箱即用的解决方案。
- 良好的文档处理。
- 活跃开发中。
缺点:
- 较新的项目。
- 定制性较低。
Perplexica#
类型:开源 Perplexity 克隆
架构:试图复制 Perplexity 的功能。
# 克隆并运行
git clone https://github.com/ItzCrazyKns/Perplexica
cd Perplexica
docker compose up
特点:
- 网页搜索集成(SearXNG)。
- 多 LLM 后端支持。
- 引用生成。
- 聚焦模式(网页、学术等)。
优点:
- 最接近 Perplexity 的体验。
- 可自托管。
- 活跃的社区。
缺点:
- 质量取决于搜索后端。
- 可能需要 LLM 的 API 密钥。
架构最佳实践#
1. 检索质量#
- 使用混合搜索(稠密 + 稀疏)。
- 使用 cross-encoder 实现重排序。
- 按来源权威性过滤。
2. 引用准确性#
- 使用结构化输出格式。
- 实现后处理验证。
- 考虑为引用任务微调模型。
3. 延迟优化#
- 缓存常见查询。
- 使用流式响应。
- 并行化检索和生成。
4. 防止幻觉#
- 将模型约束在检索到的上下文内。
- 对事实性查询使用较低的 temperature。
- 实现事实核查管道。
应用到 Coding Agent#
除了构建独立的 RAG 应用,我们也可以让日常使用的 coding agent(如 Cursor、Claude Code)具备类似 Perplexity 的能力——在生成内容时先搜索资料,并输出带有可验证来源的回答。
Cursor Rules#
Cursor 支持通过 Rules 为 AI 提供系统级指导。Rules 存储在项目的 .cursor/rules/ 目录中,使用 MDC(Markdown with frontmatter)格式1。
示例:研究与引用规则
---
description: Generate content with verifiable sources
globs:
- blog/**/*.mdx
- note/**/*.mdx
---
# Research-Based Content Generation
When editing blog posts or notes:
1. Use `web_search` tool to find authoritative sources
2. Use browser tools to verify information
3. Include inline citations with URLs
4. Add reference section for key sources
## Citation Format
Use footnote style:
- Inline: 稠密检索效果优于关键词检索[^1]
- Footer: [^1]: [Paper Title](https://arxiv.org/abs/xxx)
Cursor 内置的工具包括 web_search(网页搜索)、browser(浏览器交互)、codebase(代码库语义搜索)等,可以在规则中指导 AI 调用这些工具收集资料2。
Claude Code Skills#
Claude Code 通过 Skills 系统扩展 AI 能力。Skills 是包含 SKILL.md 文件的目录,Claude 会根据上下文自主发现并调用3。
目录结构:
.claude/skills/
└── web-research/
├── SKILL.md # 技能定义
└── resources/ # 可选:模板、参考文档
└── citation-template.md
SKILL.md 示例:
---
name: web-research
description: Search web and provide answers with citations
allowed-tools: WebSearch, Fetch, Read
---
# Web Research Skill
## When to Use
- User asks factual questions requiring up-to-date info
- User requests sources or citations
- Technical questions about libraries not in training data
## Instructions
1. Use web search to find relevant information
2. Fetch and read authoritative sources
3. Synthesize into clear answer with citations
4. Include source URLs for verification
## Citation Format
[^1]: Source Title - https://example.com
MCP Servers#
Model Context Protocol(MCP)是 Anthropic 推出的开放协议,用于标准化 AI 应用与外部数据源的连接4。通过配置 MCP Server,可以为 coding agent 添加网络搜索等能力。
常用的搜索相关 MCP Server:
| Server | 功能 | 来源 |
|---|---|---|
@anthropic-ai/mcp-server-fetch |
抓取网页内容 | 官方 |
@anthropic-ai/mcp-server-brave-search |
Brave Search API | 官方 |
tavily-mcp-server |
Tavily Search(AI 优化) | 社区 |
exa-mcp-server |
Exa AI 语义搜索 | 社区 |
配置示例(在 MCP 配置文件中):
{
"mcpServers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-server-brave-search"],
"env": {
"BRAVE_API_KEY": "your-api-key"
}
},
"fetch": {
"command": "npx",
"args": ["-y", "@anthropic-ai/mcp-server-fetch"]
}
}
}
三种方法的对比#
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Cursor Rules | Cursor 用户、项目级配置 | 简单、版本控制友好 | 仅限 Cursor |
| Claude Code Skills | Claude Code 用户 | 灵活、可复用 | 需要 Claude Code |
| MCP Servers | 需要强大搜索能力 | 标准化、可扩展 | 配置较复杂、部分需 API Key |
推荐组合:Cursor Rules(行为指导)+ MCP Server(搜索能力),或单独使用 Claude Code Skills。