Codelab - یک برنامه پیشنهادی یوگا پوزهای متنی با Firestore، Vector Search، Langchain و Gemini (نسخه پایتون) بسازید.

1. مقدمه

در این نرم افزار کد، اپلیکیشنی خواهید ساخت که از جستجوی برداری برای توصیه ژست های یوگا استفاده می کند.

از طریق کد لبه، شما یک رویکرد گام به گام را به شرح زیر به کار خواهید گرفت:

  1. از مجموعه داده‌های موجود در آغوش گرفتن صورت یوگا (فرمت JSON) استفاده کنید.
  2. مجموعه داده را با یک توضیح فیلد اضافی که از Gemini برای تولید توضیحات برای هر یک از حالت ها استفاده می کند، تقویت کنید.
  3. از Langchain برای ایجاد یک Document، استفاده از Firestore Langchain ادغام برای ایجاد مجموعه و embedding ها در Firestore.
  4. یک نمایه ترکیبی در Firestore ایجاد کنید تا امکان جستجوی برداری فراهم شود.
  5. از جستجوی برداری در یک برنامه Flask استفاده کنید که همه چیز را مطابق شکل زیر گرد هم می آورد:

84e1cbf29cbaeedc.png

کاری که خواهی کرد

  • طراحی، ساخت و استقرار یک برنامه وب که از جستجوی برداری برای توصیه ژست های یوگا استفاده می کند.

چیزی که یاد خواهید گرفت

  • نحوه استفاده از Gemini برای تولید محتوای متنی و در چارچوب این کد لبه، توضیحاتی برای ژست‌های یوگا ایجاد کنید
  • نحوه استفاده از لودر اسناد Langchain برای Firestore برای بارگیری رکوردها از مجموعه داده های پیشرفته از Hugging Face به Firestore همراه با جاسازی های برداری
  • نحوه استفاده از Langchain Vector Store برای Firestore برای جستجوی داده ها بر اساس یک جستار زبان طبیعی
  • نحوه استفاده از Google Cloud Text to Speech API برای تولید محتوای صوتی

آنچه شما نیاز دارید

  • مرورگر وب کروم
  • یک اکانت جیمیل
  • یک پروژه Cloud با فعال کردن صورت‌حساب

این کد لبه که برای توسعه دهندگان همه سطوح (از جمله مبتدیان) طراحی شده است، از پایتون در برنامه نمونه خود استفاده می کند. با این حال، دانش پایتون برای درک مفاهیم ارائه شده مورد نیاز نیست.

2. قبل از شروع

یک پروژه ایجاد کنید

  1. در Google Cloud Console ، در صفحه انتخاب پروژه، یک پروژه Google Cloud را انتخاب یا ایجاد کنید.
  2. مطمئن شوید که صورتحساب برای پروژه Cloud شما فعال است. با نحوه بررسی فعال بودن صورت‌حساب در پروژه آشنا شوید.
  3. شما از Cloud Shell استفاده خواهید کرد، یک محیط خط فرمان در حال اجرا در Google Cloud که با bq از قبل بارگذاری شده است. روی Activate Cloud Shell در بالای کنسول Google Cloud کلیک کنید.

تصویر دکمه Cloud Shell را فعال کنید

  1. پس از اتصال به Cloud Shell، با استفاده از دستور زیر بررسی می‌کنید که قبلاً احراز هویت شده‌اید و پروژه به ID پروژه شما تنظیم شده است:
gcloud auth list
  1. دستور زیر را در Cloud Shell اجرا کنید تا تأیید کنید که دستور gcloud از پروژه شما اطلاع دارد.
gcloud config list project
  1. اگر پروژه شما تنظیم نشده است، از دستور زیر برای تنظیم آن استفاده کنید:
gcloud config set project <YOUR_PROJECT_ID>
  1. API های مورد نیاز را از طریق دستور زیر فعال کنید. این ممکن است چند دقیقه طول بکشد، پس لطفا صبور باشید.
