news 2026/11/2 18:42:09

PostgresML 1.0 SDK 正式发布:用 Python 与 JavaScript 在 PostgreSQL 中构建端到端向量搜索

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PostgresML 1.0 SDK 正式发布:用 Python 与 JavaScript 在 PostgreSQL 中构建端到端向量搜索
  • 后端
  • 人工智能
  • 机器学习
  • RAG
  • 向量数据库

【免费下载链接】postgresml

Postgres with GPUs for ML/AI apps.

项目地址:https://gitcode.com/gh_mirrors/po/postgresml
点击查看免费下载

2023 年 3 月,PostgresML 团队正式发布了官方 SDK 的 1.0 稳定版本,同时覆盖 Python 与 JavaScript 两种语言。本文以这篇发布公告为主线,结合当前仓库中 pgml-sdks 的 Rust 核心源码,完整讲解 Collection(文档集合)、Pipeline(处理流水线)、语义搜索 / 全文搜索 / 混合搜索、HuggingFace 模型接入、DEBUG 调试与 ER 图生成等核心能力,帮助读者掌握在纯 PostgreSQL 环境中从"建集合、写文档、跑流水线"到"向量检索"的完整落地路径。

1.0 版本:官方 SDK 的稳定与定型

在过去几个月里,PostgresML 团队持续对 JavaScript 和 Python 两个版本的 SDK 进行稳定化与功能收尾,最终在 2023 年 3 月 4 日发布 1.0 正式版。这一版本的发布公告正是本文关联的文档 the-1.0-sdk-is-here.md。

1.0 版本带来了大量性能改进与新特性,其核心能力可以概括为以下几点:

  • Collection:创建用于存储、检索和管理成组文档的集合;
  • Pipeline:定义强大且灵活的流水线,统一编排文档的摄入(ingest)、切分(splitting)、嵌入(embedding)与索引(indexing);
  • 多模态搜索:支持语义搜索(semantic search)、全文搜索(full text search)以及二者的混合搜索(hybrid search),并可基于文档的额外元数据做丰富的过滤;
  • 模型生态:几乎可以使用 HuggingFace 上所有主流 embedding 模型;
  • 一切皆 SQL:Collection 在数据库中就是一张张真实的表,可以用 ER 图直观查看表结构,甚至绕过 SDK 直接用 SQL 查询。

SDK 本身是专为"搜索"这一任务而设计的。根据原公告,PostgresML 团队用它驱动自家官网的搜索功能,并在 ChatBot 演示中完成 RAG(检索增强生成)流程。从当前仓库的源码结构也可以印证这一技术路线:pgml-dashboard/src/utils/markdown.rs 承担了官网内容渲染与检索相关的逻辑。

为什么说这次发布值得兴奋

任何一个公司 SDK 的本质工作都是相同的:把管理 SQL 表、拼接复杂查询这些"无聊且重复"的工作抽象掉。单就 SDK 本身而言,它并不算开创性发明。但 PostgresML 1.0 SDK 让人兴奋的原因在于它底层所依赖的技术:

SDK 完全依托于开源的 PostgresML PostgreSQL 扩展,用 SQL 完成机器学习任务。闪电般快速的文档嵌入和魔术般的混合搜索,本质上都是调用 PostgresML 扩展的简单 SQL 查询。所有计算都在你的数据库本地完成,全程没有任何网络调用。

这句话值得展开理解。当你在 Python/JavaScript 中写下collection.upsert_documents(documents)时,SDK 并不是把数据发到某个 SaaS 平台,而是在你的 PostgreSQL 实例中执行 INSERT、调用pgml.embed()生成向量、写入text_chunks/text_embeddings等表,并借助 PgVector 扩展建立 HNSW 向量索引。这条技术路线与 pgml-sdks/pgml/python/README.md 中"构建端到端向量搜索应用,无需 OpenAI 与 Pinecone"的定位完全一致。

快速体验:从建集合到向量检索

下面这段代码是公告中的核心示例,完整展示了 1.0 SDK 的三个关键动作:创建 Collection 与 Pipeline、Upsert 文档、执行向量搜索。Python 与 JavaScript 两个版本的 API 几乎一一对应。

