Разработка приложений LLM с помощью Vertex AI SDK,Разработка приложений LLM с помощью Vertex AI SDK

1. Введение

Обзор

Вы — разработчик в компании, занимающейся маркетингом в сфере туризма. Ваш отдел продаж решил, что им необходимо новое приложение для чата, чтобы не отставать от более крупных компаний, занимающихся бронированием и поиском. Они также слышали о генеративном искусственном интеллекте , но мало что о нем знают. Другие отделы слышали об этой инициативе и интересуются, как это может улучшить качество обслуживания клиентов.

Что вы будете делать

В этой лабораторной работе вы создадите чат-бота-помощника для путешественников, используя модель Gemini 2.5 Flash на платформе Vertex AI .

Приложение должно:

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

Вы будете работать в предварительно настроенной среде Google Cloud, а именно в редакторе Cloud Shell. Для вас уже настроен базовый веб-интерфейс, а также предоставлены необходимые разрешения для доступа к Vertex AI. Это приложение создано с использованием Streamlit .

Что вы узнаете

В этой лабораторной работе вы научитесь выполнять следующие задачи:

2. Настройка проекта

Аккаунт Google

Если у вас еще нет личного аккаунта Google, вам необходимо его создать .

Используйте личный аккаунт вместо рабочего или учебного.

Войдите в консоль Google Cloud.

Войдите в консоль Google Cloud, используя личную учетную запись Google.

Включить выставление счетов

Обменяйте 5 долларов США на кредиты Google Cloud (по желанию)

Для проведения этого мастер-класса вам потребуется платежный аккаунт с достаточным балансом. Если вы планируете использовать собственную платежную систему, этот шаг можно пропустить.

  1. Перейдите по этой ссылке и войдите в систему, используя свой личный аккаунт Google. Вы увидите примерно следующее: Нажмите, чтобы авторизовать Cloud Shell.
  2. Нажмите кнопку «НАЖМИТЕ ЗДЕСЬ ДЛЯ ДОСТУПА К ВАШИМ КРЕДИТАМ». Это переведет вас на страницу настройки вашего платежного профиля. Нажмите, чтобы авторизовать Cloud Shell.
  3. Нажмите «Подтвердить».

Теперь вы подключены к пробному платёжному аккаунту Google Cloud Platform.

Скриншот обзора выставления счетов

Создайте личный платежный аккаунт.

Если вы настроили оплату с использованием кредитов Google Cloud, этот шаг можно пропустить.

Чтобы настроить личный платежный аккаунт, перейдите сюда, чтобы включить оплату в облачной консоли.

Несколько замечаний:

  • Выполнение этой лабораторной работы должно обойтись менее чем в 1 доллар США в виде облачных ресурсов.
  • В конце этой лабораторной работы вы можете выполнить действия по удалению ресурсов, чтобы избежать дальнейших списаний средств.
  • Новые пользователи могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .

Создать проект (необязательно)

Если у вас нет текущего проекта, который вы хотели бы использовать для этой лабораторной работы, создайте новый проект здесь .

3. Откройте редактор Cloud Shell.

  1. Нажмите на эту ссылку, чтобы перейти непосредственно в редактор Cloud Shell.
  2. Если сегодня вам будет предложено авторизоваться, нажмите «Авторизовать» , чтобы продолжить. Нажмите, чтобы авторизовать Cloud Shell.
  3. Если терминал не отображается внизу экрана, откройте его:
    • Нажмите «Просмотреть».
    • Нажмите «Терминал» Откройте новый терминал в редакторе Cloud Shell.
  4. В терминале настройте свой проект с помощью этой команды:
    gcloud config set project [PROJECT_ID]
    
    • Пример:
      gcloud config set project lab-project-id-example
      
    • Если вы не помните идентификатор своего проекта, вы можете перечислить все идентификаторы своих проектов с помощью следующей команды:
      gcloud projects list
      
      Установите идентификатор проекта в терминале редактора Cloud Shell.
  5. Вы должны увидеть следующее сообщение:
    Updated property [core/project].
    

4. Включите API.

Для использования SDK Vertex AI и взаимодействия с моделью Gemini необходимо включить API Vertex AI в вашем проекте Google Cloud.

  1. В терминале включите API:
    gcloud services enable \
      aiplatform.googleapis.com
    

Введение в SDK Vertex AI для Python

Для взаимодействия с моделями, размещенными на Vertex AI, из вашего приложения на Python вам понадобится SDK Vertex AI для Python. Этот SDK упрощает процесс отправки запросов, указания параметров модели и получения ответов, избавляя от необходимости напрямую обрабатывать сложности базовых вызовов API.

Подробную документацию по Vertex AI SDK для Python можно найти здесь: Введение в Vertex AI SDK для Python | Google Cloud .

