Bagikan melalui


Menggunakan LangChain dengan Azure Database for PostgreSQL

Azure Database for PostgreSQL terintegrasi dengan paket orkestrasi model bahasa besar (LLM) terkemuka seperti LangChain. Integrasi ini memungkinkan pengembang untuk menggunakan kemampuan AI tingkat lanjut dalam aplikasi mereka. LangChain dapat menyederhanakan manajemen dan penggunaan LLM, model penyematan, dan database sehingga aplikasi AI generatif lebih mudah dikembangkan.

Artikel ini memperlihatkan kepada Anda cara menggunakan database vektor terintegrasi di Azure Database for PostgreSQL untuk menyimpan dan mengelola dokumen dalam koleksi dengan LangChain. Ini juga menunjukkan kepada Anda cara membuat indeks dan melakukan kueri pencarian vektor dengan menggunakan algoritma tetangga terdekat seperti jarak kosinus, jarak L2 (jarak Euclidean), dan produk dalam untuk menemukan dokumen yang dekat dengan vektor kueri.

Dukungan vektor

Anda dapat menggunakan Azure Database for PostgreSQL untuk menyimpan dan mengkueri jutaan penyematan vektor secara efisien di PostgreSQL. Layanan ini dapat membantu Anda menskalakan kasus penggunaan AI Anda dari bukti konsep ke produksi. Ini menawarkan manfaat ini:

  • Menyediakan antarmuka SQL yang akrab untuk melakukan kueri penyematan vektor dan data relasional.
  • Meningkatkan performa pgvector dengan pencarian kesamaan yang lebih cepat dan lebih akurat di lebih dari 100 juta vektor menggunakan algoritma pengindeksan DiskANN.
  • Menyederhanakan operasi dengan mengintegrasikan metadata relasional, penyematan vektor, dan data rangkaian waktu ke dalam satu database.
  • Menggunakan kekuatan ekosistem PostgreSQL yang kuat dan platform cloud Azure untuk fitur tingkat perusahaan, termasuk replikasi dan ketersediaan tinggi.

Otentikasi

Azure Database for PostgreSQL mendukung autentikasi berbasis kata sandi dan Microsoft Entra (sebelumnya Azure Active Directory).

Autentikasi Microsoft Entra memungkinkan Anda menggunakan MICROSOFT Entra ID untuk mengautentikasi ke server PostgreSQL Anda. ID Microsoft Entra menghilangkan kebutuhan untuk mengelola nama pengguna dan kata sandi terpisah untuk pengguna database Anda. Ini memungkinkan Anda menggunakan mekanisme keamanan yang sama dengan yang Anda gunakan untuk layanan Azure lainnya.

Dalam artikel ini, Anda dapat menggunakan salah satu metode autentikasi.

Pengaturan

Azure Database for PostgreSQL menggunakan dukungan LangChain Postgres sumber terbuka untuk menyambungkan ke Azure Database for PostgreSQL. Pertama, unduh paket mitra resmi:

%pip install -qU langchain-azure-postgresql
%pip install -qU langchain-openai
%pip install -qU azure-identity

Mengaktifkan pgvector di Azure Database for PostgreSQL

Lihat Mengaktifkan dan menggunakan pgvector di Azure Database for PostgreSQL.

Menyiapkan kredensial

Anda perlu mendapatkan detail koneksi untuk Azure Database for PostgreSQL dan menambahkannya sebagai variabel lingkungan.

Atur bendera ke USE_ENTRA_AUTHTrue jika Anda ingin menggunakan autentikasi Microsoft Entra. Jika Anda menggunakan autentikasi Microsoft Entra, Anda perlu menyediakan satu-satunya nama host dan database. Jika Anda menggunakan autentikasi kata sandi, Anda juga perlu mengatur nama pengguna dan kata sandi.

import getpass
import os

USE_ENTRA_AUTH = True

# Supply the connection details for the database
os.environ["DBHOST"] = "<server-name>"
os.environ["DBNAME"] = "<database-name>"
os.environ["SSLMODE"] = "require"

if not USE_ENTRA_AUTH:
    # If you're using a username and password, supply them here
    os.environ["DBUSER"] = "<username>"
    os.environ["DBPASSWORD"] = getpass.getpass("Database Password:")

Menyiapkan penyematan Azure OpenAI

os.environ["AZURE_OPENAI_ENDPOINT"] = "<azure-openai-endpoint>"
os.environ["AZURE_OPENAI_API_KEY"] = getpass.getpass("Azure OpenAI API Key:")
AZURE_OPENAI_ENDPOINT = os.environ["AZURE_OPENAI_ENDPOINT"]
AZURE_OPENAI_API_KEY = os.environ["AZURE_OPENAI_API_KEY"]

