التعرُّف على كيفية إنشاء تطبيق LangChain ونشره على Cloud Run

1. نظرة عامة

في هذا الدرس التطبيقي حول الرموز البرمجية، ستتعرّف على كيفية نشر تطبيق LangChain يستخدم Gemini للسماح لك بطرح أسئلة حول ملاحظات إصدار Cloud Run.

في ما يلي مثال على طريقة عمل التطبيق: إذا طرحت السؤال "هل يمكنني ربط حزمة تخزين في Cloud Storage كوحدة تخزين في Cloud Run؟"، سيجيب التطبيق "نعم، منذ 19 كانون الثاني (يناير) 2024" أو ما شابه ذلك.

لعرض ردود مستندة إلى الحقائق، يسترجع التطبيق أولاً ملاحظات إصدار Cloud Run المشابهة للسؤال، ثم يعرض على Gemini كلّ من السؤال وملاحظات الإصدار. (هذا نمط يشار إليه عادةً باسم RAG). في ما يلي مخطّط بياني يعرض بنية التطبيق:

2. الإعداد والمتطلبات

أولاً، لنتأكد من إعداد بيئة التطوير بشكلٍ صحيح.

  • ستحتاج إلى مشروع على Google Cloud لنشر الموارد التي ستحتاج إليها للتطبيق.
  • لنشر التطبيق، يجب تثبيت gcloud على جهازك المحلي والمصادقة عليه وضبطه لاستخدام المشروع.
    • gcloud auth login
    • gcloud config set project
  • إذا أردت تشغيل التطبيق على جهازك المحلي، وهو ما أنصح به، عليك التأكّد من إعداد بيانات اعتماد التطبيق التلقائية بشكل صحيح، بما في ذلك ضبط مشروع الحصة.
    • gcloud auth application-default login
    • gcloud auth application-default set-quota-project
  • يجب أيضًا تثبيت البرامج التالية:
    • Python (يجب توفُّر الإصدار 3.11 أو إصدار أحدث)
    • LangChain CLI
    • poetry لإدارة التبعية
    • pipx لتثبيت واجهة سطر أوامر LangChain وpoetry وتشغيلهما في بيئات افتراضية معزولة

إليك مدوّنة تساعدك في بدء تثبيت الأدوات المطلوبة لهذه الجولة الإرشادية.

محطات العمل في السحابة الإلكترونية

بدلاً من جهازك المحلي، يمكنك أيضًا استخدام "محطات عمل Cloud" على Google Cloud. يُرجى العِلم أنّه اعتبارًا من أبريل 2024، سيتم تشغيل إصدار Python أقدم من 3.11، لذا قد تحتاج إلى ترقية Python قبل البدء.

تفعيل واجهات برمجة تطبيقات Cloud

أولاً، شغِّل الأمر التالي للتأكّد من ضبط مشروع 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

3- إنشاء مثيل قاعدة بيانات المتجهات

يتمثل أحد الأجزاء الرئيسية في هذا التطبيق في استرداد ملاحظات الإصدار ذات الصلة بسؤال المستخدم. لتوضيح ذلك بشكل أكبر، إذا كنت تطرح سؤالاً عن Cloud Storage، عليك إضافة ملاحظة الإصدار التالية إلى الطلب:

يمكنك استخدام عمليات تضمين النصوص وقاعدة بيانات متجهات للعثور على ملاحظات الإصدار المتشابهة من الناحية الدلالية.

سأوضح لك كيفية استخدام PostgreSQL على Cloud SQL كقاعدة بيانات متجه. يستغرق إنشاء مثيل Cloud SQL جديد بعض الوقت، لذا دعنا نفعل ذلك الآن.

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

يمكنك السماح بتنفيذ هذا الأمر ومواصلة الخطوات التالية. في مرحلة ما، ستحتاج إلى إنشاء قاعدة بيانات وإضافة مستخدم، ولكن لن نضيع الوقت في مشاهدة مؤشر التقدم الآن.

PostgreSQL هو خادم قاعدة بيانات ارتباطية، ويتم تثبيت الإضافة pgvector تلقائيًا في كل مثيل جديد من Cloud SQL، ما يعني أنّه يمكنك أيضًا استخدامه كقاعدة بيانات متجهة.

4. إنشاء إطار عمل لتطبيق LangChain

