> ## Content Index
> Fetch the complete content index at: https://nevsky.ae/llms.txt
> Use this file to discover other available public pages before exploring further.

# CallCoach — приложение, которое я построил, потому что сам не понимал что мне говорят
- URL: https://nevsky.ae/ai/callcoach-ios-app/
- Published: 2026-03-22T07:00:00.000Z
- Updated: 2026-05-21T11:56:06.000Z
- Description: Когда звонишь британцу или индийцу в холодном звонке и вообще не понимаешь что он говорит — это проблема. Я решил её сам: написал приложение на Swift с Apple Intelligence, которое в реальном времени распознаёт речь и подсказывает, что ответить
- Author: Александр Невский
- Tags: Нейросети и Вайбкодинг

> Есть такой момент в холодном звонке — трубка уже поднята, человек говорит, ты киваешь. Но внутри тишина. Ни слова не понял.

Особенно если на том конце британец с каким-то специфическим акцентом или индиец, который говорит очень быстро и очень уверенно. Оба варианта — моя реальность в первые недели работы брокером в Дубае.

Я дизайнер. Умею проектировать сложные системы. Понимаю продукт. Но телефонный разговор с незнакомым акцентом — это отдельный навык, и он не появляется от одного желания.

Можно было просто тренироваться и ждать. Я решил построить инструмент.

### Что такое CallCoach

Нативное iOS-приложение на Swift с Apple Intelligence и Live Translation.

Во время звонка оно в реальном времени распознаёт речь собеседника и показывает текст прямо на экране. Анализирует что он сказал. Предлагает подсказки — что ответить, как продолжить, какой вопрос задать.

