Извлечение текста из документов

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

Поддерживаемые форматы

ФорматРасширенияКонвертерДоступность
Jupyter notebooks.ipynbВстроенный (stdlib)Всегда
Документы Word.docxВстроенный (stdlib)Всегда
Книги Excel.xlsxВстроенный (stdlib)Всегда
Базы данных SQLite.db, .sqlite, .sqlite3Встроенный (stdlib)Всегда
PDF.pdfОпциональный конвертер anydocАвтоустановка при первом использовании*
Устаревшие форматы Office.doc, .ppt, .xls, .pptx и их вариантыОпциональный конвертер anydocАвтоустановка при первом использовании*
OpenDocument.odt, .ods, .odpОпциональный конвертер anydocАвтоустановка при первом использовании*
Rich text / электронные книги.rtf, .epubОпциональный конвертер anydocАвтоустановка при первом использовании*

* Опциональный конвертер — это пакет firecrawl-anydoc, который устанавливается лениво там, где это разрешено (security.allow_lazy_installs в config.yaml). Без него три встроенных формата на базе stdlib по-прежнему работают, а остальные попадают под защиту от бинарных файлов (binary-file guard).

Файлы SQLite отображаются не дампом, а обзором схемы: для каждой таблицы — оператор CREATE, число строк и первые пять строк, плюс список индексов, представлений и триггеров. База открывается только на чтение (mode=ro&immutable=1, поэтому живую базу, которую держит открытой другой процесс, всё равно можно прочитать без блокировок); всё, что выходит за рамки превью, запрашивайте из терминала через sqlite3. Файл .db, который на деле не SQLite (не совпадают магические байты), отклоняется с указанием настоящей причины. Собственный запретный список чтения Hermes применяется до извлечения, так что защищённые хранилища под HERMES_HOME прочитать по-прежнему нельзя.

Кроме того, read_file помечает неразрешённые конфликты слияния git: если в возвращённом диапазоне есть парные строки-маркеры <<<<<<< / >>>>>>> , в результате появляется conflict_blocks: N и подсказка разрешить их, прежде чем править код рядом. Одиночный маркер внутри строки или тестовой фикстуры не считается.

Результат конвертации — Markdown, который постранично отдаётся через обычное окно offset/limit инструмента read_file. Фонетические подсказки восточноазиатских языков (rPh в XLSX, ruby-текст в DOCX) лишь аннотируют текст ячейки или фрагмента и в извлечённое значение не попадают: ячейка с 東京 и подсказкой トウキョウ читается как 東京. Документы крупнее 50 МБ отклоняются — так объём одного вызова инструмента остаётся ограниченным.

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

Извлечение работает и с удалёнными терминальными бэкендами (Docker, Modal, SSH): байты файла передаются через границу бэкенда и конвертируются на стороне хоста, поэтому документ внутри песочницы читается точно так же, как локальный.

Сканированные PDF: предупреждение о покрытии

Конвертация PDF читает только текстовый слой. Страницы, которые на деле — сканы-изображения (частый случай для юридических документов, пакетов на перепродажу недвижимости, подписанных договоров, факсов), текстового слоя не содержат и молча конвертируются в пустоту. Узнать такую страницу легко: заголовок раздела есть, а тела под ним нет.

Если заметная доля страниц не даёт текста (больше 20% документа или от 10 страниц в абсолютных числах), read_file добавляет предупреждение перед результатом извлечения. Каждый нечитаемый пробел помечен последним извлечённым перед ним текстом — обычно это разделитель раздела, — чтобы агент мог обработать только нужные ему пробелы, а не прогонять OCR по всему документу:

[EXTRACTION COVERAGE WARNING: 198 of 311 pages in this PDF yielded no
text. ... Unreadable gaps, each labeled with the last text extracted
before it:
  pages 42-77 (36 pages) — after "Antigua Maintenance Corp Bylaws" (p41)
  pages 92-213 (122 pages) — after "... Covenants, Codes and Regulations" (p91)
  page 224 (1 page) — after "... Insurance Declaration Pages" (p223)
Decide which gaps you actually need — do NOT OCR or render everything. ...]

Предупреждение перечисляет точные диапазоны страниц и пути восстановления:

  1. Несколько страниц — рендер + vision. Конвертируйте страницы в изображения и прочитайте их инструментом vision:
    pdftoppm -jpeg -r 150 -f 92 -l 94 document.pdf $TMPDIR/page
    Затем изучите каждое изображение инструментом vision_analyze. Дополнительных зависимостей не требуется (poppler нужен только для самого обнаружения).
  2. Много страниц — OCR. Навык ocr-and-documents покрывает массовое распознавание через marker-pdf (90+ языков, обрабатывает формулы и таблицы; установка ~3-5 ГБ).

Обнаружение использует pdftotext из poppler для подсчёта текста постранично. Если poppler не установлен, извлечение всё равно работает — проверка покрытия молча пропускается.

совет

Агент сам разбирается с предупреждением — он предложит отрендерить или распознать (OCR) недостающие страницы. Если результаты извлечения читаете вы сами, воспринимайте «заголовок без содержимого» как отсканированный раздел, а не как утерянный.

перевод и редактура:

обновлено

⌕ ESC