Не пиши промпт. Пройди интервью.

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

Но у этого конвейера оставалась проблема на самом входе. Жена фотографировала документы обычной камерой телефона и присылала мне через Telegram. Перспектива, тени, блики, размытый текст, а вдобавок сжатие при пересылке — всё это попадало на вход системы, качество которой мы до этого долго улучшали.

Я купил штатив-пантограф и придумал, как мне казалось, небольшую доработку: поставить над столом Android-телефон, показывать изображение с него в браузере PaperLedger и добавить кнопку «Снять». Никаких действий на телефоне. Положил лист, посмотрел превью на компьютере, сделал снимок — фотография появилась среди страниц документа.

Стек вроде бы очевиден: Kotlin, CameraX и способ передать JPEG. Казалось, работы на одно небольшое приложение.

Вместо технического задания я попросил Codex провести со мной интервью: выяснить стек, архитектуру и границы решений. Сам разговор занял примерно час. А потом агент создал Android-приложение, перешёл в существующий Python-портал и связал их между собой.

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

Сначала я попросил об интервью

Первый ответ агента был списком из десяти вопросов. Я сразу его остановил: «по одному вопросу. 10 вопросов это не интервью».

Дальше мы действительно шли по одному вопросу. Я отвечал коротко, иногда менял предложенный сценарий, иногда не соглашался с границами задачи. Были и вопросы, о которых я сам не подумал бы, например о нескольких одновременно открытых вкладках. Были и ошибки агента — в частности, он долго расспрашивал меня об интеграции с PaperLedger, ещё не заглянув в его код.

Не все пункты из разговора попали в первую реализацию. Это тоже важно: интервью зафиксировало целевой сценарий и границы, а не список функций, автоматически признанных готовыми.

Полная стенограмма интервью

Ниже — исходный диалог от первой постановки задачи до момента, когда агент предложил приступить к прототипу. Все 72 реплики автора и 71 финальный ответ агента приведены без сокращений. Время указано в UTC; опечатки сохранены. Внешний адрес сервиса заменён на <PAPER_LEDGER_URL>. Рассуждения агента и команды инструментов в стенограмму изначально не входили. Ссылки на локальные файлы внутри реплик сохранены как часть исходного разговора.

Интервью

Автор · 18:59:56 · L56

начинаем новый проект mobile-ledger - это камера на android телефоне для фотографирования документов и отправки их в paper-ledger. сделай мне интервью по проекту. задай вопросы чтобы определить текхстек, архитекруры и границы решений

Агент · 19:00:18 · L59

Давай начнём с основного сценария и ограничений: они определят стек и архитектуру. Дальше уточним обработку изображений, интеграцию с paper-ledger и устройство приложения. Можно отвечать коротко по номерам; если решение ещё не принято — так и напиши.

  1. Кто будет пользоваться приложением: только ты, небольшая команда или внешние пользователи? Как планируешь распространять его: APK вручную, корпоративная установка, Google Play?

  2. Как выглядит основной сценарий? Например: открыть камеру → снять несколько страниц → проверить и переснять → выбрать организацию или тип документа → отправить. Что из этого нужно, а что лишнее?

  3. Что считаем одним документом: один снимок, набор страниц или целую пачку, которую paper-ledger потом самостоятельно разделяет?

  4. Что уже умеет paper-ledger для приёма документов? Есть ли API, авторизация, загрузка файлов и отслеживание обработки? Можно ответить «изучи сам» — посмотрю проект.

  5. Должна ли съёмка работать без интернета с последующей отправкой? Нужно ли сохранять очередь после закрытия приложения и перезагрузки телефона?

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

  7. На каких телефонах приложение должно работать: твоя конкретная модель или широкий набор Android-устройств? Нужна ли в обозримом будущем версия для iPhone?

  8. Есть ли предпочтения или ограничения по технологиям: Kotlin и нативный Android, Flutter, React Native? Кто будет поддерживать код и насколько важна для тебя возможность переиспользовать технологии paper-ledger?

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

  10. Какой результат первой версии будет достаточным, чтобы начать ей пользоваться? Назови обязательные возможности и то, что точно не входит в этот этап.

Автор · 19:00:42 · L66

по одному вопросу. 10 вопросов это не интервью

Агент · 19:00:47 · L69

Кто будет пользоваться mobile-ledger: только ты или ещё другие люди?

Автор · 19:03:39 · L76

paper-ledger это проект для моей жены, там есть вункции обработки бумажных документов. жена фоткает и присылает. когда жена фотографирует на фотографиях очень много искажений. так как она фоткает обычным пиложением. mobile-ledger - это дополнение к paper-ledger для вотографирования и автоматической загрузки фотографий. считай что это Документ-камера для проекта paper-ledger которым пользуется только моя жена.