gcloud services enable firestore.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       cloudfunctions.googleapis.com \
                       aiplatform.googleapis.com \
                       texttospeech.googleapis.com

در اجرای موفقیت آمیز دستور، باید پیامی مشابه تصویر زیر مشاهده کنید:

Operation "operations/..." finished successfully.

جایگزین دستور gcloud از طریق کنسول با جستجوی هر محصول یا استفاده از این پیوند است.

اگر هر یک از API از دست رفته است، همیشه می توانید آن را در طول پیاده سازی فعال کنید.

برای دستورات و استفاده از gcloud به اسناد مراجعه کنید.

کلون کردن مخزن و تنظیمات محیط راه اندازی

گام بعدی کلون کردن مخزن نمونه است که در بقیه قسمت های Codelab به آن ارجاع خواهیم داد. با فرض اینکه در Cloud Shell هستید، دستور زیر را از دایرکتوری خانه خود بدهید:

git clone https://github.com/rominirani/yoga-poses-recommender-python

برای راه اندازی ویرایشگر، روی Open Editor در نوار ابزار پنجره Cloud Shell کلیک کنید. روی نوار منو در گوشه بالا سمت چپ کلیک کنید و مانند تصویر زیر، File → Open Folder را انتخاب کنید:

66221fd0d0e5202f.png

پوشه yoga-poses-recommender-python را انتخاب کنید و مطابق شکل زیر باید فولدر را با فایل های زیر باز کنید:

44699efc7fb1b911.png

اکنون باید متغیرهای محیطی را که باید استفاده کنیم، تنظیم کنیم. روی فایل config.template.yaml کلیک کنید و محتویات آن را مطابق شکل زیر مشاهده خواهید کرد:

project_id: your-project-id
location: us-central1
gemini_model_name: gemini-1.5-flash-002
embedding_model_name: text-embedding-004
image_generation_model_name: imagen-3.0-fast-generate-002
database: (default)
collection: poses
test_collection: test-poses
top_k: "3"

لطفاً هنگام ایجاد منطقه Google Cloud Project و Firestore پایگاه داده، مقادیر project_id و location را مطابق آنچه انتخاب کرده‌اید، به‌روزرسانی کنید. در حالت ایده‌آل، ما می‌خواهیم مقادیر location برای پروژه Google Cloud و پایگاه داده Firestore یکسان باشد، برای مثال us-central1 .

برای هدف این نرم افزار کد، ما قصد داریم مقادیر از پیش پیکربندی شده را دنبال کنیم (البته به جز project_id و location که باید طبق پیکربندی خود تنظیم کنید).

لطفاً این فایل را به عنوان config.yaml در همان پوشه ای که فایل config.template.yaml قرار دارد ذخیره کنید.

مرحله آخر در حال حاضر ایجاد یک محیط پایتون است که به صورت محلی با تمام وابستگی های پایتون برای ما تنظیم شده است استفاده کنیم. به فایل pyproject.toml که حاوی جزئیات مربوط به آن است، نگاهی بیندازید که محتویات آن در زیر نشان داده شده است:

dependencies = [
    "datasets>=3.2.0",
    "flask>=3.1.0",
    "google-cloud-aiplatform>=1.78.0",
    "google-cloud-texttospeech>=2.24.0",
    "langchain-community>=0.3.15",
    "langchain-core>=0.3.31",
    "langchain-google-community>=2.0.4",
    "langchain-google-firestore>=0.5.0",
    "langchain-google-vertexai>=2.0.7",
    "pydantic-settings>=2.7.1",
    "pyyaml>=6.0.2",
    "tenacity>=9.0.0",
]

این وابستگی‌ها قبلاً نسخه قفل شده‌اند در requirements.txt . به طور خلاصه، باید یک محیط پایتون مجازی با وابستگی های بسته پایتون در requirements.txt ایجاد کنیم تا در محیط مجازی نصب شود. برای انجام این کار، به Command Palette (Ctrl+Shift+P) در Cloud Shell IDE بروید و Python: Create Environment تایپ کنید. چند مرحله بعدی را برای انتخاب یک Virtual Environment(venv) ، Python 3.x interpreter و فایل requirements.txt دنبال کنید.

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

