التعرُّف على كيفية إنشاء تطبيق 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
    • الشعر لإدارة التبعية
    • pipx لتثبيت واجهة سطر الأوامر LangChain والشعر في بيئات افتراضية معزولة

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

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

بدلاً من جهازك المحلي، يمكنك أيضًا استخدام "محطات عمل 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، والشعر لإدارة التبعيات. في ما يلي كيفية تثبيت هذه التطبيقات باستخدام pipx:

pipx install langchain-cli poetry

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

langchain app new

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

poetry install

لقد أنشأت للتو تطبيق LangServe. يلتف موقع FastAPI حول سلسلة LangChain في موقع LangSete. يتضمّن الجهاز مساحة اختبار مدمجة تسهِّل إرسال الطلبات وفحص النتائج، بما في ذلك جميع خطوات الوسيط. أقترح عليك فتح المجلد "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

أخيرًا، غيِّر السطر الذي يشير إلى "Not approveded" (لم يتم التنفيذ) إلى:

# 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 build.
  • أرسِل صورة الحاوية الناتجة إلى Artifact Registry.
  • أنشئ خدمة تشغيل السحابة الإلكترونية باستخدام صورة الحاوية.

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

8. استكشاف ساحة الألعاب

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

9. تهانينا

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

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

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

تَنظيم

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

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

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

  • مثيل Cloud SQL
  • خدمة تشغيل السحابة الإلكترونية
  • مهمة تشغيل السحابة الإلكترونية