Агент · 19:03:42 · L79

Понял: mobile-ledger — документ-камера для жены, которая помогает получить ровные, читаемые снимки и автоматически передаёт их в paper-ledger.

Что чаще портит нынешние фотографии: перспектива и обрезанные края, размытый текст, тени и блики — или что-то другое?

Автор · 19:04:25 · L86

все что перечислил плюс пересылка их через телеграм - он сильно сжимает фотографии

Агент · 19:04:29 · L89

Значит, нужно улучшать качество съёмки и передавать оригиналы напрямую в paper-ledger, без сжатия Telegram.

Допустимо ли подсказывать жене при съёмке «держи ровнее», «слишком темно», «замри» и автоматически делать снимок, когда лист хорошо виден, или она должна сама нажимать кнопку?

Автор · 19:07:32 · L96

да подсказки - это прямо огонь, рисование сетки, пед обработка… распознавание таблиц и выравнивание по ним, все что получится вытащить из процессора телефона все должно быть сделано. Но на первом этапе - можно и без подсказок. Я купил штатиф-пантограф так что камера будет расположена ровно, но следить и помогать жене надо

Агент · 19:07:35 · L99

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

На каком телефоне жена будет пользоваться приложением — какая модель? Это поможет определить, какую обработку можно выполнять прямо во время съёмки.

Автор · 19:12:41 · L106

xiaomi redmi 12

Агент · 19:12:44 · L109

Ориентируемся на Xiaomi Redmi 12; скорость обработки проверим на нём.

Жена обычно снимает отдельные листы или многостраничные документы, страницы которых нужно объединять перед отправкой?

Автор · 19:13:34 · L116

один раз документ был из 8 страниц, а документов за день 50-60-70..

Агент · 19:13:37 · L119

При 50–70 документах в день важен быстрый переход к следующему документу, а внутри одного может быть несколько страниц.

Как жена должна обозначать конец документа: нажимать «Готово» после его последней страницы, чтобы приложение отправило документ и сразу перешло к съёмке следующего?

Автор · 19:15:12 · L126

я думаю управление снимками должно быть в проекте paper-ledger из которого команды должны отправляться в mobile-ledger. то есть на телефоне вообще ничего не надо нажимать в идеале. поставили его на штатиф и используем как Документ-камеру

Агент · 19:15:16 · L129

Тогда телефон — стационарная документ-камера, а съёмкой и объединением страниц управляет paper-ledger.

Жена будет работать в paper-ledger на компьютере рядом со штативом, чтобы видеть изображение с камеры и давать команду на снимок?

Автор · 19:16:31 · L136

да на компьютере. в проекте paper-ledger смотрит камеру с телефона и из проекта paper-ledger дает команду на семку. кладет новый документ и так по кругу

Агент · 19:16:35 · L139

Понял: в paper-ledger на компьютере виден поток с камеры; жена кладёт лист, нажимает «Снять» и меняет лист. Телефон делает качественный снимок и автоматически загружает его.

Компьютер и телефон всегда будут в одной локальной сети Wi-Fi, или подключение должно работать и через интернет из разных сетей?

Автор · 19:17:23 · L146

начнем с оной сети

Агент · 19:17:25 · L149

Для первой версии телефон и компьютер работают в одной локальной сети.

Где запущен сам paper-ledger: на этом же компьютере, на другом устройстве дома или на удалённом сервере?

Автор · 19:18:00 · L156

paper-ledger запущен у меня на домашнем сервере, а жена пользуется им на работе

Агент · 19:18:04 · L159

Значит, телефон и компьютер находятся в одной сети на работе, а сервер paper-ledger — дома.

Сеть на работе позволяет устройствам обращаться друг к другу, или это пока неизвестно? От этого зависит, сможем ли передавать видео напрямую между телефоном и браузером.

Автор · 19:19:50 · L166

пока не известно. если понадобится можно будет сделать промежуточный сервачек который будет крутиться на компьютере жены и объединять paper-ledger и mobile-ledger

Агент · 19:19:53 · L169

Учтём локальную программу на компьютере как допустимый вариант.

Для первой версии приемлемо, чтобы жена один раз открыла mobile-ledger на телефоне и оставила его с включённым экраном на зарядке на время работы?

Автор · 19:20:38 · L176

нет давай сразу делать фоновую работу

Агент · 19:20:42 · L179

Фиксируем работу с выключенным экраном. На Android для камеры в таком режиме понадобится foreground service — служба с постоянным уведомлением; поведение на Xiaomi проверим отдельно.

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

Автор · 19:21:10 · L186

да допустимо один раз открыть

Агент · 19:21:18 · L189

Тогда после перезагрузки жена один раз запускает камеру, дальше управляет ею из paper-ledger.

Есть ли у тебя предпочтения по стеку мобильного приложения, или мне выбрать его под Android и обработку камеры?

