Haystack 的定位

deepset 出品的 Haystack 是一个 专注于 RAG(检索增强生成)的 NLP 框架。与 LangChain 的"万物皆链"不同,Haystack 的设计哲学是 Pipeline 即图——每个处理步骤是一个 Node,Node 之间通过类型化的连接器组装成 DAG(有向无环图)。

这种设计在 RAG 场景下优势明显:文档处理流水线天然是线性的(加载→切分→嵌入→存储→检索→生成),Haystack 的 Pipeline 模型与之完美契合。

架构核心

Pipeline:计算图

Haystack 2.x 的 Pipeline 是一个真正的计算图,支持分支、合并、循环:

from haystack import Pipeline
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack.components.retrievers import QdrantRetriever
from haystack.components.generators import OpenAIGenerator
from haystack.components.builders import PromptBuilder

# 构建 RAG Pipeline
pipe = Pipeline()

# 添加组件
pipe.add_component("embedder", SentenceTransformersTextEmbedder(model="BAAI/bge-m3"))
pipe.add_component("retriever", QdrantRetriever(document_store=doc_store))
pipe.add_component("prompt_builder", PromptBuilder(template=TEMPLATE))
pipe.add_component("generator", OpenAIGenerator(model="gpt-4o"))

# 连接组件(类型安全)
pipe.connect("embedder.embedding", "retriever.query_embedding")
pipe.connect("retriever.documents", "prompt_builder.documents")
pipe.connect("prompt_builder.prompt", "generator.prompt")

Node 类型体系

Haystack 2.x 的组件按功能分类:

类别典型组件作用
ConvertersTextFileToDocument, HTMLToDocument, PyPDFToDocument文件→Document
PreprocessorsDocumentCleaner, DocumentSplitter清洗与切分
EmbeddersSentenceTransformersTextEmbedder, OpenAITextEmbedder文本→向量
RetrieversQdrantRetriever, BM25Retriever, HybridRetriever向量/关键词/混合检索
GeneratorsOpenAIGenerator, HuggingFaceLocalGeneratorLLM 生成
JoinersDocumentJoiner, BranchJoiner合并多路检索结果
RoutersConditionalRouter, MetadataRouter条件路由

组件的输入/输出契约

每个组件声明输入输出类型,Pipeline 在连接时做类型检查:

from haystack import component

@component
class CustomReranker:
    @component.output_types(documents=list[Document])
    def run(self, documents: list[Document], query: str) -> dict:
        # 重排序逻辑
        reranked = self._rerank(documents, query)
        return {"documents": reranked}

RAG 最佳实践

索引 Pipeline

indexing = Pipeline()
indexing.add_component("converter", PyPDFToDocument())
indexing.add_component("cleaner", DocumentCleaner())
indexing.add_component("splitter", DocumentSplitter(
    split_by="sentence", split_length=5, split_overlap=1
))
indexing.add_component("embedder", SentenceTransformersDocumentEmbedder(
    model="BAAI/bge-m3", prefix="Represent this sentence for searching: "
))
indexing.add_component("writer", QdrantDocumentWriter(
    document_store=doc_store
))

indexing.connect("converter.documents", "cleaner.documents")
indexing.connect("cleaner.documents", "splitter.documents")
indexing.connect("splitter.documents", "embedder.documents")
indexing.connect("embedder.documents", "writer.documents")

混合检索 + 重排序

# 双路检索:BM25 + 向量
hybrid = Pipeline()
hybrid.add_component("bm25_retriever", BM25Retriever(document_store=doc_store, top_k=20))
hybrid.add_component("embedder", SentenceTransformersTextEmbedder(model="BAAI/bge-m3"))
hybrid.add_component("vector_retriever", QdrantRetriever(document_store=doc_store, top_k=20))
hybrid.add_component("joiner", DocumentJoiner(join_mode="reciprocal_rank_fusion"))
hybrid.add_component("reranker", SimilarityRanker(top_k=5))
hybrid.add_component("prompt_builder", PromptBuilder(template=TEMPLATE))
hybrid.add_component("generator", OpenAIGenerator(model="gpt-4o"))

