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

۱. نمای کلی

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

در اینجا مثالی از نحوه عملکرد برنامه آورده شده است: اگر بپرسید «آیا می‌توانم یک مخزن Cloud Storage را به‌عنوان حجم در 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
  • همچنین باید نرم‌افزارهای زیر را نصب کرده باشید:
    • Python (نسخه ۳.۱۱ یا بالاتر الزامی است)
    • LangChain CLI
    • شعر برای مدیریت وابستگی
    • pipx برای نصب و اجرای LangChain CLI و poetry در محیط‌های مجازی مجزا

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

رایانه‌های ابری

به‌جای ماشین محلی، می‌توانید از Cloud Workstations در Google Cloud نیز استفاده کنید. توجه داشته باشید که از آوریل ۲۰۲۴، این ابزار با نسخه Python پایین‌تر از ۳.۱۱ اجرا می‌شود، بنابراین ممکن است قبل‌از شروع کار نیاز به ارتقا دادن Python داشته باشید.

فعال کردن Cloud APIs

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

gcloud config list project

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

gcloud config set project <PROJECT_ID>

اکنون میاناهای برنامه‌سازی کاربردی زیر را فعال کنید:

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

انتخاب منطقه

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

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 را با فرمان زیر داربست‌بندی کنید. وقتی از شما خواسته شد، نام پوشه را run-rag بگذارید و با فشار دادن کلید Enter از نصب بسته‌ها رد شوید:

langchain app new

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

poetry install

به‌تازگی برنامه LangServe را ساخته‌اید. LangServe زنجیره LangChain را در FastAPI می‌پیچد. این مدل با زمین بازی داخلی ارائه می‌شود که ارسال پیام‌واره‌ها و بررسی نتایج، ازجمله همه مراحل واسطه‌ای، را آسان می‌کند. پیشنهاد می‌کنم پوشه 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 را در نمونه Cloud 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: فرمان را برای اجرا در داخل محتوی تنظیم می‌کند. در این مورد، برای اجرای Python است.
  • ‫--args app/indexer.py: آرگومان‌های فرمان پایتون را ارائه می‌دهد. این دستور به آن می‌گوید که نمایه‌گر script.py را در دایرکتوری برنامه اجرا کند.
  • --set-env-vars: متغیرهای محیطی را تنظیم می‌کند که دستورگان Python می‌تواند درطول اجرا به آن‌ها دسترسی داشته باشد.
  • --region=$REGION: منطقه‌ای را که کار باید در آن مستقر شود مشخص می‌کند.
  • ‫--execute-now: به Cloud Run می‌گوید کار را بلافاصله پس‌از استقرار شروع کند.

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

  • گزارش‌های اجرای کار را ازطریق کنسول وب بخوانید. باید «ذخیره‌سازی انجام شد: xxx یادداشت‌های انتشار» را گزارش کند (که در آن xxx تعداد یادداشت‌های انتشار ذخیره‌شده است).
  • همچنین می‌توانید در کنسول وب به نمونه Cloud SQL پیمایش کنید و از استودیو Cloud SQL برای پُرسمان تعداد گزارش‌ها در جدول 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.
  • تصویر محتوی حاصل را به 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 اجرا کنید.
  • زنجیره LangChain را در برنامه FastAPI با LangServe بسته‌بندی کنید و رابط مناسبی برای تعامل با برنامه RAG خود ارائه دهید.

مرتب‌سازی

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

  • در «کنسول Cloud»، به صفحه «مدیریت منابع» بروید.
  • در فهرست پروژه، پروژه خود را انتخاب کنید و سپس روی «حذف» کلیک کنید.
  • در چارگوش گفتگو، شناسه پروژه را تایپ کنید و سپس روی «خاموش کردن» کلیک کنید تا پروژه حذف شود.

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

  • نمونه Cloud SQL
  • خدمات Cloud Run
  • کار Cloud Run