8️⃣PostgreSQL VectorDB with pgvorco.rs

pgvorco.rs: LangChaing VectorStore

LangChain은 언어 모델로 구동되는 애플리케이션을 개발하기 위한 프레임워크입니다. 이를 통해 다음과 같은 애플리케이션이 가능합니다:

  • 문맥 인식: 언어 모델을 문맥의 출처(프롬프트 지침, 몇 개의 샷 예시, 응답의 근거가 되는 콘텐츠 등)에 연결합니다.

  • 추론: 언어 모델에 의존하여 추론(제공된 문맥에 따라 답변하는 방법, 취해야 할 조치 등)합니다.

pgvecto.rs는 PostgresSQL의 벡터 검색 확장입니다. LangChain과 pgvecto.rs로 LLM 애플리케이션을 구축하는 방법을 보여드리겠습니다.

Install dependencies

LangChain 통합을 사용하려면 일부 dependency 설정이 필요합니다:

%pip install langchain langchain-openai pgvecto-rs

도커 컨테이너에서 pgvecto.rs 확장자를 사용하여 포스트그레스 인스턴스를 시작할 수 있습니다:

docker run \
  --name pgvecto-rs-demo \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -p 5432:5432 \
  -d tensorchord/pgvecto-rs:pg16-v0.2.0

그런 다음 psql 명령줄 도구를 사용하여 데이터베이스에 연결할 수 있습니다. 기본 사용자 아이디는 postgres이고 기본 비밀번호는 mysecretpassword입니다.

psql postgresql://postgres:mysecretpassword@localhost:5432/postgres

다음 SQL을 실행하여 확장 기능이 활성화되었는지 확인합니다.

DROP EXTENSION IF EXISTS vectors;
CREATE EXTENSION vectors;

Create the database and load documents

가장 유사한 벡터를 검색하기 위해 LangChain에서 pgvecto.rs를 사용하는 방법을 보여드리겠습니다.먼저, 텍스트 로더와 텍스트 분할기를 생성하여 텍스트를 청크로 분할해야 합니다. 여기서는 마크다운 파일인 pgvecto.rs-docs/src/getting-started/overview.md를 예로 사용합니다.

## Loading Environment Variables
from dotenv import load_dotenv

load_dotenv()

from langchain.docstore.document import Document
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores.pgvecto_rs import PGVecto_rs
from langchain_openai import OpenAIEmbeddings


loader = TextLoader("./src/getting-started/overview.md")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()

그런 다음 PGVecto_rs 인스턴스를 생성하고 문서를 데이터베이스에 로드합니다.

## PGVecto.rs needs the connection string to the database.
## We will load it from the environment variables.
import os

PORT = os.getenv("DB_PORT", 5432)
HOST = os.getenv("DB_HOST", "localhost")
USER = os.getenv("DB_USER", "postgres")
PASS = os.getenv("DB_PASS", "mysecretpassword")
DB_NAME = os.getenv("DB_NAME", "postgres")

# Run tests with shell:
URL = "postgresql+psycopg://{username}:{password}@{host}:{port}/{db_name}".format(
    port=PORT,
    host=HOST,
    username=USER,
    password=PASS,
    db_name=DB_NAME,
)

# The pgvectors Module will try to create a table with the name of the collection.
# So, make sure that the collection name is unique and the user has the permission to create a table.

COLLECTION_NAME = "state_of_the_union_test"

db = PGVecto_rs.from_documents(
    embedding=embeddings,
    documents=docs,
    collection_name=COLLECTION_NAME,
    db_url=URL,
)

Query index

마지막으로 LangChain에서 가장 유사한 청크를 검색할 수 있습니다.

query = "What is pgvecto.rs"
docs_with_score = db.similarity_search_with_score(query)

for doc, score in docs_with_score:
    print("-" * 80)
    print("Score: ", score)
    print(doc.page_content)
    print("-" * 80)
> Created a chunk of size 1181, which is longer than the specified 1000
--------------------------------------------------------------------------------
Score:  0.25059962
# Overview

An introduction to the pgvecto.rs.

## What is pgvecto.rs

