1. Introdução
Neste codelab, você vai criar um aplicativo que usa a pesquisa vetorial para recomendar posturas de ioga.
Durante o codelab, você vai usar uma abordagem gradual da seguinte forma:
- Use um conjunto de dados do Hugging Face com posturas de yoga (formato JSON).
- Melhore o conjunto de dados com uma descrição de campo adicional que usa o Gemini para gerar descrições de cada uma das poses.
- Use o Langchain para criar um documento e a integração do Firestore Langchain para criar a coleção e os embeddings no Firestore.
- Crie um índice composto no Firestore para permitir a pesquisa vetorial.
- Use a pesquisa vetorial em um aplicativo Flask que reúne tudo, conforme mostrado abaixo:

O que você aprenderá
- Projetar, criar e implantar um aplicativo da Web que usa a pesquisa vetorial para recomendar posturas 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 para posturas de ioga
- Como usar o carregador de documentos do Langchain para Firestore e carregar registros de um conjunto de dados aprimorado do Hugging Face no Firestore com embeddings de vetores
- Como usar o repositório de vetores do Langchain para Firestore e pesquisar dados com base em uma consulta em linguagem natural
- Como usar a API Google Cloud Text-to-Speech 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, criado 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
- No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Verifique se o faturamento está ativado para seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto .
- 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.

- Depois de se conectar ao Cloud Shell, verifique se sua conta já está autenticada e se o projeto está configurado com o ID do seu projeto usando o seguinte comando:
gcloud auth list
- Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto.
gcloud config list project
- Se o projeto não estiver definido, use este comando:
gcloud config set project <YOUR_PROJECT_ID>
- Ative as APIs necessárias com o comando mostrado abaixo. Isso pode levar alguns minutos.
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, você vai ver uma mensagem semelhante à mostrada abaixo:
Operation "operations/..." finished successfully.
A alternativa ao comando gcloud é usar o console. Para isso, pesquise cada produto ou use este link.
Se alguma API for esquecida, você sempre 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 as definições de ambiente
A próxima etapa é clonar o repositório de amostra que vamos referenciar 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 Arquivo → Abrir pasta, conforme mostrado abaixo:

Selecione a pasta yoga-poses-recommender-python. Ela vai abrir com os seguintes arquivos, conforme mostrado abaixo:

Agora, precisamos configurar as variáveis de ambiente que vamos usar. Clique no arquivo config.template.yaml. O conteúdo vai aparecer como 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 os mesmos 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 você precisa definir de acordo com sua configuração.
Salve este arquivo como config.yaml na mesma pasta do arquivo config.template.yaml.
A etapa final agora é criar um ambiente Python que vamos usar localmente com todas as dependências do Python configuradas para nós. Confira o arquivo pyproject.toml, que contém os detalhes do mesmo. O conteúdo dele é 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 por versão no requirements.txt.. Em resumo, precisamos criar um ambiente virtual do Python com as dependências do pacote Python em 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, será necessário ativá-lo com o seguinte comando:
source .venv/bin/activate
Você vai ver (.venv) no console. Por exemplo, -> (.venv) yourusername@cloudshell:
Ótimo! Agora está tudo pronto para passar para 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 usaremos 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ê ainda não tiver inicializado um banco de dados do Firestore 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. - Selecione o tipo de local como
Regione escolha o localus-central1para a região. - Para as regras de segurança, use
Test rules. - Crie o banco de dados.

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 posturas de ioga, que vamos usar no aplicativo.
Isso conclui a seção de configuração do banco de dados do Firestore.
4. Preparar o conjunto de dados de posturas de yoga
A 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 aprimorá-lo 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, é possível usar qualquer outro e seguir as mesmas técnicas demonstradas para melhorar o conjunto de dados.

Se acessarmos a seção Files and versions, podemos acessar o arquivo de dados JSON para todas as poses.

Fizemos o download do yoga_poses.json e enviamos o arquivo para você. Esse arquivo é chamado de 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 um representa uma postura de yoga. Temos um total de três 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"]
}
Agora é uma ótima oportunidade para apresentar o Gemini e como podemos usar o modelo padrão para gerar um campo description para ele.
No editor do Cloud Shell, acesse o arquivo generate-descriptions.py. O conteúdo desse 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 postura de ioga. Ele vai receber a descrição por uma chamada ao modelo do Gemini, em que vamos fornecer o comando necessário. O campo é adicionado ao arquivo JSON, e o novo arquivo é gravado em data/yoga_poses_with_descriptions.json.
Vamos analisar as etapas principais:
- Na função
main(), você vai encontrar a invocação da funçãoadd_descriptions_to_json, além do arquivo de entrada e do arquivo de saída esperados. - A função
add_descriptions_to_jsonfaz o seguinte para cada registro JSON, ou seja, informações da postagem de yoga: - Ele extrai
pose_name,sanskrit_name,expertise_levelepose_types. - Ele invoca a função generate_description, que cria um comando e depois invoca a classe de modelo Langchain VertexAI para receber o texto da resposta.
- Esse texto de resposta é adicionado ao objeto JSON.
- A lista atualizada de objetos JSON é gravada no arquivo de destino.
Vamos executar esse aplicativo. Abra uma nova janela de terminal (Ctrl+Shift+C) e execute o seguinte comando:
python generate-descriptions.py
Se for solicitada alguma autorização, forneça-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 que possam estar presentes em novas contas do Google Cloud. Portanto, tenha paciência.
Confira abaixo um exemplo de execução em andamento:

