


Membina Enjin Carian Semantik dengan OpenAI, Go dan PostgreSQL (pgvector)
Dalam beberapa tahun kebelakangan ini, pembenaman vektor telah menjadi asas pemprosesan bahasa semula jadi (NLP) dan carian semantik moden. Daripada bergantung pada carian kata kunci, pangkalan data vektor membandingkan "makna" teks melalui perwakilan berangka (benam). Contoh ini menunjukkan cara mencipta enjin carian semantik menggunakan pembenaman OpenAI, Go dan PostgreSQL dengan sambungan pgvector.
Apakah itu pembenaman?
Pembenaman ialah perwakilan vektor teks (atau data lain) dalam ruang dimensi tinggi. Jika dua keping teks adalah serupa secara semantik, vektornya akan berdekatan antara satu sama lain dalam ruang ini. Dengan menyimpan pembenaman dalam pangkalan data seperti PostgreSQL (dengan sambungan pgvector), kami boleh melakukan carian persamaan dengan cepat dan tepat.
Mengapa memilih PostgreSQL dan pgvector?
pgvector ialah sambungan popular yang menambahkan jenis data vektor pada PostgreSQL. Ia membolehkan anda:
- Simpan benam sebagai lajur vektor
- Lakukan carian jiran terdekat anggaran atau tepat
- Jalankan pertanyaan menggunakan SQL standard
Ikhtisar Apl
- Panggil API pembenaman OpenAI untuk menukar teks input kepada pembenaman vektor.
- Gunakan sambungan pgvector untuk menyimpan benam ini dalam PostgreSQL.
- Pembenaman pertanyaan untuk mencari entri yang paling serupa dari segi semantik dalam pangkalan data.
Prasyarat
- Pergi dipasang (1.19 disyorkan).
- PostgreSQL dipasang dan dijalankan (tempatan atau dihoskan).
- Pasang sambungan pgvector dalam PostgreSQL. (Lihat halaman GitHub pgvector untuk arahan pemasangan.)
- Kunci API OpenAI dengan akses terbenam.
Makefile yang mengandungi tugasan yang berkaitan dengan postgres/pgvector dan Docker untuk ujian tempatan.
pgvector: @docker run -d \ --name pgvector \ -e POSTGRES_USER=admin \ -e POSTGRES_PASSWORD=admin \ -e POSTGRES_DB=vectordb \ -v pgvector_data:/var/lib/postgresql/data \ -p 5432:5432 \ pgvector/pgvector:pg17 psql: @psql -h localhost -U admin -d vectordb
Pastikan pgvector dipasang. Kemudian, dalam pangkalan data PostgreSQL anda:
CREATE EXTENSION IF NOT EXISTS vector;
Kod penuh
package main import ( "context" "fmt" "log" "os" "strings" "github.com/jackc/pgx/v5/pgxpool" "github.com/joho/godotenv" "github.com/sashabaranov/go-openai" ) func floats32ToString(floats []float32) string { strVals := make([]string, len(floats)) for i, val := range floats { // 将每个浮点数格式化为字符串 strVals[i] = fmt.Sprintf("%f", val) } // 使用逗号 + 空格连接它们 joined := strings.Join(strVals, ", ") // pgvector 需要方括号表示法才能输入向量,例如 [0.1, 0.2, 0.3] return "[" + joined + "]" } func main() { // 加载环境变量 err := godotenv.Load() if err != nil { log.Fatal("加载 .env 文件出错") } // 创建连接池 dbpool, err := pgxpool.New(context.Background(), os.Getenv("DATABASE_URL")) if err != nil { fmt.Fprintf(os.Stderr, "无法创建连接池:%v\n", err) os.Exit(1) } defer dbpool.Close() // 1. 确保已启用 pgvector 扩展 _, err = dbpool.Exec(context.Background(), "CREATE EXTENSION IF NOT EXISTS vector;") if err != nil { log.Fatalf("创建扩展失败:%v\n", err) os.Exit(1) } // 2. 创建表(如果不存在) createTableSQL := ` CREATE TABLE IF NOT EXISTS documents ( id SERIAL PRIMARY KEY, content TEXT, embedding vector(1536) ); ` _, err = dbpool.Exec(context.Background(), createTableSQL) if err != nil { log.Fatalf("创建表失败:%v\n", err) } // 3. 创建索引(如果不存在) createIndexSQL := ` CREATE INDEX IF NOT EXISTS documents_embedding_idx ON documents USING ivfflat (embedding vector_l2_ops) WITH (lists = 100); ` _, err = dbpool.Exec(context.Background(), createIndexSQL) if err != nil { log.Fatalf("创建索引失败:%v\n", err) } // 4. 初始化 OpenAI 客户端 apiKey := os.Getenv("OPENAI_API_KEY") if apiKey == "" { log.Fatal("未设置 OPENAI_API_KEY") } openaiClient := openai.NewClient(apiKey) // 5. 插入示例文档 docs := []string{ "PostgreSQL 是一个先进的开源关系数据库。", "OpenAI 提供基于 GPT 的模型来生成文本嵌入。", "pgvector 允许将嵌入存储在 Postgres 数据库中。", } for _, doc := range docs { err = insertDocument(context.Background(), dbpool, openaiClient, doc) if err != nil { log.Printf("插入文档“%s”失败:%v\n", doc, err) } } // 6. 查询相似性 queryText := "如何在 Postgres 中存储嵌入?" similarDocs, err := searchSimilarDocuments(context.Background(), dbpool, openaiClient, queryText, 5) if err != nil { log.Fatalf("搜索失败:%v\n", err) } fmt.Println("=== 最相似的文档 ===") for _, doc := range similarDocs { fmt.Printf("- %s\n", doc) } } // insertDocument 使用 OpenAI API 为 `content` 生成嵌入,并将其插入 documents 表中。 func insertDocument(ctx context.Context, dbpool *pgxpool.Pool, client *openai.Client, content string) error { // 1) 从 OpenAI 获取嵌入 embedResp, err := client.CreateEmbeddings(ctx, openai.EmbeddingRequest{ Model: openai.AdaEmbeddingV2, // "text-embedding-ada-002" Input: []string{content}, }) if err != nil { return fmt.Errorf("CreateEmbeddings API 调用失败:%w", err) } // 2) 将嵌入转换为 pgvector 的方括号字符串 embedding := embedResp.Data[0].Embedding // []float32 embeddingStr := floats32ToString(embedding) // 3) 插入 PostgreSQL insertSQL := ` INSERT INTO documents (content, embedding) VALUES (, ::vector) ` _, err = dbpool.Exec(ctx, insertSQL, content, embeddingStr) if err != nil { return fmt.Errorf("插入文档失败:%w", err) } return nil } // searchSimilarDocuments 获取用户查询的嵌入,并根据向量相似性返回前 k 个相似的文档。 func searchSimilarDocuments(ctx context.Context, pool *pgxpool.Pool, client *openai.Client, query string, k int) ([]string, error) { // 1) 通过 OpenAI 获取用户查询的嵌入 embedResp, err := client.CreateEmbeddings(ctx, openai.EmbeddingRequest{ Model: openai.AdaEmbeddingV2, // "text-embedding-ada-002" Input: []string{query}, }) if err != nil { return nil, fmt.Errorf("CreateEmbeddings API 调用失败:%w", err) } // 2) 将 OpenAI 嵌入转换为 pgvector 的方括号字符串格式 queryEmbedding := embedResp.Data[0].Embedding // []float32 queryEmbeddingStr := floats32ToString(queryEmbedding) // 例如 "[0.123456, 0.789012, ...]" // 3) 构建按向量相似性排序的 SELECT 语句 selectSQL := fmt.Sprintf(` SELECT content FROM documents ORDER BY embedding <-> '%s'::vector LIMIT %d; `, queryEmbeddingStr, k) // 4) 运行查询 rows, err := pool.Query(ctx, selectSQL) if err != nil { return nil, fmt.Errorf("查询文档失败:%w", err) } defer rows.Close() // 5) 读取匹配的文档 var contents []string for rows.Next() { var content string if err := rows.Scan(&content); err != nil { return nil, fmt.Errorf("扫描行失败:%w", err) } contents = append(contents, content) } if err = rows.Err(); err != nil { return nil, fmt.Errorf("行迭代错误:%w", err) } return contents, nil }
Kesimpulan
Pembenaman OpenAI dalam PostgreSQL, Go dan pgvector menyediakan penyelesaian yang mudah untuk membina aplikasi carian semantik. Dengan mewakili teks sebagai vektor dan memanfaatkan kuasa indeks pangkalan data, kami beralih daripada carian berasaskan kata kunci tradisional kepada carian mengikut konteks dan makna.
Output yang disemak ini mengekalkan gaya bahasa asal, menyusun semula ayat untuk keaslian dan mengekalkan imej dalam format dan lokasi yang sama Kod ini juga dipertingkatkan sedikit untuk kejelasan dan kebolehbacaan Perubahan utama termasuk nama pembolehubah yang lebih deskriptif.
Atas ialah kandungan terperinci Membina Enjin Carian Semantik dengan OpenAI, Go dan PostgreSQL (pgvector). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



OpenSSL, sebagai perpustakaan sumber terbuka yang digunakan secara meluas dalam komunikasi yang selamat, menyediakan algoritma penyulitan, kunci dan fungsi pengurusan sijil. Walau bagaimanapun, terdapat beberapa kelemahan keselamatan yang diketahui dalam versi sejarahnya, yang sebahagiannya sangat berbahaya. Artikel ini akan memberi tumpuan kepada kelemahan umum dan langkah -langkah tindak balas untuk OpenSSL dalam sistem Debian. Debianopenssl yang dikenal pasti: OpenSSL telah mengalami beberapa kelemahan yang serius, seperti: Kerentanan Pendarahan Jantung (CVE-2014-0160): Kelemahan ini mempengaruhi OpenSSL 1.0.1 hingga 1.0.1f dan 1.0.2 hingga 1.0.2 versi beta. Penyerang boleh menggunakan kelemahan ini untuk maklumat sensitif baca yang tidak dibenarkan di pelayan, termasuk kunci penyulitan, dll.

Artikel ini menerangkan cara menggunakan alat PPROF untuk menganalisis prestasi GO, termasuk membolehkan profil, mengumpul data, dan mengenal pasti kesesakan biasa seperti CPU dan isu memori.

Artikel ini membincangkan ujian unit menulis di GO, meliputi amalan terbaik, teknik mengejek, dan alat untuk pengurusan ujian yang cekap.

Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Artikel ini membincangkan perintah Go FMT dalam pengaturcaraan GO, yang format kod untuk mematuhi garis panduan gaya rasmi. Ia menyoroti kepentingan GO FMT untuk mengekalkan konsistensi kod, kebolehbacaan, dan mengurangkan perdebatan gaya. Amalan terbaik untuk

Laluan Pembelajaran Backend: Perjalanan Eksplorasi dari Front-End ke Back-End sebagai pemula back-end yang berubah dari pembangunan front-end, anda sudah mempunyai asas Nodejs, ...

Artikel ini memperkenalkan pelbagai kaedah dan alat untuk memantau pangkalan data PostgreSQL di bawah sistem Debian, membantu anda memahami pemantauan prestasi pangkalan data sepenuhnya. 1. Gunakan PostgreSQL untuk membina pemantauan PostgreSQL sendiri menyediakan pelbagai pandangan untuk pemantauan aktiviti pangkalan data: PG_STAT_ACTIVITY: Memaparkan aktiviti pangkalan data dalam masa nyata, termasuk sambungan, pertanyaan, urus niaga dan maklumat lain. PG_STAT_REPLITI: Memantau status replikasi, terutamanya sesuai untuk kluster replikasi aliran. PG_STAT_DATABASE: Menyediakan statistik pangkalan data, seperti saiz pangkalan data, masa komitmen/masa rollback transaksi dan petunjuk utama lain. 2. Gunakan alat analisis log pgbadg