pgvecto.rs is a Postgres extension that provides vector similarity search functions. It is written in Rust and based on [pgrx](https://github.com/tcdi/pgrx). It is currently in the beta status, we invite you to try it out in production and provide us with feedback. Read more at [📝our launch blog](https://modelz.ai/blog/pgvecto-rs).

## Why use pgvecto.rs
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Score:  0.29536954
- 💃 **Easy to use**: pgvecto.rs is a Postgres extension, which means that you can use it directly within your existing database. This makes it easy to integrate into your existing workflows and applications.
- 🔗 **Async indexing**: pgvecto.rs's index is asynchronously constructed by the background threads and does not block insertions and always ready for new queries.
- 🥅 **Filtering**: pgvecto.rs supports filtering. You can set conditions when searching or retrieving points. This is the missing feature of other postgres extensions.
- 🧮 **Quantization**: pgvecto.rs supports scalar quantization and product qutization up to 64x.
- 🦀 **Rewrite in Rust**: Rust's strict compile-time checks ensure memory safety, reducing the risk of bugs and security issues commonly associated with C extensions.

## Comparison with pgvector
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Score:  0.35845917
More details at [📝`pgvecto.rs` vs. pgvector](/faqs/comparison-pgvector.md).

## Quick start

For new users, we recommend using the [Docker image](https://hub.docker.com/r/tensorchord/pgvecto-rs) to get started quickly.
...

Initialize existing database

위에서 벡터 스토어를 처음부터 새로 만들었습니다. 하지만 기존 벡터 스토어를 사용하여 작업하고 싶을 때가 많습니다. 이를 위해 직접 초기화할 수 있습니다.

db = PGVecto_rs(
    embedding=embeddings,
    collection_name=COLLECTION_NAME,
    # OpenAI embedding has 1536 dimensions.
    dimension=1536,
    db_url=URL,
)

그런 다음 스토어에 벡터를 추가하고 쿼리할 수 있습니다:

> (Document(page_content='foo'), 0.0)

RAG pipeline with LlamaIndex and pgvecto.rs

LlamaIndex는 사용자 지정 데이터 소스를 대규모 언어 모델(LLM)에 연결하기 위한 간단하고 유연한 데이터 프레임워크입니다.pgvecto.rs는 가장 유사한 벡터를 검색할 수 있는 LlamaIndex 통합 기능을 제공합니다.

이번에는 pgvectors.rs를 LlamaIndex에서 RAG 파이프라인을 구축해 보겠습니다.

Install dependencies

LangChain 통합을 사용하려면 일부 종속성이 필요합니다:

%pip install llama-index "pgvecto_rs[sdk]"

도커 컨테이너에서 pgvecto.rs 확장자를 사용하여 포스트그레스 인스턴스를 시작할 수 있습니다: 위에서 실행했다면 다음 단계는 건너 뛰세요.

docker run \
  --name pgvecto-rs-demo \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -p 5432:5432 \
  -d tensorchord/pgvecto-rs:pg16-v0.2.0

그런 다음 psql 명령줄 도구를 사용하여 데이터베이스에 연결할 수 있습니다. 기본 사용자 아이디는 postgres이고 기본 비밀번호는 mysecretpassword입니다.

psql postgresql://postgres:mysecretpassword@localhost:5432/postgres

다음 SQL을 실행하여 확장 기능이 활성화되었는지 확인합니다.

DROP EXTENSION IF EXISTS vectors;
CREATE EXTENSION vectors;

Create the database and load documents

먼저 텍스트 로더와 텍스트 분할기를 만들어 텍스트를 청크로 분할합니다. 여기서는 마크다운 파일 pgvecto.rs-docs/src/getting-started/overview.md를 예로 사용합니다.

import logging
import os
import sys

logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

from pgvecto_rs.sdk import PGVectoRs

URL = "postgresql+psycopg://{username}:{password}@{host}:{port}/{db_name}".format(
    port=os.getenv("DB_PORT", "5432"),
    host=os.getenv("DB_HOST", "localhost"),
    username=os.getenv("DB_USER", "postgres"),
    password=os.getenv("DB_PASS", "mysecretpassword"),
    db_name=os.getenv("DB_NAME", "postgres"),
)

client = PGVectoRs(
    db_url=URL,
    collection_name="example",
    dimension=1536,  # Using OpenAI’s text-embedding-ada-002
)

그런 다음 OpenAI API 키를 설정하고 문서를 데이터베이스에 로드합니다.

import os

os.environ["OPENAI_API_KEY"] = "<Your OpenAI Key>"

from llama_index import SimpleDirectoryReader, VectorStoreIndex
from llama_index.vector_stores import PGVectoRsStore

# load documents
documents = SimpleDirectoryReader("./src/getting-started/overview.md").load_data()

# initialize without metadata filter
from llama_index.storage.storage_context import StorageContext

vector_store = PGVectoRsStore(client=client)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
    documents, storage_context=storage_context
)

Query index

마지막으로 가장 유사한 청크를 검색할 수 있습니다.

# set Logging to DEBUG for more detailed outputs
query_engine = index.as_query_engine()
response = query_engine.query("What did the author do growing up?")

Last updated