- name
- flights
- description
- Find cheapest flights via live browser search across Aviasales, other sellers (Yandex.Travel, Tutu, OneTwoTrip) AND airline sites directly, then apply money-saving strategies (date-shift, nearby airports, hidden-city, split-ticket, error fares). Asks for cities, dates, flexibility, passengers. Use when user types /flights or asks to find/compare plane tickets.
- trigger
- /flights
# /flights — Cheapest Flight Finder
Находит самые дешёвые авиабилеты живым поиском по Aviasales (через браузер Playwright),
затем применяет стратегии экономии и отдаёт честное сравнение. Построен на реальном
рабочем процессе, проверенном на маршруте Москва→Иркутск.
## Step 1 — Собрать вводные (спросить пользователя)
Используй **AskUserQuestion** (можно несколько вопросов за раз). Обязательно выясни:
1. **Откуда** (город / аэропорт).
2. **Куда** (город / аэропорт).
3. **Даты**: конкретные, либо «ближайшие выходные», либо диапазон. Преврати относительные
формулировки в конкретные даты, опираясь на сегодняшнюю дату из контекста сессии.
4. **Гибкость дат**: жёстко эти даты / ±3 дня / «лечу когда дешевле». — это главный рычаг экономии.
5. **Пассажиры** (взрослые/дети) и **класс** (эконом по умолчанию).
6. **Багаж нужен?** (по умолчанию считаем без багажа — только ручная кладь).
7. **Только прямые** или пересадки ок.
8. **Ограничения по времени** (напр. «возврат в понедельник утром»).
Если пользователь уже дал часть данных в запросе — не переспрашивай их, уточни только пробелы.
Разумные дефолты (1 взрослый, эконом, без багажа, пересадки ок) применяй молча и упомяни в ответе.
## Step 2 — Живой поиск по нескольким источникам
⚠️ **Браузер запускать ТОЛЬКО в основной сессии, не через подагентов** — у подагентов нет
интерактивного запроса разрешений, и навигация будет автоматически отклонена (проверено).
IATA-коды: Москва=`MOW` (включает DME/SVO/VKO/ZIA — все аэропорты сразу), СПб=`LED`,
Иркутск=`IKT`, Сочи=`AER`, и т.д. При сомнении — уточни/найди код.
Ищем в три захода: **(A) агрегатор-база → (B) другие селлеры для кросс-проверки →
(C) напрямую у авиакомпаний, которые реально летают по маршруту.** Цель — найти не просто
минимум на одном сайте, а лучшую цену по всем каналам и поймать расхождения/наценку агентов.
### 2A. База — Aviasales (широкий охват рынка)
URL: `https://www.aviasales.ru/search/{ORIGIN}{DDMM}{DEST}{DDMM}` (туда-обратно),
`…/{ORIGIN}{DDMM}{DEST}` (one-way). Пример: пт 19.06 Москва→Иркутск, возврат пн 22.06 =
`MOW1906IKT2206`. Прогоняй по каждой нужной комбинации дат.
Для каждого URL:
1. `mcp__playwright__browser_navigate` на URL.
2. `mcp__playwright__browser_wait_for` с `text: "в пути"` и `time: 25` — рендер цен через JS.
(Заголовок вкладки обновится на минимальную цену, напр. «48 102 ₽ | …».)
3. Достать реальные карточки билетов через `mcp__playwright__browser_evaluate`:
```js
() => {
const all = Array.from(document.querySelectorAll('div'));
const cards = all.filter(e => { const t=e.innerText||'';
return /\d{2}:\d{2}/.test(t) && /₽/.test(t) && /в пути|пересадк|прямой/.test(t)
&& t.length>100 && t.length<700; });
const leaves = cards.filter(c => !cards.some(o => o!==c && c.contains(o)));
return { cards: leaves.map(c=>c.innerText.replace(/\n{2,}/g,'\n').trim()).slice(0,6),
title: document.title };
}
```
4. Если нужна гибкость дат — со страницы любой комбинации сними **календарь соседних дат**:
```js
() => {
const cal = Array.from(document.querySelectorAll('*'))
.find(e => /Цены на соседние даты/.test(e.textContent) && e.children.length<6);
return cal ? cal.innerText.replace(/\n{2,}/g,'\n').trim() : 'no-calendar';
}
```
Из 2A зафиксируй: лучший прямой, абсолютный минимум, и **список авиакомпаний**, реально
летающих по маршруту (понадобится для 2C).
### 2B. Другие селлеры — кросс-проверка (1–2 источника)
Открой эти же даты ещё на одном-двух из списка ниже и сравни минимум. Иногда у конкретного
селлера тариф ниже, иногда — скрытый сервисный сбор всплывает только на шаге оплаты.
- **Яндекс.Путешествия** — `travel.yandex.ru` (свой инвентарь + бонусы Плюс)
- **Tutu.ru** — `tutu.ru/avia/`
- **OneTwoTrip** — `onetwotrip.com`
- **Kupibilet** — `kupibilet.ru`
- **Trip.com** — `trip.com` (международный, для кросс-курса)
- **Skyscanner** — `skyscanner.ru` (метапоиск, но в РФ покрытие урезано)
После загрузки бери минимальную цену из заголовка/верхних карточек тем же приёмом
`browser_evaluate` (подстрой селектор/regex под разметку конкретного сайта — везде это
карточки с временем `\d{2}:\d{2}`, ценой и текстом про пересадки).
### 2C. Напрямую у авиакомпаний (главное добавление)
Для **каждой авиакомпании**, которая делает лучшие/прямые рейсы (из 2A), открой её **официальный
сайт** и проверь цену того же рейса. Часто прямой тариф у перевозчика **дешевле агентского** или
имеет тарифы/багаж, которых нет у селлеров. Реестр росперевозчиков:
| Авиакомпания | Сайт |
|---|---|
| Аэрофлот | `aeroflot.ru` |
| Россия | `rossiya-airlines.com` |
| Победа (лоукостер) | `flypobeda.ru` |
| S7 Airlines | `s7.ru` |
| Уральские авиалинии | `uralairlines.ru` |
| Nordwind / Северный ветер | `nordwindairlines.ru` |
| Red Wings | `flyredwings.com` |
| Utair | `utair.ru` |
| Azimuth / Азимут | `azimuth.aero` |
| Smartavia | `smartavia.com` |
| Аврора | `flyaurora.ru` |
| iFly / Икар | `iflyltd.ru` |
Особенно важно проверять напрямую **лоукостеры (Победа, Smartavia)** — у них тариф у агентов
часто завышен, а собственный сайт даёт базовую цену без чужих сборов.
Заполни форму поиска на сайте (города/даты), дождись выдачи, сними цену через
`browser_evaluate`. Если сайт капризничает с автоматизацией — сделай скриншот
(`browser_take_screenshot`) и считай цену с него, либо честно отметь, что напрямую проверить
не вышло, и оставь ссылку.
### 2D. Платформа и устройство — анти-дискриминация по цене
Цена и сборы зависят не только от рейса, но и от того, **как и с чего** ты заходишь. Проверяй,
а не предполагай — но эти рычаги реально существуют:
- **Чистая сессия (важнее всего).** Повторные заходы с теми же cookie могут поднимать цену
(«ты уже смотрел — спешишь»). Перед контрольным замером используй чистый контекст:
`mcp__playwright__browser_close`, затем заново `browser_navigate`. Не логинься без нужды.
- **Desktop vs Mobile.** Мобильная вёрстка иногда даёт другой тариф/сбор и эксклюзивные акции.
Сравни обе: `mcp__playwright__browser_resize` к 390×844 (телефон) и к 1440×900 (десктоп),
перезагрузи выдачу, сними цену тем же `browser_evaluate`. Где доступно полноценное
эмулирование устройства — используй `mcp__chromeDevtools__emulate` (iPhone/Android),
чтобы сравнить, не выше ли цена с iO/iPhone UA, чем с Android/Windows. Если разницы нет —
так и скажи (часто её нет; «Apple-наценка» — больше городская легенда, но проверка дешёвая).
⚠️ **Обязательно перепроверяй разницу повторными замерами (A/B по 2 раза на UA).** Выдача
Aviasales сама «дрожит» на ±2–3 тыс. ₽ между перезагрузками (уходит самый дешёвый билет),
поэтому одиночный замер iPhone>Android легко принять за дискриминацию, хотя при повторе всё
сходится в одну цену. Проверено: iPhone/Android/Windows на MOW–IKT сошлись в 41 946 ₽.
- **Промокоды — ИСКАТЬ, а не советовать (обязательный шаг).** Не ограничивайся фразой «проверь
в приложении» — это заглушка. Прогони `WebSearch` по перевозчикам/селлерам с маршрута:
`промокод <S7/Kupibilet/OneTwoTrip/Яндекс Путешествия> авиабилеты <месяц год>`. Затем
**отфильтруй честно**:
- Реальные рычаги: скидка на **первый заказ в приложении** (S7 — 10% на тариф, макс. 2000 ₽;
Kupibilet/OneTwoTrip — до 2000 ₽), сезонные распродажи без кода («Неделя S7», «Счастливые
часы»), кешбэк баллами (Яндекс Плюс — но он исключает промокод).
- Кликбейт-мусор: «−80 000 ₽», «−100 000 ₽», «скидка 99%» с купонных аффилиат-сайтов — обычно
мёртвые коды или «скидка до» на дорогие пакеты с порогом (OneTwoTrip −3500 ₽ действует от
заказа 80 000 ₽, т.е. на дешёвый билет не сработает).
- Поле «Промокод» — на **шаге оплаты**, жизнь конкретного кода заранее не гарантируется;
выдавай механизм (что/где/сколько %), а не обещание. Финальный ввод кода в приложении —
явный ручной шаг для пользователя.
- **Сервисный сбор и итоговая цена.** Сбор за оформление у разных селлеров разный и часто
всплывает только на шаге оплаты. **Сравнивай финальную цену «к оплате», а не первую
показанную.** У авиакомпании напрямую сервисного сбора агента обычно нет.
- **Валюта/регион оплаты.** Для внутренних рейсов РФ оплата в рублях; смена региона сайта тут
ничего не даёт (см. стратегию VPN ниже). Релевантно только на международном инофлоте.
В итог вынеси, если нашлась разница по платформе (mobile<desktop, сбор у селлера X и т.п.) —
и обязательно напомни про app-промокоды как ручной шаг.
По завершении — `mcp__playwright__browser_close`.
### Критичные нюансы (грабли)
- Цены из календаря «Цены на соседние даты» — это **другие даты**, а НЕ выбранные. Минимум по
запрошенным датам бери из **карточек билетов** или заголовка вкладки, не из календаря.
- Самый дешёвый билет часто имеет 2 пересадки и сутки в пути — всегда показывай рядом «лучший прямой».
- Сравнивай **итоговую цену с одинаковым багажом**: у лоукостера/агента базовый тариф может быть
ниже, но доплата за место/багаж/выбор кресла переворачивает картину. Считай «с багажом» отдельно,
если пользователь летит с чемоданом.
- Если сайт отдаёт капчу/блок — переключись на следующий источник, либо сообщи и дай ссылку.
## Step 3 — Применить стратегии экономии (честно, под конкретный маршрут)
Не вываливай все стратегии скопом — оценивай применимость к конкретному направлению и помечай,
что работает, а что пустышка:
- **Сдвиг дат ±3 дня** — обычно самый сильный рычаг. Бери цифры из календаря соседних дат,
показывай таблицей, считай экономию vs запрошенные даты. Если даты гибкие — это главный совет.
- **Соседние аэропорты** — для мультиаэропортовых городов (Москва) уже учтено кодом `MOW`.
Проверь, есть ли реальные альтернативы у пункта назначения (в радиусе ~150 км); часто их нет.
- **Hidden city** — маршрут, где пункт назначения это пересадка. Предупреди о рисках: только
ручная кладь, аннулирование обратного сегмента, на внутренних рейсах РФ выигрыш мал.
- **Split ticket** — отдельные билеты через хаб. Имеет смысл только при разнице > ~5000 ₽;
предупреди про риск стыковки и багаж.
- **Error fare** — каналы (TG: @aviasales, @errorfares, @cheapflightsru; форум awd.ru). Честно
скажи: это «лечу куда угодно», не под фиксированные даты.
- **VPN/смена валюты** — для внутренних рейсов РФ на росскарьерах не работает (рубли + санкции
на оплату инокартой). Живёт на международном инофлоте.
- **Тайминг покупки** — для рейса «через пару дней» неактуально (зона last-minute, цена растёт).
Рычаг для брони за 5–8 недель.
## Step 4 — Итоговое сравнение
Выдай:
1. Таблицу по комбинациям дат: самый дешёвый (с пересадками) + лучший прямой, время/авиакомпании,
и **где дешевле — у агента или напрямую у авиакомпании** (колонка «источник/канал»). Явно
отметь, если прямая покупка у перевозчика выгоднее агентской и на сколько.
2. Что дала лучшая из применимых стратегий (обычно сдвиг дат) с конкретной экономией.
3. Чёткую рекомендацию: «нужны эти даты → …», «даты гибкие → …», «брать тут → [канал]».
4. Предложи раскрыть детали (рейсы/время/авиакомпании) выбранного варианта повторным заходом в браузер.
## Notes
- Цены динамические — всегда указывай «по состоянию на сегодня» и что багаж обычно не входит.
- Не выдумывай цены. Нет доступа к браузеру — скажи прямо и дай готовые ссылки на даты.
- Все суммы — в рублях, формат как на сайте (напр. «48 102 ₽»).
Auf GitHub ansehen