با نحوه ساخت و استقرار یک برنامه LangChain در Cloud Run آشنا شوید

۱. مرور کلی

در این آزمایشگاه کد، یاد خواهید گرفت که چگونه یک برنامه LangChain را مستقر کنید که از Gemini استفاده می‌کند تا به شما امکان دهد از طریق یادداشت‌های انتشار Cloud Run سؤال بپرسید.

در اینجا مثالی از نحوه کار برنامه آورده شده است: اگر این سوال را بپرسید که «آیا می‌توانم یک سطل ذخیره‌سازی ابری را به عنوان یک حجم در Cloud Run نصب کنم؟»، برنامه با عبارت «بله، از ۱۹ ژانویه ۲۰۲۴» یا چیزی شبیه به آن پاسخ می‌دهد.

برای بازگرداندن پاسخ‌های پایه، برنامه ابتدا یادداشت‌های انتشار Cloud Run را که مشابه سوال هستند، بازیابی می‌کند، سپس Gemini را با هر دو سوال و یادداشت‌های انتشار فراخوانی می‌کند. (این الگویی است که معمولاً به عنوان RAG شناخته می‌شود.) در اینجا نموداری وجود دارد که معماری برنامه را نشان می‌دهد:

۲. تنظیمات و الزامات

ابتدا، بیایید مطمئن شویم که محیط توسعه شما به درستی تنظیم شده است.

  • برای استقرار منابع مورد نیاز برنامه، به یک پروژه Google Cloud نیاز دارید.
  • برای استقرار برنامه، باید gcloud را روی دستگاه محلی خود نصب کرده ، احراز هویت کرده و برای استفاده از پروژه پیکربندی کنید.
    • gcloud auth login
    • gcloud config set project
  • اگر می‌خواهید برنامه را روی دستگاه محلی خود اجرا کنید، که من توصیه می‌کنم، باید مطمئن شوید که اعتبارنامه‌های پیش‌فرض برنامه شما به درستی تنظیم شده‌اند، از جمله تنظیم پروژه سهمیه .
    • gcloud auth application-default login
    • gcloud auth application-default set-quota-project
  • همچنین باید نرم‌افزارهای زیر را نصب کرده باشید:
    • پایتون (نسخه ۳.۱۱ یا بالاتر مورد نیاز است)
    • رابط خط فرمان لانگ‌چین
    • شعر برای مدیریت وابستگی
    • pipx برای نصب و اجرای رابط خط فرمان LangChain و Poetry در محیط‌های مجازی ایزوله

این وبلاگ به شما کمک می‌کند تا ابزارهای مورد نیاز برای این راهنما را نصب کنید .

ایستگاه‌های کاری ابری

به جای دستگاه محلی خود، می‌توانید از Cloud Workstations در Google Cloud نیز استفاده کنید. توجه داشته باشید که از آوریل 2024، نسخه پایتون آن پایین‌تر از 3.11 است، بنابراین ممکن است قبل از شروع، نیاز به ارتقاء پایتون داشته باشید.

فعال کردن APIهای ابری

ابتدا، دستور زیر را اجرا کنید تا مطمئن شوید که پروژه صحیح Google Cloud را برای استفاده پیکربندی کرده‌اید:

gcloud config list project

اگر پروژه صحیح نمایش داده نمی‌شود، می‌توانید آن را با این دستور تنظیم کنید:

gcloud config set project <PROJECT_ID>

حالا API های زیر را فعال کنید:

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

یک منطقه را انتخاب کنید

گوگل کلود در بسیاری از نقاط جهان در دسترس است و شما باید یکی را برای استقرار منابعی که برای این آزمایش استفاده خواهید کرد، انتخاب کنید. منطقه را به عنوان یک متغیر محیطی در پوسته خود تنظیم کنید (دستورات بعدی از این متغیر استفاده می‌کنند):

export REGION=us-central1

۳. نمونه پایگاه داده برداری را ایجاد کنید

بخش کلیدی این برنامه، بازیابی یادداشت‌های انتشار مرتبط با سوال کاربر است. برای ملموس‌تر شدن این موضوع، اگر در مورد فضای ذخیره‌سازی ابری سوالی می‌پرسید، می‌خواهید یادداشت انتشار زیر به اعلان اضافه شود:

