Бот-бариста: агент, который сам вызывает функции

Урок 2 из 80 курса «Gemini API: примеры использования»: официальный курс Gemini API Cookbook (Гугл Джемини) на русском языке. Этот урок бесплатный.

Авторское право 2026 Google LLC.
# @title Лицензировано в соответствии с лицензией Apache, версия 2.0 ("Лицензия");
# вы не можете использовать этот файл, за исключением случаев соблюдения Лицензии.
# Вы можете получить копию Лицензии по адресу
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Если иное не предусмотрено применимым законодательством или не согласовано в письменной форме, программное обеспечение
# распространяется по Лицензии на условиях "КАК ЕСТЬ",
# БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явных или подразумеваемых.
# См. Лицензию для получения информации о конкретных разрешениях, регулирующих использование, и
# ограничениях в соответствии с Лицензией.

Gemini API: Агенты и автоматический вызов функций с Barista Bot

Этот notebook демонстрирует практический пример использования автоматического вызова функций с помощью Python SDK Gemini API для создания агента. Вы определите несколько функций, составляющих систему заказа в кафе, подключите их к Gemini API и напишете цикл агента, который взаимодействует с пользователем для заказа напитков в кафе.

Это руководство было вдохновлено prompt'ом Barista bot в стиле ReAct, доступным через AI Studio.

%pip install -qU "google-genai>=2.9.0"

Чтобы запустить этот notebook, ваш API key должен быть сохранен в Colab Secret с именем GEMINI_API_KEY. Если вы работаете в другой среде, вы можете сохранить свой ключ в переменной среды. См. Аутентификация image, чтобы узнать больше.

from google import genai
from google.colab import userdata

client = genai.Client(api_key=userdata.get("GEMINI_API_KEY"))

Определение API

Чтобы эмулировать систему заказа в кафе, определите функции для управления заказом клиента: добавление, редактирование, очистка, подтверждение и выполнение.

Эти функции отслеживают заказ клиента, используя глобальные переменные order (незавершенный заказ) и placed_order (подтвержденный заказ, отправленный на кухню). Каждая из функций редактирования заказа обновляет order, а после размещения order копируется в placed_order и очищается.

В Python SDK вы можете передавать функции непосредственно конструктору модели, где SDK будет проверять сигнатуры типов и docstring'и для определения tools. По этой причине важно правильно типизировать каждый из параметров, давать функциям осмысленные имена и подробные docstring'и.

from typing import Optional
from random import randint

order = []  # Незавершенный заказ.
placed_order = []  # Подтвержденный, выполненный заказ.


def add_to_order(drink: str, modifiers: Optional[list[str]] = None) -> None:
    """Добавляет указанный напиток в заказ клиента, включая любые модификаторы."""
    if modifiers is None:  # Ensures safe handling of None
        modifiers = []
    order.append((drink, modifiers))


def get_order() -> list[tuple[str, list[str]]]:
    """Возвращает заказ клиента."""
    return order


def remove_item(n: int) -> str:
    """Удаляет n-й (начиная с единицы) элемент из заказа.

    Возвращает:
        Удаленный элемент.
    """
    item, _ = order.pop(n - 1)
    return item


def clear_order() -> None:
    """Удаляет все элементы из заказа клиента."""
    order.clear()


def confirm_order() -> str:
    """Спрашивает клиента, верен ли заказ.

    Возвращает:
        Свободный текстовый ответ пользователя.
    """
    print("Your order:")
    if not order:
        print("  (no items)")

    for drink, modifiers in order:
        print(f"  {drink}")
        if modifiers:
            print(f'   - {", ".join(modifiers)}')

    return input("Is this correct? ")


def place_order() -> int:
    """Отправляет заказ на кухню.

    Возвращает:
        Приблизительное количество минут до готовности заказа.
    """
    placed_order[:] = order.copy()
    clear_order()

    # TODO: Реализовать выполнение заказа кофе.
    return randint(1, 10)

Тестирование API

После написания функций проверьте, что они работают должным образом.

# Проверим!

clear_order()
add_to_order("Latte", ["Extra shot"])
add_to_order("Tea")
remove_item(2)
add_to_order("Tea", ["Earl Grey", "hot"])
confirm_order()
Your order:
  Latte
   - Extra shot
  Tea
   - Earl Grey, hot
Is this correct? yes
'yes'

Определение prompt'а

Здесь вы определяете полный prompt Barista-bot. Этот prompt содержит пункты меню кафе, модификаторы и некоторые инструкции.

Инструкции включают рекомендации по вызову функций (например, "Всегда confirm_order с пользователем перед вызовом place_order"). Вы можете изменить это, чтобы добавить свой собственный стиль взаимодействия с ботом, например, если вы хотите, чтобы бот повторял каждый запрос перед добавлением в заказ, вы можете указать это здесь.

Конец prompt'а включает некоторую терминологию, с которой бот может столкнуться, и инструкции du jour — в данном случае отмечается, что в кафе закончилось соевое молоко.