JavaScript 版本

// Create Collection and Pipeline const collection = pgml.newCollection("my_collection"); const pipeline = pgml.newPipeline("my_pipeline", { text: { splitter: { model: "recursive_character" }, semantic_search: { model: "Alibaba-NLP/gte-base-en-v1.5", }, }, }); await collection.add_pipeline(pipeline); // Upsert a document const documents = [ { id: "document_one", text: "Here is some hidden value 1000" } ]; await collection.upsert_documents(documents); // Search over our collection const results = await collection.vector_search( { query: { fields: { text: { query: "What is the hidden value?" }, }, }, limit: 5, }, pipeline, ); console.log(results);

Python 版本

# Create Collection and Pipeline collection = Collection("my_collection") pipeline = Pipeline( "my_pipeline", { "text": { "splitter": {"model": "recursive_character"}, "semantic_search": { "model": "Alibaba-NLP/gte-base-en-v1.5", }, }, }, ) # Upsert a document documents = [{"id": "document_one", "text": "Here is some hidden value 1000"}] await collection.upsert_documents(documents) # Search over our collection results = await collection.vector_search( { "query": { "fields": { "text": {"query": "What is the hidden value?"}, }, }, "limit": 5, }, pipeline, ) print(results)

这段示例展示了 1.0 SDK 的"声明式流水线"设计:你只需要告诉 Pipeline"对text字段先用recursive_character切分器切块,再用Alibaba-NLP/gte-base-en-v1.5模型生成语义向量",剩下的建表、建索引、切块、嵌入、检索全部由 SDK 自动完成。

从源码看 Collection 与 Pipeline 的实现

在 pgml-sdks/pgml/src/collection.rs 中,Collection::new会校验集合名只能包含字母、数字、空白、-与_,并据此生成<name>.pipelines与<name>.documents两张表名;集合本身在数据库中对应pgml.collections表,并与pgml.projects项目记录关联,创建时还会写入SDK_VERSION(当前源码中为"1.0.0",见 pgml-sdks/pgml/src/lib.rs)用于版本兼容性管理。

再看add_pipeline的调用链(pgml-sdks/pgml/src/collection.rs),其内部流程是:

  1. 若 Collection 尚不存在则先创建它;
  2. 在pipelines表中以ACTIVE = TRUE写入 Pipeline 记录;
  3. 立即对 Pipeline 执行一次resync——删除旧的 chunks、embeddings、tsvectors 并按新 schema 重建。

也就是说,"把 Pipeline 加进 Collection"这个动作本身就触发了对已有文档的首次索引构建,这与公告中"Pipeline 自动编排摄入、切分、嵌入、索引"的描述完全吻合。

Pipeline schema 的字段级配置

Pipeline 的 schema 按"文档字段"(field)维度组织,每个字段可以配置三类动作(见 pgml-sdks/pgml/src/pipeline.rs):

配置项作用关键子参数
splitter文本切分model(如recursive_character)、parameters(如chunk_size、chunk_overlap)
semantic_search语义向量化model(HuggingFace 模型名)、parameters(如prompt)、source(本地/远程)、hnsw
full_text_searchPostgreSQL 全文检索configuration(如english)

其中semantic_search的hnsw参数可以自定义 HNSW 向量索引的构建参数,默认值为m = 16、ef_construction = 64(见 pgml-sdks/pgml/src/pipeline.rs)。在 pgml-sdks/pgml/src/lib.rs 的can_specify_custom_hnsw_parameters_for_pipelines测试中,可以看到传入"hnsw": {"m": 100, "ef_construction": 200}后,SDK 生成的索引定义正是CREATE INDEX ... USING hnsw (embedding vector_cosine_ops) WITH (m='100', ef_construction='200')——索引参数完全透传到 PostgreSQL。

切分器的默认模型是recursive_character(pgml-sdks/pgml/src/splitter.rs),未指定时自动使用;在 pgml-sdks/pgml/src/lib.rs 的测试can_add_pipeline_and_upsert_documents中,一个带chunk_size: 1000、chunk_overlap: 40参数的 Pipeline 会把 2 个文档的body字段切出 12 个 chunk,并同步生成 12 行 tsvector,验证了切分与全文索引的联动行为。