للمتابعة، يجب تثبيت LangChain CLI وpoetry لإدارة التبعيات. في ما يلي كيفية تثبيت هذه التطبيقات باستخدام pipx:

pipx install langchain-cli poetry

افتح تطبيق LangChain باستخدام الأمر التالي. أدخِل اسمًا للمجلد run-rag عند طلب ذلك، وتجنَّب تثبيت الحِزم من خلال الضغط على مفتاح Enter:

langchain app new

الانتقال إلى الدليل run-rag وتثبيت المكوّنات الإضافية

poetry install

لقد أنشأت للتو تطبيق LangServe. يُغلِف LangServe FastAPI في سلسلة LangChain. يوفّر هذا التطبيق ساحة لعب مدمجة تسهّل إرسال الطلبات وفحص النتائج، بما في ذلك جميع الخطوات الوسيطة. أنصحك بفتح المجلد run-rag في المحرِّر واستكشاف ما يحتويه.

5- إنشاء وظيفة الفهرسة

قبل البدء في تجميع تطبيق الويب، لنتأكّد من أنّ ملاحظات إصدار 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: يوفّر الوسيطات لأمر python. يطلب هذا الأمر تشغيل النص البرمجي indexer.py في دليل التطبيق.
  • --set-env-vars: لضبط متغيّرات البيئة التي يمكن للنص البرمجي في Python الوصول إليها أثناء التنفيذ.
  • --region=$REGION: تحدّد هذه السمة المنطقة التي يجب نشر الوظيفة فيها.
  • --execute-now: يطلب من Cloud Run بدء المهمة فور نشرها.

للتأكّد من اكتمال المهمة بنجاح، يمكنك إجراء ما يلي:

  • يمكنك قراءة سجلّات تنفيذ المهمة من خلال وحدة تحكّم الويب. من المفترض أن يظهر الردّ "تمّ الحفظ: ملاحظات الإصدار xxx" (حيث يشير xxx إلى عدد ملاحظات الإصدار المحفوظة).
  • يمكنك أيضًا الانتقال إلى مثيل Cloud SQL في وحدة تحكّم الويب، واستخدام Cloud SQL Studio لطلب عدد السجلات في جدول langchain_pg_embedding.

6- كتابة تطبيق الويب

افتح الملف 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)

7- نشر تطبيق الويب على 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 باستخدام صورة الحاوية.

عند اكتمال الأمر، يتم إدراج عنوان URL لبروتوكول HTTPS على نطاق run.app. هذا هو عنوان URL العلني لخدمة Cloud Run الجديدة.

8. استكشاف الملعب

افتح عنوان URL لخدمة Cloud Run وانتقِل إلى /playground. سيؤدي ذلك إلى عرض حقل نص. يمكنك استخدامها لطرح أسئلة حول ملاحظات إصدار Cloud Run، كما هو موضّح هنا:

9. تهانينا

لقد أنشأت تطبيق LangChain ونشرته بنجاح على Cloud Run. أحسنت!

في ما يلي المفاهيم الأساسية:

  • استخدام إطار عمل LangChain لإنشاء تطبيق "الإنشاء المعزّز لاسترداد المعلومات" (RAG)
  • استخدام PostgreSQL على Cloud SQL كقاعدة بيانات متّجه باستخدام pgvector، والذي يتم تثبيته تلقائيًا على Cloud SQL
  • يمكنك تشغيل مهمة فهرسة تستغرق وقتًا أطول كمهام Cloud Run وتطبيق ويب كخدمة Cloud Run.
  • يمكنك استخدام LangServe لتغليف سلسلة LangChain في تطبيق FastAPI، ما يوفر واجهة ملائمة للتفاعل مع تطبيق RAG.

تَنظيم

لتجنُّب تحصيل رسوم من حسابك على Google Cloud Platform مقابل الموارد المستخدَمة في هذا الدليل التعليمي:

  • في Cloud Console، انتقِل إلى صفحة "إدارة الموارد".
  • في قائمة المشاريع، اختَر مشروعك ثم انقر على "حذف".
  • في مربع الحوار، اكتب معرّف المشروع ثم انقر على "إيقاف التشغيل" لحذف المشروع.

إذا كنت تريد الاحتفاظ بالمشروع، تأكَّد من حذف الموارد التالية:

  • مثيل Cloud SQL
  • خدمة Cloud Run
  • مهمة Cloud Run