1. Введение
В этой практической работе вы научитесь создавать и развертывать планировщик рациона питания на базе ИИ. Для пользовательского интерфейса используется Streamlit, для модели LLM — Gemini Pro 2.5, для разработки Agentic AI Engine Orchestrator используется Vertex AI, для хранения данных — BigQuery, а для развертывания — Cloud Run.
В ходе выполнения лабораторной работы вы будете применять следующий пошаговый подход:
- Подготовьте свой проект Google Cloud и включите в нем все необходимые API.
- Создайте планировщик диеты на основе агентного ИИ с использованием Streamlit, Vertex AI и BigQuery
- Разверните приложение в Cloud Run
Обзор архитектуры
Предпосылки
- Проект Google Cloud Platform (GCP) с включенным биллингом.
- Базовые знания Python
Чему вы научитесь
- Как создать планировщик диеты на основе агентного ИИ с использованием Streamlit и Vertex AI и хранить данные в BigQuery
- Как развернуть приложение в Cloud Run
Что вам понадобится
- веб-браузер Chrome
- Аккаунт Gmail
- Облачный проект с включенным биллингом
2. Базовая настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в Google Cloud Console и создайте новый проект или используйте существующий. Если у вас ещё нет учётной записи Gmail или Google Workspace, вам необходимо её создать .
- Название проекта — отображаемое имя участников проекта. Это строка символов, не используемая API Google. Вы можете изменить её в любой момент.
- Идентификатор проекта уникален для всех проектов Google Cloud и неизменяем (нельзя изменить после установки). Cloud Console автоматически генерирует уникальную строку; обычно вам не важно, какой именно. В большинстве практических работ вам потребуется указать идентификатор проекта (обычно обозначаемый как
PROJECT_ID
). Если вам не нравится сгенерированный идентификатор, вы можете сгенерировать другой случайный идентификатор. Вы также можете попробовать использовать свой собственный идентификатор и посмотреть, доступен ли он. После этого шага его нельзя будет изменить, и он останется на протяжении всего проекта. - К вашему сведению, существует третье значение — номер проекта, который используется некоторыми API. Подробнее обо всех трёх значениях можно узнать в документации .
- Далее вам нужно включить биллинг в Cloud Console для использования облачных ресурсов/API. Выполнение этой лабораторной работы не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать списания средств за пределами этого руководства, вы можете удалить созданные вами ресурсы или проект. Новые пользователи Google Cloud могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .
3. Прежде чем начать
Настройка облачного проекта в редакторе Cloud Shell
В этой лабораторной работе предполагается, что у вас уже есть проект Google Cloud с активированной функцией оплаты. Если у вас его ещё нет, следуйте инструкциям ниже, чтобы начать работу.
- В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud.
- Убедитесь, что для вашего облачного проекта включена функция выставления счетов. Узнайте, как проверить, включена ли функция выставления счетов для проекта .
- Вы будете использовать Cloud Shell — среду командной строки, работающую в Google Cloud и предустановленную вместе с bq. Нажмите «Активировать Cloud Shell» в верхней части консоли Google Cloud.
- После подключения к Cloud Shell вы проверяете, что вы уже прошли аутентификацию и что проекту присвоен ваш идентификатор проекта, с помощью следующей команды:
gcloud auth list
- Выполните следующую команду в Cloud Shell, чтобы подтвердить, что команда gcloud знает о вашем проекте.
gcloud config list project
- Если ваш проект не настроен, используйте следующую команду для его настройки:
gcloud config set project <YOUR_PROJECT_ID>
Кроме того, вы также можете увидеть идентификатор PROJECT_ID
в консоли.
Нажмите на нее, и справа вы увидите все данные вашего проекта и его идентификатор.
- Включите необходимые API с помощью команды, показанной ниже. Это может занять несколько минут, поэтому, пожалуйста, наберитесь терпения.
gcloud services enable aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudresourcemanager.googleapis.com \
bigquery.googleapis.com
При успешном выполнении команды вы должны увидеть сообщение, похожее на показанное ниже:
Operation "operations/..." finished successfully.
Альтернативой команде gcloud является поиск каждого продукта через консоль или использование этой ссылки .
Если какой-либо API отсутствует, вы всегда можете включить его в ходе реализации.
Информацию о командах и использовании gcloud см. в документации .
Настройка рабочего каталога приложения
- Нажмите кнопку «Открыть редактор», откроется редактор Cloud Shell, где мы можем написать наш код.
- Убедитесь, что проект Cloud Code выбран в левом нижнем углу (строке состояния) редактора Cloud Shell, как показано на изображении ниже, и соответствует активному проекту Google Cloud, для которого включена оплата. При необходимости авторизуйтесь . После инициализации редактора Cloud Shell может пройти некоторое время, прежде чем появится кнопка «Cloud Code — Войти» . Пожалуйста, подождите.
Далее мы подготовим нашу среду Python.
Настройка среды
Подготовка виртуальной среды Python
Следующий шаг — подготовка среды разработки. В этой лабораторной работе мы будем использовать Python 3.12 и виртуальное окружение Python для упрощения создания и управления версиями Python и виртуальными средами.
- Если вы еще не открыли терминал, откройте его, нажав «Терминал» -> «Новый терминал» или воспользуйтесь сочетанием клавиш Ctrl + Shift + C.
- Создайте новую папку и измените местоположение на эту папку, выполнив следующую команду
mkdir agent_diet_planner
cd agent_diet_planner
- Создайте новый virtualenv, выполнив следующую команду
python -m venv .env
- Активируйте virtualenv с помощью следующей команды
source .env/bin/activate
- Создайте файл
requirements.txt
. Нажмите «Файл» → «Новый текстовый файл» и заполните текст ниже. Затем сохраните его какrequirements.txt
streamlit==1.33.0
google-cloud-aiplatform
google-cloud-bigquery
pandas==2.2.2
db-dtypes==1.2.0
pyarrow==16.1.0
- Затем установите все зависимости из requirements.txt, выполнив следующую команду:
pip install -r requirements.txt
- Введите следующую команду ниже, чтобы проверить, установлены ли все зависимости библиотек Python.
pip list
Файлы конфигурации установки
Теперь нам нужно настроить файлы конфигурации для этого проекта. Они используются для хранения переменных и учётных данных сервисных учётных записей.
- Первый шаг — создать учётную запись службы. Введите в поиске «учётная запись службы» и нажмите «учётная запись службы».
- Нажмите «+ Создать учетную запись службы». Введите имя учетной записи службы, затем нажмите «Создать» и «Продолжить».
- В разделе разрешений выберите роль «Пользователь сервисной учётной записи». Нажмите «Добавить ещё одну роль» и выберите роль IAM: BigQuery Admin, Cloud Run Admin, Cloud Run Invoker, Vertex AI Service Agent и Vertex AI User, затем нажмите «Готово».
- Нажмите «Электронная почта учетной записи службы», нажмите клавишу Tab, нажмите «Добавить ключ» → «Создать новый ключ».
- Выберите JSON и нажмите «Создать». Сохраните файл учётной записи службы локально для следующего шага.
- Создайте папку с именем .streamlit со следующей конфигурацией. Щёлкните правой кнопкой мыши, выберите «Новая папка» и введите имя папки
.streamlit
- Щёлкните правой кнопкой мыши по папке
.streamlit
, выберите «Новый файл» и введите значение, указанное ниже. Сохраните файл какsecrets.toml
# secrets.toml (for Streamlit sharing)
# Store in .streamlit/secrets.toml
[gcp]
project_id = "your_gcp_project"
location = "us-central1"
[gcp_service_account]
type = "service_account"
project_id = "your-project-id"
private_key_id = "your-private-key-id"
private_key = '''-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----'''
client_email = "your-sa@project-id.iam.gserviceaccount.com"
client_id = "your-client-id"
auth_uri = "https://accounts.google.com/o/oauth2/auth"
token_uri = "https://oauth2.googleapis.com/token"
auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
client_x509_cert_url = "https://www.googleapis.com/robot/v1/metadata/x509/your-sa%40project-id.iam.gserviceaccount.com"
- Обновите значения
project_id
,private_key_id
,private_key
,client_email
,client_id , and auth_provider_x509_cert_url
на основе вашей учетной записи службы, созданной на предыдущем шаге.
Подготовка набора данных BigQuery
Следующим шагом будет создание набора данных BigQuery для сохранения результатов генерации в BigQuery.
- Введите BigQuery в поиске и нажмите BigQuery.
- Щелкните
затем нажмите «Создать набор данных»
- Введите идентификатор набора данных
diet_planner_data
, затем нажмите «Создать набор данных».
4. Создайте приложение Agent Diet Planner
Мы создадим простой веб-интерфейс с 4 входами, который будет выглядеть так:
Измените вес, рост, возраст и пол на основе данных вашего профиля, затем нажмите «Сгенерировать». Система вызовет модель LLM Gemini Pro 2.5 в библиотеке Vertex AI и сохранит полученные результаты в BigQuery.
Код будет разделен на 6 частей, чтобы не быть слишком длинным.
Создать функцию расчета статуса ИМТ
- Щелкните правой кнопкой мыши папку
agent_diet_planner
→ Новый файл .. → введите имя файлаbmi_calc.py
, затем нажмите Enter. - Заполните код следующим образом
# Add this function to calculate BMI and health status
def calculate_bmi_status(weight, height):
"""
Calculate BMI and return status message
"""
height_m = height / 100 # Convert cm to meters
bmi = weight / (height_m ** 2)
if bmi < 18.5:
status = "underweight"
message = "⚠️ Your BMI suggests you're underweight. Consider increasing calorie intake with nutrient-dense foods."
elif 18.5 <= bmi < 25:
status = "normal"
message = "✅ Your BMI is in the healthy range. Let's maintain this balance!"
elif 25 <= bmi < 30:
status = "overweight"
message = "⚠️ Your BMI suggests you're overweight. Focus on gradual weight loss through balanced nutrition."
else:
status = "obese"
message = "❗ Your BMI indicates obesity. Please consult a healthcare provider for personalized guidance."
return {
"value": round(bmi, 1),
"status": status,
"message": message
}
Создание основных приложений планировщика диеты агента
- Щелкните правой кнопкой мыши папку
agent_diet_planner
→ Новый файл .. → введите имя файлаapp.py
, затем нажмите Enter. - Заполните код следующим образом
import os
from google.oauth2 import service_account
import streamlit as st
from google.cloud import bigquery
from vertexai.preview.generative_models import GenerativeModel
import vertexai
import datetime
import time
import pandas as pd
from bmi_calc import calculate_bmi_status
# Get configuration from environment
PROJECT_ID = os.environ.get("GCP_PROJECT_ID", "your_gcp_project_id")
LOCATION = os.environ.get("GCP_LOCATION", "us-central1")
#CONSTANTS Dataset and table in BigQuery
DATASET = "diet_planner_data"
TABLE = "user_plans"
# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location=LOCATION)
# Initialize BigQuery client
try:
# For Cloud Run, use default credentials
bq_client = bigquery.Client()
except:
# For local development, use service account from secrets
if "gcp_service_account" in st.secrets:
service_account_info = dict(st.secrets["gcp_service_account"])
credentials = service_account.Credentials.from_service_account_info(service_account_info)
bq_client = bigquery.Client(credentials=credentials, project=PROJECT_ID)
else:
st.error("BigQuery client initialization failed")
st.stop()
Измените значение your_gcp_project_id
на идентификатор вашего проекта.
Создание основных приложений планировщика диеты агента — setup_bq_tables
В этом разделе мы создадим функцию setup_bq_table
с одним входным параметром bq_client
. Эта функция определит схему в таблице bigquery и создаст новую таблицу, если она отсутствует.
Заполните код следующим кодом из предыдущего файла app.py
# Create BigQuery table if not exists
def setup_bq_table(bq_client):
dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
table_id = f"{dataset_id}.{TABLE}"
schema = [
bigquery.SchemaField("user_id", "STRING", mode="REQUIRED"),
bigquery.SchemaField("timestamp", "TIMESTAMP", mode="REQUIRED"),
bigquery.SchemaField("weight", "FLOAT", mode="REQUIRED"),
bigquery.SchemaField("height", "INTEGER", mode="REQUIRED"),
bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
bigquery.SchemaField("gender", "STRING", mode="REQUIRED"),
bigquery.SchemaField("diet_plan", "STRING", mode="REQUIRED")
]
try:
bq_client.get_table(table_id)
except:
table = bigquery.Table(table_id, schema=schema)
bq_client.create_table(table)
st.toast("BigQuery table created successfully")
Создание основных приложений планировщика диеты агента — generate_diet_plan
В этом разделе мы создадим функцию generate_diet_plan
с одним входным параметром. Эта функция будет вызывать модель LLM Gemini Pro 2.5 с подсказкой «Определить» и генерировать результаты.
Заполните код следующим кодом из предыдущего файла app.py
# Generate diet plan using Gemini Pro
def generate_diet_plan(params):
try:
model = GenerativeModel("gemini-2.5-pro")
prompt = f"""
Create a personalized 7-day diet plan for:
- {params['gender']}, {params['age']} years old
- Weight: {params['weight']} kg
- Height: {params['height']} cm
Include:
1. Daily calorie target
2. Macronutrient breakdown (carbs, protein, fat)
3. Meal timing and frequency
4. Food recommendations
5. Hydration guidance
Make the plan:
- Nutritionally balanced
- Practical for daily use
- Culturally adaptable
- With portion size guidance
"""
response = model.generate_content(prompt)
return response.text
except Exception as e:
st.error(f"AI generation error: {str(e)}")
return None
Создайте основные приложения планировщика диеты агента - save_to_bq
В этом разделе мы создадим функцию save_to_bq
с тремя входными параметрами: bq_client
, user_id
и plan
. Эта функция сохранит результат генерации в таблицу BigQuery.
Заполните код следующим кодом из предыдущего файла app.py
# Save user data to BigQuery
def save_to_bq(bq_client, user_id, plan):
try:
dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
table_id = f"{dataset_id}.{TABLE}"
row = {
"user_id": user_id,
"timestamp": datetime.datetime.utcnow().isoformat(),
"weight": st.session_state.user_data["weight"],
"height": st.session_state.user_data["height"],
"age": st.session_state.user_data["age"],
"gender": st.session_state.user_data["gender"],
"diet_plan": plan
}
errors = bq_client.insert_rows_json(table_id, [row])
if errors:
st.error(f"BigQuery error: {errors}")
else:
return True
except Exception as e:
st.error(f"Data saving error: {str(e)}")
return False
Создание основных приложений для планировщика диеты агента - основное
В этом разделе мы создадим функцию main
без входных параметров. Эта функция в основном обрабатывает скрипт пользовательского интерфейса Streamlit, отображает сгенерированный результат, отображает историю сгенерированных результатов из таблицы BigQuery и загружает данные в файл Markdown.
Заполните код следующим кодом из предыдущего файла app.py
# Streamlit UI
def main():
st.set_page_config(page_title="AI Diet Planner", page_icon="🍏", layout="wide")
# Initialize session state
if "user_data" not in st.session_state:
st.session_state.user_data = None
if "diet_plan" not in st.session_state:
st.session_state.diet_plan = None
# Initialize clients
#bq_client = init_clients()
setup_bq_table(bq_client)
st.title("🍏 AI-Powered Diet Planner")
st.markdown("""
<style>
.stProgress > div > div > div > div {
background-color: #4CAF50;
}
[data-testid="stForm"] {
background: #f0f5ff;
padding: 20px;
border-radius: 10px;
border: 1px solid #e6e9ef;
}
</style>
""", unsafe_allow_html=True)
# User input form
with st.form("user_profile", clear_on_submit=False):
st.subheader("Your Profile")
col1, col2 = st.columns(2)
with col1:
weight = st.number_input("Weight (kg)", min_value=30.0, max_value=200.0, value=70.0)
height = st.number_input("Height (cm)", min_value=100, max_value=250, value=170)
with col2:
age = st.number_input("Age", min_value=18, max_value=100, value=30)
gender = st.selectbox("Gender", ["Man", "Woman"])
submitted = st.form_submit_button("Generate Diet Plan")
if submitted:
user_data = {
"weight": weight,
"height": height,
"age": age,
"gender": gender
}
st.session_state.user_data = user_data
# Calculate BMI
bmi_result = calculate_bmi_status(weight, height)
# Display BMI results in a visually distinct box
with st.container():
st.subheader("📊 Your Health Assessment")
col1, col2 = st.columns([1, 3])
with col1:
st.metric("BMI", bmi_result["value"])
with col2:
if bmi_result["status"] != "normal":
st.warning(bmi_result["message"])
else:
st.success(bmi_result["message"])
# Add BMI scale visualization
st.markdown(f"""
<div style="background:#f0f2f6;padding:10px;border-radius:10px;margin-top:10px">
<small>BMI Scale:</small><br>
<div style="display:flex;height:20px;background:linear-gradient(90deg,
#4e79a7 0%,
#4e79a7 18.5%,
#60bd68 18.5%,
#60bd68 25%,
#f28e2b 25%,
#f28e2b 30%,
#e15759 30%,
#e15759 100%);position:relative">
<div style="position:absolute;left:{min(100, max(0, (bmi_result["value"]/40)*100))}%;top:-5px">
▼
</div>
</div>
<div style="display:flex;justify-content:space-between">
<span>Underweight (<18.5)</span>
<span>Healthy (18.5-25)</span>
<span>Overweight (25-30)</span>
<span>Obese (30+)</span>
</div>
</div>
""", unsafe_allow_html=True)
# Store BMI in session state
st.session_state.bmi = bmi_result
# Plan generation and display
if submitted and st.session_state.user_data:
with st.spinner("🧠 Generating your personalized diet plan using Gemini AI..."):
#diet_plan = generate_diet_plan(st.session_state.user_data)
diet_plan = generate_diet_plan({**st.session_state.user_data,"bmi": bmi_result["value"],
"bmi_status": bmi_result["status"]
})
if diet_plan:
st.session_state.diet_plan = diet_plan
# Generate unique user ID
user_id = f"user_{int(time.time())}"
# Save to BigQuery
if save_to_bq(bq_client, user_id, diet_plan):
st.toast("✅ Plan saved to database!")
# Display generated plan
if st.session_state.diet_plan:
st.subheader("Your Personalized Diet Plan")
st.markdown("---")
st.markdown(st.session_state.diet_plan)
# Download button
st.download_button(
label="Download Plan",
data=st.session_state.diet_plan,
file_name="my_diet_plan.md",
mime="text/markdown"
)
# Show history
st.subheader("Your Plan History")
try:
query = f"""
SELECT timestamp, weight, height, age, gender
FROM `{st.secrets['gcp']['project_id']}.{DATASET}.{TABLE}`
WHERE user_id LIKE 'user_%'
ORDER BY timestamp DESC
LIMIT 5
"""
history = bq_client.query(query).to_dataframe()
if not history.empty:
history["timestamp"] = pd.to_datetime(history["timestamp"])
st.dataframe(history.style.format({
"weight": "{:.1f} kg",
"height": "{:.0f} cm"
}))
else:
st.info("No previous plans found")
except Exception as e:
st.error(f"History load error: {str(e)}")
if __name__ == "__main__":
main()
Сохраните код под именем app.py.
5. Развертывание приложений с использованием облачной сборки в Cloud Run
Теперь, конечно же, мы хотим продемонстрировать это замечательное приложение другим. Для этого мы можем упаковать его и развернуть в Cloud Run как публичный сервис, к которому смогут получить доступ другие. Для этого давайте вернёмся к архитектуре.
Сначала нам нужен Dockerfile. Нажмите Файл->Новый текстовый файл, скопируйте и вставьте следующий код, затем сохраните его как Dockerfile.
# Use official Python image
FROM python:3.12-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT 8080
# Install system dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy requirements
COPY requirements.txt .
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy application files
COPY . .
# Expose port
EXPOSE $PORT
# Run the application
CMD ["streamlit", "run", "app.py", "--server.port", "8080", "--server.address", "0.0.0.0"]
Далее мы создадим cloudbuid.yaml для сборки приложений, которые затем превратятся в образы Docker, отправятся в реестр артефактов и развернутся в облаке.
Нажмите Файл->Новый текстовый файл, скопируйте и вставьте следующий код, затем сохраните его как cloudbuild.yaml.
steps:
# Build Docker image
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID', '--no-cache',
'--progress=plain',
'.']
id: 'Build'
timeout: 1200s
waitFor: ['-']
dir: '.'
# Push to Container Registry
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID']
id: 'Push'
waitFor: ['Build']
# Deploy to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- 'run'
- 'deploy'
- 'diet-planner-service'
- '--image=gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'
- '--port=8080'
- '--region=us-central1'
- '--platform=managed'
- '--allow-unauthenticated'
- '--set-env-vars=GCP_PROJECT_ID=$PROJECT_ID,GCP_LOCATION=us-central1'
- '--cpu=1'
- '--memory=1Gi'
- '--timeout=300'
waitFor: ['Push']
options:
logging: CLOUD_LOGGING_ONLY
machineType: 'E2_HIGHCPU_8'
diskSizeGb: 100
images:
- 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'
На этом этапе у нас уже есть все файлы, необходимые для сборки приложений в образы Docker, отправки их в реестр артефактов и развертывания в Cloud Run. Давайте развернём их. Перейдите в терминал Cloud Shell и убедитесь, что текущий проект настроен на ваш активный проект. Если нет, используйте команду gcloud configure, чтобы задать идентификатор проекта:
gcloud config set project [PROJECT_ID]
Затем выполните следующую команду для сборки приложений, которые станут образами Docker, отправьте их в реестр артефактов и разверните в Cloud Run.
gcloud builds submit --config cloudbuild.yaml
Он создаст Docker-контейнер на основе ранее предоставленного Dockerfile и отправит его в реестр артефактов. После этого мы развернем созданный образ в Cloud Run. Весь этот процесс описан в шагах cloudbuild.yaml
.
Обратите внимание, что мы разрешаем доступ без аутентификации, поскольку это демонстрационное приложение. Рекомендуется использовать соответствующую аутентификацию для ваших корпоративных и производственных приложений.
После завершения развертывания мы можем проверить его на странице Cloud Run, найдя Cloud Run в верхней строке поиска облачной консоли и щелкнув продукт Cloud Run.
После этого вы можете проверить развернутую службу, указанную на странице Cloud Run Service. Щелкните по службе, чтобы получить URL-адрес службы.
URL сервиса будет на верхней панели.
Продолжайте использовать приложение в режиме инкогнито или на мобильном устройстве. Оно уже должно быть доступно.
6. Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, используемые в этой лабораторной работе, выполните следующие действия:
- В консоли Google Cloud перейдите на страницу Управление ресурсами .
- В списке проектов выберите проект, который вы хотите удалить, а затем нажмите Удалить .
- В диалоговом окне введите идентификатор проекта, а затем нажмите кнопку «Завершить» , чтобы удалить проект.
- Либо вы можете перейти в Cloud Run на консоли, выбрать службу, которую вы только что развернули, и удалить ее.