FEATURED · 精选文章

Haystack 集成指南:使用 PgvectorDocumentStore 构建 PostgreSQL 向量检索与 RAG 管线

发布时间 / 2026/9/14 9:50:24
来源 / 创域科博编辑部
栏目 / 资讯中心
Haystack 集成指南:使用 PgvectorDocumentStore 构建 PostgreSQL 向量检索与 RAG 管线 Haystack 集成指南使用 PgvectorDocumentStore 构建 PostgreSQL 向量检索与 RAG 管线【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack导读本文聚焦 Haystack 生态中的Pgvector 集成pgvector-haystack包系统讲解如何在 PostgreSQL pgvector 扩展之上构建完整的向量检索能力从环境搭建、PgvectorDocumentStore的初始化参数与文档管理 API到PgvectorEmbeddingRetriever的语义检索与PgvectorKeywordRetriever的关键词检索再到过滤器策略的底层实现。读完本文你将能够把 PostgreSQL 作为 Haystack 的生产级 Document Store搭建可复制的语义搜索、关键词搜索与 RAG 管线。文章以 version-2.21 的 Pgvector 集成 API 参考 为核心骨架并辅以仓库内文档站点与核心源码佐证。Pgvector 集成概览Pgvector 是 PostgreSQL 的扩展它在保留 PostgreSQL 经典能力如 ACID 事务、point-in-time recovery的同时引入了向量相似度搜索既支持精确最近邻exact nearest neighbor也支持基于 HNSW 的近似最近邻approximate nearest neighbor。因此把 PostgreSQL 用作 Haystack 的 Document Store可以在同一套数据库基础设施上同时获得关系查询、事务保证与向量检索能力。在 Haystack 中这一能力通过pgvector-haystack集成包提供核心组件有三个定义见 API 参考PgvectorDocumentStore基于 pgvector 扩展的 Document Store负责建表、写入、过滤、删除、统计等文档管理操作PgvectorEmbeddingRetriever基于稠密向量dense embedding的检索器从 Document Store 中取回与查询向量最相似的文档PgvectorKeywordRetriever基于关键词的检索器使用 PostgreSQL 全文检索的ts_rank_cd函数对文档排序。从仓库文档站点的 Document Store 选择指南 可以看到Pgvector 属于关系型数据库 向量扩展这一类 Document Store同时支持 Embedding 检索与关键词Keyword检索适合希望复用既有 PostgreSQL 集群、又要向量能力的场景。环境准备与安装使用 Docker 快速启动 PostgreSQL pgvector文档站点推荐直接用官方镜像启动一个带 pgvector 的 PostgreSQL 实例详见 PgvectorDocumentStore 指南docker run -d -p 5432:5432 \ -e POSTGRES_USERpostgres \ -e POSTGRES_PASSWORDpostgres \ -e POSTGRES_DBpostgres \ pgvector/pgvector:pg17该命令会在本机 5432 端口启动一个 PostgreSQL 17 容器并预置用户、密码与数据库均为postgres。安装 Python 集成包pip install pgvector-haystack如果还要运行文档中的嵌入示例使用 Sentence Transformers 生成向量需要额外安装pip install sentence-transformers-haystack配置连接字符串PgvectorDocumentStore通过PG_CONN_STR环境变量读取连接字符串默认值即Secret.from_env_var(PG_CONN_STR)见 API 参考。支持两种格式URI 格式export PG_CONN_STRpostgresql://USER:PASSWORDHOST:PORT/DB_NAME关键字/值keyword/value格式export PG_CONN_STRhostHOST portPORT dbnameDB_NAME userUSER passwordPASSWORD需要注意一个常见的坑文档站点有专门提醒见 PgvectorDocumentStore 指南URI 格式中密码等特殊字符必须做percent-encoding。例如密码为pssword则应写成export PG_CONN_STRpostgresql://postgres:p%3Dsswordlocalhost:5432/postgres否则可能触发类似psycopg.OperationalError: [Errno -2] Name or service not known的连接错误。若不想处理转义可直接改用关键字/值格式export PG_CONN_STRhostlocalhost port5432 dbnamepostgres userpostgres passwordpsswordPgvectorDocumentStore 详解初始化签名与参数PgvectorDocumentStore的完整初始化签名来自 API 参考__init__( *, connection_string: Secret Secret.from_env_var(PG_CONN_STR), create_extension: bool True, schema_name: str public, table_name: str haystack_documents, language: str english, embedding_dimension: int 768, vector_type: Literal[vector, halfvec] vector, vector_function: Literal[ cosine_similarity, inner_product, l2_distance ] cosine_similarity, recreate_table: bool False, search_strategy: Literal[ exact_nearest_neighbor, hnsw ] exact_nearest_neighbor, hnsw_recreate_index_if_exists: bool False, hnsw_index_creation_kwargs: dict[str, int] | None None, hnsw_index_name: str haystack_hnsw_index, hnsw_ef_search: int | None None, keyword_index_name: str haystack_keyword_index ) - None各参数含义如下参数默认值说明connection_stringSecret.from_env_var(PG_CONN_STR)连接 PostgreSQL 的连接串以环境变量方式提供支持 URI 与关键字/值两种格式create_extensionTrue是否在扩展缺失时自动创建 pgvector 扩展。创建扩展可能需要超级用户权限若设为False必须确保扩展已预先安装否则报错schema_namepublic建表所在的 schema 名称该 schema 必须已存在table_namehaystack_documents存储 Haystack 文档的数据表名languageenglish关键词检索中解析查询与文档内容所用的语言。可用语言可通过 SQLSELECT cfgname FROM pg_ts_config;查询embedding_dimension768向量维度必须与你的嵌入模型输出维度一致vector_typevector向量存储类型。halfvec以半精度存储向量特别适合高维向量维度大于 2000、最高 4000要求 pgvector 0.7.0 及以上版本vector_functioncosine_similarity相似度函数cosine_similarity、inner_product、l2_distance之一语义详见下文recreate_tableFalse若表已存在是否先删除再重建search_strategyexact_nearest_neighbor搜索策略exact_nearest_neighbor精确召回率高但大数据量下慢hnsw为近似最近邻牺牲少量精度换取速度适合海量文档hnsw_recreate_index_if_existsFalseHNSW 索引已存在时是否重建仅在search_strategyhnsw时生效hnsw_index_creation_kwargsNone创建 HNSW 索引时附加的关键字参数仅在 HNSW 策略下生效hnsw_index_namehaystack_hnsw_indexHNSW 索引名称hnsw_ef_searchNone查询时使用的ef_search参数仅在 HNSW 策略下生效用于控制查询阶段搜索广度keyword_index_namehaystack_keyword_index关键词检索所用索引名称初始化与写入文档文档站点给出了最简初始化与写入示例见 PgvectorDocumentStore 指南from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore from haystack import Document document_store PgvectorDocumentStore( embedding_dimension768, vector_functioncosine_similarity, recreate_tableTrue, search_strategyhnsw, ) document_store.write_documents( [ Document(contentThis is first, embedding[0.1] * 768), Document(contentThis is second, embedding[0.3] * 768), ], ) print(document_store.count_documents())要点embedding_dimension768需与嵌入模型输出维度一致recreate_tableTrue适合开发调试会丢弃已有表结构生产环境请谨慎写入带embedding字段的Document即可被向量检索命中不带向量的文档仍可参与关键词检索与元数据过滤。关于向量维度的上限vector类型支持最高约 2000 维受 PostgreSQL 行大小限制超过 2000 且不超过 4000 的维度应使用vector_typehalfvec半精度存储这要求 pgvector 0.7.0 及以上。这一点从vector_type参数文档可以直接确认。向量函数语义三个可选向量函数中cosine_similarity与inner_product是相似度函数分数越高代表越相似而l2_distance返回向量间的直线距离分数越小越相似。若使用 HNSW 搜索策略索引的构建依赖初始化时传入的vector_function因此后续查询必须沿用同一个向量函数否则无法利用该索引。文档写入与去重策略DuplicatePolicywrite_documents(documents, policyDuplicatePolicy.NONE)的policy参数控制文档去重行为。仓库核心库中的DuplicatePolicy定义于 haystack/document_stores/types/policy.pySKIP同 id 文档已存在时跳过不写入OVERWRITE同 id 文档已存在时覆盖FAIL同 id 文档已存在时抛错NONE不指定实际默认回落为FAIL语义这一点可从核心库内存存储的实现注释确认见 haystack/document_stores/in_memory/document_store.py。Pgvector 集成文档中的示例普遍使用DuplicatePolicy.OVERWRITE方便反复运行脚本在 RAG 示例中也可见到用DuplicatePolicy.SKIP实现可重复运行不报错的写法。Raises若documents含非Document对象抛出ValueError若文档 id 已存在且策略为FAIL或未指定抛出DuplicateDocumentError写入失败的其他情况抛出DocumentStoreError。文档管理 API 一览PgvectorDocumentStore除了写入还提供一整套文档管理方法且每个方法都有对应的异步版本*_async方法说明count_documents()/count_documents_async()返回文档总数filter_documents(filters)/filter_documents_async()按过滤器返回匹配文档filters非字典抛TypeError语法非法抛ValueErrordelete_documents(document_ids)/delete_documents_async()按 id 列表删除文档delete_all_documents()/delete_all_documents_async()清空所有文档delete_by_filter(filters)/delete_by_filter_async()删除匹配过滤器的所有文档返回删除数量update_by_filter(filters, meta)/update_by_filter_async()更新匹配过滤器的文档元数据返回更新数量count_documents_by_filter(filters)/count_documents_by_filter_async()统计匹配过滤器的文档数量count_unique_metadata_by_filter(filters, metadata_fields)/ 异步版统计各元数据字段的唯一值数量字段名可带或不带meta.前缀get_metadata_fields_info()/ 异步版返回元数据字段的类型信息因为元数据存于 JSONB 列该方法通过分析实际数据推断类型get_metadata_field_min_max(metadata_field)/ 异步版返回某元数据字段的最小/最大值数值字段返回数值极值文本字段按数据库排序规则返回字典序极值字段无值或存储为空时返回{min: None, max: None}get_metadata_field_unique_values(metadata_field, search_termNone, from_0, size10, filtersNone)/ 异步版分页返回某元数据字段的唯一值及总数search_term做大小写不敏感的子串过滤delete_table()/delete_table_async()删除存储 Haystack 文档的数据表schema 与表名以初始化参数为准关于get_metadata_field_unique_values有一个值得注意的细节API 参考中有明确说明不同 JSON 类型类别的值会保持独立——字符串1与数字1不会合并唯一例外是 JSONB 的相等语义会把整数值浮点1.0与整数1视为相等从而合并而带小数部分的浮点如1.5不受影响。get_metadata_fields_info的返回示例{ category: {type: text}, status: {type: text}, priority: {type: integer}, }序列化与资源释放PgvectorDocumentStore、PgvectorEmbeddingRetriever、PgvectorKeywordRetriever三个组件均实现 Haystack 标准的序列化协议to_dict() - dict[str, Any]将组件序列化为字典用于 YAML/JSON 流水线描述from_dict(data) - 组件类型从字典反序列化重建组件close()/close_async()释放底层 Document Store 的同步/异步资源。PgvectorEmbeddingRetriever基于稠密向量的语义检索初始化参数__init__( *, document_store: PgvectorDocumentStore, filters: dict[str, Any] | None None, top_k: int 10, vector_function: ( Literal[cosine_similarity, inner_product, l2_distance] | None ) None, filter_policy: str | FilterPolicy FilterPolicy.REPLACE ) - Nonedocument_store必填PgvectorDocumentStore实例。若非该类型实例抛出ValueErrorfilters作用于被检索文档的过滤器top_k最多返回的文档数默认 10vector_function本次检索使用的相似度函数。默认为None此时使用 Document Store 初始化时设定的函数若传入非法值抛出ValueError。重要若 Document Store 使用hnsw搜索策略此处传入的函数应与建索引时所用函数一致才能命中索引filter_policy过滤器应用策略详见过滤机制深入一节。单独使用检索器本身不负责生成查询向量需要先把query_embedding准备好import os from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore from haystack_integrations.components.retrievers.pgvector import ( PgvectorEmbeddingRetriever, ) os.environ[PG_CONN_STR] postgresql://postgres:postgreslocalhost:5432/postgres document_store PgvectorDocumentStore() retriever PgvectorEmbeddingRetriever(document_storedocument_store) # 这里用假向量保持示例简洁实际应使用 Text Embedder 生成 retriever.run(query_embedding[0.1] * 768)在 Pipeline 中使用语义搜索将PgvectorEmbeddingRetriever与文本嵌入器接入 Haystack Pipeline是文档推荐的标准用法完整示例见 PgvectorEmbeddingRetriever 指南import os from haystack.document_stores.types import DuplicatePolicy from haystack import Document, Pipeline from haystack_integrations.components.embedders.sentence_transformers import ( SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder, ) from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore from haystack_integrations.components.retrievers.pgvector import ( PgvectorEmbeddingRetriever, ) os.environ[PG_CONN_STR] postgresql://postgres:postgreslocalhost:5432/postgres document_store PgvectorDocumentStore( embedding_dimension768, vector_functioncosine_similarity, recreate_tableTrue, ) documents [ Document(contentThere are over 7,000 languages spoken around the world today.), Document( contentElephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors., ), Document( contentIn certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves., ), ] document_embedder SentenceTransformersDocumentEmbedder() documents_with_embeddings document_embedder.run(documents) document_store.write_documents( documents_with_embeddings.get(documents), policyDuplicatePolicy.OVERWRITE, ) query_pipeline Pipeline() query_pipeline.add_component(text_embedder, SentenceTransformersTextEmbedder()) query_pipeline.add_component( retriever, PgvectorEmbeddingRetriever(document_storedocument_store), ) query_pipeline.connect(text_embedder.embedding, retriever.query_embedding) query How many languages are there? result query_pipeline.run({text_embedder: {text: query}}) print(result[retriever][documents][0])这条管线的数据流是SentenceTransformersTextEmbedder把查询文本编码为向量 → 通过text_embedder.embedding → retriever.query_embedding连接传入检索器 → 检索器在 PostgreSQL 中执行向量相似度查询 → 返回documents列表。最终结果从result[retriever][documents]取回。run / run_async 签名run( query_embedding: list[float], filters: dict[str, Any] | None None, top_k: int | None None, vector_function: ( Literal[cosine_similarity, inner_product, l2_distance] | None ) None, ) - dict[str, list[Document]]运行时参数与初始化参数同名者会覆盖初始化值。返回值是字典键为documents值为与query_embedding最相似的Document列表。run_async提供等价异步实现。PgvectorKeywordRetriever基于关键词的全文检索初始化参数__init__( *, document_store: PgvectorDocumentStore, filters: dict[str, Any] | None None, top_k: int 10, filter_policy: str | FilterPolicy FilterPolicy.REPLACE ) - None参数含义与嵌入检索器一致document_store必填非PgvectorDocumentStore实例抛ValueErrorfilters限定检索范围top_k控制返回数量filter_policy控制过滤器应用策略。排序原理ts_rank_cd与嵌入检索不同关键词检索直接对文档文本内容做全文检索排序依据是 PostgreSQL 的ts_rank_cd函数。它综合考虑查询词在文档中出现的频率查询词在文档中彼此相距的远近越近分越高查询词出现的位置重要性出现在标题等更重要的位置得分更高。因此在配置PgvectorDocumentStore时language参数直接影响全文检索的效果——它决定了查询与文档内容按何种语言的文本搜索配置ts_config进行解析。可用语言可以通过 SQL 在数据库中查询SELECT cfgname FROM pg_ts_config;易错点文档明确指出与ElasticsearchBM25Retriever等组件不同PgvectorKeywordRetriever默认不提供模糊搜索查询词必须与文档内容精确匹配否则可能得到零结果。构造查询时需要注意措辞。单独使用from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore from haystack_integrations.components.retrievers.pgvector import ( PgvectorKeywordRetriever, ) document_store PgvectorDocumentStore() retriever PgvectorKeywordRetriever(document_storedocument_store) retriever.run(querymy nice query)在 RAG 管线中使用文档给出了一个完整的关键词检索 LLM 生成RAG 示例见 PgvectorKeywordRetriever 指南前提是设置OPENAI_API_KEY与PG_CONN_STR两个环境变量from haystack import Document from haystack import Pipeline from haystack.components.builders.answer_builder import AnswerBuilder from haystack.components.builders import ChatPromptBuilder from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage from haystack.document_stores.types import DuplicatePolicy from haystack_integrations.document_stores.pgvector import PgvectorDocumentStore from haystack_integrations.components.retrievers.pgvector import ( PgvectorKeywordRetriever, ) prompt_template [ ChatMessage.from_user( Given these documents, answer the question.\nDocuments: {% for doc in documents %} {{ doc.content }} {% endfor %} \nQuestion: {{question}} \nAnswer: , ), ] document_store PgvectorDocumentStore( languageenglish, # 该参数影响关键词检索的文本解析 recreate_tableTrue, ) documents [ Document(contentThere are over 7,000 languages spoken around the world today.), Document( contentElephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors., ), Document( contentIn certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves., ), ] # DuplicatePolicy.SKIP 可选便于脚本重复运行而不抛错 document_store.write_documents(documentsdocuments, policyDuplicatePolicy.SKIP) retriever PgvectorKeywordRetriever(document_storedocument_store) rag_pipeline Pipeline() rag_pipeline.add_component(nameretriever, instanceretriever) rag_pipeline.add_component( instanceChatPromptBuilder(templateprompt_template, required_variables*), nameprompt_builder, ) rag_pipeline.add_component(instanceOpenAIChatGenerator(), namellm) rag_pipeline.add_component(instanceAnswerBuilder(), nameanswer_builder) rag_pipeline.connect(retriever, prompt_builder.documents) rag_pipeline.connect(prompt_builder.prompt, llm.messages) rag_pipeline.connect(llm.replies, answer_builder.replies) rag_pipeline.connect(retriever, answer_builder.documents) question languages spoken around the world today result rag_pipeline.run( { retriever: {query: question}, prompt_builder: {question: question}, answer_builder: {query: question}, }, ) print(result[answer_builder])这段示例展示了关键词检索 RAG 的完整链路retriever取回相关文档 → 文档注入prompt_builder的提示模板 →llm生成回答 →answer_builder组装带引用的答案。run / run_async 签名run( query: str, filters: dict[str, Any] | None None, top_k: int | None None ) - dict[str, list[Document]]query是在文档内容中搜索的字符串返回documents键下的匹配文档列表。run_async提供等价异步实现。过滤机制深入FilterPolicy 的 REPLACE 与 MERGE两个检索器初始化时都接受filter_policy参数默认FilterPolicy.REPLACE。它的语义定义在仓库核心库的 haystack/document_stores/types/filter_policy.py 中REPLACE默认run()时传入的运行时过滤器整体替换初始化时设置的过滤器MERGE运行时过滤器与初始化过滤器合并运行时值优先覆盖初始化值中重叠的字段。底层实现apply_filter_policy函数会根据过滤器形态组合出不同的合并策略例如两个比较过滤器comparison filter含field/operator/value合并为一个AND逻辑过滤器逻辑过滤器与比较过滤器合并时若运算符一致如都是AND则把比较条件并入逻辑条件若同名字段冲突运行时条件优先两个同运算符的逻辑过滤器合并时条件列表直接拼接运算符不一致时初始化过滤器被忽略并给出警告日志。一个直观的合并效果源码 docstring 中的示例init_filters { operator: AND, conditions: [ {field: meta.type, operator: , value: article}, {field: meta.rating, operator: , value: 3}, ] } runtime_filters { operator: AND, conditions: [ {field: meta.genre, operator: IN, value: [economy, politics]}, {field: meta.publisher, operator: , value: nytimes}, ] } # MERGE 策略下得到 { operator: AND, conditions: [ ...四个条件合并... ] }因此若希望初始化时固定一部分过滤条件如租户隔离、数据范围运行时追加动态条件应使用MERGE若每次运行时都想完全重新指定过滤条件则保持默认REPLACE即可。同步 / 异步 API 对照Pgvector 集成紧跟 Haystack 的异步支持。所有涉及数据库操作的方法都提供_async变体便于在异步 Pipelinerun_async或async上下文中使用组件同步方法异步方法PgvectorDocumentStorewrite_documents、filter_documents、delete_documents、delete_all_documents、delete_by_filter、update_by_filter、count_documents、count_documents_by_filter、count_unique_metadata_by_filter、get_metadata_fields_info、get_metadata_field_min_max、get_metadata_field_unique_values、delete_table、close同名方法加_async后缀外加close_asyncPgvectorEmbeddingRetrieverrunrun_asyncPgvectorKeywordRetrieverrunrun_async总结与选型建议围绕 Pgvector 集成 API 参考本文完整覆盖了 Pgvector 集成的三个核心组件PgvectorDocumentStore以 PostgreSQL pgvector 为底座提供建表、写入含去重策略、过滤、删除、更新、统计、元数据探索等完整文档管理能力并支持vector/halfvec两种向量类型、精确搜索与 HNSW 近似搜索两种策略PgvectorEmbeddingRetriever基于稠密向量的语义检索可与任意 Text Embedder 接入 Haystack PipelinePgvectorKeywordRetriever基于 PostgreSQL 全文检索ts_rank_cd的关键词检索适合精确词匹配场景。从选型角度参考 Document Store 选择指南Pgvector 适合以下场景已经在使用或希望继续使用 PostgreSQL、看重 ACID 与点时间恢复能力、同时需要 Embedding 与关键词两种检索方式且文档规模可接受精确最近邻小规模或愿意用 HNSW 换取检索速度大规模的情况。实际使用时建议遵循以下几条经验生产环境不要设置recreate_tableTrue避免误删表数据向量维度与嵌入模型对齐高维2000使用halfvec并确保 pgvector ≥ 0.7.0使用 HNSW 策略时建索引、查询、检索器三处的vector_function必须保持一致否则索引无法生效关键词检索无模糊匹配查询构造需精确必要时可结合嵌入检索互为补充连接串中特殊字符做好 percent-encoding或直接使用关键字/值格式规避。【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