hybrid.connect("bm25_retriever.documents", "joiner.documents")
hybrid.connect("embedder.embedding", "vector_retriever.query_embedding")
hybrid.connect("vector_retriever.documents", "joiner.documents")
hybrid.connect("joiner.documents", "reranker.documents")
hybrid.connect("reranker.documents", "prompt_builder.documents")
hybrid.connect("prompt_builder.prompt", "generator.prompt")

条件路由

from haystack.components.routers import ConditionalRouter

routes = [
    {
        "condition": "{{ query|length < 100 }}",
        "output": "{{ generator_short.answer }}",
        "output_name": "short_answer",
        "output_type": str,
    },
    {
        "condition": "{{ query|length >= 100 }}",
        "output": "{{ generator_detailed.answer }}",
        "output_name": "detailed_answer",
        "output_type": str,
    }
]
router = ConditionalRouter(routes)

与 LangChain 对比

维度Haystack 2.xLangChain
架构模型显式计算图隐式链/图
类型安全组件 IO 类型检查运行时发现错误
Pipeline 可视化pipeline.draw() 生成图无原生支持
序列化YAML/JSON 序列化部分支持
RAG 专注度高,RAG 是一等公民中,RAG 是众多场景之一
Agent 支持有但非核心LangGraph 生态丰富
多模态支持但有限更全面
社区规模中等
生产就绪高(deepset 商业化)中等

关键洞察:Haystack 的 Pipeline.to_yaml() 可以把整个流水线序列化为配置文件,实现"Pipeline as Code"与"Pipeline as Config"的灵活切换。这在生产环境中价值巨大——可以不改代码调整 Pipeline 结构。

生产部署

Hayhooks:Pipeline 即服务

# config.yaml
version: ignore
components:
  - name: embedder
    type: SentenceTransformersTextEmbedder
    params:
      model: BAAI/bge-m3
  - name: retriever
    type: QdrantRetriever
    params:
      document_store:
        type: QdrantDocumentStore
        params:
          url: http://qdrant:6333
          index_name: production
pipelines:
  - name: rag
    nodes:
      - name: embedder
        inputs: [query]
      - name: retriever
        inputs: [embedder.embedding]

hayhooks 命令启动 REST API 服务,自动暴露每个 Pipeline 为 /rag/run 端点。

监控与评估

# 使用 Haystack 评估框架
from haystack.components.evaluators import (
    FaithfulnessEvaluator,
    ContextRelevanceEvaluator,
    AnswerRelevanceEvaluator
)

eval_pipeline = Pipeline()
eval_pipeline.add_component("faithfulness", FaithfulnessEvaluator())
eval_pipeline.add_component("context_relevance", ContextRelevanceEvaluator())
eval_pipeline.add_component("answer_relevance", AnswerRelevanceEvaluator())

# 每个 evaluator 独立打分
result = eval_pipeline.run({
    "faithfulness": {"questions": questions, "contexts": contexts, "answers": answers},
    "context_relevance": {"questions": questions, "contexts": contexts},
    "answer_relevance": {"questions": questions, "answers": answers}
})

不足与风险

问题影响缓解方案
Agent 能力弱无复杂多步 Agent 编排结合 LangGraph 或自建
非 RAG 场景支持少纯生成、对话管理弱不适合就别硬用
文档检索器耦合高换 Store 需改 Pipeline抽象 DocumentStore 接口
2.x 破坏性升级1.x→2.x 迁移成本高新项目直接用 2.x

适用场景判断

选 Haystack 如果你:

  • 核心场景是 RAG(文档问答、知识库检索)
  • 需要可序列化、可版本控制的 Pipeline
  • 重视类型安全和可预测性
  • 团队偏好显式配置而非隐式链

不选 Haystack 如果你:

  • 需要复杂 Agent 编排(多轮对话、工具调用循环)
  • 场景超出 RAG 范畴
  • 团队已深度使用 LangChain 生态

总结

Haystack 是 RAG 领域最工程化的框架。它的 Pipeline 计算图模型天然适合文档处理流水线,类型安全机制在编译时就能捕获连接错误,YAML 序列化让 Pipeline 可以作为配置管理。如果你的核心需求是构建生产级 RAG 系统,Haystack 比 LangChain 更值得考虑。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。