Perplexity 架构解析:如何实现有依据的 LLM 输出Tanya Barrow / Unsplash

エッセイ

Perplexity 架构解析:如何实现有依据的 LLM 输出#

Asuka 著

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)+ 检索技术成熟(向量数据库生态),将两者结合成了杀手级产品。

技术演进路径#

Perplexity 的架构#

检索增强生成(RAG)#

Perplexity 的核心是 RAG(Retrieval-Augmented Generation,检索增强生成)架构。RAG 通过在生成过程中引入外部知识检索来增强 LLM 的输出质量。整个流程如下:

  1. 用户查询:接收用户的自然语言问题。
  2. 查询处理层:查询理解和意图识别、查询改写和扩展、复杂问题的子查询分解。
  3. 检索系统:网页搜索(实时抓取)、索引搜索(预索引知识库)、多源聚合。
  4. 上下文处理层:相关性排序和过滤、分块提取和摘要、来源去重。
  5. LLM 生成层:构建带上下文的 prompt、引用感知的生成、带内联引用的回答合成。
  6. 输出:带引用的有依据回答。

核心组件#

1. 查询处理层#

查询处理层将用户输入转换为优化的搜索查询:

  • 意图识别:判断查询是需要事实信息、观点还是实时数据。
  • 查询扩展:添加相关词汇以提高检索覆盖率。
  • 查询分解:将复杂问题拆分为子查询以获得全面的答案。
意图识别的实现#

意图识别(Intent Classification)是查询处理的第一步,目的是让系统"理解"用户想要什么类型的答案,从而优化后续的检索和生成策略。

常见的意图类型

意图类型 说明 示例
factual(事实信息) 需要客观、可验证的答案 "什么是 RAG?"
comparison(对比) 需要多对象比较,结合事实参数与主观分析 "GPT-4 和 Claude 3 的区别"
realtime(实时数据) 需要最新的动态信息 "今天的股价是多少?"
howto(操作指南) 需要步骤化的指导 "如何部署 Next.js 应用?"

实现方式

  1. 基于 LLM 的分类:用 LLM 本身做意图分类,灵活但延迟较高。
Python
def classify_intent(query: str) -> str:
    response = llm.chat([
        {
            "role": "system",
            "content": """判断用户查询的意图类型,只返回以下之一:
- factual: 事实信息查询
- realtime: 实时数据查询
- comparison: 对比分析查询
- howto: 操作指南查询"""
        },
        {"role": "user", "content": query}
    ])
    return response.strip().lower()
  1. 微调的小模型:专门训练的分类模型,速度快、成本低。
Python
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"
  1. 规则 + 模型混合:关键词规则快速筛选,模型兜底处理复杂情况。
Python
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. 上下文处理#

检索到文档后,需要进行处理:

Python
# 上下文处理示意
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] 标记链接到来源。
  • 事实约束:模型被限制只能使用检索到的上下文中的信息。
Python
# Prompt 模板示意
PROMPT_TEMPLATE = """
根据以下来源回答用户的问题。
对每个观点使用内联引用 [1]、[2] 等。
只使用提供的来源中的信息。

来源:
{formatted_sources}

问题:{user_query}

带引用的回答:
"""

技术基础设施#

模型栈#

据报道,Perplexity 使用:

  • 多个 LLM 提供商(OpenAI、Anthropic、自研模型)。
  • 针对特定任务微调的模型(引用生成、摘要)。
  • 高速推理基础设施以实现低延迟响应。

搜索基础设施#

  • 自研网页爬虫用于实时索引。
  • 向量数据库用于语义搜索(可能使用 embedding)。
  • 传统搜索索引用于关键词匹配。

如何实现有依据的输出#

幻觉问题#

LLM 容易产生"幻觉"——生成看似合理但实际错误的信息。有依据的输出通过以下方式解决这个问题:

  1. 限制知识来源:模型只能引用检索到的文档。
  2. 要求引用:每个观点都必须有可验证的来源。
  3. 生成后验证:对照来源检查生成的内容。

Perplexity 的方法#

1. 检索优先的设计#

与主要依赖参数化知识的 ChatGPT 不同,Perplexity 会先检索:

  • 传统 LLM 的流程是 "查询 → LLM → 回答",
  • 而 Perplexity 是 "查询 → 搜索 → 检索 → LLM + 上下文 → 回答"。

2. 引用约束的生成#

模型被指导:

  • 只做有检索来源支持的陈述。
  • 用来源引用标记每个观点。
  • 当来源冲突时承认不确定性。

3. 来源质量过滤#

并非所有检索到的内容都是等价的:

  • 域名权威性评分。
  • 内容新鲜度加权。
  • 跨来源验证。

局限性#

  • 检索质量:检索不好会导致回答不好。
  • 引用准确性:模型可能错误引用或错误归因。
  • 延迟:实时搜索增加了响应时间。
  • 覆盖缺口:并非所有信息都可索引。

开源替代方案#

以下是两个开箱即用、内置网页搜索和引用功能的开源产品。

RAGFlow#

类型:开源 RAG 引擎

架构:带 UI 的完整 RAG 解决方案。

特点

  • 文档解析和分块。
  • 多模型支持。
  • 包含 Web UI。
  • 引用提取。

优点

  • 开箱即用的解决方案。
  • 良好的文档处理。
  • 活跃开发中。

缺点

  • 较新的项目。
  • 定制性较低。

Perplexica#

类型:开源 Perplexity 克隆

架构:试图复制 Perplexity 的功能。

Bash
# 克隆并运行
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

示例:研究与引用规则

Markdown
---
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

目录结构

Auto
.claude/skills/
└── web-research/
    ├── SKILL.md          # 技能定义
    └── resources/        # 可选:模板、参考文档
        └── citation-template.md

SKILL.md 示例

Markdown
---
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 配置文件中):

JSON
{
  "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。

Footnotes#

  1. Rules for AI - Cursor Documentation

  2. Agent Tools - Cursor Documentation

  3. Agent Skills - Claude Documentation

  4. Model Context Protocol

This browser prefers English.

You can switch the site to English and save that choice for future visits.