from langchain_openai import AzureOpenAIEmbeddings

embeddings = AzureOpenAIEmbeddings(
    model="text-embedding-3-small",
    api_key=AZURE_OPENAI_API_KEY,
    azure_endpoint=AZURE_OPENAI_ENDPOINT,
    azure_deployment="text-embedding-3-small",
)

Inisialisasi

Menggunakan autentikasi Microsoft Entra

Bagian berikut menunjukkan cara menyiapkan LangChain untuk menggunakan autentikasi Microsoft Entra. AzurePGConnectionPool Kelas dalam paket LangChain Azure Postgres mengambil token untuk layanan Azure Database for PostgreSQL dengan menggunakan DefaultAzureCredential dari azure.identity pustaka.

Koneksi dapat diteruskan ke connection parameter AzurePGVectorStore penyimpanan vektor LangChain.

Masuk ke Azure

Untuk masuk ke Azure, pastikan Anda telah menginstal Azure CLI . Jalankan perintah berikut di terminal Anda:

az login

Setelah Anda masuk, kode berikut mengambil token:

from langchain_azure_postgresql.common import (
    BasicAuth,
    AzurePGConnectionPool,
    ConnectionInfo,
)
from langchain_azure_postgresql.langchain import AzurePGVectorStore
entra_connection_pool = AzurePGConnectionPool(
        azure_conn_info=ConnectionInfo(
            host=os.environ["DBHOST"],
            dbname=os.environ["DBNAME"]
        )
    )

Gunakan autentikasi kata sandi

Jika Anda tidak menggunakan autentikasi Microsoft Entra, BasicAuth kelas memungkinkan penggunaan nama pengguna dan kata sandi:

basic_auth_connection_pool = AzurePGConnectionPool(
    azure_conn_info=ConnectionInfo(
        host=os.environ["DBHOST"],
        dbname=os.environ["DBNAME"],
        credentials=BasicAuth(
            username=os.environ["DBUSER"],
            password=os.environ["DBPASSWORD"],
        )
    )
)

Membuat penyimpanan vektor

from langchain_core.documents import Document
from langchain_azure_postgresql.langchain import AzurePGVectorStore

collection_name = "my_docs"

# The connection is either using Entra ID or Basic Auth
connection = entra_connection_pool if USE_ENTRA_AUTH else basic_auth_connection_pool

vector_store = AzurePGVectorStore(
    embeddings=embeddings,
    table_name=table_name,
    connection=connection,
)

Manajemen penyimpanan vektor

Menambahkan item ke penyimpanan vektor

Menambahkan dokumen berdasarkan ID menimpa dokumen yang sudah ada yang cocok dengan ID tersebut.

docs = [
    Document(
        page_content="there are cats in the pond",
        metadata={"doc_id": 1, "location": "pond", "topic": "animals"},
    ),
    Document(
        page_content="ducks are also found in the pond",
        metadata={"doc_id": 2, "location": "pond", "topic": "animals"},
    ),
    Document(
        page_content="fresh apples are available at the market",
        metadata={"doc_id": 3, "location": "market", "topic": "food"},
    ),
    Document(
        page_content="the market also sells fresh oranges",
        metadata={"doc_id": 4, "location": "market", "topic": "food"},
    ),
    Document(
        page_content="the new art exhibit is fascinating",
        metadata={"doc_id": 5, "location": "museum", "topic": "art"},
    ),
    Document(
        page_content="a sculpture exhibit is also at the museum",
        metadata={"doc_id": 6, "location": "museum", "topic": "art"},
    ),
    Document(
        page_content="a new coffee shop opened on Main Street",
        metadata={"doc_id": 7, "location": "Main Street", "topic": "food"},
    ),
    Document(
        page_content="the book club meets at the library",
        metadata={"doc_id": 8, "location": "library", "topic": "reading"},
    ),
    Document(
        page_content="the library hosts a weekly story time for kids",
        metadata={"doc_id": 9, "location": "library", "topic": "reading"},
    ),
    Document(
        page_content="a cooking class for beginners is offered at the community center",
        metadata={"doc_id": 10, "location": "community center", "topic": "classes"},
    ),
]

uuids = vector_store.add_documents(docs)
uuids

Memperbarui item di penyimpanan vektor

updated_docs = [
    Document(
        page_content="Updated - cooking class for beginners is offered at the community center",
        metadata={"doc_id": 10, "location": "community center", "topic": "classes"},
        id=uuids[-1],
    )
]
vector_store.add_documents(docs, ids=[uuids[-1]], on_conflict_update=True)