5. Создайте виртуальное окружение и установите зависимости.

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

  1. Создайте папку с именем wanderbot для хранения кода вашего приложения-помощника для путешествий. Запустите следующий код в терминале :
    mkdir wanderbot && cd wanderbot
    
  2. Создайте и активируйте виртуальную среду:
    uv venv --python 3.12
    source .venv/bin/activate
    
    Вы увидите префикс ( wanderbot ) перед приглашением терминала, указывающий на то, что виртуальная среда активна. Это будет выглядеть примерно так:

    Скриншот терминала с активной виртуальной средой

6. Создайте стартовые файлы для wanderbot.

  1. Создайте и откройте новый файл app.py для приложения. Запустите следующий код в терминале :
    cloudshell edit app.py
    
    Команда cloudshell edit откроет файл app.py в редакторе, расположенном над терминалом.
  2. Вставьте следующий стартовый код приложения в app.py :
    import streamlit as st
    from google import genai
    from google.genai import types
    import requests
    import logging
    
    # --- Defining variables and parameters  ---
    REGION = "global"
    PROJECT_ID = None # TODO: Insert Project ID
    GEMINI_MODEL_NAME = "gemini-2.5-flash"
    
    temperature = .2
    top_p = 0.95
    
    system_instructions = None
    
    # --- Tooling ---
    # TODO: Define the weather tool function declaration
    
    # TODO: Define the get_current_temperature function
    
    
    # --- Initialize the Vertex AI Client ---
    try:
        # TODO: Initialize the Vertex AI client
    
        print(f"VertexAI Client initialized successfully with model {GEMINI_MODEL_NAME}")
    except Exception as e:
        st.error(f"Error initializing VertexAI client: {e}")
        st.stop()
    
    
    # TODO: Add the get_chat function here in Task 15.
    
    
    # --- Call the Model ---
    def call_model(prompt: str, model_name: str) -> str:
        """
        This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions.
        It will be replaced in a later step with a more advanced version that handles tooling.
        """
        try:
    
            # TODO: Prepare the content for the model
    
            # TODO: Define generate_content configuration (needed for system instructions and parameters)
    
            # TODO: Define response
    
            logging.info(f"[call_model_response] LLM Response: \"{response.text}\"")
            # TODO: Uncomment the below "return response.text" line
            # return response.text
    
        except Exception as e:
            return f"Error: {e}"
    
    
    # --- Presentation Tier (Streamlit) ---
    # Set the title of the Streamlit application
    st.title("Travel Chat Bot")
    
    # Initialize session state variables if they don't exist
    if "messages" not in st.session_state:
        # Initialize the chat history with a welcome message
        st.session_state["messages"] = [
            {"role": "assistant", "content": "How can I help you today?"}
        ]
    
    # Display the chat history
    for msg in st.session_state.messages:
        st.chat_message(msg["role"]).write(msg["content"])
    
    # Get user input
    if prompt := st.chat_input():
        # Add the user's message to the chat history
        st.session_state.messages.append({"role": "user", "content": prompt})
        # Display the user's message
        st.chat_message("user").write(prompt)
    
        # Show a spinner while waiting for the model's response
        with st.spinner("Thinking..."):
            # Get the model's response using the call_model function
            model_response = call_model(prompt, GEMINI_MODEL_NAME)
            # Add the model's response to the chat history
            st.session_state.messages.append(
                {"role": "assistant", "content": model_response}
            )
            # Display the model's response
            st.chat_message("assistant").write(model_response)
    
  3. Создайте и откройте новый файл requirements.txt для кода приложения. Запустите следующий код в терминале :
    cloudshell edit requirements.txt
    
    Команда cloudshell edit откроет файл requirements.txt в редакторе, расположенном над терминалом.
  4. Вставьте следующий стартовый код приложения в файл requirements.txt .
    google-genai
    streamlit
    requests
    
  5. Установите необходимые зависимости Python для этого проекта. Выполните следующий код в терминале :
    uv pip install -r requirements.txt
    

7. Изучите код

Созданные вами файлы содержат базовый интерфейс приложения для чата. В их число входят:

  • app.py : Это файл, с которым мы будем работать. В настоящее время он содержит следующее:
    • необходимый импорт
    • Переменные и параметры среды (некоторые из которых являются заполнителями)
    • пустая функция call_model , которую мы будем заполнять
    • Код Streamlit для фронтенд-приложения чата
  • requirements.txt :
    • включает в себя требования к установке для запуска app.py

Теперь пришло время изучить код!

Откройте чат помощи с кодом Gemini.

Чат Gemini Code Assist должен быть уже открыт в панели справа в редакторе Cloud Shell. Если чат Gemini Code Assist еще не открыт, вы можете открыть его, выполнив следующие действия:

  1. Нажатие кнопки Gemini Code Assist ( Нажмите здесь, чтобы включить функцию Gemini Code Assist. ) в верхней части экрана.
  2. Выберите «Открыть чат помощи с кодом Gemini» . Меню помощи по коду Gemini

Воспользуйтесь Gemini Code Assist, чтобы разобраться в коде.

