Codelab: crie um app de recomendação de posições de ioga contextual com o Firestore, o Vector Search, o Langchain e o Gemini (versão Python)

1. Introdução

Neste codelab, você vai criar um aplicativo que usa a pesquisa de vetor para recomendar poses de ioga.

No codelab, você vai usar uma abordagem detalhada da seguinte forma:

  1. Use um conjunto de dados do Hugging Face de poses de ioga (formato JSON).
  2. Melhore o conjunto de dados com uma descrição de campo adicional que usa o Gemini para gerar descrições de cada pose.
  3. Use o Langchain para criar um documento e a integração do Firestore Langchain para criar a coleção e as incorporações no Firestore.
  4. Crie um índice composto no Firestore para permitir a pesquisa vetorial.
  5. Use a pesquisa de vetor em um aplicativo Flask que reúne tudo, conforme mostrado abaixo:

84e1cbf29cbaeedc.png

O que você aprenderá

  • Projete, crie e implante um aplicativo da Web que usa a Pesquisa de vetor para recomendar posições de ioga.

O que você vai aprender

  • Como usar o Gemini para gerar conteúdo de texto e, no contexto deste codelab, gerar descrições de poses de ioga
  • Como usar o Langchain Document Loader para o Firestore para carregar registros de um conjunto de dados aprimorado do Hugging Face no Firestore com embeddings de vetor
  • Como usar o Langchain Vector Store para Firestore para pesquisar dados com base em uma consulta em linguagem natural
  • Como usar a API Text-to-Speech do Google Cloud para gerar conteúdo de áudio

O que é necessário

  • Navegador da Web Google Chrome
  • Uma conta do Gmail
  • Um projeto do Cloud com faturamento ativado

Este codelab, desenvolvido para desenvolvedores de todos os níveis (inclusive iniciantes), usa Python no aplicativo de exemplo. No entanto, não é necessário ter conhecimento de Python para entender os conceitos apresentados.

2. Antes de começar

Criar um projeto

  1. No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
  2. Verifique se o faturamento está ativado para seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto .
  3. Você vai usar o Cloud Shell, um ambiente de linha de comando executado no Google Cloud que vem pré-carregado com bq. Clique em "Ativar o Cloud Shell" na parte de cima do console do Google Cloud.

Imagem do botão "Ativar o Cloud Shell"

  1. Depois de se conectar ao Cloud Shell, verifique se você já está autenticado e se o projeto está definido como seu ID usando o seguinte comando:
gcloud auth list
  1. Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto.
gcloud config list project
  1. Se o projeto não estiver definido, use este comando:
gcloud config set project <YOUR_PROJECT_ID>
  1. Ative as APIs necessárias usando o comando mostrado abaixo. Isso pode levar alguns minutos. Tenha paciência.
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

Após a execução do comando, uma mensagem semelhante à mostrada abaixo vai aparecer:

Operation "operations/..." finished successfully.

A alternativa ao comando gcloud é pelo console, pesquisando cada produto ou usando este link.

Se alguma API for perdida, você poderá ativá-la durante a implementação.

Consulte a documentação para ver o uso e os comandos gcloud.

Clonar o repositório e configurar o ambiente

A próxima etapa é clonar o repositório de exemplo que vamos usar como referência no restante do codelab. Supondo que você esteja no Cloud Shell, execute o seguinte comando no diretório principal:

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

Para iniciar o editor, clique em "Abrir editor" na barra de ferramentas da janela do Cloud Shell. Clique na barra de menu no canto superior esquerdo e selecione "File" → "Open Folder", conforme mostrado abaixo:

66221fd0d0e5202f.png

Selecione a pasta yoga-poses-recommender-python. Ela será aberta com os seguintes arquivos, conforme mostrado abaixo:

44699efc7fb1b911.png

Agora precisamos configurar as variáveis de ambiente que vamos usar. Clique no arquivo config.template.yaml e o conteúdo vai aparecer conforme mostrado abaixo:

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"

Atualize os valores de project_id e location de acordo com o que você selecionou ao criar o projeto do Google Cloud e a região do banco de dados do Firestore. O ideal é que os valores de location sejam iguais para o projeto do Google Cloud e o banco de dados do Firestore, por exemplo, us-central1.

Para este codelab, vamos usar os valores pré-configurados, exceto project_id e location, que precisam ser definidos de acordo com sua configuração.

Salve este arquivo como config.yaml na mesma pasta que o arquivo config.template.yaml.

