Cloud Run'da LangChain uygulaması oluşturup dağıtmayı öğrenin

1. Genel Bakış

Bu kod laboratuvarında, Cloud Run sürüm notları aracılığıyla soru sormanıza olanak tanımak için Gemini'ı kullanan bir LangChain uygulamasını nasıl dağıtacağınızı öğreneceksiniz.

Uygulamanın işleyiş şekline dair bir örnek: "Cloud Run'da birim olarak Cloud Storage paketi ekleyebilir miyim?" sorusu sorarsanız uygulama, "19 Ocak 2024'ten itibaren Evet, 19 Ocak 2024'ten itibaren" veya benzer bir yanıt verebilir.

Güvenilir yanıtlar döndürmek için uygulama önce soruya benzer Cloud Run sürüm notlarını alır. Ardından Gemini'a hem soru hem de sürüm notlarını içeren bir istem gönderir. (Bu, genellikle RAG olarak adlandırılan bir kalıptır.) Uygulamanın mimarisini gösteren bir şemayı aşağıda bulabilirsiniz:

2. Kurulum ve şartlar

Öncelikle, geliştirme ortamınızın doğru ayarlandığından emin olalım.

  • Uygulamada ihtiyacınız olacak kaynakları dağıtmak için Google Cloud projesi gerekir.
  • Uygulamayı dağıtmak için yerel makinenizde gcloud'un yüklü, kimliği doğrulanmış ve projeyi kullanacak şekilde yapılandırılmış olması gerekir.
    • gcloud auth login
    • gcloud config set project
  • Uygulamayı yerel makinenizde çalıştırmak istiyorsanız kota projesini ayarlama da dahil olmak üzere uygulama varsayılan kimlik bilgilerinizin doğru şekilde ayarlandığından emin olmanız gerekir.
    • gcloud auth application-default login
    • gcloud auth application-default set-quota-project
  • Ayrıca şu yazılımları da yüklemeniz gerekir:
    • Python (3.11 veya sonraki sürümler gerekir)
    • LangChain CLI
    • Bağımlılık yönetimi için poetry
    • LangChain KSA'yı ve poetry'yi izole sanal ortamlarda yüklemek ve çalıştırmak için pipx

Bu adım adım açıklamalı kılavuz için gereken araçları yüklemeye başlamanıza yardımcı olacak bir blogu burada bulabilirsiniz.

Cloud İş İstasyonları

Yerel makineniz yerine Google Cloud'daki Cloud Workstations'ı da kullanabilirsiniz. Nisan 2024'ten itibaren 3.11'den eski bir Python sürümü çalıştırılacağından, çalışmaya başlamadan önce Python'u yükseltmeniz gerekebilir.

Cloud API'lerini etkinleştirme

Öncelikle aşağıdaki komutu çalıştırarak kullanılacak doğru Google Cloud projesini yapılandırdığınızdan emin olun:

gcloud config list project

Doğru proje gösterilmiyorsa şu komutla projeyi ayarlayabilirsiniz:

gcloud config set project <PROJECT_ID>

Şimdi aşağıdaki API'leri etkinleştirin:

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

Bir bölge seçin

Google Cloud dünya genelinde birçok konumda kullanılabilir. Bu laboratuvar için kullanacağınız kaynakları dağıtmak üzere bir konum seçmeniz gerekir. Bölgeyi, kabuğunuzda bir ortam değişkeni olarak ayarlayın (sonraki komutlar bu değişkeni kullanır):

export REGION=us-central1

3. Vektör veritabanı örneğini oluşturma

Bu uygulamanın önemli bir parçası, kullanıcının sorusuyla alakalı sürüm notları almaktır. Bunu daha somut hale getirmek için Cloud Storage hakkında soru soruyorsanız istem kutusuna aşağıdaki sürüm notunun eklenmesini istersiniz:

Anlamsal olarak benzer sürüm notlarını bulmak için metin yerleştirilmiş öğeleri ve bir vektör veritabanını kullanabilirsiniz.

PostgreSQL'i Cloud SQL'de vektör veritabanı olarak nasıl kullanacağınızı göstereceğim. Yeni Cloud SQL örneği oluşturmak zaman alabilir. Şimdi bu işlemi yapalım.

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

Bu komutun çalışmasına izin verip sonraki adımlara geçebilirsiniz. Bir noktada veritabanı oluşturmanız ve kullanıcı eklemeniz gerekecek. Ancak şimdilik dönen simgeyi izleyerek zaman kaybetmeyelim.

PostgreSQL ilişkisel bir veritabanı sunucusudur ve her yeni Cloud SQL örneğinde varsayılan olarak pgvector uzantısı yüklenmiştir. Bu sayede onu vektör veritabanı olarak da kullanabilirsiniz.

4. LangChain uygulaması için iskelet oluşturma

Devam etmek için LangChain CLI'nin yüklü olması ve bağımlılıkları yönetmek için poetry'nin yüklü olması gerekir. Pipx'i kullanarak bunları nasıl yükleyeceğiniz aşağıda açıklanmıştır:

pipx install langchain-cli poetry

Aşağıdaki komutla LangChain uygulamasını sabitleyin. Sorulduğunda, run-rag klasörünü adlandırın ve Enter tuşuna basarak paket yüklemeyi atlayın:

langchain app new

run-rag dizinine geçin ve bağımlılıkları yükleyin

poetry install

LangServe uygulaması oluşturdunuz. LangServe, FastAPI'yi bir LangChain zincirine sarar. İstem göndermeyi ve tüm ara adımlar da dahil olmak üzere sonuçları incelemeyi kolaylaştıran yerleşik bir oyun alanı bulunur. Düzenleyicinizde run-rag klasörünü açıp içindekileri keşfetmenizi öneririz.