Для лучшего понимания кода вы можете воспользоваться чатом Gemini Code Assist.

  1. Выделите или выберите нужный участок кода.
  2. В чате Близнецов напишите "Поясните этот код".
  3. Нажмите Enter для отправки

Видеоролик, демонстрирующий выделение части кода, передачу параметра 'Explain this' в функцию автозаполнения кода gemini и получение ответа.

8. Запустите веб-приложение

Перед подключением этого приложения к LLM запустите его, чтобы посмотреть, как оно работает на начальном этапе.

  1. В каталоге wanderbot выполните в терминале следующую команду, чтобы запустить приложение Streamlit и сделать его локально доступным в вашей среде Cloud Shell:
    streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080
    
    Оставьте это окно терминала открытым, так как приложение Streamlit продолжит работу. Вы можете открыть новое окно терминала в Cloud Shell для выполнения других команд.
  2. После выполнения команды нажмите кнопку « Предварительный просмотр веб-страницы» в верхней части редактора Cloud Shell и выберите «Предварительный просмотр на порту 8080» .
    Открыто меню предварительного просмотра, в котором

    Вы увидите простой интерфейс чата для вашего туристического приложения.
  3. Введите любое сообщение (например, Hi! ») и нажмите ENTER.

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

9. Инициализируйте клиент Vertex AI.

Изучите доступные модели в Vertex AI.

Платформа Vertex AI от Google Cloud предоставляет доступ к различным моделям генеративного искусственного интеллекта . Прежде чем интегрировать какую-либо из них, вы можете изучить доступные варианты в консоли Google Cloud.

  1. В консоли Google Cloud перейдите в Model Garden. Для этого введите «Model Garden» в строку поиска в верхней части экрана и выберите Vertex AI. шоу )
  2. Просмотрите доступные модели. Вы можете отфильтровать их по таким параметрам, как режимы работы, типы задач и характеристики.

Для выполнения этой лабораторной работы вы будете использовать модель Flash Gemini 2.5 , которая благодаря своей скорости является хорошим выбором для создания адаптивных чат-приложений.

Инициализируйте клиент Vertex AI.

Теперь вам нужно изменить раздел --- Initialize the Vertex AI Client --- в app.py , чтобы инициализировать клиент Vertex AI. Этот объект клиента будет использоваться для отправки запросов модели.

  1. Откройте app.py в редакторе Cloud Shell.
  2. В app.py найдите строку PROJECT_ID = None .
  3. Замените None на идентификатор вашего проекта Google Cloud в кавычках. (например, PROJECT_ID = "google-cloud-labs" )
    Если вы не помните идентификатор своего проекта, вы можете перечислить все идентификаторы своих проектов с помощью следующей команды:
    gcloud projects list | awk '/PROJECT_ID/{print $2}'
    
  4. Определение клиента : внутри блока try инициализируйте клиент Vertex AI.
        client = genai.Client(
            vertexai=True,
            project=PROJECT_ID,
            location=REGION,
        )
    

Обновлена ​​инициализация клиента Vertex AI.

На этом этапе раздел «Инициализация клиента Vertex AI» будет выглядеть следующим образом:

# --- Initialize the Vertex AI Client ---
try:
    client = genai.Client(
        vertexai=True,
        project=PROJECT_ID,
        location=REGION,
    )
    print(f"VertexAI Client initialized successfully with model {GEMINI_MODEL_NAME}")
except Exception as e:
    st.error(f"Error initializing VertexAI client: {e}")
    st.stop()

10. Подготовьте данные и вызовите модель.

Теперь вам нужно подготовить контент для отправки модели и совершить звонок модели Gemini.

  1. Найдите раздел --- Call the Model --- , где определена функция call_model .
  2. Определение содержимого : В разделе # TODO: Prepare the content for the model определите входное содержимое, которое будет отправлено в модель. Для простого запроса это будет сообщение, введенное пользователем.
            contents = [prompt]
    
  3. Определите ответ : вставьте этот код под # TODO: Define response .
            response = client.models.generate_content(
                model=model_name,
                contents=contents,
            )
    
  4. Верните ответ : раскомментируйте следующую строку:
            return response.text
    
  5. Внимательно изучите строку, где вызывается функция call_model , в нижней части файла, в блоке with . Если вы не понимаете, что здесь происходит, выделите эту строку и попросите Gemini Code Assist объяснить.

Более явный способ определения contents

Описанный выше способ определения contents работает, потому что SDK достаточно интеллектуален, чтобы понимать, что список, содержащий строки, представляет собой текстовый ввод пользователя. Он автоматически правильно форматирует его для API модели.

Однако более явный и фундаментальный способ структурирования входных данных предполагает использование объектов types.Part и types.Content , например, так:

user_message_parts = [types.Part.from_text(text=prompt)]
contents = [
    types.Content(
        role="user", # Indicates the content is from the user
        parts=user_message_parts, # A list, allowing multiple types of content
    ),
]