揭开魔术的面纱:vector_search 背后的 SQL

SDK 的封装看似"魔术",但公告特意强调:你看到的每次搜索,底层都是一段可审计的 SQL。上面vector_search调用实际生成的 SQL 如下:

WITH "pipeline" ( "schema" ) AS ( SELECT "schema" FROM "my_collection"."pipelines" WHERE "name" = 'my_pipeline' ), "text_embedding" ( "embedding" ) AS ( SELECT pgml.embed (transformer => ( SELECT SCHEMA #>> '{text,semantic_search,model}' FROM pipeline), text => 'What is the hidden value?', kwargs => '{}') AS "embedding" ) SELECT "document", "chunk", "score" FROM ( SELECT 1 - (embeddings.embedding <=> ( SELECT embedding FROM "text_embedding")::vector) AS score, "documents"."id", "chunks"."chunk", "documents"."document" FROM "my_collection_my_pipeline"."text_embeddings" AS "embeddings" INNER JOIN "my_collection_my_pipeline"."text_chunks" AS "chunks" ON "chunks"."id" = "embeddings"."chunk_id" INNER JOIN "my_collection"."documents" AS "documents" ON "documents"."id" = "chunks"."document_id" ORDER BY embeddings.embedding <=> ( SELECT embedding FROM "text_embedding")::vector ASC LIMIT 5) AS "s" ORDER BY "score" DESC LIMIT 5

这段 SQL 有几点值得拆解:

  • 查询文本的嵌入是在数据库内部完成的:pgml.embed(...)直接从pipelines表的 JSONB schema 中取出{text,semantic_search,model}对应的模型名(Alibaba-NLP/gte-base-en-v1.5),对查询串在线生成向量,全程不离开数据库;
  • 相似度用余弦距离计算:1 - (embedding <=> query_embedding)把 PgVector 的余弦距离换算成相似度分数score;
  • 三表 JOIN:text_embeddings(向量)→text_chunks(文本块)→documents(原始文档),搜索结果自然包含命中的 chunk 文本与完整 document。

关于冗余 LIMIT 的说明:这段 SQL 是程序化生成的,设计目标是为了兼容"一个查询搜索多个字段"的场景。因此在单字段情况下你会看到一次多余的排序与 LIMIT。公告明确指出:它对这个查询的速度没有实质性影响。

这套"查询生成器"的实现位于 pgml-sdks/pgml/src/vector_search_query_builder.rs(向量搜索)与 pgml-sdks/pgml/src/search_query_builder.rs(混合搜索)。在 pgml-sdks/pgml/src/collection.rs 的vector_search方法中,SDK 会执行生成好的 SQL,并把结果组装为{document, chunk, score, rerank_score}四个字段的 JSON 数组返回。

三种搜索模式与过滤能力

公告列举了 1.0 SDK 的搜索能力:语义搜索、全文搜索、混合搜索,以及基于额外元数据的丰富过滤。对应到源码,Collection上同时提供search(可混合多字段多模式)与vector_search(纯向量召回)两条入口。

在 pgml-sdks/pgml/src/lib.rs 的测试can_search_with_local_embeddings中可以看到混合搜索的完整 query 形态:

{ "query": { "full_text_search": { "title": { "query": "test 9", "boost": 4.0 }, "body": { "query": "Test", "boost": 1.2 } }, "semantic_search": { "title": { "query": "This is a test", "parameters": { "prompt": "query: " }, "boost": 2.0 }, "body": { "query": "This is the body test", "parameters": { "prompt": "query: " }, "boost": 1.01 } }, "filter": { "id": { "$gt": 1 } } }, "limit": 5 }

要点:

  • 逐字段配置:full_text_search与semantic_search可以作用于不同的字段,各自的 query 独立书写;
  • boost 加权:每个字段的查询可以设置boost权重,用于调整混合打分中各路信号的贡献比例;
  • 元数据过滤:顶层filter使用$gt、$eq等操作符对文档元数据做条件过滤,其底层实现是 pgml-sdks/pgml/src/filter_builder.rs 中的FilterBuilder,会把 JSON 过滤条件翻译成 SQL WHERE 子句;
  • 结果可追溯:混合搜索会在数据库中写入searches与search_results表,记录每次搜索的 query 与排序后的结果列表,并可通过add_search_event(pgml-sdks/pgml/src/collection.rs)记录点击等行为事件,为后续的效果监控与调优留好数据。

向量搜索(vector_search)同样支持full_text_filter、boost、字段级parameters(如 query 侧的prompt前缀)以及document.keys(只返回文档的指定字段,测试见 pgml-sdks/pgml/src/lib.rs)。

打开调试日志,看见每一次 SQL

SDK 运行时的每一次数据库查询都是透明的。公告给出了开启 DEBUG 日志的方法,Python 与 JavaScript 写法一致:

pgml.init_logger("DEBUG");
pgml.init_logger("DEBUG")

在源码层面,init_logger的实现位于 pgml-sdks/pgml/src/lib.rs,其日志级别映射为TRACE/DEBUG/INFO/WARN/ERROR(未识别时默认ERROR),输出格式可选Pretty(默认)或Json。除代码传参外,还支持通过环境变量LOG_LEVEL与LOG_FORMAT控制,方便在容器或生产环境中直接配置,无需改动代码。

当你把日志级别开到 DEBUG 时,就能看到 SDK 实际执行的每一条 SQL——包括建表语句、切块/嵌入的同步语句、搜索的 CTE 查询等,这既是排查问题的利器,也是理解"一切皆 SQL"这一理念的最直观方式。

用 ER 图看清你的 Collection

"It's all SQL!" 意味着 Collection 的每一个组成部分在数据库里都是真实可查的表。公告展示了如何直接打印 Collection 与 Pipeline 的实体关系图:

console.log(await collection.generate_er_diagram(pipeline));
print(await collection.generate_er_diagram(pipeline))

上述代码会输出一段PlantUML 脚本,将其粘贴到 PlantUML 在线解释器中即可渲染出关系图。

在 pgml-sdks/pgml/src/collection.rs 的generate_er_diagram实现中,可以看到这张图实际上就是 SDK 在数据库里创建的表结构全景:

  • pgml.collections:集合主表(id、created_at、name、active、project_id、sdk_version);
  • <collection>.documents:文档表(id、source_uuid、documentJSONB);
  • <collection>.pipelines:流水线表(name、active、schemaJSONB);
  • <collection>_<pipeline>.<field>_chunks:切分后的文本块表(document_id、chunk_index、chunk);
  • <collection>_<pipeline>.<field>_embeddings:向量表(chunk_id、embeddingvector),仅在字段配置了semantic_search时生成;
  • <collection>_<pipeline>.<field>_tsvectors:全文检索向量表(chunk_id、tsvector),仅在字段配置了full_text_search时生成。

图上的表间关系(documents → chunks → embeddings / tsvectors)与搜索 SQL 中的 JOIN 链一一对应。换句话说,ER 图不只是"查看工具",它直接反映了你在 SQL 层可以如何绕过 SDK 进行自定义查询——这正是公告强调"query from it however you want"的含义。

进阶:让 1.0 SDK 在生产中更好用

除了公告中直接演示的能力,当前仓库的源码还揭示了 1.0 SDK 面向生产使用的一系列细节:

1. 批量 Upsert 与并行

upsert_documents支持两个可选参数batch_size(默认 100)与parallel_batches(默认 1),SDK 会把文档分批并用 tokio 的JoinSet并行提交事务(见 pgml-sdks/pgml/src/collection.rs)。对应测试can_add_pipeline_and_upsert_documents_with_parallel_batches(pgml-sdks/pgml/src/lib.rs)以batch_size: 2、parallel_batches: 5并行写入 20 个文档并断言了 chunk 数量。批量导入大量文档时,合理调大这两个参数能显著提升吞吐。

2. 连接与环境变量

SDK 通过环境变量PGML_DATABASE_URL(或回退到DATABASE_URL)定位数据库连接串,并以全局连接池的方式复用连接;池的规模可通过PGML_POOL_MAX_CONNECTIONS(默认 10)、PGML_POOL_MIN_CONNECTIONS(默认 0)、PGML_POOL_ACQUIRE_TIMEOUT/PGML_CHECKOUT_TIMEOUT(默认 30000 毫秒)、PGML_POOL_MAX_LIFETIME、PGML_POOL_IDLE_TIMEOUT等变量调优(见 pgml-sdks/pgml/src/lib.rs)。在 pgml-sdks/pgml/python/README.md 的快速开始中,第一步就是设置DATABASE_URL指向 PostgresML 数据库。

3. 流水线生命周期管理

除add_pipeline之外,Collection 还提供remove_pipeline(删除流水线并级联删除其 schema)、enable_pipeline/disable_pipeline(激活/停用流水线,停用期间 upsert 的文档不会生成 chunk 与向量,重新启用时会自动补齐),以及get_pipeline_status查看每个字段的 chunks / embeddings / tsvectors 的同步进度(synced、not_synced、total)。对应的测试disable_enable_pipeline与pipeline_sync_status位于 pgml-sdks/pgml/src/lib.rs。

4. 版本迁移

SDK 版本间的变化并不保证完全向后兼容,因此提供migrate()函数(Python 中为from pgml import migrate; await migrate(),见 pgml-sdks/pgml/src/lib.rs 与 pgml-sdks/pgml/python/README.md 的 Upgrading 一节),它会把所有 Collection 迁移到与当前 SDK 兼容的结构,升级 SDK 后应执行一次。

5. 目录与文件摄入

upsert_directory支持按file_types(如['md', 'txt'])、file_batch_size(默认 10)、follow_links、ignore_paths(正则)批量摄入目录下的文件,upsert_file则可摄入单个文件(pgml-sdks/pgml/src/collection.rs),非常适合把本地知识库一键倒入 Collection,作为 RAG 应用的数据底座。

总结

PostgresML 1.0 SDK 的意义不在于"又一个客户端库",而在于它把搜索应用的全部复杂度——表管理、文本切分、向量化、索引构建、混合排序——收敛为"Collection + Pipeline"两个高层抽象,并且每一层都保持 SQL 级透明:

  • 上手快:Python 与 JavaScript 两套 API 语义一致,声明式 Pipeline 让建索引变成几行配置;
  • 能力全:语义搜索、全文搜索、混合搜索、元数据过滤、HNSW 参数透传、批量并行 upsert 一应俱全;
  • 可审计:DEBUG 日志输出全部 SQL,ER 图展示真实表结构,搜索事件落库,为调优与监控留足数据;
  • 本地化:嵌入与检索都在 PostgreSQL 内部完成,不依赖外部网络调用。

如果你正准备在自有 PostgreSQL 上搭建向量搜索或 RAG 应用,可以按 pgml-sdks/pgml/python/README.md 的快速开始跑通第一个例子,并用本文提到的init_logger("DEBUG")与generate_er_diagram深入观察 SDK 在数据库里做了什么——你会发现,所谓"魔术",不过是一套组织良好的 SQL。

  • 后端
  • 人工智能
  • 机器学习
  • RAG
  • 向量数据库

【免费下载链接】postgresml

Postgres with GPUs for ML/AI apps.

项目地址:https://gitcode.com/gh_mirrors/po/postgresml
点击查看免费下载
上一篇:2025新范式:gh_mirrors/co/comparator实现PHP复杂数据类型精准对比
下一篇:ts-jest测试代码审查清单:确保测试质量的检查要点

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 22:00:33

在 Kotlin(Android)中使用 Xberg 递归提取 URL 文档链接

后端AI 应用NLP 【免费下载链接】xberg Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with …

作者头像 李华
网站建设 2026/10/19 22:00:33

pyprobml 软件学习路线指南:Python、ML 工具链与开发环境选型

机器学习深度学习 【免费下载链接】pyprobml Python code for "Probabilistic Machine learning" book by Kevin Murphy 项目地址&#xff1a; https://gitcode.com/gh_mirrors/py/pyprobml 点击查看 免费下载 本文是 pyprobml 项目&#xff08;《Probabilistic Mac…

作者头像 李华