Когда-то за последние пятнадцать лет веб тихо решил, что каждому важному сайту также нужно мобильное приложение. Не потому что HTML перестал работать — а потому что приложение — это контролируемая поверхность: курируемый набор действий, без хрома, который вы не выбирали, интерфейс, построенный под один способ взаимодействия.
Мы думаем, что тот же ход ждёт своего часа для другого набора пользователей и другого набора интерфейсов. Если все превращают свой сайт в Android-приложение, мы можем превращать сайты в голосовые приложения — и в приложения командной строки, и в потоки, нативные для программ чтения с экрана. Та же идея, обратное направление: обернуть сайт в поверхность, построенную под то, как вы хотите с ним взаимодействовать, только поверхность — это ваш голос и ваш терминал вместо сенсорного экрана.
Веб едва пригоден на слух
Для зрячего пользователя с мышью современный сайт в порядке. Для того, кто просматривает голосом, или через программу чтения с экрана, или из терминала, большая часть веба — враждебная среда: стены бесконечной прокрутки, баннеры куки, всплывающие окна, меню, которым нужен указатель, содержимое, погребённое под тремя слоями интерактивного хлама. Информация там, внутри. Достать её оттуда, без рук, мучительно.
Обычный ответ — «сайты должны быть доступнее», и это так. Но мы не собираемся чинить весь веб, вежливо попросив. Что мы можем сделать — взять сайты, которые важны, и построить чистый, произносимый интерфейс к каждому — так, как магазины приложений сделали для касания, но для голоса и CLI, и открыто.
Два слоя: чистый API, затем голосовой навык
Каждое из этих голосовых приложений — две сложенные части, и мы уже строим обе.
Слой один — типизированный клиент, превращающий сайт в API. Это ровно наша работа по скрейпингу и реверс-инжинирингу API: дотянуться до сайта, у которого нет пригодного публичного интерфейса, и вернуть структурированные, типизированные объекты вместо хрупкого HTML — глаголы, а не скрейпинг:
from py_bandcamp import BandCamp
for release in BandCamp.search_albums("king gizzard"):
artist = release.work.credits[0].entity.name if release.work.credits else ""
print(release.work.title, artist, release.uri)
Инструменты разведки и
антибот-транспорта
под капотом поддерживают этот доступ рабочим по мере изменения сайта. Этот клиент
уже полезен сам по себе: для терминального пользователя API и есть доступная
версия сайта — наш клиент SoundCloud даже поставляет nds, приложение командной
строки для поиска и воспроизведения музыки без единого браузера в поле зрения. Как только сайт становится
API, он перестаёт быть визуальным артефактом и становится чем-то, что машина — или
голосовой конвейер — может приводить в действие.
Слой два — плагин OVOS, который говорит на этом API. Поверх клиента сидит плагин OpenVoiceOS, который отображает произносимые интенты в вызовы API и озвучивает результаты нашими офлайн-голосами TTS. Это намеренно не заказной навык на каждый сайт — та дорога ведёт к десяткам одноразовых навыков, которые никто не может сопровождать. Для всего медиа-образного это OCP провайдер-плагин: один небольшой адаптер, раскрывающий поверхность поиска-и-воспроизведения сайта всему фреймворку Open Common Play, так что «поиск», «воспроизведение», «дальше» и «продолжить» уже работают так же, как для любого другого источника. Сайт вписывается в единообразный голосовой интерфейс вместо изобретения собственного.
Результат: «Включи канал SomaFM Groove Salad». «Найди на Bandcamp Creative-Commons эмбиент». Сайт, превращённый в то, что вы можете использовать не глядя на него — и без новой грамматики, которую нужно учить для каждого сайта.
В эпоху LLM типизированный API — это готовый к рождению интерфейс на естественном языке
Есть вторая причина, почему эта форма важнее сейчас, чем была бы пять лет назад. Чистый, типизированный клиент — это ровно то, что нужно большой языковой модели, чтобы стать фронт-эндом на естественном языке к сайту.
Дайте LLM документированный набор функций — search_albums, get_recommendations,
stream_url — и она с радостью переведёт «найди мне что-нибудь как Naxatras,
но тяжелее» в правильные вызовы, свяжет их в цепочку и озвучит результат обратно.
Структурированный API — это трудная часть; разговорный интерфейс поверх —
всё чаще нечто, что модель просто предоставляет, лишь бы инструменты, которые ей
вручили, были хорошо типизированы и честны в том, что они возвращают. Грязный HTML не даёт
LLM ничего, за что можно ухватиться. Типизированный клиент даёт ей поверхность управления.
Поэтому наши клиенты сайтов поставляют SKILL.md — описание на простом
языке того, что делает API, его глаголы, его типы возврата и примеры
вызовов, написанное, чтобы его читал агент. Наведите на него LLM-управляемого ассистента, и
клиент становится инструментом, который модель может использовать немедленно: без клеевого кода, без заказной
интеграции, просто «вот что этот сайт умеет, словами». Один документ превращает
скрейпер в нечто, чем языковая модель может оперировать от вашего имени.
Это одни и те же структурированные данные, обслуживающие три фронт-энда сразу: CLI для терминальных пользователей, OCP/голосовой плагин для использования без рук и инструмент LLM для управления на естественном языке. Постройте API один раз; носите его тремя способами.
Почему это важнее всего для тех, кто не видит экран
Для слепых и слабовидящих пользователей это не удобная фича — это разница между доступом и исключением. Программа чтения с экрана может читать только то, что страница раскрывает чисто, а большинство страниц этого не делают. Выделенное голосовое приложение пропускает страницу целиком: оно идёт к структурированным данным и произносит их, в потоке, спроектированном под слушание с первой строки кода.
Это тот же принцип, что и за нашими аудио-первыми играми — построенными для ушей, а не для глаз, со слепыми игроками как основной аудиторией, а не запоздалой мыслью. Голосовые приложения для сайтов распространяют этот принцип с игр на остальной веб.
По одному сайту за раз — но направление это голосовой браузер
Вот честная часть: универсального сокращения нет. Вы не можете голосово-включить «веб» одним махом, потому что каждый сайт — это свой собственный клубок. Это нужно делать посайтно — один клиент, один навык, один тщательно размеченный набор интентов за раз. Это звучит как ограничение, и в краткосрочной перспективе так и есть.
Но посмотрите, куда указывает накопление. Каждый сайт, который мы оборачиваем, — это ещё один угол веба, теперь достижимый голосом и через CLI. Соедините достаточно из них вместе — общий словарь метаданных, разделяемый голосовой слой, согласованный набор интентов «поиск / открыть / прочитать / воспроизвести / дальше» — и вы уже смотрите не на кучу отдельных навыков. Вы смотрите на зачатки голосового браузера: способа двигаться по вебу, разговаривая, где отдельные сайты — просто пункты назначения, которые уже знают, как ответить.
Ставка мобильной эры была в том, что сайт, стоящий использования, стоит приложения. Наша — в том, что сайт, стоящий использования, стоит голоса. Мы строим их по одному за раз, в открытую, и каждый из них делает веб чуть более просматриваемым для тех, кого визуальный веб оставил позади.
Хотите, чтобы конкретный сайт превратили в голосовое или CLI-приложение — ради доступности, ради вашего продукта или просто потому что оно должно существовать? Давайте поговорим.