Quando todos os três registros forem aprimorados com a chamada do Gemini, um arquivo data/yoga_poses_with_description.json será gerado. Você pode dar uma olhada nisso.
Agora estamos prontos com nosso 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 de vetor
Temos o arquivo data/yoga_poses_with_description.json e agora precisamos preencher o banco de dados do Firestore com ele e, principalmente, gerar os embeddings de vetor para cada um dos registros. Os embeddings de vetores serão úteis mais tarde, quando precisarmos fazer uma pesquisa de similaridade neles com 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:
- Vamos converter a lista de objetos JSON em uma lista de objetos Langchain Document. Cada documento terá dois atributos:
page_contentemetadata. O objeto de metadados vai conter todo o objeto JSON com atributos comoname,description,sanskrit_nameetc. Opage_contentserá um texto de string que vai ser uma concatenação de alguns campos. - Depois de ter uma lista de objetos
Document, vamos usar a classeFirestoreVectorStoredo Langchain e, especificamente, o métodofrom_documentscom essa lista de documentos, um nome de coleção (estamos usando a variávelTEST_COLLECTIONque aponta paratest-poses), uma classe de embeddings da Vertex AI e os detalhes da conexão do Firestore (nomePROJECT_IDeDATABASE). Isso vai criar a coleção e gerar um campoembeddingpara cada um dos atributos.
O código de import-data.py é mostrado abaixo. Algumas partes foram truncadas para facilitar a leitura:
...
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 esse aplicativo. Abra uma nova janela de terminal (Ctrl+Shift+C) e execute o seguinte comando:
python import-data.py
Se tudo correr bem, você vai receber uma mensagem parecida com esta:
2025-01-21 14:50:06,479 - INFO - Added documents to the vector store.
Para verificar se os registros foram inseridos e os embeddings gerados, acesse a página do Firestore no console do Cloud.

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

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

Agora que os registros foram enviados para o banco de dados do Firestore com os embeddings, podemos passar para a próxima etapa e ver como fazer a pesquisa de similaridade vetorial no Firestore.
6. Importar posturas 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. 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 para gerar o banco de dados que contém a descrição e as incorporações é o mesmo que vimos na seção anterior.
Para importar o banco de dados, siga estas etapas:
- Crie um bucket no seu projeto com o comando
gsutilabaixo. Substitua a variável<PROJECT_ID>no comando abaixo pelo ID do seu projeto do Google Cloud.
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
- Agora que o bucket foi criado, precisamos copiar a exportação do 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 para o banco de dados do Firebase (default) que criamos.
- Use o comando gcloud abaixo:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615
A importação leva alguns segundos. Depois que ela estiver pronta, você poderá validar seu banco de dados e a coleção do Firestore acessando https://console.cloud.google.com/firestore/databases, selecionando o banco de dados default e a coleção poses, conforme mostrado abaixo:

Isso conclui a criação da coleção do Firestore que vamos usar no aplicativo.
7. Realizar pesquisa de similaridade vetorial no Firestore
Para realizar uma 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 principal função a ser analisada é a de pesquisa, mostrada abaixo. Em geral, ele cria uma classe de embedding que será usada para gerar o 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 consultas, 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, uma mensagem de erro indicando que é necessário criar o índice primeiro será exibida com o comando para fazer isso.
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
O índice vai levar alguns minutos para ser concluído, já que há mais de 150 registros presentes no banco de dados. Depois de concluído, você pode conferir o índice com o comando mostrado abaixo:
gcloud firestore indexes composite list
Você vai encontrar o índice que acabou de criar na lista.
Teste o seguinte comando agora:
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']
Depois de fazer isso funcionar, entendemos como trabalhar com o banco de dados vetorial do Firestore para fazer upload de registros, gerar embeddings e realizar uma pesquisa de similaridade vetorial. Agora podemos criar um web app 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 de 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. Ele usa o comando transmitido do arquivo HTML index.html do front-end. Isso invoca o método de pesquisa, que faz a pesquisa de similaridade de vetores que vimos na seção anterior.
A resposta é enviada de volta ao index.html com a lista de recomendações. O index.html mostra as recomendações como cards diferentes.
Executar o aplicativo localmente
Abra uma nova janela de terminal (Ctrl+Shift+C) ou qualquer janela de terminal aberta e execute o seguinte comando:
python main.py
Confira um exemplo de execução abaixo:
* 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
Depois de tudo pronto, acesse o URL da página inicial do aplicativo clicando no botão "Visualização na Web" mostrado abaixo:

Ele vai mostrar o arquivo index.html veiculado, como mostrado abaixo:

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 gera um stream de áudio com base na descrição. É possível ouvir o áudio diretamente.

9. (Opcional) Como implantar no Google Cloud Run
A etapa final será implantar esse 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 os valores que você pode 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 seja necessário ativar as APIs do Cloud e confirmar várias permissões.
O processo de implantação leva de 5 a 7 minutos. Aguarde.

Depois de implantado, a saída da implantação vai fornecer o URL do serviço do Cloud Run. Ele vai estar no formato:
Service URL: https://yogaposes-<<UNIQUEID>.us-central1.run.app
Acesse esse URL público para ver o mesmo aplicativo da Web implantado e em execução.

Também é possível acessar o Cloud Run no console do Google Cloud para ver a lista de serviços no Cloud Run. O serviço yogaposes precisa ser um dos serviços (se não o único) listados ali.

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

Isso conclui o desenvolvimento e a implantação do nosso aplicativo da Web de recomendação de posturas 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 faz uma pesquisa de similaridade vetorial com base na consulta dos usuários.