Pelajari cara membangun dan men-deploy aplikasi LangChain di Cloud Run

1. Ringkasan

Dalam codelab ini, Anda akan mempelajari cara men-deploy aplikasi LangChain yang menggunakan Gemini untuk memungkinkan Anda mengajukan pertanyaan melalui catatan rilis Cloud Run.

Berikut contoh cara kerja aplikasi: Jika Anda mengajukan pertanyaan "Dapatkah saya memasang bucket Cloud Storage sebagai volume di Cloud Run?", aplikasi akan merespons dengan "Ya, sejak 19 Januari 2024", atau sesuatu yang serupa.

Untuk menampilkan respons yang berdasar, aplikasi akan mengambil catatan rilis Cloud Run yang mirip dengan pertanyaan terlebih dahulu, lalu meminta Gemini dengan pertanyaan dan catatan rilis. (Ini adalah pola yang biasa disebut sebagai RAG.) Berikut adalah diagram yang menunjukkan arsitektur aplikasi:

2. Penyiapan dan persyaratan

Pertama, mari kita pastikan lingkungan pengembangan Anda sudah disiapkan dengan benar.

  • Anda memerlukan project Google Cloud untuk men-deploy resource yang diperlukan untuk aplikasi.
  • Untuk men-deploy aplikasi, Anda harus menginstal gcloud di komputer lokal, diautentikasi, dan dikonfigurasi untuk menggunakan project.
    • gcloud auth login
    • gcloud config set project
  • Jika ingin menjalankan aplikasi di komputer lokal, yang saya rekomendasikan, Anda harus memastikan kredensial default aplikasi disiapkan dengan benar, termasuk menetapkan project kuota.
    • gcloud auth application-default login
    • gcloud auth application-default set-quota-project
  • Anda juga harus menginstal software berikut:
    • Python (versi 3.11 atau yang lebih tinggi diperlukan)
    • LangChain CLI
    • poetry untuk pengelolaan dependensi
    • pipx untuk menginstal dan menjalankan LangChain CLI dan poetry di lingkungan virtual yang terisolasi

Berikut adalah blog yang membantu Anda memulai penginstalan alat yang diperlukan untuk panduan ini.

Cloud Workstations

Selain komputer lokal, Anda juga dapat menggunakan Cloud Workstation di Google Cloud. Perhatikan bahwa mulai April 2024, versi Python yang dijalankan lebih rendah dari 3.11, sehingga Anda mungkin perlu mengupgrade Python sebelum memulai.

Mengaktifkan Cloud API

Pertama, jalankan perintah berikut untuk memastikan Anda telah mengonfigurasi project Google Cloud yang benar untuk digunakan:

gcloud config list project

Jika project yang benar tidak ditampilkan, Anda dapat menyetelnya dengan perintah ini:

gcloud config set project <PROJECT_ID>

Sekarang aktifkan API berikut:

gcloud services enable \
  bigquery.googleapis.com \
  sqladmin.googleapis.com \
  aiplatform.googleapis.com \
  cloudresourcemanager.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  secretmanager.googleapis.com

Pilih wilayah

Google Cloud tersedia di banyak lokasi secara global, dan Anda harus memilih salah satunya untuk men-deploy resource yang akan digunakan untuk lab ini. Tetapkan region sebagai variabel lingkungan di shell Anda (perintah berikutnya akan menggunakan variabel ini):

export REGION=us-central1

3. Membuat instance database vektor

Bagian penting dari aplikasi ini adalah mengambil catatan rilis yang relevan dengan pertanyaan pengguna. Agar lebih konkret, jika Anda mengajukan pertanyaan tentang Cloud Storage, sebaiknya tambahkan catatan rilis berikut ke dialog:

Anda dapat menggunakan embedding teks dan database vektor untuk menemukan catatan rilis yang mirip secara semantik.

Saya akan menunjukkan cara menggunakan PostgreSQL di Cloud SQL sebagai database vektor. Membuat instance Cloud SQL baru memerlukan waktu beberapa saat, jadi mari kita lakukan sekarang.

gcloud sql instances create sql-instance \
  --database-version POSTGRES_14 \
  --tier db-f1-micro \
  --region $REGION

Anda dapat membiarkan perintah ini berjalan dan melanjutkan ke langkah berikutnya. Pada titik tertentu Anda harus membuat database dan menambahkan pengguna, tetapi jangan buang waktu melihat indikator lingkaran berputar sekarang.

PostgreSQL adalah server database relasional, dan setiap instance Cloud SQL baru memiliki ekstensi pgvector yang diinstal secara default, yang berarti Anda juga dapat menggunakannya sebagai database vektor.

4. Membuat scaffold aplikasi LangChain

Untuk melanjutkan, Anda harus menginstal LangChain CLI, dan poetry untuk mengelola dependensi. Berikut cara menginstalnya menggunakan pipx:

pipx install langchain-cli poetry

Buat scaffold aplikasi LangChain dengan perintah berikut. Saat diminta, beri nama folder run-rag dan lewati penginstalan paket dengan menekan enter:

langchain app new

