ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

rig-postgres 演进全解:用 Rust 与 pgvector 构建 PostgreSQL 向量存储

rig-postgres 演进全解:用 Rust 与 pgvector 构建 PostgreSQL 向量存储 AI AgentAgent 框架RAG后端【免费下载链接】rig⚙️ Build modular and scalable LLM Applications in Rust项目地址https://gitcode.com/GitHub_Trending/rig2/rig点击查看免费下载导读rig-postgres 是 Rig 生态中专为 PostgreSQL 打造的向量存储集成 crate它借助 pgvector 扩展把文档嵌入向量直接存放在 PostgreSQL 表中并复用 rig-core 的VectorStoreIndex接口完成插入、检索与过滤。本文以crates/rig-postgres/CHANGELOG.md的版本演进为主线结合crates/rig-postgres/README.md、crates/rig-postgres/src/lib.rs源码与测试完整呈现该组件的配置方式、SQL 渲染原理、过滤算子体系与历次破坏性变更读完即可在自己的 Rust 项目中完成 PostgreSQL 向量库的搭建、写入与语义检索。一、组件定位Rig 生态中的 PostgreSQL 向量存储rig-postgres 从 0.1.02025-01-27postgres vector store integration一路演进到当前工作区统一版本 0.42.0始终承担同一职责把 Rig 的文档嵌入结果持久化到 PostgreSQL并在其上执行相似度检索。仓库根目录Cargo.toml将rig作为工作区汇聚 craterig-postgres位于 crates/rig-postgres其定位在源码文档字符串中写得很清楚PostgresVectorStoresearches a table holding apgvectorembedding column using aPgVectorDistanceFunctionand optionalPgSearchFilterconditions。见 crates/rig-postgres/src/lib.rs它实现 rig-core 的VectorStoreIndex与InsertDocuments两个 trait因此对上层 API 完全透明——无论是top_n还是insert_documents调用方式与其他向量存储保持一致。使用前需要在Cargo.toml同时引入 rig-core 与 rig-postgres[dependencies] rig-core 0.42.0 rig-postgres 0.42.0也可以直接运行cargo add rig-core rig-postgres获取最新版本。二、环境准备PostgreSQL 与 pgvector 扩展该 crate 依赖 pgvector 扩展其官方支持 PostgreSQL 13 及更高版本CHANGELOG 中 0.40.0 也记录了升级 sqlx 与 pgvector 依赖的维护动作。最省事的启动方式是使用 Docker 运行带 pgvector 的镜像docker pull pgvector/pgvector:pg17 docker run -e POSTGRES_USERmyuser \ -e POSTGRES_PASSWORDmypassword \ -e POSTGRES_DBmydatabase \ --name my_postgres \ -p 5432:5432 \ -d ankane/pgvector之后声明连接串export DATABASE_URLpostgres://myuser:mypasswordlocalhost:5432/mydatabase建表推荐使用 sqlx migrations 管理。仓库中 crates/rig-postgres/examples/migrations/001_setup.sql 提供了可直接复制的初始 SQL-- ensure extension is installed CREATE EXTENSION IF NOT EXISTS vector; -- create table with embeddings using 1536 dimensions (text-embedding-3-small) CREATE TABLE documents ( id uuid DEFAULT gen_random_uuid(), -- we can have repeated entries document jsonb NOT NULL, embedded_text text NOT NULL, embedding vector(1536) ); -- create index on embeddings CREATE INDEX IF NOT EXISTS document_embeddings_idx ON documents USING hnsw(embedding vector_cosine_ops);字段语义如下id文档唯一标识gen_random_uuid()保证同一文档可重复入库document完整的文档 JSONjsonb检索时反序列化为自定义类型embedded_text被嵌入的原始文本便于追溯embeddingpgvector 向量列维度必须与所用嵌入模型一致示例按 OpenAItext-embedding-3-small的 1536 维配置。表名与维度可以调整但四列的结构需要保持。索引策略随距离函数变化文本嵌入推荐vector_cosine_ops的 HNSW 索引若改用其他距离度量可参考 pgvector 文档选择对应的 ops 类。注意 HNSW 索引建在 embedding 列上实际检索 SQL 由PostgresVectorStore在运行时拼接。三、文档建模Embed派生与多字段嵌入要入库的文档结构需要同时实现Embed、Serialize、Deserialize。Embed由 rig-core 的 derive 宏提供rig-postgres 的Cargo.toml中rig-core依赖显式开启了derivefeature#[derive(Embed, Clone, Serialize, Deserialize, Debug)] pub struct Product { name: String, category: String, #[embed] description: String, price: f32 }用#[embed]标注的字段会参与嵌入生成。值得注意的是同一张表可以混合存放不同类型的文档只要都能序列化README 中对此有明确说明。示例 crates/rig-postgres/examples/vector_search_postgres.rs 还演示了一个进阶技巧对不需要落库、仅用于生成嵌入的字段可以同时加#[serde(skip)]与#[embed]让该字段既不序列化进document列、又参与向量生成#[derive(Embed, Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Default)] struct WordDefinition { id: String, word: String, #[serde(skip)] // we dont want to serialize this field, we use only to create embeddings #[embed] definitions: VecString, }四、向量化与入库EmbeddingsBuilder到insert_documents完整的写入链路分为三步构建嵌入 → 初始化向量存储 → 插入。// OpenAI 的嵌入模型构建器与存储各持有一份克隆 let model rig::providers::openai::OpenAI::from_env()? .embedding(rig::providers::openai::TEXT_EMBEDDING_3_SMALL, None) .erase(); // 连接 PostgreSQL let database_url std::env::var(DATABASE_URL).expect(DATABASE_URL not set); let pool PgPoolOptions::new().connect(database_url).await?; // 运行迁移可选但推荐 sqlx::migrate!(./migrations).run(pool).await?; // 批量向量化 let documents EmbeddingsBuilder::new(model.clone()) .documents(products) .unwrap() .build() .await?; // 初始化向量存储默认使用 cosine 距离、documents 表 let vector_store PostgresVectorStore::with_defaults(model, pool); // 入库 vector_store.insert_documents(documents).await?;从源码看crates/rig-postgres/src/lib.rsinsert_documents对每个文档生成Uuid::new_v4()把文档序列化为 jsonb并逐条执行参数化 INSERT$1id、$2document、$3embedded_text、$4embedding。因此一张表可以容纳同一个文档的多条嵌入记录对应建表注释中 we can have repeated entries 的设计意图。PostgresVectorStore有两个构造入口crates/rig-postgres/src/lib.rsnew(model, pool, documents_table: OptionString, distance_function)完全定制documents_table传None时回落到默认表名documentswith_defaults(model, pool)等价于new(.., None, PgVectorDistanceFunction::Cosine)即默认 cosine 距离。需要提醒的是检索必须使用与入库相同的嵌入模型——CHANGELOG 与源码注释均强调结果仅在相同模型下才有意义。五、距离函数与检索请求VectorSearchRequest全配置检索入口是 rig-core 的VectorSearchRequest构建器可用配置项包括配置项说明query检索查询文本必填samples返回结果数量上限必填对应 SQL 中LIMIT $2filterPgSearchFilter过滤条件threshold最小相似度阈值低于该值的候选会被排除典型调用let req VectorSearchRequest::builder() .query(Which phones have more than 16Gb and support 5G) .samples(50) .build(); let results vector_store.top_n::Product(req).await?;top_n返回Vec(f64, String, T)即(距离, id, 反序列化后的文档)按距离升序排列top_n_ids则只返回(距离, id)跳过文档反序列化见 crates/rig-postgres/src/lib.rs。5.1 距离函数与相似度表达式的换算PgVectorDistanceFunction枚举映射到 pgvector 运算符crates/rig-postgres/src/lib.rs枚举值SQL 运算符适用场景L2-欧氏距离InnerProduct#内积Cosine余弦距离默认L1曼哈顿距离Hamming~二值向量汉明距离Jaccard%二值向量 Jaccard 距离其中 Hamming 与 Jaccard 面向二值向量且除 L2、内积、余弦外其余算子需要 pgvector 0.7 及以上版本。为了让threshold最小相似度语义统一score_expressioncrates/rig-postgres/src/lib.rs对余弦与 Jaccard 使用1 - distance对其余算子使用-distance取负使值越大越相似从而可以用统一的score $n作为过滤条件。5.2samples的上限约束run_searchcrates/rig-postgres/src/lib.rs在构造 SQL 前会校验req.samples() i64::MAX超限直接返回VectorStoreError::BuilderError。这是因为该值最终以i64绑定到LIMIT $2这也是集成层针对 PostgreSQL 特有约束做的防御性处理。六、PgSearchFilter过滤算子体系与 SQL 渲染原理0.1.25 版本引入了后端特定的向量搜索过滤器add backend specific vector search filters随后 0.1.30 又做了filter ergonomics改进。经过 0.42.0 的重构PgSearchFilter现在是rig_core::vector_store::request::SqlConditionserde_json::Value的 newtype见 crates/rig-postgres/src/lib.rs构造器不变但序列化格式跟随内部类型变化详见第八节。6.1 构造器速查PgSearchFilter提供以下构造器crates/rig-postgres/src/lib.rs构造器SQL 语义说明eq(key, value)key value相等gt(key, value)key value大于lt(key, value)key value小于gte(key, value)key value大于等于lte(key, value)key value小于等于is_null(key)key is null空值判断is_not_null(key)key is not null非空判断between(key, range)key between lo and hi闭区间member(key, values)key IN (v1, v2, ...)枚举匹配like(key, pattern)key like pattern大小写敏感 LIKEpattern需自带引号similar_to(key, pattern)key similar to patternSQL SIMILAR TOpattern需自带引号not(self)NOT (...)逻辑取反组合方式上SearchFiltertrait 提供了and/or两个组合方法。between、like、similar_to、is_null、is_not_null属于raw类条件键名、模式与区间边界会逐字拼入 SQL只有普通二元条件eq/gt/lt/gte/lte/member的值走参数绑定。因此使用 raw 类构造器时pattern必须自带 SQL 引号且任何拼接片段都不能携带不可信输入。6.2$占位符修复0.42.0 的关键 bug 故事CHANGELOG 0.42.0 记录了一个非常典型的参数绑定缺陷Fixed小节gte、lte、member三个构造器曾经把占位符渲染成?而eq、gt、lt渲染成$。查询渲染阶段的占位符重编号只遍历$开头的占位符——该遍历从$3开始编号$1是查询向量$2是 sample 数——因此用三个有问题的构造器构建的过滤器会带着字面的?到达 PostgreSQL例如id is in (?,?)而值仍然按位置绑定导致语句被服务器判定为格式错误而不是返回错误行。修复方式是把所有构造器统一收口到共享的SqlCondition渲染路径让占位符令牌只在单一位置产生。crates/rig-postgres/src/tests.rs中新增的every_parameterised_operator_uses_dollar_placeholders测试crates/rig-postgres/src/tests.rs断言整个渲染结果gte(5).and(lte(10))渲染为(price $) AND (price $)且$的数量与绑定值数量严格一致。这套测试同时覆盖了多个相关回归点single_condition_filter_renders_where_with_separator单个条件正确渲染WHERE (price $3)修复了WHERE condition拼出WHEREprice的问题member_filter_renders_sql_inmember正确渲染id IN ($3, $4)而不是非法的id is in (...)threshold_renders_minimum_similarity_per_distance_function六种距离函数各自生成正确的相似度表达式如余弦为1 - (embedding $1) $3threshold_and_compound_filter_number_parameters_in_bind_order阈值先绑定占$3过滤器占位符从$4续编且$1查询向量在相似度表达式中不被重编号outer_query_orders_by_distance_and_limits_on_second_parameter外层查询仍按原始距离升序排列并以$2绑定 LIMIT。6.3 检索 SQL 的完整形状综合源码crates/rig-postgres/src/lib.rs一次带阈值与过滤器的检索渲染为两层查询SELECT id, document, distance FROM ( SELECT DISTINCT ON (id) id, document, embedding op $1 as distance FROM documents WHERE (1 - (embedding $1) $3) AND ((kind $4) AND (id IN ($5, $6))) ORDER BY id, distance ) as d ORDER BY distance LIMIT $2设计要点阈值条件必须放进内层SELECT因为distance只是 select-list 别名外层不可见DISTINCT ON (id)配合ORDER BY id, distance保证同一文档只保留距离最近的一条嵌入返回给调用方的仍是原始距离升序阈值过滤只影响候选集合不影响返回值的语义。七、检索调用组合示例把过滤与阈值组合进真实查询use rig_postgres::PgSearchFilter; let filter PgSearchFilter::eq(category, serde_json::json!(electronics)) .and(PgSearchFilter::gte(price, serde_json::json!(500))); let req VectorSearchRequest::builder() .query(wireless noise-cancelling headphones) .samples(20) .filter(filter) .threshold(0.75) .build(); let results vector_store.top_n::Product(req).await?;八、0.42.0 破坏性变更序列化与签名迁移CHANGELOG 0.42.0 还列出了两项破坏性变更Changed小节升级时需要同步调整代码PgSearchFilter成为SqlConditionserde_json::Value的 newtype。字段原本是私有的{ condition, values }结构构造器不变但派生的Serialize/Deserialize跟随内部类型序列化后的过滤器把绑定列表从values改名为params。任何持久化或日志中依赖旧字段名的代码需要更新。InsertDocuments::insert_documents签名改为Vec(Doc, VecEmbedding)。此前是Vec(Doc, OneOrManyEmbedding)跟随 rig-core 移除非空容器OneOrManyT的全局动作仓库 MIGRATING.md 中 OneOrManyTis gone; lists areVecT 一节给出了完整迁移表OneOrMany::one(x)→vec![x]OneOrMany::many(xs)→Vec本身merge→flatten。这属于源码级签名变更序列化后的嵌入数据不受影响。此外 0.42.0 还进行了工作区范围的代码精简LOC consolidation净删数千行并同步校准了迁移指南与 CHANGELOG保证文档与合并结果一致。九、版本演进时间线一览对照 crates/rig-postgres/CHANGELOG.md可以清晰看到该组件的能力成长脉络版本时间关键内容0.1.02025-01首次发布PostgreSQL 向量存储集成0.1.102025-07支持以 trait 方式插入文档0.1.132025-07引入向量存储索引请求结构体0.1.142025-08向量搜索支持余弦相似度0.1.252025-11增加后端特定向量搜索过滤器0.1.262025-12统一 provider client 与模型/Agent 初始化方式0.1.282025-12crate 重组0.1.302026-01改进向量存储文档与过滤器易用性breaking修复 JSON 值绑定0.38.12026-06工作区统一 crate 版本0.40.02026-07升级 sqlx 与 pgvector 依赖0.42.02026-08修复$占位符缺陷PgSearchFilternewtype 化OneOrMany→Vec中间多个版本0.1.20.2.x 系列以跟随 rig-core 更新为主体现该 crate 与核心库的紧密耦合。整体上rig-postgres 的能力演进遵循先有基础存储 → 增加过滤器 → 完善距离函数与易用性 → 统一序列化契约的路径0.42.0 之后的实现已把 SQL 渲染的各个细节占位符、阈值语义、参数编号全部纳入测试保护。十、进阶阅读路径想进一步深入可以在仓库中依次查看crates/rig-postgres/README.md官方使用说明与配置总览crates/rig-postgres/src/lib.rsPostgresVectorStore、PgVectorDistanceFunction、PgSearchFilter与 SQL 渲染的完整实现crates/rig-postgres/src/tests.rsSQL 渲染的逐算子回归测试是理解参数编号与阈值语义的最佳入口crates/rig-postgres/examples/vector_search_postgres.rs从迁移、建表、向量化到检索的端到端可运行示例crates/rig-postgres/examples/migrations/001_setup.sql可直接落库的初始化 SQLMIGRATING.md涉及PgSearchFilter、OneOrMany等破坏性变更的官方迁移对照表。需要说明的是本组件的能力边界取决于 PostgreSQL 与 pgvector 的实际部署版本HNSW 索引质量、非默认距离算子L1、Hamming、Jaccard的可用性都受服务端 pgvector 版本约束生产环境建议先核对版本再启用对应特性。赞分享AI AgentAgent 框架RAG后端【免费下载链接】rig⚙️ Build modular and scalable LLM Applications in Rust项目地址https://gitcode.com/GitHub_Trending/rig2/rig点击查看免费下载相关推荐rig pgvector在 Rust 中构建基于 PostgreSQL 的向量检索实战指南rig pgvector在 Rust 中构建基于 PostgreSQL 的向量检索实战指南 本篇指南围绕 Rig 仓库中的配套 crate rig posAI AgentAgent 框架RAG后端揭秘WinAsar551KB轻量级asar文件处理神器Electron开发者的必备工具揭秘WinAsar551KB轻量级asar文件处理神器Electron开发者的必备工具 你是否正在为复杂的asar文件处理而烦恼WinAsar就是你的救星AI AgentAgent 框架RAG后端AnythingLLM PGVector支持PostgreSQL向量存储AnythingLLM PGVector支持PostgreSQL向量存储 引言 在AI应用开发中向量数据库的选择至关重要。AnythingLLM作为一款全栈人工智能AI 应用RAGAI Agent后端前端上一篇5分钟快速配置物联网开发环境vcpkg MQTT与CoAP协议库实战指南下一篇LiteLLM BI工具集成终极指南可视化分析与智能报表解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表