Автор · 19:22:48 · L196

kotlin, compouse, в идеале делать кросплатформу KMP (вдруг проект выстрелит чтобы iOS тоже работал), CameraX

Агент · 19:22:57 · L199

Фиксируем Kotlin, Compose и CameraX для Android, с KMP для общей логики и возможной iOS-версии.

Допустимо подключать готовые библиотеки обработки документов, включая нативные, или есть ограничения по лицензиям, платным SDK и зависимости от сервисов Google?

Автор · 19:24:29 · L206

слишком общий вопрос. давай каждую библиотеку решать индивидуально

Агент · 19:24:33 · L209

Библиотеки будем выбирать по отдельности, под конкретные задачи.

Нужно ли сохранять снимки на телефоне до подтверждения, что paper-ledger их принял, и автоматически повторять загрузку после обрыва связи?

Автор · 19:25:19 · L216

да

Агент · 19:25:28 · L219

Снимки сохраняем до подтверждения приёма, при сбоях повторяем загрузку.

После успешной передачи удаляем оригинал с телефона сразу или оставляем на несколько дней как страховку?

Автор · 19:25:40 · L226

удаляем

Агент · 19:25:48 · L229

После подтверждённого приёма удаляем снимок с телефона.

Что жена должна видеть в paper-ledger после съёмки: сразу обработанный снимок для проверки или достаточно миниатюры, пока камера уже готова снимать следующий лист?

Автор · 19:26:58 · L236

зависит от флоу paper-ledger, это не зона ответственности mobile-ledger. mobile-ledger - это камера. как ей будут пользоваться зависит от paper-ledger

Агент · 19:27:00 · L239

Да, граница понятна: mobile-ledger предоставляет камеру, обработку снимка и надёжную передачу; пользовательский сценарий определяет paper-ledger.

Передавать в paper-ledger нужно только обработанный снимок или вместе с исходным — чтобы сервер мог повторить обработку?

Автор · 19:29:06 · L246

снимок передается всегда 1. если paper-ledger включил какую то обработку на mobile-ledger значит получает обработанный, если не включил значит оригинал

Агент · 19:29:10 · L249

На команду съёмки передаём один снимок; обработку включает и настраивает paper-ledger.

Если mobile-ledger обнаружит смаз, блик или обрезанный лист, он должен всё равно выполнить команду съёмки и сообщить о проблеме или может отклонить команду и потребовать переснять?

Автор · 19:30:51 · L256

ему пиходит команда, он запускает автофокус если его небыло давно. после автофокуса делается снимок как есть

Агент · 19:30:55 · L259

Принято: по команде камера при необходимости обновляет автофокус и снимает как есть. Проверка качества не блокирует съёмку.

Какая обработка снимка обязательна для первой версии: достаточно оригинала или сразу нужны обрезка по границам листа и исправление перспективы?

Автор · 19:31:28 · L266

для первой версии достаточно оригинала

Агент · 19:31:31 · L269

Первая версия передаёт оригинал, обработку добавим позже.

Как хочешь связывать телефон с paper-ledger: отсканировать телефоном QR-код из paper-ledger один раз, после чего он будет подключаться автоматически?

Автор · 19:32:14 · L276

да

Агент · 19:32:17 · L279

Привязку делаем через QR-код, затем телефон подключается автоматически.

При съёмке важнее максимальная детализация текста, даже если фото загружается несколько секунд, или быстрый цикл с меньшим размером снимка?

Автор · 19:33:46 · L286

исходить надо из DPI для текстовых документов говорят 300 DPI. то есть нужно минимальное качество с некоторым запасом

Агент · 19:33:49 · L289

Берём 300 DPI с небольшим запасом как ориентир для разрешения. Для A4 это примерно 8,7 Мп на сам лист; поля вокруг него потребуют дополнительного разрешения.

Какие форматы бумаги жена снимает чаще всего: A4, A5, чеки или другие?

Автор · 19:34:05 · L296

А4

Агент · 19:34:09 · L299

Тогда разрешение подбираем под A4 с запасом на поля вокруг листа.

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

Автор · 19:34:24 · L306

да только основная

Агент · 19:34:28 · L309

Используем только основную заднюю камеру.

На компьютере жены Windows, Linux или macOS? Это нужно учесть для возможной локальной программы-посредника.

Автор · 19:34:40 · L316

windows

Агент · 19:34:44 · L319

Учтём Windows для возможного посредника.

Для первой версии достаточно, чтобы видео позволяло удобно разместить лист и проверить, что он целиком в кадре, или на превью нужно уверенно читать мелкий текст?

Автор · 19:35:09 · L326

чтобы видео позволяло удобно разместить лист

Агент · 19:35:14 · L329