Beralih ke direktori run-rag dan instal dependensi

poetry install

Anda baru saja membuat aplikasi LangServe. LangServe menggabungkan FastAPI dengan rantai LangChain. Library ini dilengkapi dengan playground bawaan yang memudahkan pengiriman perintah dan pemeriksaan hasil, termasuk semua langkah perantara. Sebaiknya buka folder run-rag di editor Anda dan jelajahi konten di dalamnya.

5. Membuat tugas pengindeksan

Sebelum Anda mulai menyusun aplikasi web, mari kita pastikan catatan rilis Cloud Run diindeks di database Cloud SQL. Di bagian ini, Anda akan membuat tugas pengindeksan yang melakukan hal berikut:

Tugas pengindeksan mengambil catatan rilis, mengonversinya menjadi vektor menggunakan model penyematan teks, dan menyimpannya dalam database vektor. Hal ini memungkinkan penelusuran yang efisien untuk menemukan catatan rilis serupa berdasarkan makna semantiknya.

Di folder run-rag/app, buat file indexer.py dengan konten berikut:

import os
from google.cloud.sql.connector import Connector
import pg8000
from langchain_community.vectorstores.pgvector import PGVector
from langchain_google_vertexai import VertexAIEmbeddings
from google.cloud import bigquery


# Retrieve all Cloud Run release notes from BigQuery 
client = bigquery.Client()
query = """
SELECT
  CONCAT(FORMAT_DATE("%B %d, %Y", published_at), ": ", description) AS release_note
FROM `bigquery-public-data.google_cloud_release_notes.release_notes`
WHERE product_name= "Cloud Run"
ORDER BY published_at DESC
"""
rows = client.query(query)

print(f"Number of release notes retrieved: {rows.result().total_rows}")

# Set up a PGVector instance 
connector = Connector()

def getconn() -> pg8000.dbapi.Connection:
    conn: pg8000.dbapi.Connection = connector.connect(
        os.getenv("DB_INSTANCE_NAME", ""),
        "pg8000",
        user=os.getenv("DB_USER", ""),
        password=os.getenv("DB_PASS", ""),
        db=os.getenv("DB_NAME", ""),
    )
    return conn

store = PGVector(
    connection_string="postgresql+pg8000://",
    use_jsonb=True,
    engine_args=dict(
        creator=getconn,
    ),
    embedding_function=VertexAIEmbeddings(
        model_name="textembedding-gecko@003"
    ),
    pre_delete_collection=True  
)

# Save all release notes into the Cloud SQL database
texts = list(row["release_note"] for row in rows)
ids = store.add_texts(texts)

print(f"Done saving: {len(ids)} release notes")

Tambahkan dependensi yang diperlukan:

poetry add \
  "cloud-sql-python-connector[pg8000]" \
  langchain-google-vertexai==1.0.5 \
  langchain-community==0.2.5 \
  pgvector

Membuat database dan pengguna

Buat database release-notes di instance Cloud SQL sql-instance:

gcloud sql databases create release-notes --instance sql-instance

Buat pengguna database bernama app:

gcloud sql users create app --instance sql-instance --password "myprecious"

Men-deploy dan menjalankan tugas pengindeksan

Sekarang deploy dan jalankan tugas:

DB_INSTANCE_NAME=$(gcloud sql instances describe sql-instance --format="value(connectionName)")

gcloud run jobs deploy indexer \
  --source . \
  --command python \
  --args app/indexer.py \
  --set-env-vars=DB_INSTANCE_NAME=$DB_INSTANCE_NAME \
  --set-env-vars=DB_USER=app \
  --set-env-vars=DB_NAME=release-notes \
  --set-env-vars=DB_PASS=myprecious \
  --region=$REGION \
  --execute-now

Perintah ini panjang, mari kita lihat apa yang terjadi:

Perintah pertama mengambil nama koneksi (ID unik yang diformat sebagai project:region:instance) dan menetapkannya sebagai variabel lingkungan DB_INSTANCE_NAME.

Perintah kedua men-deploy tugas Cloud Run. Berikut adalah fungsi flag tersebut:

  • --source .: Menentukan bahwa kode sumber untuk tugas berada di direktori kerja saat ini (direktori tempat Anda menjalankan perintah).
  • --command python: Menetapkan perintah yang akan dieksekusi di dalam penampung. Dalam hal ini, perintahnya adalah untuk menjalankan Python.
  • --args app/indexer.py: Memberikan argumen ke perintah python. Tindakan ini akan memerintahkannya untuk menjalankan skrip indexer.py di direktori aplikasi.
  • --set-env-vars: Menetapkan variabel lingkungan yang dapat diakses oleh skrip Python selama eksekusi.
  • --region=$REGION: Menentukan region tempat tugas harus di-deploy.
  • --execute-now: Memberi tahu Cloud Run untuk segera memulai tugas setelah di-deploy.