A etapa final agora é criar um ambiente Python que usaremos localmente com todas as dependências do Python configuradas para nós. Confira o arquivo pyproject.toml, que contém os detalhes, conforme mostrado abaixo:

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",
]

Essas dependências já estão bloqueadas pela versão no requirements.txt.. Para resumir, precisamos criar um ambiente virtual do Python com as dependências de pacotes do Python no requirements.txt para serem instaladas no ambiente virtual. Para fazer isso, acesse o Command Palette (Ctrl+Shift+P) no Cloud Shell IDE e digite Python: Create Environment. Siga as próximas etapas para selecionar um Virtual Environment(venv), Python 3.x interpreter e o arquivo requirements.txt.

Depois que o ambiente for criado, vamos precisar ativar o ambiente criado com o seguinte comando:

source .venv/bin/activate

Você vai encontrar (.venv) no console. Por exemplo, -> (.venv) yourusername@cloudshell:

Ótimo! Agora está tudo pronto para prosseguir com a tarefa de configurar o banco de dados do Firestore.

3. Configurar o Firestore

O Cloud Firestore é um banco de dados de documentos sem servidor totalmente gerenciado que vamos usar como back-end para os dados do aplicativo. Os dados no Cloud Firestore são estruturados em coleções de documentos.

Inicialização do banco de dados do Firestore

Acesse a página do Firestore no Console do Cloud.

Se você não tiver inicializado um banco de dados do Firestore antes no projeto, crie o banco de dados default clicando em Create Database. Durante a criação do banco de dados, use os seguintes valores:

  • Modo do Firestore: Native.
  • Localização: use as configurações de localização padrão.
  • Para as regras de segurança, use Test rules.
  • Crie o banco de dados.

504cabdb99a222a5.png

Na próxima seção, vamos preparar o terreno para criar uma coleção chamada poses no nosso banco de dados padrão do Firestore. Essa coleção vai conter dados de amostra (documentos) ou informações sobre as posições de ioga, que serão usadas no nosso aplicativo.

Isso conclui a seção de configuração do banco de dados do Firestore.

4. Preparar o conjunto de dados de poses de ioga

Nossa primeira tarefa é preparar o conjunto de dados de posturas de ioga que vamos usar no aplicativo. Vamos começar com um conjunto de dados do Hugging Face e depois aprimorar com mais informações.

Confira o conjunto de dados do Hugging Face para posturas de ioga. Embora este codelab use um dos conjuntos de dados, você pode usar qualquer outro conjunto de dados e seguir as mesmas técnicas demonstradas para aprimorar o conjunto de dados.

298cfae7f23e4bef.png

Se formos à seção Files and versions, vamos conseguir o arquivo de dados JSON de todas as poses.

3fe6e55abdc032ec.png

Fizemos o download do arquivo yoga_poses.json e o enviamos para você. Esse arquivo é chamado yoga_poses_alldata.json e está na pasta /data.

Acesse o arquivo data/yoga_poses.json no editor do Cloud Shell e confira a lista de objetos JSON, em que cada objeto JSON representa uma postura de ioga. Temos um total de 3 registros, e um exemplo é mostrado abaixo:

{
   "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"]
 }

Esta é uma ótima oportunidade para apresentar o Gemini e como podemos usar o modelo padrão para gerar um campo description.

No editor do Cloud Shell, acesse o arquivo generate-descriptions.py. O conteúdo do arquivo é mostrado abaixo:

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

Esse aplicativo vai adicionar um novo campo description a cada registro JSON de pose de ioga. Ela vai receber a descrição por uma chamada ao modelo Gemini, onde vamos fornecer o comando necessário. O campo é adicionado ao arquivo JSON, e o novo arquivo é gravado no arquivo data/yoga_poses_with_descriptions.json.

Vamos conferir as principais etapas:

  1. Na função main(), ela invoca a função add_descriptions_to_json e fornece o arquivo de entrada e o arquivo de saída esperados.
  2. A função add_descriptions_to_json faz o seguinte para cada registro JSON, ou seja, informações sobre a postagem de ioga:
  3. Ele extrai pose_name, sanskrit_name, expertise_level e pose_types.
  4. Ele invoca a função generate_description, que constrói um comando e, em seguida, invoca a classe de modelo Langchain VertexAI para receber o texto de resposta.
  5. Esse texto de resposta é adicionado ao objeto JSON.
  6. A lista JSON atualizada de objetos é gravada no arquivo de destino.

Vamos executar este aplicativo. Inicie uma nova janela de terminal (Ctrl+Shift+C) e digite o seguinte comando:

python generate-descriptions.py

Se você receber uma solicitação de autorização, envie-a.

