1. Введение
Генеративные модели ИИ замечательно справляются с пониманием естественного языка и реагированием на него. Но что делать, если для таких важных задач, как стандартизация адресов, необходимы точные и предсказуемые результаты? Традиционные генеративные модели иногда могут давать разные ответы в разное время на одни и те же запросы, что потенциально может привести к несоответствиям. Именно здесь проявляется преимущество функции вызова функций Gemini, позволяющей детерминированно управлять элементами ответа ИИ.
В этом практическом занятии данная концепция иллюстрируется на примере автозаполнения и стандартизации адресов. Для этого мы создадим облачную функцию на Java, которая будет выполнять следующие задачи:
- Принимает координаты широты и долготы.
- Вызывает API геокодирования Google Maps для получения соответствующих адресов.
- Использует функцию вызова функций Gemini 1.0 Pro для детерминированной стандартизации и суммирования адресов в необходимом нам формате.
Давайте начнём!
2. Вызов функции Gemini
Функция Gemini Function Calling выделяется в эпоху генеративного ИИ тем, что позволяет сочетать гибкость генеративных языковых моделей с точностью традиционного программирования.
Вот задачи, которые необходимо выполнить для реализации вызова функций Gemini:
- Определение функций : четко опишите функции. Описание должно включать следующую информацию:
- Название функции, например,
getAddress. - Параметры, которые ожидает функция, например,
latlngв виде строки. - Тип данных, возвращаемых функцией, например, список строковых адресов.
- Создайте инструменты для Gemini : упакуйте описания функций в виде спецификаций API в инструменты. Рассматривайте инструмент как специализированный набор инструментов, который Gemini может использовать для понимания функциональности API.
- Управление API с помощью Gemini : когда вы отправляете запрос в Gemini, он может проанализировать ваш запрос и определить, где можно использовать предоставленные вами инструменты. Затем Gemini выступает в роли интеллектуального оркестратора, выполняя следующие задачи:
- Генерирует необходимые параметры API для вызова определенных вами функций. Gemini не вызывает API от вашего имени. Вы должны вызывать API, используя параметры и сигнатуру, сгенерированные для вас функцией вызова Gemini.
- Gemini обрабатывает результаты, передавая их обратно в процесс генерации, и включает структурированную информацию в свой окончательный ответ. Вы можете обрабатывать эту информацию так, как вам удобно для вашего приложения.
На следующем изображении показан поток данных, этапы реализации и ответственный за каждый этап, например, приложение, LLM или API:

Что вы построите
Вам предстоит создать и развернуть Java-функцию Cloud Function, которая будет выполнять следующие действия:
- Принимает координаты широты и долготы.
- Вызывает API геокодирования Google Maps для получения соответствующих адресов.
- Использует функцию вызова функций Gemini 1.0 Pro для детерминированной стандартизации и суммирования этих адресов в определенном формате.
3. Требования
4. Прежде чем начать
- В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud.
- Убедитесь, что для вашего проекта Google Cloud включена функция выставления счетов. Узнайте, как проверить, включена ли функция выставления счетов для проекта .
- Активируйте Cloud Shell из консоли Google Cloud. Для получения дополнительной информации см. раздел «Использование Cloud Shell» .
- Если ваш проект не задан, используйте следующую команду для его задания:
gcloud config set project <YOUR_PROJECT_ID>
- В оболочке Cloud Shell установите следующие переменные среды:
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
- Для активации необходимых API Google Cloud выполните следующие команды в Cloud Shell:
gcloud services enable cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com logging.googleapis.com storage-component.googleapis.com cloudaicompanion.googleapis.com aiplatform.googleapis.com
- Откройте редактор Cloud Shell , нажмите «Расширения» , а затем установите расширение Gemini + Google Cloud Code .
5. Внедрить облачные функции.
- Запустите редактор Cloud Shell .
- Нажмите на Cloud Code , а затем разверните раздел Cloud Functions .
- Нажмите на значок «Создать функцию» (+).
- В диалоговом окне «Создать новое приложение» выберите параметр «Java: Hello World» .
- Укажите имя проекта в пути к проекту, например, GeminiFunctionCalling .
- Нажмите «Проводник» , чтобы просмотреть структуру проекта, а затем откройте файл pom.xml. На следующем изображении показана структура проекта:

