AI 与向量

LangChain


LangChain 是一个流行的AI、向量和嵌入工作框架。LangChain支持使用Supabase作为向量存储,通过pgvector扩展实现。

初始化数据库

准备相关数据表:

  1. 进入控制面板中的SQL编辑器页面
  2. 在快速开始部分点击 LangChain
  3. 点击 运行

使用方式

您现在可以通过任何 Node.js 应用程序搜索文档。此功能设计运行在安全的服务器路由上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'import { OpenAIEmbeddings } from 'langchain/embeddings/openai'import { createClient } from '@supabase/supabase-js'const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEYif (!supabaseKey) throw new Error(`Expected SUPABASE_SERVICE_ROLE_KEY`)const url = process.env.SUPABASE_URLif (!url) throw new Error(`Expected env var SUPABASE_URL`)export const run = async () => { const client = createClient(url, supabaseKey) const vectorStore = await SupabaseVectorStore.fromTexts( ['Hello world', 'Bye bye', "What's this?"], [{ id: 2 }, { id: 1 }, { id: 3 }], new OpenAIEmbeddings(), { client, tableName: 'documents', queryName: 'match_documents', } ) const resultOne = await vectorStore.similaritySearch('Hello world', 1) console.log(resultOne)}

简单的元数据过滤

基于上述的 match_documents Postgres 函数,您还可以传递一个过滤参数来仅返回具有特定元数据字段值的文档。这个过滤参数是一个 JSON 对象,match_documents 函数将使用 Postgres 的 JSONB 包含操作符 @> 来根据您指定的元数据字段值过滤文档。更多详情请参阅 Postgres JSONB 包含操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'import { OpenAIEmbeddings } from 'langchain/embeddings/openai'import { createClient } from '@supabase/supabase-js'// 首先,按照上述设置步骤进行操作const privateKey = process.env.SUPABASE_SERVICE_ROLE_KEYif (!privateKey) throw new Error(`Expected env var SUPABASE_SERVICE_ROLE_KEY`)const url = process.env.SUPABASE_URLif (!url) throw new Error(`Expected env var SUPABASE_URL`)export const run = async () => { const client = createClient(url, privateKey) const vectorStore = await SupabaseVectorStore.fromTexts( ['Hello world', 'Hello world', 'Hello world'], [{ user_id: 2 }, { user_id: 1 }, { user_id: 3 }], new OpenAIEmbeddings(), { client, tableName: 'documents', queryName: 'match_documents', } ) const result = await vectorStore.similaritySearch('Hello world', 1, { user_id: 3, }) console.log(result)}

高级元数据过滤

您也可以使用查询构建器风格的过滤方式(类似于Supabase JavaScript库的工作方式),而不是传递对象。请注意,由于过滤属性将位于元数据列中,您需要使用箭头操作符(整数用->或文本用->>),如PostgREST API文档所定义,并指定属性的数据类型(例如,列应类似于metadata->some_int_value::int)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { SupabaseFilterRPCCall, SupabaseVectorStore } from 'langchain/vectorstores/supabase'import { OpenAIEmbeddings } from 'langchain/embeddings/openai'import { createClient } from '@supabase/supabase-js'// 首先,按照上述设置步骤操作const privateKey = process.env.SUPABASE_SERVICE_ROLE_KEYif (!privateKey) throw new Error(`Expected env var SUPABASE_SERVICE_ROLE_KEY`)const url = process.env.SUPABASE_URLif (!url) throw new Error(`Expected env var SUPABASE_URL`)export const run = async () => { const client = createClient(url, privateKey) const embeddings = new OpenAIEmbeddings() const store = new SupabaseVectorStore(embeddings, { client, tableName: 'documents', }) const docs = [ { pageContent: '这是一段长文本,但它实际上有意义,因为向量数据库不理解Lorem Ipsum。因此我需要扩展量子泡沫的概念,这是一种理论概念,其中亚原子粒子结合形成瞬态的多维空间。然而,这种抽象在现实世界中没有任何应用或可理解的意义,反映了一个宇宙之谜。', metadata: { b: 1, c: 10, stuff: 'right' }, }, { pageContent: '这是一段长文本,但它实际上有意义,因为向量数据库不理解Lorem Ipsum。因此我需要继续讨论数字宇宙二进制走廊中虚拟推文的回声。每条推文就像一个像素化的金丝雀,以看不见的频率嗡嗡作响,这是一个令人着迷的复杂现象,虽然能唤起生动的意象,但缺乏任何具体的含义或现实世界的相关性,描绘了网络民俗时代多维空间的悖论。', metadata: { b: 2, c: 9, stuff: 'right' }, }, { pageContent: '你好', metadata: { b: 1, c: 9, stuff: 'right' } }, { pageContent: '你好', metadata: { b: 1, c: 9, stuff: 'wrong' } }, { pageContent: '', metadata: { b: 2, c: 8, stuff: 'right' } }, { pageContent: '再见', metadata: { b: 3, c: 7, stuff: 'right' } }, { pageContent: "这是什么", metadata: { b: 4, c: 6, stuff: 'right' } }, ] await store.addDocuments(docs) const funcFilterA: SupabaseFilterRPCCall = (rpc) => rpc .filter('metadata->b::int', 'lt', 3) .filter('metadata->c::int', 'gt', 7) .textSearch('content', `'multidimensional' & 'spaces'`, { config: 'english', }) const resultA = await store.similaritySearch('quantum', 4, funcFilterA) const funcFilterB: SupabaseFilterRPCCall = (rpc) => rpc .filter('metadata->b::int', 'lt', 3) .filter('metadata->c::int', 'gt', 7) .filter('metadata->>stuff', 'eq', 'right') const resultB = await store.similaritySearch('hello', 2, funcFilterB) console.log(resultA, resultB)}

混合搜索

LangChain 支持混合搜索的概念,它将相似性搜索与全文搜索相结合。阅读官方文档开始使用:Supabase 混合搜索

您可以通过我们的 database.dev 包管理器 安装 LangChain 混合搜索功能。

资源