O aplicativo vai começar a ser executado. Adicionamos um atraso de 30 segundos entre os registros para evitar cotas de limite de taxa nas novas contas do Google Cloud. Tenha paciência.

Confira abaixo um exemplo de execução em andamento:

8e830d9ea9b6c60.png

Depois que os três registros forem aprimorados com a chamada do Gemini, um arquivo data/yoga_poses_with_description.json será gerado. Confira.

Agora que temos o arquivo de dados, a próxima etapa é entender como preencher um banco de dados do Firestore com ele, além da geração de incorporações.

5. Importar dados para o Firestore e gerar embeddings vetoriais

Temos o arquivo data/yoga_poses_with_description.json e agora precisamos preencher o banco de dados do Firestore com ele e, principalmente, gerar as inclusões de vetor para cada um dos registros. As incorporações vetoriais serão úteis mais tarde, quando precisarmos fazer uma pesquisa de similaridade com elas usando a consulta do usuário fornecida em linguagem natural.

Vamos usar os componentes do Langchain Firestore para implementar o processo acima.

Para isso, siga estas etapas:

  1. Vamos converter a lista de objetos JSON em uma lista de objetos Langchain Document. Cada documento terá dois atributos: page_content e metadata. O objeto de metadados vai conter todo o objeto JSON com atributos como name, description, sanskrit_name etc. O page_content será um texto de string que será uma concatenação de alguns campos.
  2. Depois de ter uma lista de objetos Document, vamos usar a classe Langchain FirestoreVectorStore e, especificamente, o método from_documents com essa lista de documentos, um nome de coleção (usamos a variável TEST_COLLECTION que aponta para test-poses), uma classe de incorporação do Vertex AI e os detalhes de conexão do Firestore (nome PROJECT_ID e DATABASE). Isso vai criar a coleção e gerar um campo embedding para cada um dos atributos.

Confira abaixo o código de import-data.py (partes do código foram truncadas para encurtar):

... 

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

Vamos executar este aplicativo. Inicie uma nova janela de terminal (Ctrl+Shift+C) e digite o seguinte comando:

python import-data.py

Se tudo correr bem, você vai receber uma mensagem semelhante a esta:

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

Para verificar se os registros foram inseridos e as incorporações foram geradas, acesse a página do Firestore no Console do Cloud.

504cabdb99a222a5.png

Clique no banco de dados (padrão), que vai mostrar a coleção test-poses e vários documentos nessa coleção. Cada documento é uma pose de ioga.

d0708499e403aebc.png

Clique em qualquer um dos documentos para investigar os campos. Além dos campos importados, você também encontra o campo embedding, que é um campo de vetor gerado automaticamente para você pela classe VertexAIEmbeddings do Langchain, em que fornecemos o modelo de embedding text-embedding-004 da Vertex AI.

d67113e2dc63cd6b.png

Agora que temos os registros enviados para o banco de dados do Firestore com os embeddings, podemos passar para a próxima etapa e conferir como fazer a pesquisa de similaridade vetorial no Firestore.

6. Importar poses de yoga completas para a coleção do banco de dados do Firestore

Agora vamos criar a coleção poses, que é uma lista completa de 160 posturas de ioga, para as quais geramos um arquivo de importação de banco de dados que você pode importar diretamente. Isso é feito para economizar tempo no laboratório. O processo de geração do banco de dados que contém a descrição e as embeddings é o mesmo que vimos na seção anterior.

Siga as etapas abaixo para importar o banco de dados:

  1. Crie um bucket no seu projeto com o comando gsutil abaixo. Substitua a variável <PROJECT_ID> no comando abaixo pelo ID do projeto do Google Cloud.
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
  1. Agora que o bucket foi criado, precisamos copiar a exportação de banco de dados que preparamos para ele antes de importar para o banco de dados do Firebase. Use o comando abaixo:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615  gs://<PROJECT_ID>-my-bucket

Agora que temos os dados para importar, podemos passar para a etapa final de importação dos dados para o banco de dados do Firebase (default) que criamos.

  1. Use o comando gcloud abaixo:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615

A importação vai levar alguns segundos. Quando estiver pronta, você poderá validar seu banco de dados do Firestore e a coleção acessando https://console.cloud.google.com/firestore/databases, selecionando o banco de dados default e a coleção poses, conforme mostrado abaixo:

a8f5a6ba69bec69b.png

Isso conclui a criação da coleção do Firestore que vamos usar no nosso app.

7. Realizar pesquisa de similaridade vetorial no Firestore