- Добавьте необходимые зависимости внутри тега
<dependencies>... </dependencies>в файлеpom.xml. Полный текст файлаpom.xmlможно найти в репозитории этого проекта на GitHub. Скопируйте файл pom.xml оттуда в файлpom.xmlвашего текущего проекта, который вы редактируете. - Скопируйте класс
HelloWorld.javaиз репозитория GeminiFunctionCalling на GitHub . Необходимо обновить поляAPI_KEYиproject_id, указав в них ваш ключ API для геокодирования и идентификатор проекта Google Cloud соответственно.
6. Разберитесь с вызовом функций, используя класс HelloWorld.java.
Запрос ввода
В этом примере в качестве входных данных используется следующий запрос: Какой адрес соответствует значению широты и долготы 40.714224, -73.961452 ?
Ниже приведён фрагмент кода, соответствующий подсказке ввода в файле:
String promptText = "What's the address for the latlong value '" + latlngString + "'?"; //40.714224,-73.961452
спецификация API
В этом примере используется API обратного геокодирования. Ниже приведена спецификация API:
/* Declare the function for the API to invoke (Geo coding API) */
FunctionDeclaration functionDeclaration =
FunctionDeclaration.newBuilder()
.setName("getAddress")
.setDescription("Get the address for the given latitude and longitude value.")
.setParameters(
Schema.newBuilder()
.setType(Type.OBJECT)
.putProperties(
"latlng",
Schema.newBuilder()
.setType(Type.STRING)
.setDescription("This must be a string of latitude and longitude coordinates separated by comma")
.build())
.addRequired("latlng")
.build())
.build();
Организуйте подсказку с помощью Близнецов.
В Gemini отправляются входные данные и спецификация API:
// Add the function to a "tool"
Tool tool = Tool.newBuilder()
.addFunctionDeclarations(functionDeclaration)
.build();
// Invoke the Gemini model with the use of the tool to generate the API parameters from the prompt input.
GenerativeModel model = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.setTools(Arrays.asList(tool))
.build();
GenerateContentResponse response = model.generateContent(promptText);
Content responseJSONCnt = response.getCandidates(0).getContent();
В ответ на это API получает JSON-данные с параметрами конфигурации. Вот пример выходных данных:
role: "model"
parts {
function_call {
name: "getAddress"
args {
fields {
key: "latlng"
value {
string_value: "40.714224,-73.961452"
}
}
}
}
}
Передайте следующий параметр в API Reverse Geocoding : "latlng=40.714224,-73.961452"
Сопоставьте полученный результат с форматом "latlng=VALUE" .
Вызовите API
Ниже приведён фрагмент кода, который вызывает API:
// Create a request
String url = API_STRING + "?key=" + API_KEY + params;
java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
// Send the request and get the response
java.net.http.HttpResponse<String> httpresponse = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
// Save the response
String jsonResult = httpresponse.body().toString();
Строка jsonResult содержит ответ от API обратного геокодирования. Ниже представлена отформатированная версия выходных данных:
"...277 Bedford Ave, Brooklyn, NY 11211, USA; 279 Bedford Ave, Brooklyn, NY 11211, USA; 277 Bedford Ave, Brooklyn, NY 11211, USA;..."
Обработайте ответ API и подготовьте запрос.
Следующий код обрабатывает ответ от API и подготавливает запрос с инструкциями по обработке ответа:
// Provide an answer to the model so that it knows what the result
// of a "function call" is.
String promptString =
"You are an AI address standardizer for assisting with standardizing addresses accurately. Your job is to give the accurate address in the standard format as a JSON object containing the fields DOOR_NUMBER, STREET_ADDRESS, AREA, CITY, TOWN, COUNTY, STATE, COUNTRY, ZIPCODE, LANDMARK by leveraging the address string that follows in the end. Remember the response cannot be empty or null. ";
Content content =
ContentMaker.fromMultiModalData(
PartMaker.fromFunctionResponse(
"getAddress",
Collections.singletonMap("address", formattedAddress)));
String contentString = content.toString();
String address = contentString.substring(contentString.indexOf("string_value: \"") + "string_value: \"".length(), contentString.indexOf('"', contentString.indexOf("string_value: \"") + "string_value: \"".length()));
List<SafetySetting> safetySettings = Arrays.asList(
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build(),
SafetySetting.newBuilder()
.setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT)
.setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
.build()
);
Вызовите Gemini и верните стандартизированный адрес.
Следующий код передает обработанные данные с предыдущего шага в качестве запроса в Gemini:
GenerativeModel modelForFinalResponse = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.build();
GenerateContentResponse finalResponse = modelForFinalResponse.generateContent(promptString + ": " + address, safetySettings);
System.out.println("promptString + content: " + promptString + ": " + address);
// See what the model replies now
System.out.println("Print response: ");
System.out.println(finalResponse.toString());
String finalAnswer = ResponseHandler.getText(finalResponse);
System.out.println(finalAnswer);
Переменная finalAnswer содержит стандартизированный адрес в формате JSON. Ниже приведён пример выходных данных:
{"replies":["{ \"DOOR_NUMBER\": null, \"STREET_ADDRESS\": \"277 Bedford Ave\", \"AREA\": \"Brooklyn\", \"CITY\": \"New York\", \"TOWN\": null, \"COUNTY\": null, \"STATE\": \"NY\", \"COUNTRY\": \"USA\", \"ZIPCODE\": \"11211\", \"LANDMARK\": null} null}"]}
Теперь, когда вы поняли, как работает вызов функций Gemini в контексте стандартизации адресов, вы можете приступить к развертыванию облачной функции.
7. Развертывание и тестирование
- Если вы уже создали проект GeminiFunctionCalling и реализовали облачную функцию, перейдите к шагу 2. Если вы еще не создали проект, перейдите в терминал Cloud Shell и клонируйте этот репозиторий:
git clonehttps://github.com/AbiramiSukumaran/GeminiFunctionCalling - Перейдите в папку проекта:
cd GeminiFunctionCalling - Выполните следующую команду для создания и развертывания облачной функции:
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http
Ниже представлен формат URL-адреса после развертывания: https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling
- Протестируйте облачную функцию, выполнив следующую команду в терминале:
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'
Ниже приведён ответ на случайный пример запроса: '{"replies":["{ "DOOR_NUMBER": "277", "STREET_ADDRESS": "Bedford Ave", "AREA": null, "CITY": "Brooklyn", "TOWN": null, "COUNTY": "Kings County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "11211", "LANDMARK": null}}```"]}'
8. Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этой статье, выполните следующие действия:
- В консоли Google Cloud перейдите на страницу «Управление ресурсами» .
- В списке проектов выберите проект, который хотите удалить, и нажмите кнопку «Удалить».
- В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить», чтобы удалить проект.
- Если вы хотите сохранить свой проект, пропустите описанные выше шаги и удалите облачную функцию, перейдя в раздел «Облачные функции», выбрав в списке функций ту, которую хотите удалить, и нажав кнопку «УДАЛИТЬ».
9. Поздравляем!
Поздравляем! Вы успешно использовали функцию вызова функций Gemini в Java-приложении и преобразовали задачу генеративного ИИ в детерминированный, надежный процесс. Чтобы узнать больше о доступных моделях, см. документацию по продукту Vertex AI LLM .