The native RAG is part of thenative AI integrated into the Aurabasebackend, alongside NL2SQL: not a third-party service to be assembled on top of a general base. Prerequisites to follow this tutorial: an existing Aurabase project, a configured LLM provider (OpenAI or Google Gemini for embeddings, one of the three native providers for generation), and a project API key.
- Aurabase RAG 管道包含两个调用:
ragIngest()用于索引文档,rag()用于查询并生成响应。分块、嵌入和向量搜索在服务器端进行管理。 - 在底层,它是标准的 PostgreSQL 和 pgvector:一个
embeddings表,每个维度类(768、1536、3072)有一个向量列,每个类有一个部分 HNSW 索引。 - 分块使用真正的分词器 (
tiktokeno200k),具有可配置的重叠和大型文档的防爆防护装置。 - 检索到的内容在注入提示之前会被中和:尝试转义其标签以欺骗系统指令的文档会被明确地化解。
- 只有 OpenAI 和 Gemini 在 Aurabase 端生成嵌入。 Anthropic/Claude 没有公共嵌入 API,它仍然保留用于生成最终响应。
RAG 管道的工作原理
该管道分五个阶段进行。摄取后,文本被分割,每个块被批量矢量化然后存储。查询时,与余弦相似度存储的块进行比较,依次对问题进行向量化,并将最接近的片段注入到发送到生成模型的提示中。
分块(tiktoken)→嵌入(批量)→pg向量存储(HNSW)→相似性搜索→增强生成
在生产中很重要的架构细节:在对嵌入或生成提供程序的网络调用期间不保留 Postgres 连接。 DB 事务在外部调用之前关闭,并在外部调用之后重新打开,以免因第三方网络延迟而阻塞共享 PgBouncer 后端。
创建项目
与典型的自托管 pgvector 不同,您不需要运行 CREATE EXTENSION vector 或自己为此管道创建表。创建项目时会自动配置项目的 embeddings 架构及其向量列和 HNSW 索引。
嵌入提供程序在项目端配置一次(Studio→IA→供应商)。正是这个提供程序决定了向量的有效维度,因此决定了 embeddings表上使用的列。
使用 ragIngest() 索引您的文档
一次调用就足以索引文档:文本被分成块,每个块被向量化,然后存储在请求的命名空间中。拆分使用真正的分词器(tiktoken,编码 o200k_base),而不是简单的按空格拆分,这在没有空格的文本(如某些亚洲语言)上保持正确。
在原始 HTTP 中,等效路由是 POST /v1/ai/{project_id}/rag/ingest,由项目的 API 密钥进行身份验证。
默认情况下,摄取是幂等的:自动派生文档标识符(内容的 SHA-256 哈希值,或 metadata.document_id 如果您提供)。重新摄取相同的内容会替换其现有的块,而不是复制它们,从而使定期同步作业可以安全地重播。
实际落在 Postgres 中的是什么
这里没有专有魔法:接收向量的表是一个普通的 Postgres 表,每个维度类有一个 vector 列,每列有一个部分 HNSW 索引(仅在填充它的行上有效)。这是它的真实定义,经过简化:
每次搜索都会将向量与余弦距离运算符 (<=>) 进行比较,余弦距离运算符是索引的 vector_cosine_ops 和 halfvec_cosine_ops 运算符类的目标运算符。有关 HNSW 与 IVFFlat 的召回/延迟权衡的详细信息,请参阅 专门用于 HNSW 索引的文章。对于嵌入维度本身的选择,请参阅 比较 768 vs 1536 vs 3072。
使用 rag() 查询并生成响应
在查询方面,rag() 将问题的矢量化、命名空间中的相似性搜索、增强提示的构建以及对生成模型的调用链接到客户端的单个网络往返中。
响应携带生成的响应及其来源,以及实际使用的提供者:
检索到的内容永远不会原始注入到系统提示符中。这是不可靠的数据(用户上传、索引页面):包含例如结束部分标记和后跟错误指令的文档在组装之前被中和,其尖括号被括号替换,文本被保留但结构被消除。
如果 rag() 没有找到任何内容,即使您的命名空间不为空,响应也会带有明确的警告,而不是误导性的沉默:您的语料库可能在另一个模型或另一个嵌入维度下建立了索引。通过 POST /v1/ai/{project_id}/rag/{namespace}/reindex重新索引它。
来自 LangChain 和手工制作的 pgvector:发生了什么变化
如果您已经使用 LangChain 在 PostgreSQL 上构建了 RAG 聊天机器人,则每个手动块都有一个服务器端管理的等效项,无需更改底层数据库。
| 分解文本 | RecursiveCharacterTextSplitter 自己设置 | ragIngest():集成tiktoken分块,默认512个token/64个重叠 |
|---|---|---|
| 嵌入 | 手动调用OpenAIEmbeddings,批量限制管理 | 自动批量、内置瞬态重试 |
| 矢量存储 | pgvector表+HNSW索引自行创建和迁移 | 每个项目配置的架构和索引 |
| 搜索+提示 | PGVector.similarity_search() 然后手动组装提示 | rag():一次调用即可搜索和增强生成 |
| 恢复的内容 | 按照提示注入 | 装配前自动中和结构标签 |
您是否正在使用这种手动组装迁移基于 Supabase 构建的现有项目?后端其余部分(架构、RLS 策略、SDK)的迁移逻辑包含在我们的 Supabase 到 Aurabase 迁移指南中。
投入生产前需要注意的设置和限制
三个设置直接影响成本和延迟,全部在 aura-ai服务代码中进行验证。默认情况下,瞬态嵌入调用(网络故障、提供程序错误 429)的尝试次数为 3 次,基本退避时间为 100 毫秒。默认情况下,大型文档嵌入到限制为 2048 个块的子批次中,以尊重供应商的 API 上限,而不会在单个大型文档上失败。护栏(默认情况下为 10,000 个块,可配置)明确拒绝摄取会产生异常数量块的文档。
在搜索方面,HNSW 候选列表的大小会自动调整为 max(64, top_k × 4):您请求的结果越多,索引探索的候选者就越多,以保留召回率。如果您的语料库具有特定的配置文件,则仍然可以通过环境变量获得固定值。
不同模型的向量空间永远不会相互比较:每次搜索仍然仅限于当前的嵌入模型,并且更改模型需要显式重新索引,而不是静默切换,这会破坏结果的一致性。
需要注意的当前限制
嵌入维度必须属于三个受支持的类别之一:768、1536 或 3072。返回另一个维度的提供程序会被拒绝并出现显式错误,并且不会被截断或静默转换。
嵌入生成只能通过 OpenAI 或 Google Gemini 在三个本地提供商中使用:Anthropic/Claude 不公开公共嵌入 API,因此它仅用于在此管道中生成最终响应,从不用于矢量化。
JavaScript SDK 尚未公开 rag() 调用上的 top_k 和 threshold 覆盖:它们仍然可以通过直接 HTTP 访问,分别限制为 [1, 50] 和 [0, 1],但不能像现在一样从 aura.ai.rag() 访问。默认的相似度阈值(0.3)是故意允许的;将其缩小到密集的语料库,以避免提示中出现不相关的来源。
为了走得更远
RAG 涵盖有关非结构化内容(文档、注释、票据)的问题。对于有关关系数据的问题,Aurabase 的本机 NL2SQL 直接将问题转换为经过验证的 SQL。上面提到的 HNSW 参数和维度类的详细信息,请参见 HNSW 索引 和 嵌入维度比较的文章。完整的 API 参考仍然是 RAG 和 pgvector 文档 和 AI Gateway 文档。