source .venv/bin/activate

شما باید (.venv) را در کنسول خود ببینید. به عنوان مثال -> (.venv) yourusername@cloudshell:

عالیه اکنون همه آماده هستیم تا به کار راه اندازی پایگاه داده Firestore برویم.

3. Firestore را راه اندازی کنید

Cloud Firestore یک پایگاه داده اسناد بدون سرور کاملاً مدیریت شده است که ما از آن به عنوان پشتیبان برای داده های برنامه خود استفاده خواهیم کرد. داده ها در Cloud Firestore در مجموعه ای از اسناد ساختار یافته اند.

راه اندازی پایگاه داده Firestore

از صفحه Firestore در کنسول Cloud دیدن کنید.

اگر قبلاً در پروژه پایگاه داده Firestore را مقداردهی اولیه نکرده اید، با کلیک بر روی Create Database پایگاه داده default را ایجاد کنید. در هنگام ایجاد پایگاه داده، مقادیر زیر را دنبال کنید:

  • حالت Firestore: Native.
  • مکان: با تنظیمات موقعیت مکانی پیش فرض بروید.
  • برای قوانین امنیتی، با Test rules بروید.
  • پایگاه داده را ایجاد کنید.

504cabdb99a222a5.png

در بخش بعدی، زمینه ایجاد مجموعه ای به نام poses در پایگاه داده Firestore پیش فرض خود ایجاد می کنیم. این مجموعه داده های نمونه (اسناد) یا اطلاعات پوزهای یوگا را در خود نگه می دارد که سپس در برنامه خود از آنها استفاده خواهیم کرد.

این بخش راه اندازی پایگاه داده Firestore را تکمیل می کند.

4. مجموعه داده پوزهای یوگا را آماده کنید

اولین وظیفه ما این است که مجموعه داده Yoga Poses را آماده کنیم که از آن برای برنامه استفاده خواهیم کرد. ما با مجموعه داده Hagging Face موجود شروع می کنیم و سپس آن را با اطلاعات اضافی تقویت می کنیم.

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

298cfae7f23e4bef.png

اگر به قسمت Files and versions برویم، می توانیم فایل داده JSON را برای همه پوزها دریافت کنیم.

3fe6e55abdc032ec.png

ما yoga_poses.json را دانلود کرده ایم و آن فایل را در اختیار شما قرار داده ایم. نام این فایل yoga_poses_alldata.json است و در پوشه /data وجود دارد.

به فایل data/yoga_poses.json در ویرایشگر پوسته ابری بروید و نگاهی به لیست اشیاء JSON بیندازید، جایی که هر شی JSON نشان دهنده یک حالت یوگا است. ما در مجموع 3 رکورد داریم و یک نمونه رکورد در زیر نشان داده شده است:

{
   "name": "Big Toe Pose",
   "sanskrit_name": "Padangusthasana",
   "photo_url": "https://pocketyoga.com/assets/images/full/ForwardBendBigToe.png",
   "expertise_level": "Beginner",
   "pose_type": ["Standing", "Forward Bend"]
 }

اکنون یک فرصت عالی برای ما است تا Gemini را معرفی کنیم و اینکه چگونه می توانیم از خود مدل پیش فرض برای ایجاد یک فیلد description برای آن استفاده کنیم.

در ویرایشگر پوسته ابری، به فایل generate-descriptions.py بروید. محتویات این فایل در زیر نشان داده شده است:

import json
import time
import logging
import vertexai
from langchain_google_vertexai import VertexAI
from tenacity import retry, stop_after_attempt, wait_exponential
from settings import get_settings

settings = get_settings()
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
# Initialize Vertex AI SDK
vertexai.init(project=settings.project_id, location=settings.location)
logging.info("Done Initializing Vertex AI SDK")