Обновлена ​​функция call_model

На этом этапе функция call_model должна выглядеть следующим образом:

def call_model(prompt: str, model_name: str) -> str:
    """
    This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions. 
    It will be replaced in a later step with a more advanced version that handles tooling.
    """
    try:

        contents = [prompt]

        # TODO: Define generate_content configuration (needed later for system instructions and parameters)

        response = client.models.generate_content(
            model=model_name,
            contents=contents,
        )
        logging.info(f"[call_model_response] LLM Response: \"{response.text}\"")

        return response.text
    except Exception as e:
        return f"Error: {e}"

11. Проверьте работу подключенного приложения.

  1. В терминале завершите текущий запущенный процесс ( CTRL+C ).
  2. Повторите команду, чтобы снова запустить приложение Streamlit.
    streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080
    
  3. Обновите приложение Streamlit. Если приложение Streamlit все еще запущено, вы можете просто обновить страницу предварительного просмотра в браузере.
  4. Теперь введите вопрос в поле ввода чата, например, такой:
    What is the best time of year to go to Iceland?
    
  5. Нажмите ENTER.

    Вы должны увидеть, как приложение отобразит ваше сообщение, всплывающее окно «Размышляю...», а затем ответ, сгенерированный моделью Gemini! Если это так, значит, вы успешно подключили ваше веб-приложение к LLM на Vertex AI. 🙌 🥳

12. Определите системные инструкции.

Хотя базовая связь работает, качество и стиль ответов LLM в значительной степени зависят от получаемых входных данных. Разработка подсказок — это процесс проектирования и уточнения этих входных данных (подсказок) для направления модели к генерации желаемого результата.

С этой целью вы начнете с создания нескольких системных инструкций и передачи их модели.

