概览
Supabase 是一款以开源身份对标 Firebase 的强大体系,并通过 pgvector 库原生构建了向量支持。与 ModelRiver 协同工作后,不仅能够使人工智能生成的模型向量随其他常见数据库应用数据混编一同存放,并且可以借用该体系内的高性能语义搜索引擎执行基于这些信息的发文应答。一切都在这一片体系平台内。
快速上手
安装相关依赖
Bash
pip install supabase openai在 Supabase 中启用开启 pgvector
在 Supabase SQL 网页主控编辑器下挂上跑一遍这里的内容:
SQL
1-- 开通启用 pgvector 的拓展能力2create extension if not exists vector;3 4-- 创建数据落足存放并带有嵌入项存储格的数据库表5create table documents (6 id bigserial primary key,7 content text not null,8 metadata jsonb default '{}',9 embedding vector(1536), -- 需对齐您模型所挂出生成的基维度数10 created_at timestamptz default now()11);12 13-- 添加一条提升查表索引以加快查询匹配14create index on documents using ivfflat (embedding vector_cosine_ops) with (lists = 100);配置启动相关客户端口
PYTHON
1from supabase import create_client2from openai import OpenAI3 4# 导入 Supabase 大底5supabase = create_client(6 "https://YOUR_PROJECT.supabase.co",7 "YOUR_SUPABASE_ANON_KEY",8)9 10# 挂上 ModelRiver 客户端11ai = OpenAI(12 base_url="https://api.modelriver.com/v1",13 api_key="mr_live_YOUR_API_KEY",14)将嵌入数据写入数据库 (Store embeddings)
PYTHON
1def store_document(content: str, metadata: dict = {}):2 """利用 ModelRiver 将内容转为嵌入式并保存进 Supabase。"""3 # 抽取并生成文档项的表示向量4 response = ai.embeddings.create(5 model="my-embedding-workflow",6 input=[content],7 )8 embedding = response.data[0].embedding9 10 # 给其入库写档至 Supabase 中11 supabase.table("documents").insert({12 "content": content,13 "metadata": metadata,14 "embedding": embedding,15 }).execute()16 17# 测试将文本保存18store_document("ModelRiver routes AI requests across providers.", {"source": "docs"})19store_document("Workflows configure provider and fallback settings.", {"source": "docs"})20store_document("Structured outputs guarantee JSON compliance.", {"source": "docs"})语义检索大搜底以及 RAG 系统实现 (Semantic search + RAG)
首先需要在上端 Supabase 创建建立一个对应远程程序查问搜索函数模块:
SQL
1-- Supabase SQL 编辑器中运行2create or replace function match_documents(3 query_embedding vector(1536),4 match_count int default 5,5 match_threshold float default 0.76)7returns table (id bigint, content text, metadata jsonb, similarity float)8language plpgsql9as $$10begin11 return query12 select13 documents.id,14 documents.content,15 documents.metadata,16 1 - (documents.embedding <=> query_embedding) as similarity17 from documents18 where 1 - (documents.embedding <=> query_embedding) > match_threshold19 order by documents.embedding <=> query_embedding20 limit match_count;21end;22$$;编写基于 Python 的实现请求
PYTHON
1def ask(question: str, top_k: int = 3) -> str:2 """结合语义查询搜索内容以及 AI 在基础层作发文生应答。"""3 # 让此要问查询出的结果向量表示大化4 query_embedding = ai.embeddings.create(5 model="my-embedding-workflow",6 input=[question],7 ).data[0].embedding8 9 # 去叫寻 Supabase 并取搜索果实10 results = supabase.rpc("match_documents", {11 "query_embedding": query_embedding,12 "match_count": top_k,13 }).execute()14 15 # 排版结为关联查询大语料文字环境背景16 context = "\n\n".join([r["content"] for r in results.data])17 18 # 输生成最结尾的发话终落响应回应19 response = ai.chat.completions.create(20 model="my-chat-workflow",21 messages=[22 {"role": "system", "content": f"依据语境下作答:\n\n{context}"},23 {"role": "user", "content": question},24 ],25 )26 27 return response.choices[0].message.content28 29print(ask("How does ModelRiver handle failover?"))接入向 JavaScript / Next.js 开去挂件
TYPESCRIPT
1import { createClient } from "@supabase/supabase-js";2import OpenAI from "openai";3 4const supabase = createClient(5 process.env.SUPABASE_URL!,6 process.env.SUPABASE_ANON_KEY!,7);8 9const ai = new OpenAI({10 baseURL: "https://api.modelriver.com/v1",11 apiKey: process.env.MODELRIVER_API_KEY!,12});13 14async function ask(question: string): Promise<string> {15 const { data: embeddingData } = await ai.embeddings.create({16 model: "my-embedding-workflow",17 input: [question],18 });19 20 const { data: docs } = await supabase.rpc("match_documents", {21 query_embedding: embeddingData[0].embedding,22 match_count: 3,23 });24 25 const context = docs.map((d: any) => d.content).join("\n\n");26 27 const response = await ai.chat.completions.create({28 model: "my-chat-workflow",29 messages: [30 { role: "system", content: `依据语境回答:\n\n${context}` },31 { role: "user", content: question },32 ],33 });34 35 return response.choices[0].message.content!;36}最佳实践 (Best practices)
- 如若您的记录已大于过数万点 (也就是万数行时):务必开挂加护启用使用 IVFFlat 或 HNSW 技术类下层大库护索。
- 切记让在基底挂在维度生成这端表长上的维长能够对对挂齐
- 连将本该随在被切段了这文字与段表数据也存并在落本旁 以让供取随存调起之大需
- 把自带上可做列排的 Row Level Security 安全级别过滤挂落开启
- 别忘上 可观测日志监控页面 (Request Logs):去观察了解生成的用工耗字钱以及监控它。