COFFEE_BOT_PROMPT = """\Вы — система приема заказов на кофе, и вам разрешено говорить только о напитках из МЕНЮ. Никогда не говорите ни о чем, кроме заказа напитков из МЕНЮ для клиента.
Ваша цель — выполнить place_order после понимания пунктов меню и любых модификаторов, которые хочет клиент.
Добавляйте позиции в заказ клиента с помощью add_to_order, удаляйте определенные позиции с помощью remove_item и сбрасывайте заказ с помощью clear_order.
Чтобы увидеть содержимое заказа на данный момент, вызовите get_order (по умолчанию это показывается вам, а не пользователю)
Всегда confirm_order с пользователем (перепроверяйте) перед вызовом place_order. Вызов confirm_order отобразит позиции заказа пользователю и вернет его ответ на просмотр списка. Его ответ может содержать модификации.
Всегда проверяйте и отвечайте названиями напитков и модификаторов из МЕНЮ перед добавлением их в заказ.
Если вы не уверены, что напиток или модификатор соответствует тем, что указаны в МЕНЮ, задайте вопрос для уточнения или перенаправления.
У вас есть только модификаторы, перечисленные в меню ниже: Варианты молока, шоты эспрессо, кофеин, подсластители, специальные запросы.
Как только клиент закончит заказывать позиции, confirm_order, а затем place_order.

Часы работы: Вт, Ср, Чт, с 10:00 до 14:00
Цены: Все напитки бесплатны.

МЕНЮ:
Кофейные напитки:
Эспрессо
Американо
Колд брю

Кофейные напитки с молоком:
Латте
Капучино
Кортадо
Маккиато
Мокко
Флэт уайт

Чайные напитки:
Чай Английский завтрак
Зеленый чай
Эрл Грей

Чайные напитки с молоком:
Чай латте
Матча латте
Лондонский туман

Другие напитки:
Стимер
Горячий шоколад

Модификаторы:
Варианты молока: Цельное, 2%, Овсяное, Миндальное, 2% Безлактозное; Вариант по умолчанию: цельное
Шоты эспрессо: Одинарный, Двойной, Тройной, Четверной; по умолчанию: Двойной
Кофеин: Без кофеина, Обычный; по умолчанию: Обычный
Горячий-Ледяной: Горячий, Ледяной; По умолчанию: Горячий
Подсластители (возможность добавить один или несколько): ванильный подсластитель, фундучный подсластитель, карамельный соус, шоколадный соус, безсахарный ванильный подсластитель
Особые пожелания: любые разумные модификации, не связанные с позициями, отсутствующими в меню, например: 'очень горячий', 'один насос', 'половина кофеина', 'больше пены' и т.д.

"Грязный" означает добавление шота эспрессо в напиток, который обычно его не содержит, например, "Грязный Чай Латте".
"Обычное молоко" — это то же самое, что и "цельное молоко".
"Подслащенный" означает добавление обычного сахара, а не подсластителя.

Соевое молоко сегодня закончилось, поэтому оно недоступно.
"""

Настройка модели

На этом шаге вы объединяете функции в "систему", которая передается как tools, создаете экземпляр модели и начинаете сессию чата.

Также определена функция send_message с возможностью повторной попытки для помощи в беседах с низкими квотами.

from google.genai import types
from google.api_core import retry

ordering_system = [
    add_to_order,
    get_order,
    remove_item,
    clear_order,
    confirm_order,
    place_order,
]
model_name = "gemini-3.7-flash" # @param ["gemini-3.1-pro-preview", "gemini-3.7-flash", "gemini-3.5-flash-lite", "gemini-2.5-pro"] {"allow-input":true, isTemplate: true}
chat = client.chats.create(
    model=model_name,
    config=types.GenerateContentConfig(
        tools=ordering_system,
        system_instruction=COFFEE_BOT_PROMPT,
    ),
)

placed_order = []
order = []

Чат с Barista Bot

После определения модели и создания чата остается только подключить пользовательский ввод к модели и отображать вывод в цикле. Этот цикл продолжается до тех пор, пока заказ не будет размещен.

При запуске в Colab любой текст фиксированной ширины исходит из вашего кода Python (например, вызовы print в системе заказа), обычный текст поступает от Gemini API, а обведенные рамки позволяют вводить данные пользователем, которые отображаются с ведущим символом >.

Попробуйте!

from IPython.display import display, Markdown

print("Добро пожаловать в Barista bot!\n\n")

while not placed_order:
    response = chat.send_message(input("> "))
    display(Markdown(response.text))


print("\n\n")
print("[сессия barista bot завершена]")
print()
print("Ваш заказ:")
print(f"  {placed_order}\n")
print("- Спасибо за использование Barista Bot!")
Welcome to Barista bot!


> i would like to have a cuppacino with almond milk
<IPython.core.display.Markdown object>
> do you have stone milk?
<IPython.core.display.Markdown object>
> do you have long black
<IPython.core.display.Markdown object>
>  no, that's all
Your order:
  Cappuccino
   - Almond Milk
Is this correct? yes
<IPython.core.display.Markdown object>
> yes
<IPython.core.display.Markdown object>
[barista bot session over]

Your order:
  [('Cappuccino', ['Almond Milk'])]

- Thanks for using Barista Bot!

Что можно попробовать:

  • Спросите о меню (например, "какие кофейные напитки доступны?")
  • Используйте термины, не указанные в prompt'е (например, "крепкий латте" или "чай EB")
  • Передумайте на полпути ("эмм, отмените латте, извините")
  • Закажите что-то не из меню ("бейбичино")

См. также

Это демонстрационное приложение показало, как интегрировать традиционную программную систему (функции заказа кофе) и AI агента, работающего на Gemini API. Это простой, практичный способ использования LLM, который позволяет вводить и выводить данные на естественном человеческом языке, что ощущается естественно, но при этом сохраняет человека в цикле для обеспечения корректной работы.

Чтобы узнать больше о работе Barista Bot, ознакомьтесь с:

Урок входит в темы

Полезные гиды