Вы будете использовать сервис Ask Gemini , чтобы составить полезные инструкции для системы.

  1. В app.py найдите переменную system_instructions , которая в данный момент имеет значение None .
    system_instructions = None
    
    Вам нужно будет заменить None многострочной строкой, содержащей инструкции для нашего бота-помощника в путешествиях.
  2. Обратитесь в Gemini Code Assist : введите следующую подсказку в Gemini Code Assist (или придумайте свою собственную!):
    I am a developer at a travel marketing company, and my sales department has decided that they need a new chat application to keep up with the bigger booking and search companies. I'm building a simple travel assistant chatbot using the Gemini 2.5 Flash model on Vertex AI.
    
    The application should:
    - Helps users ask questions about travel, book travel, and learn about places they are going to go
    - Provides users ways to get help about their specific travel plans
    - Provides all this in a production quality way (multiple environments, logging and monitoring, etc.)
    
    Please create system instructions appropriate for that chat app. Be thorough.
    
    Do not alter the code in any way beyond providing me with system instructions.
    
  3. Определите system_instructions : установите system_instructions равным системным инструкциям, сгенерированным с помощью Gemini Code Assist. В качестве альтернативы вы можете использовать эти системные инструкции, созданные Gemini с помощью аналогичной подсказки.
    system_instructions = """
    You are a sophisticated travel assistant chatbot designed to provide comprehensive support to users throughout their travel journey. Your capabilities include answering travel-related questions, assisting with booking travel arrangements, offering detailed information about destinations, and providing support for existing travel plans.
    
    **Core Functionalities:**
    
    1.  **Travel Information and Recommendations:**
        *   Answer user inquiries about travel destinations, including popular attractions, local customs, visa requirements, weather conditions, and safety advice.
        *   Provide personalized recommendations for destinations, activities, and accommodations based on user preferences, interests, and budget.
        *   Offer insights into the best times to visit specific locations, considering factors like weather, crowds, and pricing.
        *   Suggest alternative destinations or activities if the user's initial choices are unavailable or unsuitable.
    
    2.  **Booking Assistance:**
        *   Facilitate the booking of flights, hotels, rental cars, tours, and activities.
        *   Search for available options based on user-specified criteria such as dates, destinations, budget, and preferences.
        *   Present clear and concise information about available options, including pricing, amenities, and booking terms.
        *   Guide users through the booking process, ensuring accurate information and secure transactions.
        *   Provide booking confirmations and relevant details, such as booking references and contact information.
    
    3.  **Travel Planning and Itinerary Management:**
        *   Assist users in creating detailed travel itineraries, including flights, accommodations, activities, and transportation.
        *   Offer suggestions for optimizing travel plans, such as minimizing travel time or maximizing sightseeing opportunities.
        *   Provide tools for managing and modifying existing itineraries, including adding or removing activities, changing booking dates, or upgrading accommodations.
        *   Offer reminders and notifications for upcoming travel events, such as flight check-in or tour departure times.
    
    4.  **Customer Support and Troubleshooting:**
        *   Provide prompt and helpful support to users with questions or issues related to their travel plans.
        *   Assist with resolving booking discrepancies, cancellations, or modifications.
        *   Offer guidance on travel-related emergencies, such as lost luggage or travel delays.
        *   Provide access to relevant contact information for airlines, hotels, and other travel providers.
    
    **Interaction Guidelines:**
    
    *   **Professionalism:** Maintain a polite, respectful, and professional tone in all interactions.
    *   **Clarity and Conciseness:** Provide clear, concise, and easy-to-understand information. Avoid jargon or technical terms unless necessary and always explain them.
    *   **Accuracy:** Ensure all information provided is accurate and up-to-date. Double-check details before sharing them with users. If unsure about something, admit that you don't know and offer to find the information.
    *   **Personalization:** Tailor your responses and recommendations to the specific needs and preferences of each user.
    *   **Proactive Assistance:** Anticipate user needs and offer relevant information or suggestions proactively.
    *   **Error Handling:** Gracefully handle user errors or misunderstandings. Provide helpful guidance and alternative options when necessary.
    *   **Confidentiality:** Respect user privacy and handle personal information with the utmost confidentiality and in compliance with data protection regulations.
    
    **Example Interactions:**
    
    **User:** "I want to go on a beach vacation in the Caribbean. I have a budget of $2000 per person for a week."
    **Chatbot:** "Certainly! The Caribbean offers many beautiful beach destinations within your budget. Some popular options include Punta Cana in the Dominican Republic, Cancun in Mexico, and Montego Bay in Jamaica. These destinations offer stunning beaches, all-inclusive resorts, and various activities. Would you like me to search for flights and accommodations for these locations based on your travel dates?"
    
    **User:** "My flight is delayed. What should I do?"
    **Chatbot:** "I'm sorry to hear about the delay. Please check with the airline for the updated departure time and any assistance they can offer. You may be entitled to compensation or rebooking options depending on the length of the delay and the airline's policy. Do you have your flight number handy so I can look up the current status for you?"
    
    **User:** "Tell me about the best time to visit Japan."
    **Chatbot:** "Japan is a fantastic destination with distinct seasons offering unique experiences. Spring (March-May) is famous for the beautiful cherry blossoms, while autumn (September-November) boasts stunning fall foliage. Both seasons have pleasant temperatures, making them ideal for sightseeing. Summer (June-August) can be hot and humid, but it's a great time for festivals and outdoor activities in the mountains. Winter (December-February) offers opportunities for skiing and snowboarding in the Japanese Alps, though some areas may experience heavy snowfall. To recommend the best time for you, could you tell me what you'd like to experience in Japan?"
    
    By following these instructions, you will be able to provide exceptional travel assistance and create a positive experience for every user.
    """
    
  4. Определите конфигурацию generate_content: инициализируйте объект конфигурации, которому вы будете передавать эти системные инструкции. Поскольку system_instructions определен глобально в нашем скрипте, функция может получить к нему прямой доступ.
            generate_content_config = types.GenerateContentConfig(
                system_instruction=[
                    types.Part.from_text(text=system_instructions)
                ],
            )
            logging.info(f"[generate_config_details] System Instruction: {generate_content_config.system_instruction[0].text}")
    
  5. Чтобы добавить инструкции системы в ответ , добавьте параметр config в метод generate_content и присвойте ему значение объекта generate_content_config созданного выше.
            response = client.models.generate_content(
                model=model_name,
                contents=contents,
                config=generate_content_config, # This is the new line
            )
    

Обновлена ​​функция call_model

Теперь полная функция call_model выглядит следующим образом:

def call_model(prompt: str, model_name: str) -> str:
    """
    This function interacts with a large language model (LLM) to generate text based on a given prompt and system instructions. 
    It will be replaced in a later step with a more advanced version that handles tooling.
    """
    try:
        contents = [prompt]

        generate_content_config = types.GenerateContentConfig(
            system_instruction=[
                types.Part.from_text(text=system_instructions)
            ],
        )
        logging.info(f"[generate_config_details] System Instruction: {generate_content_config.system_instruction[0].text}")
        response = client.models.generate_content(
            model=model_name,
            contents=contents,
            config=generate_content_config,
        )

        logging.info(f"[call_model_response] LLM Response: \"{response.text}\"")
        
        return response.text
    except Exception as e:
        return f"Error: {e}"

13. Протестируйте приложение, следуя инструкциям системы.

  1. В терминале завершите текущий запущенный процесс ( CTRL+C ).
  2. Повторите команду, чтобы снова запустить приложение Streamlit.
    streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080
    
  3. Обновите приложение Streamlit. Если приложение Streamlit все еще запущено, вы можете просто обновить страницу предварительного просмотра в браузере.
  4. Попробуйте задать тот же вопрос, что и раньше:
    What is the best time of year to go to Iceland?
    
  5. Нажмите ENTER.
    Сравните, как она реагирует на этот раз по сравнению с прошлым разом.

14. Дайте определение инструменту прогнозирования погоды.