@retry(
    stop=stop_after_attempt(5),
    wait=wait_exponential(multiplier=1, min=4, max=10),
)
def generate_description(pose_name, sanskrit_name, expertise_level, pose_types):
    """Generates a description for a yoga pose using the Gemini API."""

    prompt = f"""
    Generate a concise description (max 50 words) for the yoga pose: {pose_name}
    Also known as: {sanskrit_name}
    Expertise Level: {expertise_level}
    Pose Type: {", ".join(pose_types)}

    Include key benefits and any important alignment cues.
    """
    try:
        model = VertexAI(model_name=settings.gemini_model_name, verbose=True)
        response = model.invoke(prompt)
        return response
    except Exception as e:
        logging.info(f"Error generating description for {pose_name}: {e}")
        return ""


def add_descriptions_to_json(input_file, output_file):
    """Loads JSON data, adds descriptions, and saves the updated data."""

    with open(input_file, "r") as f:
        yoga_poses = json.load(f)

    total_poses = len(yoga_poses)
    processed_count = 0

    for pose in yoga_poses:
        if pose["name"] != " Pose":
            start_time = time.time()  # Record start time
            pose["description"] = generate_description(
                pose["name"],
                pose["sanskrit_name"],
                pose["expertise_level"],
                pose["pose_type"],
            )
            end_time = time.time()  # Record end time

            processed_count += 1
            end_time = time.time()  # Record end time
            time_taken = end_time - start_time
            logging.info(
                f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
            )

        else:
            pose["description"] = ""
            processed_count += 1
            logging.info(
                f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
            )
        # Adding a delay to avoid rate limit
        time.sleep(30)

    with open(output_file, "w") as f:
        json.dump(yoga_poses, f, indent=2)


def main():
    # File paths
    input_file = "./data/yoga_poses.json"
    output_file = "./data/yoga_poses_with_descriptions.json"

    # Add descriptions and save the updated JSON
    add_descriptions_to_json(input_file, output_file)


if __name__ == "__main__":
    main()

این برنامه یک فیلد description جدید به هر رکورد JSON ژست یوگا اضافه می کند. توضیحات را از طریق تماس با مدل Gemini بدست می‌آورد، جایی که ما اعلان لازم را به آن ارائه می‌کنیم. فیلد به فایل JSON اضافه می شود و فایل جدید در فایل data/yoga_poses_with_descriptions.json نوشته می شود.

بیایید مراحل اصلی را طی کنیم:

  1. در تابع main() خواهید دید که تابع add_descriptions_to_json را فراخوانی می کند و فایل ورودی و فایل خروجی مورد انتظار را ارائه می کند.
  2. تابع add_descriptions_to_json کارهای زیر را برای هر رکورد JSON انجام می دهد، یعنی اطلاعات پست یوگا:
  3. pose_name , sanskrit_name , expertise_level و pose_types استخراج می کند .
  4. تابعgene_description را فراخوانی می‌کند که یک اعلان می‌سازد و سپس کلاس مدل Langchain VertexAI را برای دریافت متن پاسخ فراخوانی می‌کند.
  5. سپس این متن پاسخ به شی JSON اضافه می شود.
  6. لیست به روز شده JSON از اشیاء سپس در فایل مقصد نوشته می شود.

اجازه دهید این برنامه را اجرا کنیم. یک پنجره ترمینال جدید (Ctrl+Shift+C) راه اندازی کنید و دستور زیر را بدهید:

python generate-descriptions.py

اگر مجوزی از شما خواسته شد، لطفاً ادامه دهید و آن را ارائه دهید.

متوجه خواهید شد که برنامه شروع به اجرا می کند. برای جلوگیری از هر گونه سهمیه محدودیت نرخی که ممکن است در حساب‌های جدید Google Cloud وجود داشته باشد، 30 ثانیه تاخیر بین رکوردها اضافه کرده‌ایم، بنابراین لطفاً صبور باشید.

یک نمونه اجرا در حال انجام در زیر نشان داده شده است:

8e830d9ea9b6c60.png