Тогда превью делаем для размещения листа, а полное разрешение используем при съёмке.

Если связь с сервером пропала, mobile-ledger должен продолжать показывать видео и принимать команды от компьютера в локальной сети?

Автор · 19:36:00 · L336

не понял как этот вопрос относится к mobile-ledger это не его зона ответственности

Агент · 19:36:04 · L339

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

Настройки камеры — разрешение, вспышку, фокус — тоже должен задавать paper-ledger, или часть настроек нужна в самом mobile-ledger?

Автор · 19:36:23 · L346

да должен задавать paper-ledger

Агент · 19:36:26 · L349

Тогда настройки камеры тоже задаёт paper-ledger.

Если придёт новая команда съёмки, пока предыдущий снимок ещё загружается, mobile-ledger должен сделать следующий снимок и поставить его в очередь отправки?

Автор · 19:37:08 · L356

нет такого не надо делать на paper-ledger будет в UI ограничение на такие действия

Агент · 19:37:12 · L359

Понял, paper-ledger обеспечивает последовательную съёмку.

Теперь изучу существующий paper-ledger, чтобы следующие вопросы опирались на его реальный стек и API?

Автор · 19:37:38 · L366

да изучи. странно что ты не начал с этого

Агент · 19:38:06 · L397

Изучил код. Ты прав: это стоило сделать перед интервью.

В paper-ledger сейчас:

  • Python, FastAPI, Jinja2 и обычный JavaScript.
  • Загрузка одной или нескольких страниц запускает обработку документа сразу: POST /api/documents/process.
  • Уже есть серверное выравнивание по сетке таблицы и распознавание.
  • Нет подключения устройств, команд камеры, видеопотока и QR-привязки.
  • Авторизация — опциональный HTTP Basic. Отдельной авторизации камеры пока нет.

Поэтому для mobile-ledger нужен отдельный интерфейс подключения камеры: команды, настройки, превью и надёжный приём снимков. Приём снимка должен подтверждаться независимо от успешности OCR — иначе телефон будет хранить и повторно отправлять уже доставленные фотографии при ошибке распознавания.

Каталог mobile-ledger пока пуст. В paper-ledger есть неотслеживаемая папка docs/ с фотографиями; ничего не менял.

Следующий вопрос: допустимо передавать видеопревью через домашний сервер, если прямое соединение телефона с браузером на работе не получится?

Автор · 19:39:26 · L404

да допустимо, но скорость будет маленькая. но да это надо прредусмотреть

Агент · 19:39:31 · L407

Предусмотрим прямое соединение для превью и передачу через домашний сервер как запасной путь.

Полноразмерный снимок mobile-ledger должен всегда загружать непосредственно на сервер paper-ledger, независимо от того, каким путём идёт превью?

Автор · 19:40:57 · L414

я не знаю как это сделано сейчас в paper-ledger7 там есть файловый пикер. вот тут тоже самое это обычный пикер только с камеры. есть 2 входа - файл и камера. дальше код одинаковый должен быть в paper-ledger

Агент · 19:41:02 · L417

Да, в текущем paper-ledger файловый пикер собирает страницы в браузере, затем форма отправляет их на обработку. Камера должна стать вторым источником для того же списка страниц; дальше используется общий код.

Тут нужно согласовать прежнее требование: снимок удаляется с телефона после подтверждения, что его получил браузер, или только после сохранения на сервере paper-ledger?

Автор · 19:41:40 · L424

получил браузер

Агент · 19:41:44 · L427

Фиксируем: браузер подтверждает получение снимка, после этого mobile-ledger удаляет локальную копию. Дальнейшая работа со снимком — ответственность paper-ledger.

При повторном открытии paper-ledger камера должна подключаться автоматически к ранее привязанному телефону?

Автор · 19:42:08 · L434

да

Агент · 19:42:11 · L437

Камера будет подключаться автоматически к привязанному телефону.

Если paper-ledger закрыт, телефон должен продолжать держать камеру активной или освобождать её до следующего подключения браузера?

Автор · 19:42:48 · L444

лучше конечно не держать

Агент · 19:42:51 · L447

Тогда служба остаётся на связи, а камеру включает при подключении paper-ledger и освобождает после отключения.

Нужно ли в первой версии поддерживать несколько одновременно открытых вкладок paper-ledger, или камерой управляет только одна вкладка за раз?

Автор · 19:43:39 · L454

я никогда не думал о таком. да надо поддержать несколько одновременно открытых вкладок paper-ledger

Агент · 19:43:42 · L457

Тогда при нескольких вкладках нужно определить, кому достанется снимок.

Подойдёт такой вариант: превью доступно всем вкладкам, команды съёмки выполняются по одной, а снимок получает только та вкладка, которая его запросила?

Автор · 19:44:04 · L464