Para realizar a pesquisa de similaridade vetorial, vamos usar a consulta do usuário. Um exemplo dessa consulta pode ser "Suggest me some exercises to relieve back pain".

Confira o arquivo search-data.py. A função principal a ser analisada é a de pesquisa, mostrada abaixo. De forma geral, ele cria uma classe de embedding que será usada para gerar a embedding da consulta do usuário. Em seguida, ele usa a classe FirestoreVectorStore para invocar a função 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)

Antes de executar isso com alguns exemplos de consulta, gere um índice composto do Firestore, que é necessário para que as consultas de pesquisa sejam bem-sucedidas. Se você executar o aplicativo sem criar o índice, um erro indicando que você precisa criar o índice primeiro será exibido com o comando para criar o índice primeiro.

O comando gcloud para criar o índice composto é mostrado abaixo:

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

A indexação vai levar alguns minutos, porque há mais de 150 registros no banco de dados. Quando ele for concluído, você poderá conferir o índice usando o comando mostrado abaixo:

gcloud firestore indexes composite list

Você vai encontrar o índice que acabou de criar na lista.

Teste o seguinte comando:

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

Você vai receber algumas recomendações. Confira um exemplo de execução abaixo:

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']

Agora que você já sabe como usar o Banco de Dados Vetorial do Firestore para fazer upload de registros, gerar embeddings e realizar uma pesquisa de similaridade de vetores, vamos continuar. Agora podemos criar um aplicativo da Web que vai integrar a pesquisa vetorial a um front-end da Web.

8. O aplicativo da Web

O aplicativo da Web Python Flask está disponível no arquivo main.py, e o arquivo HTML do front-end está presente no templates/index.html..

Recomendamos que você analise os dois arquivos. Comece com o arquivo main.py que contém o gerenciador /search, que recebe a solicitação transmitida do arquivo HTML index.html do front-end. Isso invoca o método de pesquisa, que faz a pesquisa de similaridade vetorial que analisamos na seção anterior.

A resposta é enviada de volta para o index.html com a lista de recomendações. O index.html mostra as recomendações como cards diferentes.

Executar o aplicativo localmente

Inicie uma nova janela de terminal (Ctrl+Shift+C) ou qualquer janela de terminal existente e execute o seguinte comando:

python main.py

Confira abaixo um exemplo de execução:

 * 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

Quando estiver tudo pronto, acesse o URL da página inicial do aplicativo clicando no botão "Visualização da Web" mostrado abaixo:

de297d4cee10e0bf.png

O arquivo index.html vai ser mostrado como mostrado abaixo:

20240a0e885ac17b.png

Forneça uma consulta de exemplo (por exemplo, Provide me some exercises for back pain relief) e clique no botão Search. Isso vai recuperar algumas recomendações do banco de dados. Você também vai encontrar um botão Play Audio, que vai gerar um stream de áudio com base na descrição, que você pode ouvir diretamente.

789b4277dc40e2be.png

9. (Opcional) Implantar no Google Cloud Run

A etapa final será implantar este aplicativo no Google Cloud Run. O comando de implantação é mostrado abaixo. Antes de implantar, substitua os valores da variável (<<YOUR_PROJECT_ID>>) pelos específicos do seu projeto. Esses são valores que você poderá recuperar do arquivo 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

Execute o comando acima na pasta raiz do aplicativo. Talvez você também precise ativar as APIs do Google Cloud e confirmar várias permissões.

O processo de implantação leva de 5 a 7 minutos para ser concluído. Tenha paciência.

3a6d86fd32e4a5e.png

Depois de implantada, a saída da implantação vai fornecer o URL do serviço do Cloud Run. Ele vai estar neste formato:

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

Acesse esse URL público e o mesmo aplicativo da Web implantado e em execução vai aparecer.

84e1cbf29cbaeedc.png

Você também pode acessar o Cloud Run no console do Google Cloud e conferir a lista de serviços no Cloud Run. O serviço yogaposes precisa ser um dos serviços (ou o único) listados.

f2b34a8c9011be4c.png

Para conferir os detalhes do serviço, como URL, configurações, registros e muito mais, clique no nome do serviço específico (yogaposes no nosso caso).

faaa5e0c02fe0423.png

Isso conclui o desenvolvimento e a implantação do nosso aplicativo da Web de recomendação de poses de ioga no Cloud Run.

10. Parabéns

Parabéns! Você criou um aplicativo que faz upload de um conjunto de dados para o Firestore, gera os embeddings e realiza uma pesquisa de similaridade vetorial com base na consulta do usuário.

Documentos de referência