شما می‌توانید از جاسازی‌های متنی و یک پایگاه داده برداری برای یافتن یادداشت‌های انتشار مشابه از نظر معنایی استفاده کنید.

من به شما نشان خواهم داد که چگونه از PostgreSQL روی Cloud SQL به عنوان یک پایگاه داده برداری استفاده کنید. ایجاد یک نمونه جدید Cloud SQL کمی زمان می‌برد، بنابراین بیایید همین حالا این کار را انجام دهیم.

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

می‌توانید اجازه دهید این دستور اجرا شود و مراحل بعدی را ادامه دهید. در مقطعی باید یک پایگاه داده ایجاد کنید و یک کاربر اضافه کنید، اما بیایید الان وقت را با تماشای اسپینر تلف نکنیم.

PostgreSQL یک سرور پایگاه داده رابطه‌ای است و هر نمونه جدید از Cloud SQL به طور پیش‌فرض افزونه pgvector را نصب دارد، به این معنی که می‌توانید از آن به عنوان یک پایگاه داده برداری نیز استفاده کنید.

۴. برنامه LangChain را در چارچوب قرار دهید

برای ادامه، باید رابط خط فرمان LangChain و همچنین Poetry را برای مدیریت وابستگی‌ها نصب کرده باشید. در اینجا نحوه نصب آنها با استفاده از pipx آورده شده است:

pipx install langchain-cli poetry

برنامه LangChain را با دستور زیر Scaffold کنید. وقتی از شما خواسته شد، نام پوشه را run-rag و با فشردن Enter از نصب بسته‌ها صرف نظر کنید:

langchain app new

به پوشه run-rag بروید و وابستگی‌ها را نصب کنید

poetry install

شما به تازگی یک برنامه LangServe ایجاد کرده‌اید. LangServe، FastAPI را حول یک زنجیره LangChain می‌پیچد. این برنامه دارای یک محیط بازی داخلی است که ارسال اعلان‌ها و بررسی نتایج، از جمله تمام مراحل واسطه را آسان می‌کند. پیشنهاد می‌کنم پوشه run-rag را در ویرایشگر خود باز کنید و آنچه در آنجا وجود دارد را بررسی کنید.

۵. ایجاد کار فهرست‌بندی

قبل از شروع به ساخت برنامه وب، مطمئن شوید که یادداشت‌های انتشار Cloud Run در پایگاه داده Cloud SQL فهرست‌بندی شده‌اند. در این بخش، یک کار فهرست‌بندی ایجاد خواهید کرد که موارد زیر را انجام می‌دهد:

کار نمایه‌سازی، یادداشت‌های انتشار را دریافت می‌کند، آنها را با استفاده از یک مدل جاسازی متن به بردار تبدیل می‌کند و در یک پایگاه داده برداری ذخیره می‌کند. این امر امکان جستجوی کارآمد یادداشت‌های انتشار مشابه را بر اساس معنای معنایی آنها فراهم می‌کند.

در پوشه run-rag/app ، فایلی indexer.py با محتوای زیر ایجاد کنید:

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

وابستگی‌های مورد نیاز را اضافه کنید:

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

ایجاد پایگاه داده و یک کاربر

یک release-notes پایگاه داده در نمونه SQL ابری sql-instance ایجاد کنید:

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

یک کاربر پایگاه داده به نام app ایجاد کنید:

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

استقرار و اجرای کار نمایه‌سازی

اکنون کار را مستقر و اجرا کنید:

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

این یک دستور طولانی است، بیایید نگاهی به آنچه اتفاق می‌افتد بیندازیم:

دستور اول نام اتصال (یک شناسه منحصر به فرد با فرمت project:region:instance ) را بازیابی کرده و آن را به عنوان متغیر محیطی DB_INSTANCE_NAME تنظیم می‌کند.