да команды съёмки выполняются по одной, а снимок получает только та вкладка, которая его запросила

Агент · 19:44:08 · L467

Фиксируем: команды выполняются последовательно, снимок получает запросившая вкладка.

Если эта вкладка закрылась до получения снимка, подойдёт хранить его на телефоне и передать после повторного открытия paper-ledger в раздел восстановления снимков?

Автор · 19:44:46 · L474

закрылась значит забываем про запрос на снимок

Агент · 19:44:48 · L477

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

Если связь временно оборвалась, но вкладка осталась открытой, сохраняем запрос и снимок до восстановления соединения?

Автор · 19:45:15 · L484

да

Агент · 19:45:19 · L487

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

Если другая вкладка прислала команду, пока камера занята, отклоняем её с ответом «камера занята», чтобы paper-ledger предложил повторить?

Автор · 19:45:34 · L494

да

Агент · 19:45:38 · L497

Фиксируем: при занятой камере новая команда получает ответ «камера занята».

Для KMP предлагаю вынести в общий код протокол команд, состояния подключения и логику доставки снимков, а CameraX и фоновую службу оставить в Android-части. iOS-реализацию камеры добавим, когда она понадобится. Такой объём KMP подходит?

Автор · 19:46:32 · L504

я думал CameraX кросплатформенная, но если не так то да подходит

Агент · 19:46:42 · L516

Да, CameraX работает только на Android — это библиотека Android Jetpack. Документация.

Фиксируем KMP для общей логики, CameraX — для Android-реализации камеры.

Для первой версии приложение устанавливаем вручную через APK?

Автор · 19:46:54 · L523

да

Агент · 19:46:59 · L526

Первую версию распространяем через APK.

Настройки камеры при нескольких вкладках предлагаю применять вместе с командой съёмки: каждая вкладка передаёт свои параметры, mobile-ledger применяет их и делает снимок. Подходит?

Автор · 19:47:13 · L533

да

Агент · 19:47:17 · L536

Параметры снимка передаём в каждой команде съёмки.

Для превью предлагаю один общий поток с телефона для всех вкладок. Подходит?

Автор · 19:47:22 · L543

да

Агент · 19:47:32 · L546

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

Какую версию Android сейчас использует Redmi 12? Это нужно для проектирования фоновой работы камеры.

Автор · 19:48:39 · L553

15

Агент · 19:48:44 · L556

Android 15 зафиксировал.

Что включаем в первую версию из удалённых настроек камеры: достаточно разрешения снимка и включения подсветки, а экспозицию и баланс белого пока оставим автоматическими?

Автор · 19:49:01 · L563

да

Агент · 19:49:04 · L566

Для первой версии: разрешение и подсветка задаются из paper-ledger, экспозиция и баланс белого — автоматические.

Если автофокус не смог навестись за отведённое время, всё равно делаем снимок и возвращаем вместе с ним статус фокусировки?

Автор · 19:49:13 · L573

да

Агент · 19:49:16 · L576

При неудаче автофокуса всё равно снимаем и передаём статус фокусировки.

Разрешение paper-ledger должен задавать из списка режимов, которые mobile-ledger сообщает как доступные на телефоне. Подходит?

Автор · 19:49:24 · L583

да

Агент · 19:49:27 · L586

Mobile-ledger будет сообщать доступные разрешения, а paper-ledger — выбирать из них.

Если связь оборвалась и восстановилась, согласен повторную команду с тем же идентификатором считать тем же запросом: вернуть уже сделанный снимок, а не фотографировать повторно?

Автор · 19:49:45 · L593

да

Агент · 19:49:49 · L596

Фиксируем защиту от повторной съёмки по идентификатору команды.

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

Привязка телефона должна быть только к одному серверу paper-ledger одновременно?

Автор · 19:50:13 · L603

да

Агент · 19:50:16 · L606

Один телефон привязан к одному серверу paper-ledger.

Для первой версии ограничиваемся одним телефоном на сервер или сразу предусматриваем выбор из нескольких камер?

Автор · 19:50:42 · L613

несколько

Агент · 19:50:49 · L616

Предусматриваем несколько телефонов: paper-ledger выбирает камеру, каждая камера отдельно выполняет команды.

При привязке дать каждому телефону понятное имя, например «Камера на штативе», чтобы различать их в paper-ledger?

Автор · 19:51:05 · L623

да

Агент · 19:51:15 · L626

У каждой камеры будет понятное имя.

Если камера временно недоступна, команда должна сразу возвращать ошибку, чтобы paper-ledger показал её пользователю?

Автор · 19:51:26 · L633

да

Агент · 19:51:37 · L638

Недоступная камера сразу возвращает ошибку.

Какое время от нажатия «Снять» до появления фотографии в браузере считаешь приемлемым при нормальной связи — например, 2–3 секунды или до 5 секунд?