5. Dizine ekleme işi oluşturma

Web uygulamasını oluşturmaya başlamadan önce Cloud Run sürüm notlarının Cloud SQL veritabanında dizine eklendiğinden emin olalım. Bu bölümde şunları yapan bir dizine ekleme işi oluşturacaksınız:

Dizine ekleme işi, sürüm notlarını alır, metin gömme modeli kullanarak vektörlere dönüştürür ve bir vektör veritabanında depolar. Bu sayede, benzer sürüm notlarını semantik anlamlarına göre verimli bir şekilde arayabilirsiniz.

run-rag/app klasöründe aşağıdaki içeriğe sahip bir indexer.py dosyası oluşturun:

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")

Gerekli bağımlılıkları ekleyin:

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

Veritabanı ve kullanıcı oluşturma

sql-instance Cloud SQL örneğinde release-notes veritabanı oluşturun:

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

app adlı bir veritabanı kullanıcısı oluşturun:

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

Dizine ekleme işini dağıtma ve çalıştırma

Şimdi işi dağıtın ve çalıştırın:

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

Bu uzun bir komut. Neler olduğuna bakalım:

İlk komut, bağlantı adını (project:region:instance biçiminde benzersiz bir kimlik) alır ve bunu DB_INSTANCE_NAME ortam değişkeni olarak ayarlar.

İkinci komut Cloud Run işini dağıtır. İşaretlerin işlevi:

  • --source .: İşin kaynak kodunun, geçerli çalışma dizininde (komutu çalıştırdığınız dizin) olduğunu belirtir.
  • --command python: Kapsayıcı içinde çalıştırılacak komutu ayarlar. Bu durumda, Python'u çalıştırmak için kullanılır.
  • --args app/indexer.py: python komutuna bağımsız değişkenleri sağlar. Bu işlem, uygulama dizininde indexer.py komut dosyasını çalıştırmasını belirtir.
  • --set-env-vars: Python komut dosyasının yürütülme sırasında erişebileceği ortam değişkenlerini ayarlar.
  • --region=$REGION: İşin dağıtılması gereken bölgeyi belirtir.
  • --execute-now: Cloud Run'a, dağıtıldıktan hemen sonra işi başlatmasını söyler.

İşin başarıyla tamamlandığını doğrulamak için aşağıdakileri yapabilirsiniz:

  • Web konsolu üzerinden iş yürütme günlüklerini okuyabilirsiniz. "Kayıt tamamlandı: xxx sürüm notu" (xxx, kaydedilen sürüm notu sayısıdır) mesajı gösterilir.
  • Ayrıca web konsolunda Cloud SQL örneğine gidebilir ve langchain_pg_embedding tablosundaki kayıt sayısını sorgulamak için Cloud SQL Studio'yu kullanabilirsiniz.

6. Web uygulamasını yazma

Düzenleyicinizde app/server.py dosyasını açın. Aşağıdaki satırı görürsünüz:

# Edit this to add the chain you want to add

Bu yorumu aşağıdaki snippet ile değiştirin:

# (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()
)

Bu içe aktarma işlemlerini de eklemeniz gerekir:

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

Son olarak, "NotImplemented" yazan satırı değiştirin alıcı:

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

7. Web uygulamasını Cloud Run'a dağıtma

Uygulamayı Cloud Run'a dağıtmak için run-rag dizininden aşağıdaki komutu kullanın:

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

Bu komut şunları yapar:

  • Kaynak kodunu Cloud Build'e yükleme
  • Docker derlemesini çalıştırın.
  • Elde edilen kapsayıcı görüntüsünü Artifact Registry'ye aktarın.
  • Container görüntüsünü kullanarak bir Cloud Run hizmeti oluşturun.

Komut tamamlandığında run.app alanında bir HTTPS URL'si listelenir. Bu, yeni Cloud Run hizmetinizin herkese açık URL'sidir.

8. Oyun alanını keşfetme

Cloud Run hizmet URL'sini açıp /playground adresine gidin. Bir metin alanı açılır. Cloud Run sürüm notları hakkında soru sormak için bu aracı kullanabilirsiniz:

9. Tebrikler

Cloud Run'da LangChain uygulaması oluşturma ve dağıtma işlemlerini başarıyla tamamladınız. Tebrikler!

Temel kavramlar şunlardır:

  • Almayla Artırılmış Üretim (RAG) uygulaması oluşturmak için LangChain çerçevesini kullanma.
  • Cloud SQL'de PostgreSQL, varsayılan olarak Cloud SQL'e yüklü olan pgvector'a sahip bir vektör veritabanı olarak Cloud SQL'de kullanılıyor.
  • Cloud Run işleri olarak daha uzun çalışan bir dizine ekleme işini, Cloud Run hizmeti olarak bir web uygulamasını çalıştırın.
  • Bir LangChain zincirini FastAPI uygulamasında LangServe ile sarmalayarak RAG uygulamanızla etkileşim kurmak için kullanışlı bir arayüz sağlar.

Temizleme

Bu eğiticide kullanılan kaynaklar için Google Cloud Platform hesabınızın ücretlendirilmesini istemiyorsanız şunları yapın:

  • Cloud Console'da "Kaynakları yönetin" sayfasına gidin.
  • Proje listesinde projenizi seçin ve Sil'i tıklayın.
  • İletişim kutusuna proje kimliğini yazın ve ardından projeyi silmek için Kapat'ı tıklayın.

Projeyi saklamak istiyorsanız aşağıdaki kaynakları sildiğinizden emin olun:

  • Cloud SQL örneği
  • Cloud Run hizmeti
  • Cloud Run işi