免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

pgai 文档向量化完整指南:用声明式 Vectorizer 把 S3 与本地文件嵌入 PostgreSQL 向量库

pgai 文档向量化完整指南:用声明式 Vectorizer 把 S3 与本地文件嵌入 PostgreSQL 向量库 pgai 文档向量化完整指南用声明式 Vectorizer 把 S3 与本地文件嵌入 PostgreSQL 向量库【免费下载链接】pgaiA suite of tools to develop RAG, semantic search, and other AI applications more easily with PostgreSQL项目地址: https://gitcode.com/GitHub_Trending/pg/pgai本文围绕 pgaiPostgreSQL 的 RAG / 语义搜索工具套件中的文档向量化document embeddings能力展开先建一张文档元数据表再用ai.create_vectorizer声明式地配置“加载 → 解析 → 切块 → 嵌入”流水线最后通过 pgvector 语义检索查询生成的嵌入并结合仓库源码loading.py、parsing.py、chunking.py讲解各配置项的底层实现。读完后你将能够把 PDF、DOCX、XLSX、EPUB、HTML 等文档存入数据库向量库并保持嵌入与源文档自动同步。为什么 RAG 需要“文档级”向量化RAGRetrieval Augmented Generation应用通常需要文本数据但真实场景中的知识往往以文档形式存在存储在 S3、本地文件系统等外部系统中格式多样PDF、DOCX、XLSX、EPUB、HTML 等会频繁更新需要源文档与嵌入之间持续同步。pgai 的文档向量化系统通过声明式方式直接嵌入文档你只需描述“数据从哪来、怎么解析、怎么切块、用哪个模型嵌入”pgai 会负责加载loading、解析parsing、切块chunking和嵌入embedding整个流程并自动保持嵌入与源文档同步。仓库中附带一个可运行的完整示例 examples/embeddings_from_documents包含 Markdown、XLSX、HTML、PDF 四种真实文档可快速验证全流程。第一步建立文档存储表文档管理的基石是 PostgreSQL 中的一张文档元数据表。文档内容本身可以以BYTEA列直接存在库里或以 URI 形式指向外部存储如 S3中的文件。这张表还可以携带应用需要的任意元数据标题、属主、标签、访问级别等。如果你的应用已经管理文档通常已经有一张这样的表可以直接作为 vectorizer 的源表。最小文档表最小可用的文档源表只需要一个标识列和一个指向文档的 URI 列两者可以是同一列。updated_at列可选但推荐便于文档更新时触发重新嵌入CREATE TABLE document ( uri TEXT PRIMARY KEY, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); -- Example records INSERT INTO document (uri) VALUES (s3://my-bucket/documents/product-manual.pdf), (s3://my-bucket/documents/api-reference.md),带完整元数据的文档表实际应用中通常需要额外元数据用于过滤和分类文档CREATE TABLE document ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, uri TEXT NOT NULL, content_type TEXT, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, owner_id INTEGER, access_level TEXT, tags TEXT[] ); -- Example with rich metadata INSERT INTO document (title, uri, content_type, owner_id, access_level, tags) VALUES (Product Manual, s3://my-bucket/documents/product-manual.pdf, application/pdf, 12, internal, ARRAY[product, reference]), (API Reference, s3://my-bucket/documents/api-reference.md, text/markdown, 8, public, ARRAY[api, developer]);直接把文档内容存进数据库对于小文档或没有外部存储的系统也可以用BYTEA直接存二进制内容CREATE TABLE document ( id SERIAL PRIMARY KEY, file BYTEA ); -- 从服务器本地文件读入文件必须对 worker 可读 INSERT INTO document (file) VALUES (pg_read_binary_file(/tmp/sample.pdf)::bytea);第二步配置文档 VectorizerVectorizer 是一份声明式配置定义文档如何被处理、切块和嵌入pgai 会自动把嵌入与源文档保持同步。完整的参数参考见 Vectorizer API Reference。从源码看create_vectorizer的 Python 侧参数模型create_vectorizer.py与 SQL 函数一一对应文档场景主要用到loading、parsing、chunking、embedding、destination五个配置对象此外还有indexing索引、processing批处理、scheduling调度等可选项。完整配置示例S3 文档 OpenAI 嵌入SELECT ai.create_vectorizer( document::regclass, loading ai.loading_uri(column_name uri), parsing ai.parsing_auto(), -- 可选自动检测解析器这是默认值可省略 chunking ai.chunking_recursive_character_text_splitter( chunk_size 700, separators array[E\n## , E\n### , E\n#### , E\n- , E\n1. , E\n\n, E\n, ., ?, !, , , |] ), embedding ai.embedding_openai(text-embedding-3-small, 768), destination ai.destination_table(document_embeddings) );这条配置做了五件事以document表为源表从uri列加载文档自动检测并解析文档格式按 Markdown 常见断点标题、段落等切块用 OpenAI 的text-embedding-3-small生成嵌入写入document_embeddings目标表。组件一Loading文档加载pgai 支持两种加载方式从 URI 引用列加载外部文件ai.loading_uri或直接从BYTEA列加载ai.loading_column。1. 从 URI 列加载ai.loading_uriloading ai.loading_uri( column_name uri, retries 6, -- 可选重试次数默认 6 aws_role_arn arn:aws:iam::123456789012:role/S3AccessRole -- 可选通过角色扮演访问 S3 )这是最常用的文档加载方式支持下载S3 URL如s3://bucket/path/to/file.pdfHTTP/HTTPS URL如https://example.com/file.pdfworker 机器上的本地文件如/path/to/file.pdf。源码实现细节loading.pyUriLoading默认retries6加载失败会重试应对瞬时网络/存储故障当 URI 以s3://开头且配置了aws_role_arn时源码会用 boto3 的 STSassume_role换取临时凭证会话名timescale-vectorizer再创建带该凭证的 S3 client 传给smart_open——这就是跨账号访问 S3 的机制还支持通过环境变量AWS_ASSUME_ROLE_EXTERNAL_ID附加外部 ID文件内容读取基于 smart_open因此理论上任何 smart_open 支持的 URI 都能工作GCS、Azure 等但在 Timescale Cloud 上仅支持 AWS S3自托管场景下其他云厂商需自行安装对应的 smart_open 依赖并自行测试加载后源码用filetype库嗅探二进制 magic number 判断文件类型嗅探失败再回退到从 URL 路径解析扩展名guess_filetypeloading.py——这个类型判断结果会传给解析器用于自动选择。2. 从 BYTEA 列加载ai.loading_columnloading ai.loading_column( column_name content )当文档内容已经在数据库里、不想引入外部存储时使用。对应源码ColumnLoading同样默认retries6且对bytes类型内容会嗅探文件类型后交给解析器处理loading.py。如果文档存放在 S3可参考 S3 文档指南 配置认证并学习如何将 S3 bucket 与文档表同步。组件二Parsing文档解析为了让文档对 LLM 友好需要先解析成 Markdown。pgai 支持两种解析器pymupdf和docling。多数情况下无需关心这个细节——ai.parsing_auto会根据文件类型自动选择解析器你也可以显式指定。更完整的参数说明见 解析配置参考。源码实现细节parsing.pyParsingAuto的分发逻辑parsing.pyEPUB 文件走PyMuPDF因为 docling 不支持 epub其余文档走Docling文本类文件txt、md不走任何解析器直接按 UTF-8 解码parsing.pyPyMuPDF 路径使用pymupdf4llm.to_markdown()直接产出面向 LLM 的 Markdownparsing.pyDocling 路径使用DocumentConverter对 PDF 默认关闭 OCRdo_ocrFalse对图片格式则启用 OCR 流水线模型缓存在~/.cache/docling/models可用环境变量VECTORIZER_DOCLING_CACHE_DIR覆盖parsing.py。组件三Chunking切块切块把文档切成适合嵌入的小片段。由于解析后的内容是 Markdown切分策略应尊重 Markdown 结构chunking ai.chunking_recursive_character_text_splitter( chunk_size 700, chunk_overlap 150, separators array[ E\n## , -- 按二级标题切分 E\n### , -- 按三级标题切分 E\n#### , -- 按四级标题切分 E\n- , -- 按列表项切分 E\n1. , -- 按编号列表项切分 E\n\n, -- 按段落切分 E\n, -- 按行切分 ., -- 按句子切分 ?, !, -- 按问句/感叹句切分 ] )该配置会依次尝试更细粒度的分隔符以在尽量保留文档结构的前提下逼近目标块大小。源码实现细节chunking.pyai.chunking_recursive_character_text_splitter底层包装的是langchain_text_splitters的RecursiveCharacterTextSplitter参数separators、chunk_size、chunk_overlap、is_separator_regex原样透传。根据 API Reference该切分器的默认值为chunk_size800、chunk_overlap400上面的示例覆盖了这些默认值。另有ai.chunking_character_text_splitter单一分隔符和ai.chunking_none()不切块仅在“一行一嵌入”的场景可用两个变体。组件四Embedding嵌入pgai 支持多种嵌入提供方全部遵循相似的配置模式完整参数见 嵌入配置参考。以 OpenAI 为例embedding ai.embedding_openai( text-embedding-3-small, -- 模型名 768 -- 嵌入维度 )本地模型可换用 Ollamaembedding ai.embedding_ollama(nomic-embed-text, 768, base_url http://ollama:11434)组件五Destination嵌入存放位置文档场景几乎总要用table destination一个源行对应多个 chunk 即多条嵌入即ai.destination_table(document_embeddings)。源码中它由TableDestination表示包含target_schema与target_tabledestination.py另一种ColumnDestination只在“一行恰好一条嵌入”且必须搭配ai.chunking_none()的场景使用不适合文档。查询文档嵌入Vectorizer 创建后pgai 会自动生成一张嵌入目标表和一个视图view 把嵌入与原表 join 起来。视图名就是ai.destination_table(document_embeddings)中指定的名字。视图包含原文档表的所有列另加以下列列名类型说明embedding_uuidUUID嵌入的唯一标识chunkTEXT被嵌入的文本片段embeddingVECTOR该 chunk 的向量表示chunk_seqINTchunk 在文档中的序号从 0 开始基础语义搜索-- Basic similarity search SELECT title, chunk, embedding search_embedding AS distance FROM document_embeddings ORDER BY distance LIMIT 5;向量相似度 元数据过滤pgai 文档方案最强大的特性之一是可以把向量相似度和传统 SQL 过滤条件写在同一条查询里-- Find recent documentation about configuration SELECT title, chunk FROM document_embeddings WHERE updated_at (CURRENT_DATE - INTERVAL 30 days) AND title ILIKE %configuration% ORDER BY embedding search_embedding LIMIT 5;与应用数据联表查询-- Find documents relevant to customers with pending support tickets SELECT c.name, d.title, e.chunk FROM customers c JOIN support_tickets t ON c.id t.customer_id JOIN customer_documentation cd ON c.id cd.customer_id JOIN document_embeddings e ON cd.document_id e.id WHERE t.status pending ORDER BY e.embedding search_embedding LIMIT 10;监控与排障文档嵌入是异步生成的可以用 vectorizer 的标准监控工具查看状态查看待处理项pending itemsSELECT * FROM ai.vectorizer_status;查看失败项-- 查看所有 vectorizer 的错误 SELECT * FROM ai.vectorizer_errors; -- 查看某个 vectorizer 的错误 SELECT * FROM ai.vectorizer_errors WHERE id vectorizer_id;错误表包含失败原因的详细信息可据此区分是加载失败URI 不可达、凭证错误、解析失败不支持的文件格式还是嵌入失败API 报错、限流。查看队列与重试计数SELECT * FROM ai._vectorizer_q_1队列名可以从ai.vectorizer表中查到。重试发生时retries默认 6 次队列行会记录重试进度帮助判断是瞬时故障还是持续性失败。常见问题与解决方案嵌入 API 限流如果遇到提供方限流调整processing配置中的批大小和并发参见 processing 配置参考。对文档类 vectorizer一般推荐小 batch size如 1 高并发如 10因为解析本身耗时较长。这与源码/API 参考中“使用ai.loading_uri的 vectorizer 默认batch_size1其他场景为 50”的默认行为一致见 api-reference.md 的 processing 章节考虑升级 API 等级或换用其他提供方。文档规模限制pgai 文档 vectorizer 面向小到中等尺寸的文档设计大文档解析和嵌入耗时会明显变长。在 Timescale Cloud 上PDF 的页数上限约为 50 页更大的文档建议先在上游拆分支持哪些文档格式取决于所用解析器请对照 解析器参考 确认所用解析器支持的文件类型。附录更多 Vectorizer 配置示例示例一S3 文档 OpenAI 嵌入含元数据列-- Create document table CREATE TABLE documentation ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, file_uri TEXT NOT NULL, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); -- Add documents INSERT INTO documentation (title, file_uri) VALUES (Product Manual, s3://company-docs/manuals/product-v2.pdf), (API Reference, s3://company-docs/api/reference.md); -- Create vectorizer SELECT ai.create_vectorizer( documentation::regclass, loading ai.loading_uri(column_name file_uri), parsing ai.parsing_auto(), -- 自动检测解析器默认值可省略 chunking ai.chunking_recursive_character_text_splitter( chunk_size 700, separators array[E\n## , E\n### , E\n#### , E\n- , E\n1. , E\n\n, E\n, ., ?, !, , , |] ), embedding ai.embedding_openai(text-embedding-3-small, 768) );示例二库内 BYTEA 文档 本地 Ollama 嵌入-- Create document table with binary storage CREATE TABLE internal_document ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, content BYTEA NOT NULL, created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP ); -- Add documents INSERT INTO internal_document (title, content) VALUES (Internal Report, pg_read_binary_file(/path/to/report.pdf)::bytea), (Internal Memo, pg_read_binary_file(/path/to/memo.docx)::bytea); -- Create vectorizer SELECT ai.create_vectorizer( internal_document::regclass, loading ai.loading_column(column_name content), chunking ai.chunking_recursive_character_text_splitter( chunk_size 500, chunk_overlap 100, separators array[E\n\n, E\n, ., , ] ), embedding ai.embedding_ollama(nomic-embed-text, 768, base_url http://ollama:11434) );注意此例省略了destination嵌入视图会按默认命名规则生成。快速上手可运行的完整示例仓库提供了端到端示例 examples/embeddings_from_documents含 MD、XLSX、HTML、PDF 四种文档。流程概要建表CREATE TABLE documentation (id SERIAL PRIMARY KEY, title TEXT NOT NULL, file_uri TEXT NOT NULL);灌入文档 URI支持本地路径与 S3如INSERT INTO documentation (title, file_uri) VALUES (pgai documentation, /app/documents/pgai.md), (pgai models support table, /app/documents/pgai_models_support.xlsx), (pgvectorscale documentation, /app/documents/pgvectorscale.html), (Sacred Texts of Postgres, /app/documents/sacred_texts_of_postgres.pdf);本地文件需要让 vectorizer worker 能读到示例建议修改 compose-dev.yaml 给vectorizer-worker服务挂载卷./documents:/app/documents创建 vectorizer与本文的完整配置示例一致监控进度SELECT * FROM ai.vectorizer_status;直到 pending 为 0查询嵌入可在库内直接生成查询嵌入例如embedding ai.openai_embed(text-embedding-3-small, 你的查询文本, dimensions768)距离值越小匹配度越高。该示例还验证了自动同步对源表的插入、更新、删除会被 pgai 自动处理——例如更新file_uri列会触发对应嵌入重新生成无需人工干预。小结pgai 的文档向量化把“文件 → Markdown → 切块 → 向量”这条 RAG 数据管线收敛为一条ai.create_vectorizer声明loadingURI 或 BYTEA默认 6 次重试、S3 支持 STS 角色扮演、parsingauto/PyMuPDF/Docling 自动分发、chunkingLangChain 递归字符切分器尊重 Markdown 结构、embedding多提供方同构接口与destination自动建表 联合视图各司其职。生成的嵌入视图保留了源表全部元数据列使得语义搜索与 SQL 过滤、联表查询可以在同一条语句中完成配合ai.vectorizer_status与ai.vectorizer_errors即可闭环监控与排障。相关深入资料S3 文档配置、Vectorizer Worker 部署、API Reference 以及可运行示例 examples/embeddings_from_documents。【免费下载链接】pgaiA suite of tools to develop RAG, semantic search, and other AI applications more easily with PostgreSQL项目地址: https://gitcode.com/GitHub_Trending/pg/pgai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表