Автор · 19:51:49 · L645

2-3

Агент · 19:51:59 · L648

Берём 2–3 секунды как целевое время при нормальной связи; проверим на Redmi 12.

Как долго хранить непереданный снимок при обрыве связи: до восстановления соединения без ограничения по времени или с заданным сроком?

Автор · 19:52:22 · L655

до новой команды

Агент · 19:52:26 · L660

Храним непереданный снимок до новой команды съёмки.

Новая команда от любой вкладки для этой камеры отменяет предыдущий запрос и удаляет его снимок — верно?

Автор · 19:52:41 · L667

да

Агент · 19:52:46 · L670

Тогда камера занята до завершения съёмки, а непереданный снимок хранится до подтверждения браузера либо до следующей команды, которая его заменяет.

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

Автор · 19:53:11 · L677

нет

Агент · 19:53:14 · L680

После перезапуска незавершённый запрос не восстанавливаем, оставшийся снимок удаляем.

Для первой версии достаточно JPEG, без RAW и PNG?

Автор · 19:53:29 · L687

да

Агент · 19:53:33 · L690

Формат снимка — JPEG.

Как управляем подсветкой: включаем постоянно для размещения листа и съёмки или используем вспышку только в момент снимка?

Автор · 19:54:03 · L697

настраивается в paper-ledger

Агент · 19:54:10 · L700

Режим подсветки задаёт paper-ledger.

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

Автор · 19:54:23 · L707

да

Агент · 19:54:28 · L710

Для постоянной подсветки действует последняя настройка, её состояние получают все вкладки.

Осталось уточнить запуск на Android 15: допустимо, если после освобождения камеры системой для её повторного включения придётся открыть mobile-ledger на телефоне? Возможность незаметно включать камеру из фона нужно отдельно проверить на устройстве.

Автор · 19:54:57 · L717

допустимо

Агент · 19:55:01 · L720

Это допустимый сценарий восстановления: paper-ledger сообщает, что нужно открыть mobile-ledger на телефоне.

Для первой версии достаточно установки обновлений новым APK вручную, без встроенного обновления приложения?

Автор · 19:55:13 · L727

да

Агент · 19:55:19 · L732

Обновления — вручную через APK. Основные границы первой версии уже определены; осталось уточнить подключение.

По какому адресу жена открывает paper-ledger на работе: это HTTPS-адрес с действующим сертификатом или доступ организован иначе? Пароли и токены не нужны.

Автор · 19:56:46 · L739

ты же смотрел проект

Агент · 19:56:54 · L742

В коде я посмотрел приложение, но внешний адрес не установил. Фиксирую: <PAPER_LEDGER_URL>.

Можно ли для подключения камеры настроить HTTPS на этом адресе?

Автор · 19:57:06 · L749

нет

Агент · 19:57:10 · L752

Фиксируем: текущий адрес остаётся на HTTP.

Допустим ли отдельный защищённый адрес для связи с камерами, если сам paper-ledger продолжит работать по прежнему HTTP-адресу?

Автор · 19:57:39 · L759

по прежднему

Агент · 19:57:43 · L762

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

Основные требования для первой версии собраны. Следующий шаг — оформить их в спецификацию mobile-ledger и проверить варианты связи с учётом HTTP, Android 15 и работы камеры в фоне.

Автор · 19:58:02 · L769

продолжай

Автор · 19:59:37 · L805

заложи как вариант сделать камеру телефона веб камерой системы

Спецификация и варианты транспорта

Агент · 20:00:03 · L818

Добавил в спецификацию вариант «телефон как системная веб-камера Windows», включая гибрид: веб-камера для превью, отдельный канал для оригинальных фотографий и команд.

Перед выбором проверим качество снимков, работу нескольких вкладок и ограничения текущего HTTP-адреса.

Автор · 20:01:02 · L825

еще можно на телефоне поднимать сервер и paper-ledger будет коннектиться на сервер телефона

Агент · 20:01:30 · L835

Добавил в спецификацию вариант со встроенным HTTP/WebSocket-сервером телефона.

Браузер paper-ledger сможет подключаться к нему напрямую в рабочей сети — если сеть и браузер разрешают. Подключение с домашнего сервера потребует отдельного маршрута до телефона.

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

Автор · 20:02:10 · L842

что дальше?

Агент · 20:02:19 · L845

Дальше — проверить варианты связи небольшим прототипом, прежде чем писать всё приложение.

Предлагаю начать со встроенного сервера телефона: CameraX показывает превью, браузер paper-ledger подключается, отправляет «Снять» и получает оригинальный JPEG. Проверяем на Redmi 12:

  • работу с выключенным экраном;
  • подключение с текущей HTTP-страницы;
  • время получения фотографии — целевые 2–3 секунды.