На данный момент наш чат-бот обладает достаточными знаниями, но их объем ограничен данными, на которых он обучался. Он не может получить доступ к информации в режиме реального времени. Для туристического бота возможность получать данные в реальном времени, такие как прогнозы погоды, является огромным преимуществом.

Здесь вступает в дело инструментарий , также известный как вызов функций . Мы можем определить набор инструментов (функций Python), которые LLM может вызывать для получения внешней информации.

Как работает инструментарий

  1. Мы описываем наши инструменты для модели, включая их функции и параметры, которые они принимают.
  2. Пользователь отправляет запрос (например, " Какая погода в Лондоне? ").
  3. Модель получает запрос и видит, что пользователь спрашивает о чем-то, что она может узнать с помощью одного из своих инструментов.
  4. Вместо текстового ответа модель отправляет специальный объект function_call , указывающий, какой инструмент она хочет вызвать и с какими аргументами.
  5. Наш код на Python получает этот function_call , выполняет нашу фактическую функцию get_current_temperature с предоставленными аргументами и получает результат (например, 15 °C).
  6. Мы отправляем этот результат обратно в модель.
  7. Модель получает результат и генерирует для пользователя ответ на естественном языке (например, «Текущая температура в Лондоне составляет 15°C»).

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

Определите инструмент для прогнозирования погоды

Если путешественник ищет совета о том, чем заняться, и выбирает между видами деятельности, зависящими от погоды, инструмент для прогноза погоды может оказаться очень полезным! Давайте создадим инструмент для нашей модели, чтобы получать текущую погоду. Нам нужны две части: объявление функции, описывающей инструмент для модели, и собственно функция Python, которая его реализует.

  1. В app.py найдите комментарий # TODO: Define the weather tool function declaration .
  2. Под этим комментарием добавьте переменную weather_function . Это словарь, который сообщает модели все, что ей нужно знать о назначении функции, ее параметрах и необходимых аргументах.
    weather_function = {
        "name": "get_current_temperature",
        "description": "Gets the current temperature for a given location.",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city name, e.g. San Francisco",
                },
            },
            "required": ["location"],
        },
    }
    
  3. Далее найдите комментарий # TODO: Define the get_current_temperature function . Под ним добавьте следующий код на Python. Эта функция выполнит следующее:
    • Для получения координат местоположения воспользуйтесь API геокодирования .
    • Используйте эти координаты для вызова API погоды .
    • Возвращает простую строку, содержащую температуру и единицу измерения.
    def get_current_temperature(location: str) -> str:
        """Gets the current temperature for a given location."""
    
        try:
            # --- Get Latitude and Longitude for the location ---
            geocode_url = f"https://geocoding-api.open-meteo.com/v1/search?name={location}&count=1&language=en&format=json"
            geocode_response = requests.get(geocode_url)
            geocode_data = geocode_response.json()
    
            if not geocode_data.get("results"):
                return f"Could not find coordinates for {location}."
    
            lat = geocode_data["results"][0]["latitude"]
            lon = geocode_data["results"][0]["longitude"]
    
            # --- Get Weather for the coordinates ---
            weather_url = f"https://api.open-meteo.com/v1/forecast?latitude={lat}&longitude={lon}&current_weather=true"
            weather_response = requests.get(weather_url)
            weather_data = weather_response.json()
    
            temperature = weather_data["current_weather"]["temperature"]
            unit = "°C"
    
            return f"{temperature}{unit}"
    
        except Exception as e:
            return f"Error fetching weather: {e}"
    

15. Рефакторинг для чата и инструментов.

В настоящее время наша функция call_model использует простой одноразовый вызов generate_content . Это отлично подходит для отдельных вопросов, но не идеально для многоэтапного диалога, особенно для диалога, включающего обмен данными для разработки инструментов.

Более целесообразно использовать сессию чата , которая сохраняет контекст разговора. Сейчас мы переработаем наш код, чтобы использовать сессию чата, что необходимо для корректной реализации инструментов.

  1. Удалите существующую функцию call_model . Мы заменим её более совершенной версией.
  2. Вместо него добавьте новую функцию call_model из приведенного ниже блока кода. Эта новая функция содержит логику для обработки цикла вызова инструмента, который мы обсуждали ранее. Обратите внимание, что в ней есть несколько комментариев TODO, которые мы завершим на следующих шагах.
    # --- Call the Model ---
    def call_model(prompt: str, model_name: str) -> str:
        """
        This function interacts with a large language model (LLM) to generate text based on a given prompt.
        It maintains a chat session and handles function calls from the model to external tools.
        """
        try:
            # TODO: Get the existing chat session or create a new one.
    
            message_content = prompt
    
            # Start the tool-calling loop
            while True:
                # TODO: Send the message to the model.
    
                # Check if the model wants to call a tool
                has_tool_calls = False
                for part in response.candidates[0].content.parts:
                    if part.function_call:
                        has_tool_calls = True
                        function_call = part.function_call
                        logging.info(f"Function to call: {function_call.name}")
                        logging.info(f"Arguments: {function_call.args}")
    
                        # TODO: Call the appropriate function if the model requests it.
    
    
                    elif part.text:
                        logging.info("No function call found in the response.")
                        logging.info(response.text)
                # If no tool call was made, break the loop
                if not has_tool_calls:
                    break
    
            # TODO: Return the model's final text response.
    
        except Exception as e:
            return f"Error: {e}"
    
  3. Теперь добавим вспомогательную функцию для управления сеансом чата. Над новой функцией call_model добавим функцию get_chat . Эта функция создаст новый сеанс чата с инструкциями нашей системы и определениями инструментов или получит существующий. Это хорошая практика для организации кода.
    def get_chat(model_name: str):
        if f"chat-{model_name}" not in st.session_state:
    
            # TODO: Define the tools configuration for the model
    
            # TODO: Define the generate_content configuration, including tools
    
            # TODO: Create a new chat session
    
            st.session_state[f"chat-{model_name}"] = chat
        return st.session_state[f"chat-{model_name}"]
    