دستور دوم، عملیات Cloud Run را اجرا می‌کند. عملکرد پرچم‌ها به شرح زیر است:

  • --source . : مشخص می‌کند که کد منبع مربوط به کار در دایرکتوری کاری فعلی (دایرکتوری که دستور را در آن اجرا می‌کنید) قرار دارد.
  • --command python : دستوری را که باید درون کانتینر اجرا شود، تنظیم می‌کند. در این مورد، این دستور برای اجرای پایتون است.
  • --args app/indexer.py : آرگومان‌های دستور پایتون را ارائه می‌دهد. این به آن می‌گوید که اسکریپت indexer.py را در دایرکتوری app اجرا کند.
  • --set-env-vars : متغیرهای محیطی را که اسکریپت پایتون می‌تواند در حین اجرا به آنها دسترسی داشته باشد، تنظیم می‌کند.
  • --region=$REGION : منطقه‌ای را که کار باید در آن مستقر شود، مشخص می‌کند.
  • --execute-now : به Cloud Run می‌گوید که کار را بلافاصله پس از استقرار آن آغاز کند.

برای تأیید اینکه کار با موفقیت انجام شده است، می‌توانید موارد زیر را انجام دهید:

  • گزارش‌های اجرای کار را از طریق کنسول وب بخوانید. باید عبارت «ذخیره‌سازی انجام شد: یادداشت‌های انتشار xxx» (که xxx تعداد یادداشت‌های انتشار ذخیره شده است) را گزارش دهد.
  • همچنین می‌توانید در کنسول وب به نمونه Cloud SQL بروید و از Cloud SQL Studio برای پرس‌وجوی تعداد رکوردهای جدول langchain_pg_embedding استفاده کنید.

۶. برنامه وب را بنویسید

فایل app/server.py در ویرایشگر خود باز کنید. خطی با محتوای زیر خواهید یافت:

# Edit this to add the chain you want to add

آن کامنت را با قطعه کد زیر جایگزین کنید:

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

شما همچنین باید این ایمپورت‌ها را اضافه کنید:

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

در نهایت، خطی که می‌گوید "NotImplemented" را به صورت زیر تغییر دهید:

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

۷. برنامه وب را روی Cloud Run مستقر کنید

از پوشه run-rag ، از دستور زیر برای استقرار برنامه در 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

این دستور کارهای زیر را انجام می‌دهد:

  • کد منبع را در Cloud Build بارگذاری کنید
  • دستور docker build را اجرا کنید.
  • تصویر کانتینر حاصل را به رجیستری مصنوعات (Artifact Registry) منتقل کنید.
  • با استفاده از تصویر کانتینر، یک سرویس Cloud Run ایجاد کنید.

وقتی دستور کامل شد، یک آدرس اینترنتی HTTPS در دامنه run.app نمایش داده می‌شود. این آدرس اینترنتی عمومی سرویس Cloud Run جدید شماست.

۸. زمین بازی را کاوش کنید

آدرس اینترنتی سرویس Cloud Run را باز کنید و به /playground بروید. این یک فیلد متنی را نمایش می‌دهد. از آن برای پرسیدن سوالات در مورد یادداشت‌های انتشار Cloud Run استفاده کنید، مانند اینجا:

۹. تبریک

شما با موفقیت یک برنامه LangChain را در Cloud Run ساختید و مستقر کردید. آفرین!

در اینجا مفاهیم کلیدی آمده است:

  • استفاده از چارچوب LangChain برای ساخت یک برنامه بازیابی نسل افزوده (RAG).
  • استفاده از PostgreSQL روی Cloud SQL به عنوان یک پایگاه داده برداری با pgvector که به طور پیش فرض روی Cloud SQL نصب شده است.
  • یک کار نمایه‌سازی طولانی‌تر را به عنوان یک کار Cloud Run و یک برنامه وب را به عنوان یک سرویس Cloud Run اجرا کنید.
  • با استفاده از LangServe، یک زنجیره LangChain را در یک برنامه FastAPI قرار دهید و رابط کاربری مناسبی برای تعامل با برنامه RAG خود فراهم کنید.

تمیز کردن

برای جلوگیری از تحمیل هزینه به حساب پلتفرم گوگل کلود خود برای منابع استفاده شده در این آموزش:

  • در کنسول ابری، به صفحه مدیریت منابع بروید.
  • در لیست پروژه‌ها، پروژه خود را انتخاب کنید و سپس روی حذف کلیک کنید.
  • در کادر محاوره‌ای، شناسه پروژه را تایپ کنید و سپس برای حذف پروژه، روی خاموش کردن (Shut down) کلیک کنید.

اگر می‌خواهید پروژه را نگه دارید، حتماً منابع زیر را حذف کنید:

  • نمونه SQL ابری
  • سرویس کلود ران
  • شغل اجرای ابری