Если прямое подключение не проходит, проверяем серверную ретрансляцию. По результатам выбираем транспорт и реализуем привязку, несколько камер и вкладок.

Какой браузер жена использует на Windows?

Автор · 20:03:00 · L853

я не знаю. завтра спрошу

Агент · 20:03:06 · L856

Браузер проверим завтра. До этого можно сделать Android-прототип: CameraX, фоновая служба, встроенный сервер, превью и снимок по команде. Его проверим с доступного компьютера, а затем — на рабочем месте жены.

Первый результат — APK для Redmi 12 и тестовая страница управления камерой. Это позволит проверить выключенный экран, качество A4 и задержку съёмки.

Что получилось из разговора

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

Например, сначала агент предположил, что жена будет нажимать «Готово» на телефоне. Но я хотел обратного: телефон постоянно стоит на штативе и служит камерой. Весь пользовательский сценарий находится в PaperLedger. Это определило главное разделение ответственности:

  • mobile-ledger управляет камерой, делает снимок и предоставляет его по запросу;
  • PaperLedger показывает превью, управляет съёмкой, собирает страницы и запускает обработку документа.

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

Следующим неожиданным поворотом оказались несколько вкладок. Когда агент спросил об этом сценарии, я ответил, что вообще о нём не думал. Но если вкладки могут одновременно видеть превью и отдавать команды, приходится определить уже не просто API capture, а поведение целой небольшой системы.

Вопрос из интервью Что он меняет в реализации
На телефоне ничего не нажимают Камера управляется из браузера; Android-приложению нужна служба, обслуживающая команды.
Экран выключен Нужно проверять работу CameraX в фоне именно на целевом Redmi, а не только на эмуляторе.
Несколько вкладок смотрят одну камеру Превью может быть общим, но запрос съёмки принадлежит конкретной вкладке.
Команда повторилась из-за обрыва связи Один requestId должен означать один снимок, а не новую фотографию.
Сервер получил файл, но браузер — ещё нет Подтверждение сервера не должно считаться подтверждением браузера.
Вкладка закрылась или связь временно пропала Это разные состояния с разным поведением для незавершённого запроса.
Надо снимать A4 примерно с запасом к 300 DPI При выборе разрешения нужно смотреть реальные режимы камеры и проверять результат на устройстве.

Мне кажется, в этом и состоит польза такого формата. Я не садился заранее писать документ с разделами «идемпотентность», «конкурентный доступ», «подтверждение доставки» и «жизненный цикл камеры». Они появились из вопросов о конкретном рабочем сценарии.

При этом нельзя сказать, что агент сам «придумал все требования». Я определял, чего хочу от продукта, где заканчивается ответственность мобильного приложения, какие компромиссы допустимы. Агент помогал находить развилки и превращал ответы в формальные правила.

Агент не начал с изучения существующего проекта

В какой-то момент меня удивило, что он спрашивает, как PaperLedger устроен, хотя у него есть доступ к исходникам. Я прямо написал: «да изучи. странно что ты не начал с этого».

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

Из этого же выросло важное правило доставки. Если сервер получил фотографию, но OCR завершился ошибкой, заставлять телефон хранить снимок и отправлять его заново бессмысленно. А раз список страниц формируется в браузере, то подтверждение приёма от браузера и подтверждение от сервера — разные вещи.

На этот раз замечание «сначала изучи проект» дало не косметическую правку процесса, а конкретное архитектурное следствие.

После интервью я дал команду «приступай»

Примерно в 20:05 я подключил Redmi 12 и разрешил начинать работу. Через пару минут ушёл по своим делам, оставив агенту инструкцию не останавливаться, даже если какие-то проверки на физическом устройстве окажутся недоступны.

Агент создал отдельный Android-проект: Kotlin, Compose, CameraX, Android foreground service, встроенный HTTP-сервер и небольшой KMP-модуль для общей логики. Сначала он собрал APK, написал проверочный сценарий и попытался установить приложение через ADB.

Здесь всё и остановилось — но не по причине ошибки в коде:

INSTALL_FAILED_USER_RESTRICTED: Install canceled by user

Телефон блокировал установку. Агент не пытался обходить защитные настройки и не стал считать приложение проверенным. Вместо этого создал эмулятор Android 14 и продолжил там: собрал прототип, проверил команды, получение JPEG и время ответа. В отчёте отдельно указал, что эти измерения относятся к эмулятору, а не к Redmi.

Когда я вернулся, мы обошли установочное ограничение обычным способом: агент перенёс APK в «Загрузки», а я вручную установил его через приложение «Файлы». После этого начались испытания на настоящем телефоне.

Эмулятор прошёл проверки, а Redmi показал другую проблему

Первый реальный снимок оказался размером 3264×2448 — примерно 8 Мп. Для нашего ориентира по детализации A4 этого было недостаточно с учётом полей вокруг листа.