![](https://storage.ghost.io/c/c3/b4/c3b47bf9-b397-4fd6-898c-a34ffdda20bc/content/images/2026/05/callcoach_xcode.webp)

Приложение CallCoach внутри XCode для запуска эмулятора и тестов

Это не транскрипция ради транскрипции. Это скрипт-ассистент, который всплывает именно тогда, когда нужен — в живом разговоре, без задержки.

### Почему Swift и Apple Intelligence

Мог взять любой веб-стек. Но веб не даёт нужной скорости и нативной интеграции с микрофоном и системными API.

Apple Intelligence — локальный языковой движок прямо на устройстве. Никаких запросов в облако, никакой задержки, никакой утечки данных разговора. Всё на телефоне.

Live Translation справляется с акцентированным английским с нужной точностью. Именно то, что нужно для мультинационального Дубая.

![](https://storage.ghost.io/c/c3/b4/c3b47bf9-b397-4fd6-898c-a34ffdda20bc/content/images/2026/05/callcoach_codex.webp)

Работа с приложением внутри Codex – 5-ти часовое окно токенов закончилось, теперь ждем следующего

### Как это изменило работу

Когда видишь текст того, что говорит собеседник — тревога уходит. Перестаёшь тратить энергию на «что он сказал» и начинаешь думать про «что ответить».

Из режима выживания — в режим диалога. Принципиальный сдвиг.

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

### Почему я это рассказываю

CallCoach — пример того, как я думаю о продуктах.

Не «какую технологию попробовать», а «какую проблему решить». Проблема была конкретная и личная. Решение — нативное, быстрое, без лишних зависимостей.

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

## Техническая реализация

> С технической точки зрения CallCoach я собирал как реальный рабочий инструмент, а не как концепт.

Сначала я проработал саму идею и архитектуру вместе с ChatGPT: сформулировал продуктовую задачу, пользовательский сценарий и подготовил большой стартовый промт для Codex, чтобы он создал базовый Swift-проект, поднял зависимости и собрал первый рабочий каркас приложения.

Когда окно токенов у Codex закончилось, я передал проект в Claude Code. Дальше основная «мясная» часть разработки шла уже там — с моделью Opus 4.7.

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

После этого я уже регулярно переходил в Xcode: собирал билд, запускал тесты, ловил падения, возвращал ошибки обратно в Claude Code и вместе с ним фиксировал проблемные места. Часть правок вносил уже прямо внутри Xcode, где тоже подключал Codex и Claude как помощников по месту.

### Как устроена логика приложения

> Само приложение построено вокруг локальной обработки речи на устройстве.

В обычном режиме CallCoach может слушать поток через микрофон и показывать живую транскрипцию. Но ключевым техническим решением стало разделение голосов.

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

Чтобы это решить, я сделал два режима работы.

### Режим 1 — System Audio

Это основной и рекомендуемый режим.

Через ScreenCaptureKit приложение захватывает системный аудиовыход, то есть только то, что уходит в динамики. Это позволяет транскрибировать именно голос собеседника, не захватывая мой собственный голос из микрофона.

Дополнительно используется флаг `excludesCurrentProcessAudio = true`, чтобы исключить звуки самого приложения.

При первом запуске macOS запрашивает разрешение на запись экрана — без этого системный захват аудио невозможен.

### Режим 2 — Microphone + Push-to-Mute

Это запасной сценарий.

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

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

### Что было написано в коде

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

#### `AudioCaptureManager`

Отвечает за захват звука через `AVAudioEngine`.

- использует `installTap` на `inputNode`
- `startRecording()` возвращает `AsyncStream<AVAudioPCMBuffer>`
- поток буферов передаётся дальше без проблем с `actor crossing`
- параллельно считается уровень сигнала через RMS и dB metering
- обновления UI отправляются на `@MainActor` через `Task`

#### `SystemAudioCaptureManager`

Это отдельный класс, который я добавил для захвата системного аудио через `SCStream`.

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

#### `TranscriptionManager`

Этот слой принимает поток аудиобуферов и передаёт его в `SpeechAnalyzer` из Speech framework.

Дальше он итерирует `AsyncThrowingStream<SpeechTranscriptionResult>`, разделяет partial и final transcription и явно управляет переходами на `@MainActor`.

То есть это уже не просто «распознать звук», а аккуратно встроить потоковую транскрипцию в живой интерфейс.

#### `CoachingEngine`

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

- `processNewTranscript(_:)` использует debounce на 1.5 секунды
- предыдущий `Task` отменяется, если приходит новый кусок речи
- `LanguageModelSession` создаётся один раз на сессию и потом переиспользуется
- история контекста сохраняется
- парсер разбирает ответы в формате `[ТИП]: текст` с fallback на `.phrase`
- определяется этап разговора по ключевым словам
- в модель отправляются последние примерно 300 слов, а не весь транскрипт целиком

Отдельно я подмешивал контекст под рынок Дубая: `Emaar`, `DAMAC`, `Binghatti`, `ROI`, бронь, встреча, Zoom и другие характерные для разговора сигналы.

#### `ContentView`

Здесь всё связывается в пользовательский интерфейс.

- `.task` запрашивает разрешение на микрофон при запуске
- `.onChange(segments.count)` триггерит `coach.processNewTranscript`
- `toggleSession()` передаёт поток и формат в `startTranscription`
- ошибки менеджеров выводятся через отдельные `.onChange`

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

### Как я обучал подсказки

Отдельно я подкармливал систему прикладным контекстом.

Для сценария холодных звонков использовал реальные sales scripts: приветствие, удержание разговора, базовая квалификация клиента, прояснение бюджета, работа с сомнениями и закрытие либо на встречу, либо на подробный Zoom.

Причём это были не абстрактные шаблоны из интернета, а логика, которой нас учили в агентстве SPI Dubai.

За счёт этого подсказки стали более прикладными. Не просто «ответь что-нибудь вежливое», а именно продолжение разговора в нужной структуре и на нужном этапе.

### Второй сценарий — собеседования на продуктового дизайнера

Параллельно я сделал второе направление использования этого же подхода: прохождение собеседований на продуктового дизайнера.

Там я уже обучал систему на своих проектах, кейсах и портфолио, чтобы она помогала не в cold calling, а в другом типе разговора — когда тебе важно быстро, уверенно и структурно отвечать на вопросы о собственном опыте.

То есть по сути CallCoach стал не просто speech-to-text приложением, а универсальным conversational assistant, который можно адаптировать под конкретный сценарий общения.

### Как выглядел реальный процесс разработки

И если совсем честно, для меня это ещё и важный пример того, как сегодня выглядит реальная продуктовая разработка.

Идея рождается из собственной боли.

Архитектура быстро собирается с помощью языковых моделей.

Тяжёлый код пишется в связке с агентами.

Финальная доводка происходит уже руками в Xcode — через сборки, падения, отладку и повторные итерации.

Не «магия нейросети», а нормальный инженерный процесс, просто ускоренный новыми инструментами.

---

## Changelog / как собирался CallCoach

### 1\. Формулировка идеи

- Зафиксировал конкретную проблему: в холодных звонках с британскими и индийскими акцентами часть речи просто не успевает распознаваться на слух.
- Определил задачу продукта: не просто транскрибировать разговор, а помогать вести его дальше.
- Вместе с ChatGPT проработал концепцию, user flow и структуру будущего приложения.
- Сгенерировал большой стартовый промт для Codex, чтобы быстро поднять каркас проекта на Swift.

### 2\. Первичная сборка проекта

- Codex создал базовый Swift-проект.
- Были подняты основные зависимости.
- Подготовлена базовая архитектура.
- Собран первый runnable prototype.

### 3\. Основная инженерная реализация

- После исчерпания окна токенов Codex проект был передан в Claude Code.
- Основная разработка продолжилась с использованием Opus 4.7.
- Через Claude Code была собрана «мясная» часть приложения: захват аудио, транскрипция, коучинговая логика, связка с интерфейсом.

### 4\. Решение главной продуктовой проблемы — разделение голосов

- Выявлена ключевая проблема: микрофон слышит и пользователя, и собеседника.
- Реализованы два режима:
  - **System Audio** — захват только системного аудиовыхода через `ScreenCaptureKit`
  - **Microphone + Push-to-Mute** — fallback-режим с ручным отключением передачи буферов в транскрибер
- Добавлен `excludesCurrentProcessAudio = true`, чтобы исключить звуки самого приложения.

### 5\. Реализованные компоненты

- `**SystemAudioCaptureManager.swift**` — новый класс для захвата системного аудио через `SCStream`
- `**AudioCaptureManager.swift**` — захват звука через `AVAudioEngine`, добавлен `isMuted`
- `**TranscriptionManager**` — потоковая транскрипция через `SpeechAnalyzer`
- **`CoachingEngine`** — debounce, переиспользование сессии модели, разбор фраз, логика этапов звонка
- **`ContentView.swift`** — управление сессией, выбор источника аудио, ошибки, кнопки и интерфейс
- **`Info.plist`** — разрешения для системного захвата
- `**project.pbxproj**` — подключение `ScreenCaptureKit.framework`

### 6\. Отладка и тесты

- Сборка и запуск шли через Xcode.
- При каждом падении приложения ошибка возвращалась в Claude Code.
- Исправления вносились итеративно: Xcode → crash/error → Claude Code → фикс → новая сборка.
- Часть быстрых правок делалась уже прямо внутри Xcode с подключёнными Codex и Claude.

### 7\. Обучение под реальные сценарии

- Для cold calling в систему были добавлены реальные sales scripts:
  - приветствие
  - обычный small talk
  - квалификация клиента
  - выявление интереса
  - закрытие на встречу или Zoom
- Скрипты опирались на реальную практику и обучение в SPI Dubai.
- Параллельно создан второй сценарий использования: помощь при собеседованиях на роль продуктового дизайнера.
- Для этого модель обучалась на моих проектах, кейсах и портфолио.

### 8\. Что получилось в итоге

- локальная транскрипция без отправки данных в облако
- realtime-подсказки по ходу разговора
- отдельная логика для продаж и интервью
- нативный стек без веб-костылей
- рабочий продукт, собранный в связке ChatGPT + Codex + Claude Code + Xcode