Коротко
Автор создал локально запускаемое приложение PDF Desk, которое отвечает на вопросы по текстовым PDF и позволяет открыть страницу-источник рядом с ответом. Пример с DeepSeek подтвердил работу всего маршрута на коротком документе, но не доказывает точность на других PDF: существующая ссылка ещё не подтверждает истинность утверждения.
Контекст
Автор предыдущего проекта local-docs-ai — приложения для поиска по Markdown и TXT — разработал PDF Desk на Python, Streamlit, PageIndex и PDFium. Задача — сделать проверку ответов по PDF удобнее, показывая физическую страницу оригинала и текстовый слой. Приложение рассчитано на одного пользователя и один активный документ. Файлы и индекс остаются локально, но текст документа отправляется внешнему API выбранной модели.
Главное
- Проект называется PDF Desk; интерфейс построен на Streamlit, обработка и рендеринг PDF — на PDFium, поиск — на локальном режиме PageIndex SDK.
- Зафиксированы версии PageIndex 0.2.20, Streamlit 1.64.0, pypdfium2 5.13.0 и PyPDF2 3.0.1; требуется Python 3.11 или новее.
- Ограничения загрузки: не более 25 МиБ и 500 страниц. В документе должно быть не менее 20 непробельных символов; сканы без текстового слоя не распознаются.
- Проверка API выполняет обычный запрос к модели индексации и отдельную проверку вызова ping у модели ответов. Тайм-аут пробных запросов — 15 секунд; модель ответов должна поддерживать tool calls.
- Для теста использовались https://api.deepseek.com/v1 и deepseek-flash для обеих моделей. Подключение OpenCode Go не подтвердилось: сервис потребовал x-opencode-session.
- Отпечаток индекса включает SHA-256 PDF, base_url, index_model и версию SDK; chat_model и API-ключ не включены. Ключ сохраняется только в состоянии текущей сессии, не в settings.json.
- PageIndex работает без обязательной векторной базы, но локальность относится к индексу и хранению: текст документа при внешнем backend уходит провайдеру модели.
- Цитаты принимаются только при совпадении doc_id с активным документом и корректном номере страницы; повторные ссылки на одну страницу удаляются.
- Смена настроек сбрасывает отметку проверки и старый ответ. Навигация по страницам показывает PDFium-рендер страницы без нового обращения к модели.
- Автоматический набор включает 44 теста; реальные модельные ответы и тесты с подставным клиентом проверяют разные части системы.
Как сделано
PDF Desk проверяет загруженный файл средствами PDFium: допускает PDF до 25 МиБ и 500 страниц, проверяет открываемость и наличие читаемого текстового слоя. Если во всём файле меньше 20 непробельных символов, подготовка прекращается; OCR не предусмотрен. PageIndex 0.2.20 строит локальный древовидный индекс, а модель выполняет поиск и отвечает. Используются Streamlit 1.64.0, pypdfium2 5.13.0 и PyPDF2 3.0.1; требуется Python 3.11+ и OpenAI-совместимый POST /chat/completions с поддержкой вызова инструментов.
Перед загрузкой текста приложение проверяет подключение двумя запросами: получает обычный непустой ответ от модели индексации и проверяет вызов инструмента ping моделью ответов. В конфигурации PageIndex установлен mode=“local”, тайм-аут backend — 60 секунд, max_retries=0. URL внешнего API должен использовать HTTPS и оканчиваться на /v1; перенаправления запрещены.
Идентификатор индекса вычисляется из SHA-256 PDF, адреса API, модели индексации и версии SDK. Модель ответов в отпечаток не входит, поэтому её можно сменить без переиндексации. Новый документ становится активным только после завершённой индексации и проверки числа страниц; манифест active.json записывается атомарно. Для ответа приложение проверяет, что цитата относится к текущему документу и указывает на целую страницу в пределах файла, затем кнопка открывает её изображение и текстовый слой. Запрос вопроса выполняется по кнопке, переход между страницами не вызывает модель.
Результаты
На DeepSeek API (https://api.deepseek.com/v1) с deepseek-flash для обеих моделей автор успешно проверил ping, проиндексировал демонстрационный PDF из трёх страниц и получил ответы на четыре отдельных вопроса: гарантия — 18 месяцев (страница 2); условие прекращения — вскрытие корпуса (страница 3, также упомянут срок на странице 2); часы поддержки — понедельник–пятница, 09:00–18:00 (страница 3); цена в документе не указана (проверялись страницы 1–3). После исправления пробела перед точкой повторно проверили вопрос о гарантии. Headless Chrome также прошёл маршрут от ввода настроек до открытия изображения страницы 2. 44 автоматических теста прошли; CI для Python 3.11 и 3.12 завершился успешно на коммите 1bbb5f0. OpenCode Go проверку не прошёл: запрос требовал заголовок x-opencode-session, поэтому полноценный прогон PDF с ним не заявлен.
Ограничения
Проверен один небольшой демонстрационный PDF; это smoke test, а не оценка качества поиска. Нет замеров времени и стоимости, испытаний на большом наборе документов, таблицах, сложной вёрстке или сканах. OCR отсутствует; пустые страницы и ошибки извлечения могут ухудшить поиск. Проверка doc_id и номера страницы подтверждает лишь, что ссылка ведёт на существующую страницу текущего PDF, но не что страница доказывает каждую часть ответа — требуется чтение человеком. Локальное хранение не означает конфиденциальность: текст отправляется провайдеру, а PDF и индекс хранятся без шифрования. Приложение рассчитано на один процесс; threading.Lock не координирует отдельные экземпляры. Совместимость с OpenAI-совместимым API не гарантирует работу любого провайдера. Автор не проводил систематический бенчмарк и прямо предлагает сначала собрать размеченный набор вопросов и документов.
Что взять себе
- Проверяйте не только связность с API, но и нужные приложению возможности модели — здесь отдельно тестируется вызов инструмента.
- При работе с PDF полезно показывать изображение страницы и машинно извлечённый текст: так проще замечать сбои чтения таблиц, колонок и вёрстки.
- Не принимайте наличие ссылки на страницу за доказательство ответа; сверяйте страницу глазами и отдельно оценивайте точность поиска и пересказа.
- Для конфиденциальных документов учитывайте, что локальный индекс не предотвращает передачу текста внешнему модельному API.
- Перед расширением системы подготовьте набор документов и вопросов с ожидаемыми фактами, страницами и случаями, где ответа в документе нет.
Читать оригинал, если…
Откройте исходник, если нужны код и команды запуска, подробности валидации и хранения, таблица тестовых вопросов или планы оценки на собственных PDF.