Агент проверил режимы камеры через dumpsys media.camera и выяснил, что устройство поддерживает и более высокое разрешение — вплоть до 4080×3060. Но обычный выбор разрешения CameraX не использовал этот режим. После изменения ResolutionSelector и повторной сборки APK мы получили 4080×3060, около 12,5 Мп.

Это хороший пример того, почему я не считаю зелёные проверки на эмуляторе доказательством работы на реальном Android-устройстве. Эмулятор подтвердил, что протокол и базовый сценарий функционируют. Но специфическое поведение камеры Redmi обнаружилось только на Redmi.

Отдельно проверили работу с выключенным экраном. Я физически нажал кнопку питания; агент подтвердил по состоянию устройства, что экран действительно спит, и прогнал съёмку. В коротком тесте камера снимала в полном разрешении, а после простоя освобождалась и открывалась снова. Это не восьмичасовой стресс-тест рабочего дня, и я не хочу выдавать его за такой.

Агент перешёл в другой проект и сам соединил обе стороны

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

Это для меня самая интересная часть эксперимента. В одной Codex-сессии агент работал уже в двух проектах. Ему не пришлось вручную передавать спецификацию из «Android-команды» в «backend-команду»: он сам сформулировал контракт и реализовал его на обеих сторонах.

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

Для первого интеграционного прогона агент выбрал путь через сервер PaperLedger:

Браузер PaperLedger
        │  «Снять», превью
        ▼
Сервер PaperLedger (FastAPI)
        │  команды HTTP
        ▼
mobile-ledger на Redmi 12
        │  JPEG с камеры
        ▼
Сервер PaperLedger
        │  ответ браузеру
        ▼
Тот же список страниц, что и у файлового пикера
        │  подтверждение приёма браузером
        └──────────────────────────────► камера удаляет снимок

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

Агент запустил изолированный экземпляр PaperLedger, не трогая работающий публичный сервер, и проверил цепочку с реальной камерой Redmi. Снимок 4080×3060 действительно попал из телефона в браузер через FastAPI.

В новой интеграции также появились 33 целевых теста и 9 браузерных сценариев. Здесь важно уточнить: браузерные сценарии проверялись с тестовым источником камеры. Это не девять независимых сквозных съёмок настоящим Redmi. На реальном устройстве были отдельные проверки камеры и два измеренных снимка по интегрированному пути.

Через сервер получение фотографий в браузере заняло 3,14 и 3,43 секунды. В интервью мы выбрали цель 2–3 секунды. То есть система заработала, но целевую задержку в этих измерениях не достигла. В итоговом сообщении агент перечислил успешные проверки, а этот факт не вынес в краткую сводку — пришлось смотреть подробный отчёт.

Что осталось за пределами прототипа

У этой истории есть принципиальное ограничение. Мы проверили работу телефона и сервера в доступной тестовой сети. Но реальный сценарий другой: жена находится на работе с телефоном и Windows-компьютером, а PaperLedger запущен у меня дома.

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

Есть и другие незавершённые пункты: QR-привязка камер пока не реализована, снимки на телефоне пока не выравниваются и не обрабатываются, корректная работа весь рабочий день не подтверждена, а 12,5 Мп сами по себе ещё не доказывают фактические 300 DPI на листе. На момент этой истории публичный экземпляр PaperLedger не обновлялся и жена не проходила с ним полноценный рабочий сценарий.

Отдельная тема — защита данных. В эксперименте использовался существующий HTTP-доступ без HTTPS, а рабочие бухгалтерские документы могут быть конфиденциальными. Такой прототип нельзя автоматически считать пригодным для использования в корпоративной сети: перед этим нужно разбираться и с защищённым транспортом, и с согласованием использования данных.

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

Что я вынес из этого эксперимента

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

Здесь я попробовал другой способ работы. На входе у агента была идея — «телефон как документ-камера для PaperLedger» — и доступ к существующему проекту. Вместо того чтобы самостоятельно расписывать протоколы, состояния и детали реализации, я попросил его сначала задать мне вопросы.

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

Но после того как эти решения были приняты, мне уже не понадобилось самому проектировать каждый маршрут FastAPI, писать службу CameraX или вручную согласовывать код двух приложений. Агент реализовал обе стороны, собрал APK, организовал проверки и показал работающий сквозной сценарий. Моё участие в реализации свелось главным образом к решениям, которые требовали физического телефона, и к оценке результата.

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

Для меня вывод не в том, что простое приложение оказалось сложным. И не в том, что AI написал его за вечер.

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

А полную стенограмму я оставил именно поэтому. Думаю, каждый, кто когда-нибудь говорил «да там всего одна кнопка и камера», найдёт в ней свой неожиданный вопрос.