LangChain
LangChain 是一个流行的用于处理 AI、向量和嵌入的框架。LangChain 支持使用 Supabase 作为 向量存储,使用 pgvector 扩展。
正在初始化你的数据库 #
🌐 Initializing your database
准备好你的数据库,并建立相关的表格:
🌐 Prepare your database with the relevant tables:
- 在仪表板中转到SQL 编辑器页面。
- 在快速开始部分点击 LangChain。
- 点击运行。
用法 #
🌐 Usage
你现在可以使用任何 Node.js 应用搜索你的文档。这是打算在安全的服务器路由上运行的。
🌐 You can now search your documents using any Node.js application. This is intended to be run on a secure server route.
1import { SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'2import { OpenAIEmbeddings } from '@langchain/openai'3import { createClient } from '@supabase/supabase-js'45const supabaseKey = process.env.SUPABASE_SECRET_KEY6if (!supabaseKey) throw new Error(`Expected SUPABASE_SECRET_KEY`)78const url = process.env.SUPABASE_URL9if (!url) throw new Error(`Expected env var SUPABASE_URL`)1011export const run = async () => {12 const client = createClient(url, supabaseKey)1314 const vectorStore = await SupabaseVectorStore.fromTexts(15 ['Hello world', 'Bye bye', "What's this?"],16 [{ id: 2 }, { id: 1 }, { id: 3 }],17 new OpenAIEmbeddings(),18 {19 client,20 tableName: 'documents',21 queryName: 'match_documents',22 }23 )2425 const resultOne = await vectorStore.similaritySearch('Hello world', 1)2627 console.log(resultOne)28}基本元数据过滤 #
🌐 Basic metadata filtering [#simple-metadata-filtering]
根据上面的 match_documents Postgres 函数,你也可以传入一个过滤参数,只返回具有特定元数据字段值的文档。这个过滤参数是一个 JSON 对象,match_documents 函数会使用 Postgres JSONB 包含运算符 @> 来按你指定的元数据字段值过滤文档。更多信息请查看 Postgres JSONB 包含运算符 的详情。
🌐 Given the above match_documents Postgres function, you can also pass a filter parameter to only return documents with a specific metadata field value. This filter parameter is a JSON object, and the match_documents function will use the Postgres JSONB Containment operator @> to filter documents by the metadata field values you specify. See details on the Postgres JSONB Containment operator for more information.
1import { SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'2import { OpenAIEmbeddings } from '@langchain/openai'3import { createClient } from '@supabase/supabase-js'45// First, follow set-up instructions above67const privateKey = process.env.SUPABASE_SECRET_KEY8if (!privateKey) throw new Error(`Expected env var SUPABASE_SECRET_KEY`)910const url = process.env.SUPABASE_URL11if (!url) throw new Error(`Expected env var SUPABASE_URL`)1213export const run = async () => {14 const client = createClient(url, privateKey)1516 const vectorStore = await SupabaseVectorStore.fromTexts(17 ['Hello world', 'Hello world', 'Hello world'],18 [{ user_id: 2 }, { user_id: 1 }, { user_id: 3 }],19 new OpenAIEmbeddings(),20 {21 client,22 tableName: 'documents',23 queryName: 'match_documents',24 }25 )2627 const result = await vectorStore.similaritySearch('Hello world', 1, {28 user_id: 3,29 })3031 console.log(result)32}高级元数据过滤 #
🌐 Advanced metadata filtering
你也可以使用类似查询构建器的过滤([类似于 Supabase JavaScript 库的工作原理](/docs/reference/javascript/using-filters)),而不是传递对象。注意,由于过滤器属性会在元数据列中,你需要使用箭头运算符(整数用'->',文本用'->>'),按照 [PostgREST API 文档](https://postgrest.org/en/stable/references/api/tables_views.html?highlight=operators#json-columns)定义),并指定属性的数据类型(例如列应该看起来像是“metadata->some_int_value::int”)。
🌐 You can also use query builder-style filtering (similar to how the Supabase JavaScript library works) instead of passing an object. Note that since the filter properties will be in the metadata column, you need to use arrow operators (-> for integer or ->> for text) as defined in PostgREST API documentation and specify the data type of the property (e.g. the column should look something like metadata->some_int_value::int).
1import { SupabaseFilterRPCCall, SupabaseVectorStore } from '@langchain/community/vectorstores/supabase'2import { OpenAIEmbeddings } from '@langchain/openai'3import { createClient } from '@supabase/supabase-js'45// First, follow set-up instructions above67const privateKey = process.env.SUPABASE_SECRET_KEY8if (!privateKey) throw new Error(`Expected env var SUPABASE_SECRET_KEY`)910const url = process.env.SUPABASE_URL11if (!url) throw new Error(`Expected env var SUPABASE_URL`)1213export const run = async () => {14 const client = createClient(url, privateKey)1516 const embeddings = new OpenAIEmbeddings()1718 const store = new SupabaseVectorStore(embeddings, {19 client,20 tableName: 'documents',21 })2223 const docs = [24 {25 pageContent:26 'This is a long text, but it actually means something because vector database does not understand Lorem Ipsum. So I would need to expand upon the notion of quantum fluff, a theoretical concept where subatomic particles coalesce to form transient multidimensional spaces. Yet, this abstraction holds no real-world application or comprehensible meaning, reflecting a cosmic puzzle.',27 metadata: { b: 1, c: 10, stuff: 'right' },28 },29 {30 pageContent:31 'This is a long text, but it actually means something because vector database does not understand Lorem Ipsum. So I would need to proceed by discussing the echo of virtual tweets in the binary corridors of the digital universe. Each tweet, like a pixelated canary, hums in an unseen frequency, a fascinatingly perplexing phenomenon that, while conjuring vivid imagery, lacks any concrete implication or real-world relevance, portraying a paradox of multidimensional spaces in the age of cyber folklore.',32 metadata: { b: 2, c: 9, stuff: 'right' },33 },34 { pageContent: 'hello', metadata: { b: 1, c: 9, stuff: 'right' } },35 { pageContent: 'hello', metadata: { b: 1, c: 9, stuff: 'wrong' } },36 { pageContent: 'hi', metadata: { b: 2, c: 8, stuff: 'right' } },37 { pageContent: 'bye', metadata: { b: 3, c: 7, stuff: 'right' } },38 { pageContent: "what's this", metadata: { b: 4, c: 6, stuff: 'right' } },39 ]4041 await store.addDocuments(docs)4243 const funcFilterA: SupabaseFilterRPCCall = (rpc) =>44 rpc45 .filter('metadata->b::int', 'lt', 3)46 .filter('metadata->c::int', 'gt', 7)47 .textSearch('content', `'multidimensional' & 'spaces'`, {48 config: 'english',49 })5051 const resultA = await store.similaritySearch('quantum', 4, funcFilterA)5253 const funcFilterB: SupabaseFilterRPCCall = (rpc) =>54 rpc55 .filter('metadata->b::int', 'lt', 3)56 .filter('metadata->c::int', 'gt', 7)57 .filter('metadata->>stuff', 'eq', 'right')5859 const resultB = await store.similaritySearch('hello', 2, funcFilterB)6061 console.log(resultA, resultB)62}混合搜索 #
🌐 Hybrid search
LangChain 支持混合搜索的概念,它将相似性搜索与全文搜索结合起来。阅读官方文档以开始使用:Supabase 混合搜索。
🌐 LangChain supports the concept of a hybrid search, which combines Similarity Search with Full Text Search. Read the official docs to get started: Supabase Hybrid Search.
你可以通过我们的 database.dev 包管理器 安装 LangChain 混合搜索功能。
🌐 You can install the LangChain Hybrid Search function through our database.dev package manager.
资源 #
🌐 Resources
- 官方 LangChain 网站。
- 官方 LangChain 文档。
- Supabase 混合搜索。