هنگامی که هر 3 رکورد با تماس جمینی بهبود یافتند، یک فایل data/yoga_poses_with_description.json ایجاد خواهد شد. می توانید نگاهی به آن بیندازید.

ما اکنون با فایل داده خود آماده هستیم و گام بعدی این است که بدانیم چگونه یک پایگاه داده Firestore را با آن پر کنیم، همراه با تولید embeddings.

5. وارد کردن داده ها به Firestore و تولید Vector Embeddings

ما فایل data/yoga_poses_with_description.json را داریم و اکنون باید پایگاه داده Firestore را با آن پر کنیم و مهمتر از همه، جاسازی های برداری را برای هر یک از رکوردها ایجاد کنیم. جاسازی‌های برداری بعداً زمانی مفید خواهند بود که باید جستجوی مشابهی را روی آنها با درخواست کاربر که به زبان طبیعی ارائه شده است انجام دهیم.

ما از اجزای Langchain Firestore برای اجرای فرآیند فوق استفاده خواهیم کرد.

مراحل انجام آن به شرح زیر خواهد بود:

  1. ما لیست اشیاء JSON را به لیستی از اشیاء Langchain Document تبدیل می کنیم. هر سند دارای دو ویژگی است: page_content و metadata . شیء فراداده شامل کل شیء JSON خواهد بود که دارای ویژگی هایی مانند name ، description ، sanskrit_name ، و غیره است. page_content یک متن رشته ای خواهد بود که ترکیبی از چند فیلد خواهد بود.
  2. هنگامی که لیستی از اشیاء Document داشته باشیم، از کلاس FirestoreVectorStore Langchain و به طور خاص از متد from_documents با این فهرست اسناد، نام مجموعه (از متغیر TEST_COLLECTION استفاده می کنیم که به test-poses اشاره می کند)، کلاس Embedding AI Vertex و جزئیات اتصال Firestore (نام و DATABASE PROJECT_ID استفاده می کنیم. این مجموعه را ایجاد می کند و همچنین یک فیلد embedding برای هر یک از ویژگی ها ایجاد می کند.

کد import-data.py در زیر آورده شده است (بخش هایی از کد برای اختصار کوتاه شده اند):

... 

def create_langchain_documents(poses):
   """Creates a list of Langchain Documents from a list of poses."""
   documents = []
   for pose in poses:
       # Convert the pose to a string representation for page_content
       page_content = (
           f"name: {pose.get('name', '')}\n"
           f"description: {pose.get('description', '')}\n"
           f"sanskrit_name: {pose.get('sanskrit_name', '')}\n"
           f"expertise_level: {pose.get('expertise_level', 'N/A')}\n"
           f"pose_type: {pose.get('pose_type', 'N/A')}\n"
       ).strip()
       # The metadata will be the whole pose
       metadata = pose

       document = Document(page_content=page_content, metadata=metadata)
       documents.append(document)
   logging.info(f"Created {len(documents)} Langchain documents.")
   return documents

def main():
    all_poses = load_yoga_poses_data_from_local_file(
        "./data/yoga_poses_with_descriptions.json"
    )
    documents = create_langchain_documents(all_poses)
    logging.info(
        f"Successfully created langchain documents. Total documents: {len(documents)}"
    )

    embedding = VertexAIEmbeddings(
        model_name=settings.embedding_model_name,
        project=settings.project_id,
        location=settings.location,
    )

    client = firestore.Client(project=settings.project_id, database=settings.database)

    vector_store = FirestoreVectorStore.from_documents(
        client=client,
        collection=settings.test_collection,
        documents=documents,
        embedding=embedding,
    )
    logging.info("Added documents to the vector store.")


if __name__ == "__main__":
    main()

اجازه دهید این برنامه را اجرا کنیم. یک پنجره ترمینال جدید (Ctrl+Shift+C) راه اندازی کنید و دستور زیر را بدهید:

python import-data.py

اگر همه چیز خوب پیش برود، باید پیامی مشابه پیام زیر مشاهده کنید:

2025-01-21 14:50:06,479 - INFO - Added documents to the vector store.

برای بررسی اینکه آیا رکوردها با موفقیت درج شده‌اند و جاسازی‌ها ایجاد شده‌اند، از صفحه Firestore در کنسول Cloud دیدن کنید.

504cabdb99a222a5.png

روی پایگاه داده (پیش‌فرض) کلیک کنید، این باید مجموعه test-poses و چندین سند زیر آن مجموعه را نشان دهد. هر سند یک ژست یوگا است.

d0708499e403aebc.png

برای بررسی فیلدها روی هر یک از اسناد کلیک کنید. علاوه بر فیلدهایی که وارد کردیم، فیلد embedding نیز خواهید یافت، که یک فیلد Vector است که به طور خودکار از طریق کلاس Langchain VertexAIEmbeddings که استفاده کردیم، برای شما ایجاد شده است، که در آن مدل text-embedding-004 Vertex AI Embedding را ارائه کردیم.

d67113e2dc63cd6b.png

اکنون که رکوردهای آپلود شده در پایگاه داده Firestore را با جاسازی‌های موجود در اختیار داریم، می‌توانیم به مرحله بعدی برویم و ببینیم که چگونه جستجوی Vector Similarity را در Firestore انجام دهیم.

6. ژست های کامل یوگا را به مجموعه پایگاه داده Firestore وارد کنید

ما اکنون مجموعه poses را ایجاد می کنیم که یک لیست کامل از 160 حالت یوگا است که برای آن یک فایل واردات پایگاه داده ایجاد کرده ایم که می توانید مستقیماً آن را وارد کنید. این کار برای صرفه جویی در زمان در آزمایشگاه انجام می شود. فرآیند تولید پایگاه داده که حاوی توضیحات و جاسازی است، همان است که در بخش قبل دیدیم.

با دنبال کردن مراحل زیر، پایگاه داده را وارد کنید:

  1. با دستور gsutil که در زیر داده شده است یک سطل در پروژه خود ایجاد کنید. متغیر <PROJECT_ID> در دستور زیر را با شناسه پروژه Google Cloud خود جایگزین کنید.
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
  1. اکنون که سطل ایجاد شده است، قبل از اینکه بتوانیم آن را به پایگاه داده Firebase وارد کنیم، باید صادرات دیتابیس را که آماده کرده ایم در این سطل کپی کنیم. از دستور زیر استفاده کنید:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615  gs://<PROJECT_ID>-my-bucket

اکنون که داده‌هایی برای وارد کردن داریم، می‌توانیم به مرحله نهایی وارد کردن داده‌ها به پایگاه داده Firebase ( default ) که ایجاد کرده‌ایم برویم.

  1. از دستور gcloud زیر استفاده کنید:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615

وارد کردن چند ثانیه طول می‌کشد و پس از آماده شدن، می‌توانید با مراجعه به https://console.cloud.google.com/firestore/databases پایگاه داده Firestore و مجموعه را تأیید کنید، پایگاه داده default و مجموعه poses را مطابق شکل زیر انتخاب کنید:

a8f5a6ba69bec69b.png

این کار ایجاد مجموعه Firestore را که در برنامه خود استفاده خواهیم کرد، تکمیل می کند.

7. جستجوی شباهت برداری را در Firestore انجام دهید

برای انجام جستجوی Vector Similarity ، پرس و جو را از کاربر دریافت می کنیم. نمونه ای از این پرس و جو می تواند این باشد که "Suggest me some exercises to relieve back pain" .

به فایل search-data.py نگاهی بیندازید. تابع کلیدی که باید به آن نگاه کرد، تابع جستجو است که در زیر نشان داده شده است. در سطح بالا، یک کلاس جاسازی ایجاد می کند که باید برای ایجاد تعبیه برای درخواست کاربر استفاده شود. سپس از کلاس FirestoreVectorStore برای فراخوانی تابع similarity_search خود استفاده می کند.

def search(query: str):
    """Executes Firestore Vector Similarity Search"""
    embedding = VertexAIEmbeddings(
        model_name=settings.embedding_model_name,
        project=settings.project_id,
        location=settings.location,
    )

    client = firestore.Client(project=settings.project_id, database=settings.database)

    vector_store = FirestoreVectorStore(
        client=client, collection=settings.collection, embedding_service=embedding
    )

    logging.info(f"Now executing query: {query}")
    results: list[Document] = vector_store.similarity_search(
        query=query, k=int(settings.top_k), include_metadata=True
    )
    for result in results:
        print(result.page_content)

قبل از اینکه این کار را با چند نمونه پرس و جو اجرا کنید، ابتدا باید یک فهرست ترکیبی Firestore ایجاد کنید، که برای موفقیت پرس و جوهای جستجوی شما لازم است. اگر برنامه را بدون ایجاد نمایه اجرا کنید، خطایی که نشان می دهد ابتدا باید ایندکس را ایجاد کنید با دستور ایجاد ایندکس ابتدا نمایش داده می شود.

دستور gcloud برای ایجاد ایندکس ترکیبی در زیر نشان داده شده است:

gcloud firestore indexes composite create --project=<YOUR_PROJECT_ID> --collection-group=poses --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding

این فهرست چند دقیقه طول می کشد تا تکمیل شود زیرا بیش از 150 رکورد در پایگاه داده وجود دارد. پس از تکمیل، می توانید فهرست را از طریق دستور زیر مشاهده کنید:

gcloud firestore indexes composite list

باید نمایه ای را که به تازگی ایجاد کرده اید در لیست ببینید.

اکنون دستور زیر را امتحان کنید:

python search-data.py --prompt "Recommend me some exercises for back pain relief"

باید چند توصیه به شما ارائه شود. یک نمونه اجرا در زیر نشان داده شده است:

2025-01-21 15:48:51,282 - INFO - Now executing query: Recommend me some exercises for back pain relief
name: Supine Spinal Twist Pose
description: A gentle supine twist (Supta Matsyendrasana), great for beginners.  Releases spinal tension, improves digestion, and calms the nervous system.  Keep shoulders flat on the floor and lengthen the spine.

sanskrit_name: Supta Matsyendrasana
expertise_level: Beginner
pose_type: ['Supine', 'Twist']
name: Cow Pose
description: Cow Pose (Bitilasana) is a gentle backbend, stretching the chest, shoulders, and abdomen.  Maintain a neutral spine, lengthen the tailbone, and avoid hyperextension.  Benefits include improved posture and stress relief.

sanskrit_name: Bitilasana
expertise_level: Beginner
pose_type: ['Arm Leg Support', 'Back Bend']
name: Locust I Pose
description: Locust Pose I (Shalabhasana A) strengthens the back, glutes, and shoulders.  Lie prone, lift chest and legs simultaneously, engaging back muscles.  Keep hips grounded and gaze slightly forward.

sanskrit_name: Shalabhasana A
expertise_level: Intermediate
pose_type: ['Prone', 'Back Bend']

هنگامی که این کار را انجام دادید، اکنون نحوه کار با پایگاه داده بردار Firestore را برای آپلود رکوردها، ایجاد جاسازی ها و انجام جستجوی مشابه برداری بردار درک کرده ایم. اکنون می‌توانیم یک برنامه کاربردی وب ایجاد کنیم که جستجوی برداری را در یک وب جلویی ادغام می‌کند.

8. برنامه وب

برنامه وب Python Flask در فایل main.py موجود است و فایل HTML جلویی در templates/index.html.

توصیه می شود هر دو فایل را مشاهده کنید. ابتدا با فایل main.py شروع کنید که حاوی /search handler است، که دستوری را می‌گیرد که از فایل HTML index.html جلویی ارسال شده است. سپس متد جستجو را فراخوانی می کند، که جستجوی Vector Similarity را که در بخش قبل به آن نگاه کردیم، انجام می دهد.

سپس پاسخ با لیستی از توصیه ها به index.html ارسال می شود. سپس index.html توصیه ها را به صورت کارت های مختلف نمایش می دهد.

برنامه را به صورت محلی اجرا کنید

یک پنجره ترمینال جدید (Ctrl+Shift+C) یا هر پنجره ترمینال موجود را اجرا کنید و دستور زیر را بدهید:

python main.py

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

 * Serving Flask app 'main'
 * Debug mode: on
2025-01-21 16:02:37,473 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:8080
 * Running on http://10.88.0.4:8080
2025-01-21 16:02:37,473 - INFO - Press CTRL+C to quit
2025-01-21 16:02:37,474 - INFO -  * Restarting with stat
2025-01-21 16:02:41,462 - WARNING -  * Debugger is active!
2025-01-21 16:02:41,484 - INFO -  * Debugger PIN: 440-653-555

پس از راه‌اندازی و اجرا، با کلیک بر روی دکمه پیش‌نمایش وب که در زیر نشان داده شده است، از URL اصلی برنامه دیدن کنید:

de297d4cee10e0bf.png

باید فایل index.html ارائه شده را مطابق شکل زیر به شما نشان دهد:

20240a0e885ac17b.png

یک نمونه پرس و جو ارائه کنید (مثال: Provide me some exercises for back pain relief ) و روی دکمه Search کلیک کنید. این باید برخی از توصیه ها را از پایگاه داده بازیابی کند. همچنین دکمه Play Audio را مشاهده خواهید کرد که بر اساس توضیحات یک جریان صوتی ایجاد می کند که می توانید مستقیماً آن را بشنوید.

789b4277dc40e2be.png

9. (اختیاری) استقرار در Google Cloud Run

گام نهایی ما، استقرار این برنامه در Google Cloud Run خواهد بود. دستور استقرار در زیر نشان داده شده است، اطمینان حاصل کنید که قبل از استقرار آن، مقادیر متغیر (<<YOUR_PROJECT_ID>>) را با مقادیری که مختص پروژه شما هستند جایگزین کنید. اینها مقادیری هستند که می توانید از فایل config.yaml بازیابی کنید.

gcloud run deploy yogaposes --source . \
  --port=8080 \
  --allow-unauthenticated \
  --region=us-central1 \
  --platform=managed  \
  --project=<<YOUR_PROJECT_ID>> \
  --env-vars-file=config.yaml

دستور بالا را از پوشه ریشه برنامه اجرا کنید. همچنین ممکن است از شما خواسته شود APIهای Google Cloud را فعال کنید، مجوزهای مختلف را تأیید کنید، لطفاً این کار را انجام دهید.

مراحل استقرار حدود 5 تا 7 دقیقه طول می کشد، بنابراین لطفا صبور باشید.

3a6d86fd32e4a5e.png

پس از استقرار موفقیت آمیز، خروجی استقرار URL سرویس Cloud Run را ارائه می دهد. به این شکل خواهد بود:

Service URL: https://yogaposes-<<UNIQUEID>.us-central1.run.app

از آن URL عمومی بازدید کنید و خواهید دید که همان برنامه وب مستقر شده و با موفقیت اجرا می شود.

84e1cbf29cbaeedc.png

همچنین می توانید از طریق کنسول Google Cloud به Cloud Run مراجعه کنید و لیست خدمات را در Cloud Run مشاهده خواهید کرد. سرویس yogaposes باید یکی از خدمات (اگر نه تنها) باشد که در آنجا ذکر شده است.

f2b34a8c9011be4c.png

با کلیک کردن روی نام سرویس خاص (در مورد ما yogaposes ) می‌توانید جزئیات سرویس مانند URL، پیکربندی‌ها، گزارش‌ها و موارد دیگر را مشاهده کنید.

faaa5e0c02fe0423.png

این توسعه و استقرار برنامه وب توصیه‌کننده پوزهای یوگا ما را در Cloud Run کامل می‌کند.

10. تبریک می گویم

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

اسناد مرجع