Вы создали основу для нашей продвинутой, интегрированной с инструментами логики чата!

16. Реализуйте логику вызова инструментов.

Теперь давайте заполним поля TODOs , чтобы наша логика вызова инструментов стала полностью работоспособной.

Реализуйте функцию get_chat

  1. В функции get_chat в комментарии # TODO: Define the tools configuration... , определите объект tools , создав экземпляр types.Tool из объявления функции weather_function .
            tools = types.Tool(function_declarations=[weather_function])
    
  2. В разделе # TODO: Define the generate_content configuration... определите generate_content_config , убедившись, что передаете объект tools в модель. Таким образом модель узнает, какие инструменты она может использовать.
            generate_content_config = types.GenerateContentConfig(
                system_instruction=[types.Part.from_text(text=system_instructions)],
                tools=[tools] # Pass the tool definition here
            )
    
  3. В разделе # TODO: Create a new chat session , создайте объект чата с помощью client.chats.create() , передав имя нашей модели и конфигурацию.
            chat = client.chats.create(
                model=model_name,
                config=generate_content_config,
            )
    

Реализуйте call_model

  1. В разделе # TODO: Get the existing chat session... в функции call_model вызовите нашу новую вспомогательную функцию get_chat .
            chat = get_chat(model_name)
    
  2. Далее найдите # TODO: Send the message to the model . Отправьте сообщение пользователю, используя метод chat.send_message() .
                response = chat.send_message(message_content)
    
  3. Найдите # TODO: Call the appropriate function... . Здесь мы проверяем, какую функцию хочет использовать модель, и выполняем её.
                    if function_call.name == "get_current_temperature":
                      result = get_current_temperature(**function_call.args)
                    function_response_part = types.Part.from_function_response(
                        name=function_call.name,
                        response={"result": result},
                    )
                    message_content = [function_response_part]
  1. Наконец, найдите # TODO: Return the model's final text response and add the return statement.
            return response.text
    

Обновлена ​​функция get_chat

Обновленная функция get_chat теперь должна выглядеть следующим образом:

def get_chat(model_name: str):
    if f"chat-{model_name}" not in st.session_state:
        # Tools
        tools = types.Tool(function_declarations=[weather_function])

        # Initialize a configuration object
        generate_content_config = types.GenerateContentConfig(
            system_instruction=[types.Part.from_text(text=system_instructions)],
            tools=[tools]
        )
        chat = client.chats.create(
            model=model_name,
            config=generate_content_config,
        )
        st.session_state[f"chat-{model_name}"] = chat
    return st.session_state[f"chat-{model_name}"]

Обновлена ​​функция call_model

Обновленная функция call_model теперь должна выглядеть следующим образом:

def call_model(prompt: str, model_name: str) -> str:
    try:
        chat = get_chat(model_name)
        message_content = prompt
        
        while True:
            response = chat.send_message(message_content)
            has_tool_calls = False
            for part in response.candidates[0].content.parts:
                if part.function_call:
                    has_tool_calls = True
                    function_call = part.function_call
                    logging.info(f"Function to call: {function_call.name}")
                    logging.info(f"Arguments: {function_call.args}")
                    if function_call.name == "get_current_temperature":
                        result = get_current_temperature(**function_call.args)
                        function_response_part = types.Part.from_function_response(
                            name=function_call.name,
                            response={"result": result},
                        )
                        message_content = [function_response_part]
                elif part.text:
                    logging.info("No function call found in the response.")
                    logging.info(response.text)

            if not has_tool_calls:
                break

        return response.text

    except Exception as e:
        return f"Error: {e}"

17. Протестируйте приложение, использующее этот инструмент.

