«Сен кімсің?»: Как мы подключили Vertex AI к WhatsApp и научили ЦОН-бота понимать шала-казахский
Каждый казахстанец хотя бы раз в жизни испытывал эту боль. Вы пишете в официальный WhatsApp-бот какого-нибудь ведомства или банка: «Сәлеметсіз бе! Менің ЭЦП кілтімнің мерзімі өтіп кетті, қалай жаңартсам болады? Только без похода в ЦОН, пожалуйста». А в ответ получаете бездушное:
- [1] Узнать статус заявки
- [2] Адреса отделений
- [3] Позвать оператора (Ожидание: 4 часа)
Классические кнопочные чат-боты — это технология из каменного века. Они не понимают контекст, они ломаются от малейшей опечатки, и они абсолютно бессильны перед нашим уникальным лингвистическим феноменом — шала-казахским языком (когда в одном предложении органично сплетаются казахские, русские слова и англицизмы).
Месяц назад к нам в OZAT обратился крупный квазигосударственный сектор с задачей: «Нам нужен умный ассистент для WhatsApp. Он должен консультировать по госуслугам, бронировать очередь и, самое главное, разговаривать с людьми как живой человек, понимая сленг и опечатки». Мы сразу поняли — время расчехлять Vertex AI и модели Gemini.
Почему именно Gemini и Vertex AI?
В мире LLM (Large Language Models) много крутых игроков. Но для проектов в госсекторе и финтехе Казахстана у Google Cloud (а именно Vertex AI) есть два убийственных преимущества:
- Мультиязычность из коробки. Gemini (особенно последние модели 1.5 Pro и Flash) феноменально хорошо понимает казахский язык. Более того, модель не «спотыкается», когда пользователь переключается между языками прямо посреди предложения.
- Enterprise Security (GDPR/SOC2). Использовать публичный API ChatGPT или Claude для обработки данных граждан — это прямой путь к уголовному делу или огромным штрафам. Данные, отправляемые в Vertex AI, не используются для дообучения базовых моделей Google, а весь трафик можно изолировать внутри VPC Service Controls. Данные не покидают защищенный периметр.
Архитектура решения: От WhatsApp до LLM и обратно
Мы построили легковесную и бесконечно масштабируемую serverless-архитектуру на базе сервисов GCP. Никаких виртуальных машин, которые нужно администрировать — только код и управляемые сервисы.
- WhatsApp Business API: Принимает сообщения от пользователей и шлет Webhook на наш бэкенд.
- Cloud Run: Сервис на Node.js (TypeScript), который выступает в роли оркестратора. Он валидирует вебхук, извлекает текст и управляет бизнес-логикой.
- Firestore: NoSQL база данных, где мы храним контекст диалога (Memory) для каждого номера телефона.
- Vertex AI (Gemini 1.5 Flash): Наш «мозг», который понимает текст, принимает решения и формулирует ответы. Скорость Flash-модели идеальна для чатов (ответ генерируется за 1-1.5 секунды).
- Google Cloud Secret Manager: Хранит API-ключи от WhatsApp и токены внутренних систем.
Инициализация Vertex AI на TypeScript
Для работы с Vertex AI мы используем официальный SDK от Google @google/genai. Важный момент: мы используем метод аутентификации через Application Default Credentials (ADC), который автоматически подхватывает сервисный аккаунт нашего Cloud Run. Никаких хардкодов JSON-ключей!
import { GoogleGenAI } from '@google/genai';
// Инициализация клиента Vertex AI.
// Так как код крутится в Cloud Run, учетные данные (ADC)
// и проект подтягиваются автоматически из среды окружения.
const ai = new GoogleGenAI();
export async function generateBotReply(userMessage: string, chatHistory: any[]) {
// Формируем системный промпт (System Instruction),
// задающий персону и ограничения нашего ЦОН-бота
const systemInstruction = `
Ты — официальный виртуальный ассистент Центров Обслуживания Населения (ЦОН) Казахстана.
Твоя цель — вежливо и точно консультировать граждан по вопросам получения госуслуг.
Правила:
1. Отвечай на том языке, на котором пишет пользователь. Если пользователь использует смешанный (шала-казахский), старайся отвечать на чистом казахском или русском, в зависимости от преобладающего языка.
2. Будь краток и эмпатичен. Никаких длинных простыней текста.
3. Никогда не запрашивай полный ИИН в целях безопасности, проси только последние 4 цифры для верификации, если это необходимо для вызова функции.`;
const response = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: [
...chatHistory,
{ role: 'user', parts: [{ text: userMessage }] }
],
config: {
systemInstruction: systemInstruction,
temperature: 0.3, // Низкая температура для большей точности и предсказуемости
maxOutputTokens: 500,
}
});
return response.text;
}Смотреть код на GitHub (OZAT-kz)
Обратите внимание на temperature: 0.3. Для креативных задач (например, написания стихов) температуру завышают. Но бот госуслуг не должен фантазировать и галлюцинировать. Ему нужна хирургическая точность.
Проблема: «Шала-казахский» и распознавание намерений
Давайте посмотрим, как классический бот с NLP-модулем (например, Dialogflow ES) и Gemini реагируют на реальный запрос из логов.
Запрос пользователя: «Брат, менің правам срок бітіп қалды, новый алу үшін қайда барам? Шоферская справка керек па?»
Классический бот: Извините, я не понял ваш запрос. Выберите пункт меню: [1] Получить ЭЦП... (NLP-движок не смог вычленить entity и intent из смеси сленга и двух языков).
Наш бот на Vertex AI (Gemini): «Сәлеметсіз бе! Жүргізуші куәлігін (права) ауыстыру үшін сізге Мамандандырылған ХҚКО-ға (СпецЦОН) бару қажет немесе eGov.kz порталы арқылы онлайн өтінім қалдыра аласыз. Иә, 073/у формалы медициналық анықтама (шоферская справка) міндетті түрде қажет.»
Gemini блестяще справляется с деконструкцией смешанного языка, понимая контекст «права» (водительское удостоверение) и «срок бітіп қалды» (истек срок действия).
Терминатор для продаж: Как мы прокачали AI Ментора для Скаутов и почему конкуренты уже плачут
Точность классификации намерений (Intent Recognition)
Вызов функций (Function Calling): Учим LLM нажимать кнопки
Консультировать — это хорошо. Но настоящая магия начинается тогда, когда ИИ может совершать реальные действия в бэкенд-системах. Пользователь пишет: «Забронируй мне очередь в Алмалинский ЦОН на завтра на 10 утра». LLM сама по себе не может записать вас в базу данных. Для этого используется механизм Function Calling (или Tools).
Мы описываем для Gemini список доступных функций в виде JSON-схемы (названия функций, их описание и требуемые параметры). Если Gemini понимает, что для ответа на запрос пользователя ей нужно выполнить действие, она возвращает не текст ответа, а структурированный JSON с названием функции и извлеченными параметрами.
import { GoogleGenAI, Type } from '@google/genai';
const ai = new GoogleGenAI();
// Описываем инструмент (функцию), которую может вызывать Gemini
const bookAppointmentTool = {
functionDeclarations: [
{
name: 'book_con_appointment',
description: 'Бронирование очереди в ЦОН. Вызывай эту функцию, если пользователь просит забронировать очередь, записаться в ЦОН или взять талон.',
parameters: {
type: Type.OBJECT,
properties: {
con_name: {
type: Type.STRING,
description: 'Название или район ЦОНа (например, "Алмалинский", "СпецЦОН Астана")'
},
date_time: {
type: Type.STRING,
description: 'Желаемая дата и время в формате ISO 8601 (например, "2026-08-15T10:00:00")'
}
},
required: ['con_name', 'date_time'],
},
},
],
};
// Функция обработки диалога с поддержкой Tools
export async function handleUserMessageWithTools(userMessage: string) {
const response = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: [{ role: 'user', parts: [{ text: userMessage }] }],
config: {
tools: [bookAppointmentTool], // Передаем наши инструменты модели
}
});
// Проверяем, решила ли модель вызвать функцию
if (response.functionCalls && response.functionCalls.length > 0) {
const call = response.functionCalls[0];
if (call.name === 'book_con_appointment') {
const args = call.args as any;
console.log(`[System] Модель хочет забронировать очередь: ЦОН - ${args.con_name}, Время - ${args.date_time}`);
// Здесь мы делаем реальный HTTP-запрос к API базы данных бронирования
// const result = await api.book(args.con_name, args.date_time);
// Возвращаем результат выполнения функции обратно в модель,
// чтобы она сформировала человечный ответ
const functionResponse = await ai.models.generateContent({
model: 'gemini-1.5-flash',
contents: [
{ role: 'user', parts: [{ text: userMessage }] },
// Добавляем запрос функции от модели в историю
{ role: 'model', parts: [{ functionCall: call }] },
// Возвращаем результат выполнения
{ role: 'function', parts: [{ functionResponse: { name: call.name, response: { status: 'success', booking_id: 'A-123' } } }] }
]
});
return functionResponse.text;
}
}
// Если функция не вызывалась, просто возвращаем текст ответа
return response.text;
}Смотреть код на GitHub (OZAT-kz)
Таким образом, когда пользователь пишет неструктурированный текст «Братан, запиши на завтра после обеда в Бостандыкский», Gemini извлекает con_name: "Бостандыкский" и вычисляет date_time на основе текущего времени, вызывая наш внутренний API. Пользователь получает ответ: «Сіздің кезегіңіз Бостандық ауданының ХҚКО-на ертең сағат 14:00-ге сәтті брондалды. Талон нөмірі: A-123.»
Безопасность и PII (Персональные данные)
В работе с государственными и финансовыми ботами критически важно не скармливать в LLM чувствительные данные (номера паспортов, ИИН, полные номера банковских карт). Да, Vertex AI не использует данные для обучения, но хранить PII в логах чат-истории — плохая практика.
Поэтому перед отправкой текста в Vertex AI мы пропускаем сообщение пользователя через Google Cloud DLP (Data Loss Prevention) API (сейчас переименован в Sensitive Data Protection). Этот сервис на лету с помощью регулярных выражений и машинного обучения находит ИИН (12 цифр, подпадающих под контрольную сумму) и маскирует их.
Пользователь пишет: «Мой ИИН 900101300123, проверь статус».
Vertex AI получает: «Мой ИИН [IIN_MASKED], проверь статус».
ИИН извлекается на уровне нашего Node.js бэкенда, сохраняется в защищенную переменную и используется ТОЛЬКО для запроса к внутренним API ЦОНа, минуя «мозг» LLM.
Выводы
Классические чат-боты умирают. Пользователи устали пробираться сквозь деревья меню и угадывать формулировки команд. Интеграция больших языковых моделей вроде Gemini 1.5 в мессенджеры полностью меняет правила игры в Customer Service.
Наш опыт показывает, что использование Vertex AI в связке с Function Calling позволяет создать не просто «болталку», а полноценного цифрового сотрудника, который понимает локальную специфику (тот самый шала-казахский), выполняет бизнес-процедуры и соблюдает строгие enterprise-стандарты безопасности.
Архитектура на базе Cloud Run делает это решение невероятно дешевым (оплата только за реальное время работы процессора при обработке запроса) и отказоустойчивым. Ни один вирусный репост в WhatsApp, вызывающий шквал обращений, не положит ваш бэкенд.
Если ваша компания все еще мучает клиентов фразами «Нажмите 0 для возврата в главное меню» — самое время написать нам в OZAT. Пора переходить на светлую сторону ИИ!

Рустам Шарафутдинов
Эксперт в области архитектуры Google Cloud и Senior Full-Stack разработчик с более чем 15-летним опытом. Специализируется на отказоустойчивых архитектурах, оптимизации высоконагруженных проектов и интеграции AI (Vertex AI).