Lihat item dari penyimpanan vektor

vector_store.get_by_ids([str(uuids[-1])])

Menghapus item dari penyimpanan vektor

vector_store.delete(ids=[uuids[-1]])

Permintaan ke penyimpanan vektor

Setelah membuat penyimpanan vektor dan menambahkan dokumen yang relevan, Anda bisa mengkueri penyimpanan vektor di rantai atau agen Anda.

Dukungan pemfilteran

Penyimpanan vektor mendukung serangkaian filter yang dapat diterapkan terhadap bidang metadata dokumen melalui FilterCondition, , OrFilterdan AndFilter dalam paket LangChain Azure PostgreSQL :

Pengoperasi Arti/Kategori
= Kesetaraan (==)
!= Ketidaksamaan (!=)
< Kurang dari (<)
<= Kurang dari atau sama dengan (<=)
> Lebih besar dari (>)
>= Lebih besar dari atau sama dengan (>=)
in Kasus khusus (termasuk)
not in Perlakuan khusus (tidak termasuk)
is null Huruf besar/kecil khusus (null)
is not null Huruf besar/kecil khusus (bukan null)
between Kasus khusus (antara)
not between Kasus khusus (bukan antara)
like Teks (seperti)
ilike Teks (tidak peka terhadap huruf besar/kecil seperti)
AND Logika (dan)
OR Logis (atau)

Kueri langsung

Anda dapat melakukan pencarian kesamaan sederhana sebagai berikut:

from langchain_azure_postgresql import FilterCondition, AndFilter

results = vector_store.similarity_search(
    "kitty",
    k=10,
    filter=FilterCondition(
        column="(metadata->>'doc_id')::int",
        operator="in",
        value=[1, 5, 2, 9],
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]
    * ducks are also found in the pond [{'doc_id': 2, 'topic': 'animals', 'location': 'pond'}]
    * the new art exhibit is fascinating [{'doc_id': 5, 'topic': 'art', 'location': 'museum'}]
    * the library hosts a weekly story time for kids [{'doc_id': 9, 'topic': 'reading', 'location': 'library'}]

Jika Anda menyediakan kamus dengan beberapa bidang tetapi tidak ada operator, tingkat atas ditafsirkan sebagai filter logis AND :

results = vector_store.similarity_search(
    "ducks",
    k=10,
    filter=AndFilter(
        AND=[
            FilterCondition(
                column="(metadata->>'doc_id')::int",
                operator="in",
                value=[1, 5, 2, 9],
            ),
            FilterCondition(
                column="metadata->>'location'",
                operator="in",
                value=["pond", "market"],
            ),
        ]
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * ducks are also found in the pond [{'topic': 'animals', 'doc_id': 2, 'location': 'pond'}]
    * there are cats in the pond [{'topic': 'animals', 'doc_id': 1, 'location': 'pond'}]

Jika Anda ingin menjalankan pencarian kesamaan dan menerima skor yang sesuai, Anda dapat menjalankan:

results = vector_store.similarity_search_with_score(query="cats", k=1)
for doc, score in results:
    print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")
* [SIM=0.528338] there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]

Jika Anda ingin menggunakan pencarian relevansi marginal maks di penyimpanan vektor Anda:

results = vector_store.max_marginal_relevance_search(
    "query about cats",
    k=10,
    lambda_mult=0.5,
    filter=FilterCondition(
        column="(metadata->>'doc_id')::int",
        operator="in",
        value=[1, 2, 5, 9],
    ),
)

for doc in results:
    print(f"* {doc.page_content} [{doc.metadata}]")
    * there are cats in the pond [{'doc_id': 1, 'topic': 'animals', 'location': 'pond'}]
    * ducks are also found in the pond [{'doc_id': 2, 'topic': 'animals', 'location': 'pond'}]
    * the new art exhibit is fascinating [{'doc_id': 5, 'topic': 'art', 'location': 'museum'}]
    * the library hosts a weekly story time for kids [{'doc_id': 9, 'topic': 'reading', 'location': 'library'}]

Untuk daftar lengkap pencarian yang dapat Anda jalankan di PGVector penyimpanan vektor, lihat referensi API.

Transformasi menjadi penelusur (retriever)

Anda juga dapat mengubah penyimpanan vektor menjadi retriever untuk penggunaan yang lebih mudah dalam rantai Anda:

retriever = vector_store.as_retriever(search_type="mmr", search_kwargs={"k": 1})
retriever.invoke("kitty")
[Document(id='9fe8bc1c-9a8e-4f83-b546-9b64527aa79d', metadata={'doc_id': 1, 'topic': 'animals', 'location': 'pond'}, page_content='there are cats in the pond')]