Давайте посмотрим, как работает ваша новая функция!

  1. В терминале завершите текущий запущенный процесс ( CTRL+C ).
  2. Повторите команду, чтобы снова запустить приложение Streamlit.
    streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080
    
  3. Обновите приложение Streamlit. Если приложение Streamlit все еще запущено, вы можете просто обновить страницу предварительного просмотра в браузере.
  4. Теперь задайте вопрос, который должен активировать ваш новый инструмент, например, следующий:
    I'm looking for something to do in New York today. What do you recommend? Would it be a good day to go to Ellis Island?
    
  5. Нажмите ENTER
    Сравните этот ответ с предыдущими. В чём разница?
    Вы должны увидеть ответ, включающий температуру, полученную из вашей функции! Проверьте также свой терминал Cloud Shell; вы должны увидеть сообщения, подтверждающие выполнение вашей функции Python.

18. Уточните выходные данные модели с помощью параметров.

Отличная работа! Ваш ассистент для путешествий теперь может использовать инструменты для получения актуальных внешних данных, что значительно повышает его эффективность.

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

В этой лабораторной работе мы сосредоточимся на temperature и top_p . (Полный список настраиваемых параметров и их описания см. в описании параметра GenerateContentConfig в нашем справочнике API.)

  • temperature : контролирует случайность выходных данных. Более низкое значение (ближе к 0) делает выходные данные более детерминированными и целенаправленными, в то время как более высокое значение (ближе к 2) увеличивает случайность и креативность. Для бота вопросов и ответов или бота-помощника обычно предпочтительнее более низкая температура для получения более последовательных и фактических ответов.
  • top_p : Максимальная суммарная вероятность токенов, учитываемых при выборке. Токены сортируются на основе присвоенных им вероятностей, так что учитываются только наиболее вероятные токены. Модель учитывает наиболее вероятные токены, сумма вероятностей которых равна значению top_p . Более низкое значение ограничивает выбор токенов, что приводит к менее разнообразному результату.

Параметры вызова

  1. Найдите переменные temperature и top_p , определенные в верхней части app.py Обратите внимание, что они еще нигде не использовались.
  2. Добавьте параметры temperature и top_p , определенные в функции get_chat в параметре GenerateContentConfig .
            generate_content_config = types.GenerateContentConfig(
                temperature=temperature,
                top_p=top_p,
                system_instruction=[types.Part.from_text(text=system_instructions)],
                tools=[tools] # Pass the tool definition here
            )
    
    

Обновлена ​​функция get_chat

Приложение get_chat теперь выглядит так:

def get_chat(model_name: str):
    if f"chat-{model_name}" not in st.session_state:
        # Tools
        tools = types.Tool(function_declarations=[weather_function])

        # Initialize a configuration object
        generate_content_config = types.GenerateContentConfig(
            temperature=temperature,
            top_p=top_p,
            system_instruction=[types.Part.from_text(text=system_instructions)],
            tools=[tools] 
        )
        chat = client.chats.create(
            model=model_name,
            config=generate_content_config,
        )
        st.session_state[f"chat-{model_name}"] = chat
    return st.session_state[f"chat-{model_name}"]

19. Тестирование с использованием параметров модели.

  1. В терминале завершите текущий запущенный процесс ( CTRL+C ).
  2. Повторите команду, чтобы снова запустить приложение Streamlit.
    streamlit run app.py --browser.serverAddress=localhost --server.enableCORS=false --server.enableXsrfProtection=false --server.port 8080
    
  3. Обновите приложение Streamlit. Если приложение Streamlit все еще запущено, вы можете просто обновить страницу предварительного просмотра в браузере.
  4. Попробуйте задать тот же вопрос, что и раньше.
    I'm looking for something to do in New York today. What do you recommend? Would it be a good day to go to Ellis Island?
    
  5. Нажмите ENTER
    Сравните этот ответ с предыдущими ответами.

20. Поздравляем!

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

Продолжение экспериментов

Существует множество вариантов дальнейшей оптимизации вашего запроса. Вот некоторые из них, которые стоит рассмотреть:

  • Отрегулируйте temperature и top_p и посмотрите, как это повлияет на отклик, получаемый от LLM.
  • Полный список настраиваемых параметров и их описаний см. в разделе GenerateContentConfig в нашей справочной документации по API. Попробуйте определить больше параметров и изменить их, чтобы посмотреть, что произойдет!

Краткий обзор

В этой лабораторной работе вы выполнили следующее:

  • Для разработки использовал редактор Cloud Shell и терминал.
  • Используйте Python SDK от Vertex AI для подключения вашего приложения к модели Gemini.
  • Применялись системные инструкции и параметры модели для управления действиями LLM.
  • Изучил концепцию инструментов ( вызов функций ) и их преимущества.
  • Ваш код был переработан для использования сессии чата с сохранением состояния, что является передовой практикой для разговорного ИИ.
  • Определил инструмент для модели, используя объявление функции.
  • Реализована функция на языке Python для обеспечения логики работы инструмента.
  • Написал код для обработки запросов на вызов функций модели и возврата результатов.