Untuk memverifikasi bahwa tugas berhasil diselesaikan, Anda dapat melakukan hal berikut:

  • Baca log eksekusi tugas melalui konsol web. Tindakan ini akan melaporkan "Selesai menyimpan: catatan rilis xxx" (dengan xxx adalah jumlah catatan rilis yang disimpan).
  • Anda juga dapat membuka instance Cloud SQL di konsol web, dan menggunakan Cloud SQL Studio untuk membuat kueri jumlah data dalam tabel langchain_pg_embedding.

6. Menulis aplikasi web

Buka file app/server.py di editor Anda. Anda akan menemukan baris yang bertuliskan hal berikut:

# Edit this to add the chain you want to add

Ganti komentar tersebut dengan cuplikan berikut:

# (1) Initialize VectorStore
connector = Connector()


def getconn() -> pg8000.dbapi.Connection:
    conn: pg8000.dbapi.Connection = connector.connect(
        os.getenv("DB_INSTANCE_NAME", ""),
        "pg8000",
        user=os.getenv("DB_USER", ""),
        password=os.getenv("DB_PASS", ""),
        db=os.getenv("DB_NAME", ""),
    )
    return conn


vectorstore = PGVector(
    connection_string="postgresql+pg8000://",
    use_jsonb=True,
    engine_args=dict(
        creator=getconn,
    ),
    embedding_function=VertexAIEmbeddings(
        model_name="textembedding-gecko@003"
    )
)

# (2) Build retriever


def concatenate_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


notes_retriever = vectorstore.as_retriever() | concatenate_docs

# (3) Create prompt template
prompt_template = PromptTemplate.from_template(
    """You are a Cloud Run expert answering questions. 
Use the retrieved release notes to answer questions
Give a concise answer, and if you are unsure of the answer, just say so.

Release notes: {notes}

Here is your question: {query}
Your answer: """)

# (4) Initialize LLM
llm = VertexAI(
    model_name="gemini-1.0-pro-001",
    temperature=0.2,
    max_output_tokens=100,
    top_k=40,
    top_p=0.95
)

# (5) Chain everything together
chain = (
    RunnableParallel({
        "notes": notes_retriever,
        "query": RunnablePassthrough()
    })
    | prompt_template
    | llm
    | StrOutputParser()
)

Anda juga perlu menambahkan impor ini:

import pg8000
import os
from google.cloud.sql.connector import Connector
from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings
from langchain_core.runnables import RunnablePassthrough, RunnableParallel
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_community.vectorstores.pgvector import PGVector

Terakhir, ubah baris yang bertuliskan "NotImplemented" menjadi:

# add_routes(app, NotImplemented)
add_routes(app, chain)

7. Men-deploy aplikasi web ke Cloud Run

Dari direktori run-rag, gunakan perintah berikut untuk men-deploy aplikasi ke Cloud Run:

DB_INSTANCE_NAME=$(gcloud sql instances describe sql-instance --format="value(connectionName)")

gcloud run deploy run-rag \
  --source . \
  --set-env-vars=DB_INSTANCE_NAME=$DB_INSTANCE_NAME \
  --set-env-vars=DB_USER=app \
  --set-env-vars=DB_NAME=release-notes \
  --set-env-vars=DB_PASS=myprecious \
  --region=$REGION \
  --allow-unauthenticated

Perintah ini akan melakukan hal berikut:

  • Mengupload kode sumber ke Cloud Build
  • Jalankan build docker.
  • Kirim image container yang dihasilkan ke Artifact Registry.
  • Buat layanan Cloud Run menggunakan image container.

Setelah selesai, perintah ini akan mencantumkan URL HTTPS di domain run.app. Ini adalah URL publik layanan Cloud Run baru Anda

8. Jelajahi taman bermain

Buka URL layanan Cloud Run dan buka /playground. Tindakan ini akan menampilkan kolom teks. Gunakan untuk mengajukan pertanyaan tentang catatan rilis Cloud Run, seperti di sini:

9. Selamat

Anda telah berhasil mem-build dan men-deploy aplikasi LangChain di Cloud Run. Bagus!

Berikut adalah konsep utamanya:

  • Menggunakan framework LangChain untuk mem-build aplikasi Retrieval Augmented Generation (RAG).
  • Menggunakan PostgreSQL di Cloud SQL sebagai database vektor dengan pgvector, yang diinstal secara default di Cloud SQL.
  • Jalankan tugas pengindeksan yang berjalan lebih lama sebagai tugas Cloud Run dan aplikasi web sebagai layanan Cloud Run.
  • Gabungkan rantai LangChain dalam aplikasi FastAPI dengan LangServe, sehingga menyediakan antarmuka yang praktis untuk berinteraksi dengan aplikasi RAG Anda.

Pembersihan

Agar tidak menimbulkan biaya pada akun Google Cloud Platform Anda untuk resource yang digunakan dalam tutorial ini:

  • Di Cloud Console, buka halaman Manage resources.
  • Dalam daftar project, pilih project Anda lalu klik Hapus.
  • Pada dialog, ketik project ID, lalu klik Shut Down untuk menghapus project.

Jika Anda ingin mempertahankan project, pastikan untuk menghapus resource berikut:

  • Instance Cloud SQL
  • Layanan Cloud Run
  • Tugas Cloud Run