Для Эльмиры · подготовка к защите

Как устроено решение и как его защищать

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

Рассказ за одну минуту

Можно сказать почти дословно

«Я взяла „Петербургский некрополь“ 1912 года — словарь погребённых на петербургских кладбищах. Первый том, буквы А–Г, это 13,6 тысячи статей. Текст получен распознаванием (OCR), поэтому в нём много ошибок: знак смерти † превратился в плюс, единицу, букву Т, а „іюля“ — в „поля“.

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

Дата смерти найдена у 94,8 % статей. Для честной проверки вручную размечено 40 статей, которые модель не видела: точность по дате смерти 97 %, полнота 100 %. Ещё 516 подозрительных статей программа сама пометила для ручной проверки. Единственная ошибка на проверке — две статьи, которые OCR склеил ещё на этапе разбиения. Это и есть следующая доработка.»

Что решено: пункт за пунктом

Цель работы — практическое задание со слайда 13. Ниже его текст разбит на отдельные требования. Для каждого указано, что сделано, где это лежит и чем подтверждается. «§» — номер раздела в отчёте result.html.

Требование заданияЧто сделаноГдеДоказательство
«…задачи, связанной с извлечением данных из вашего источника»Выбран «Петербургский некрополь», т. 1 (1912), OCR-текст с archive.org. Задача — извлечь из статей даты рождения и смерти.§00; data/necropol_t1.txt; code/download.pyИсточник скачивается командой; 13 620 статей
«По предложенной на семинаре схеме сформулируйте алгоритм»Шесть шагов схемы со слайда 12 применены к некрополю: структурные элементы → принципы деления → перевод на язык компьютера → этапы → описание этапов → контроль.§01, нумерованный списокКаждому шагу схемы соответствует свой пункт
(часть алгоритма) разбить задачу на этапы и описать каждыйСемь этапов (0–6): подготовка, статьи, имя, даты, статус, кладбище, таблица. Для каждого записаны правило и способ контроля. Этапы 0–1 реализованы кодом, без них этап 3 не запустить.§01, таблица; code/segment.pyКонтроль этапа 1: статьи по буквам, нарушения алфавита
«Выберите один этап алгоритма»Этап 3 «Даты рождения и смерти»: самый сложный из-за OCR и самый ценный для исследования.§01, выделенная строка; §02—
«…напишите для него серию промтов»Пять промтов на обычном языке для модели Claude Sonnet: задача → искажения OCR → чьи это даты → контроль → сверка с эталоном.§02; prompts/sonnet_prompts.mdПолный текст каждого промта в §02, раскрывающиеся блоки
«…которая будет включать описание задачи»В каждом промте словами описано, что дано, что нужно получить и какие тонкости в источнике, с примерами из настоящих статей.§02, строка «Задача» у каждого промта—
«…и механизм контроля её выполнения»Четыре уровня: (1) 18 примеров «текст → ответ», из которых модель сделала самопроверку; (2) шесть видов пометок подозрительных статей; (3) файл на ручную проверку; (4) сверка с ручной разметкой — 60 статей для отладки и 40 отложенных.§02, строка «Контроль»; §03; code/evaluate.py18/18 примеров; 516 статей на проверку; точность и полнота
«Протестируйте работу кода на выбранном источнике»Код Sonnet запущен на всём томе после каждого из пяти шагов.§03, таблица «Как шла работа»11 319 → 11 467 → 11 577 → 11 577 → 11 694 дат смерти
«оцените соответствие его поставленной задаче»Сравнение с ручной разметкой на отложенной выборке и разбор каждой ошибки.§03, «Оценка по ручной разметке»; §04Смерть: точность 97 %, полнота 100 %; рождение: 94 % и 100 %
«…и отметьте, какая доработка потребуется на следующем этапе»Шесть пунктов: склейка статей с «‚» на этапе 1; ручной разбор 516 пометок (в первую очередь 228 дат «без креста»); восстановление годов; дата погребения; кодировка для Excel; этапы 2, 4, 5.§04Каждый пункт привязан к находке контроля
«Результат загружать в форму до четверга 15 октября 23:59»Отчёт (HTML и Word) и проект готовы к загрузке, есть публичная ссылка.Раздел «Как заполнить форму»Отправку делаете вы
Что сюда не входит

Домашнее задание 2 (слайд 15, срок 4 ноября) — отдельная работа. Его не закрывает это решение: нужны исследовательский вопрос, малый корпус из 10–20 статей, база с выходными данными, сводная таблица и график. Код дат пригодится для пункта 3 домашнего задания.

Как заполнить форму

Форма: https://forms.yandex.ru/u/6a9a9a279029027489b7e596/ («Семинарские задания по ЦГ»). Отправлять её нужно вам самой: это ваша работа, и после нажатия «Отправить» ответ уже не изменить.

Поле формыОбязательноеЧто вписать
ФИОдаВаши фамилия, имя, отчество полностью, как в списке группы.
Выберите свою группуда«Практики» или «ИИ» — ту, в которой вы числитесь. Из материалов этого не видно, выберите сами.
Введите текст ссылки на заданиенетСсылка на сайт с отчётами, она открывается без входа и без запроса доступа:
https://ztar42.github.io/necropol-seminar7/
В форме нет поля «номер семинара», поэтому лучше назвать семинар и в имени файла (ниже).
Загрузите ответ на задание семинаранетИз папки share: отчёт result.html или его Word-версию result.docx, а также Семинар7_практика.zip (250 КБ). В архиве только то, что нужно проверяющему: отчёт, промты, код, ручная разметка и результаты. Шпаргалки explain там нет. Если преподаватель привык к Word, загрузите result.docx. Лимит формы — 20 файлов и 20 МБ, запас большой. Перед загрузкой переименуйте отчёт, например в Семинар7_Фамилия_отчёт.html.

Словарь терминов

OCR
Распознавание текста со скана. Машина «читает» картинку страницы и ошибается: путает похожие знаки († → «+», «8» → «3»), теряет дореформенную «і».
Статья
Одна запись словаря об одном человеке: «Фамилия, Имя Отчество, …, р. дата † дата (кладбище)».
Промт
Текстовое задание для модели ИИ. Серия промтов — несколько заданий подряд в одном диалоге, каждое продолжает предыдущее.
Claude Sonnet
Модель ИИ компании Anthropic, хорошо пишет код. Ей можно объяснить задачу обычными словами и примерами.
Самопроверка
Список примеров «на такой текст ответ должен быть такой». Программа проверяет себя на них перед каждой обработкой и останавливается, если хоть один пример не прошёл.
Регулярное выражение
Шаблон для поиска в тексте. Например, «одна-две цифры, пробел, месяц, пробел, четыре цифры» находит «16 декабря 1782». На семинаре так искали «продал», «продала»… Шпаргалка по значкам — в разделе «Что происходит в коде».
CSV
Таблица в виде текстового файла, столбцы разделены запятыми. Открывается в Excel и Google Таблицах.
Скрипт, функция
Скрипт — файл с программой (.py), запускается одной командой. Функция — именованный кусок программы, делающий одно действие, например norm_year «чинит» год: «т852» → 1852.
Покрытие
У какой доли статей программа что-то нашла. Покрытие не говорит, верно ли найденное.
Пометка (флаг)
Отметка «тут подозрительно», например «рождение позже смерти». Программа не исправляет такие места сама, а откладывает их человеку.
Эталон
Статьи, где правильный ответ записан вручную. С ним сравнивается ответ программы.
Точность и полнота
Точность — какая доля выданных дат верна (95 % — из 100 выданных 95 правильные). Полнота — какая доля дат, которые есть в тексте, найдена (97 % — из 100 найдено 97).
Отложенная выборка
Вторая порция эталона, которую модели не показывали. Если код подгонять под проверочные примеры, оценка будет завышена. Отложенная выборка даёт честную цифру, как экзамен задачами, которых не было на тренировке.
«Своя» часть статьи
Начало статьи до родственников («Жена:», «Съ …») и до скобки с кладбищем. Только там лежат даты самого человека.

Почему этот источник

Как работает решение в целом

Решение — цепочка скриптов: каждый берёт результат предыдущего и кладёт свой в папку output. Код этапов 0–1 и проверки подготовлен заранее; код этапа 3 написала Sonnet по промтам.

СкриптЭтапКто написалБерётСоздаёт
necropol_dates.pyВсё сразу: 0, 1, 3 и проверкаСборка из файлов нижеarchive.orgВсе файлы output/ + цифры на экране
code/download.py0. Скачать источникClaude Opusarchive.orgdata/necropol_t1.txt
code/segment.py0–1. Очистить и разбить на статьиClaude Opusnecropol_t1.txtoutput/entries.csv
code/dates_sonnet.py3. Даты + контрольClaude Sonnet по 5 промтамentries.csvoutput/dates_sonnet.csv, dates_sonnet_review.csv
code/evaluate.pyПроверка по эталонуClaude Opusdates_sonnet.csv + data/*_dates.csvЦифры на экране

Почему промты написаны так

Промты рассчитаны на Claude Sonnet — сильную модель, которой задачу можно объяснить, как коллеге. Поэтому они короткие и написаны обычным языком:

  • Задача словами, а не инструкциями. «Нам нужны только даты самого человека — те, что идут до упоминания родственников». Без регулярных выражений, имён функций и технических требований.
  • Сначала посмотреть на данные. Промт 2 просит модель саму посчитать, как OCR записал крест и месяцы, и показать это. Она нашла то же, что видно глазами: «+» 1955 раз, «1» 1012 раз, «поля» вместо «іюля» 386 раз.
  • Примеры вместо правил. Вместо «знак 1 считается крестом, если после него пробел» — пример: «р. 15 ноября 1852 1 5 марта 1856 значит, что человек умер 5 марта 1856». Модель сама выводит правило.
  • Контроль через примеры. Каждый пример «текст → ответ» модель превращает в самопроверку. Если правка что-то сломала, программа сразу остановится. Это и есть механизм контроля, который требует задание.
  • Последний шаг — честная самопроверка. «Если ошибся код — исправь. Если ошибка в самом источнике — не подгоняй». Так Sonnet нашла пять ошибок кода и не стала «подкручивать» ответы.
Если спросят «почему Sonnet?»

«Мне было важно, чтобы промты читались как обычный текст, без программистских инструкций. Sonnet достаточно сильная, чтобы понять задачу по описанию и примерам и самой разобраться в данных. Качество я проверяла не на слово: на 40 статьях, которые модель не видела, точность 97 %, полнота 100 %.»

Что происходит в коде

Каждый файл разобран по смысловым блокам. Построчно разбираться не нужно: достаточно понимать, что делает блок и зачем он нужен. Код открывается в любом текстовом редакторе. Строки, которые начинаются с #, и текст в тройных кавычках """…""" — комментарии для человека, компьютер их пропускает.

Как читать регулярные выражения: шпаргалка

ЗначокЗначитПример
\dлюбая цифра\d\d находит «16»
\s / \Sпробел / любой знак, кроме пробелаапр\S{0,3}ля — «апрЪля», «апр$ля», «апрфля»
[абв]одна буква из списка[юо]ля — «юля» или «оля»
?предыдущее может быть, а может не бытьф?февраля — «февраля» и «ффевраля»
{1,2}от одного до двух раз\d{1,2} — день «5» или «15»
|«или»марта|мая
( … )«запомни этот кусок»: так программа достаёт день, месяц, год по отдельности(\d{1,2}) — день
(?=…) (?<!…)«проверь, что дальше / перед этим стоит…», не забирая это в результат1(?=\s) — «1», за которой пробел
re.Iне различать заглавные и строчные«Февраля» = «февраля»

code/dates_sonnet.py — этап 3, код Sonnet (главный файл)

Вход: output/entries.csvВыход: dates_sonnet.csv (id, рождение, смерть, пометки), dates_sonnet_review.csv (на проверку), сводка на экране

Около 270 строк, и их удобно читать сверху вниз: сначала «словари», потом функции, которые ими пользуются, в конце — примеры для самопроверки и запуск.

Блок 1 · как узнать месяц: month_of · промт 2
MONTH_PREFIX = [("янв", 1), ("фев", 2), ("мар", 3), ("апр", 4), … ("юл", 7), …]
MONTH_PART   = [… ("оня", 6), ("оля", 7), ("густ", 8), ("кабр", 12)]

Здесь нет длинных шаблонов. Программа сначала убирает из слова мусорные знаки ($, %, !, цифры) и заменяет «ѣ» на «е». Потом смотрит, с чего начинается слово («апр…» → апрель), а если не вышло — нет ли в нём узнаваемого куска («оля» → июль, «густ» → август, «кабр» → декабрь). Так «поля», «1юля», «апр$ля» и «азгуста» узнаются без отдельного правила на каждый вариант. Обрывок «ня» от «іюня» учтён отдельно.

Блок 2 · год и поиск всех дат: fix_year, find_dates · промты 1–2
  • fix_year: «т852» → 1852; год, начинающийся на «13», → «18» (OCR путает 8 и 3, XIV века в издании нет).
  • DATE_RE: «число — слово — год». Слово может начинаться с лишней «1» («19 1юля 1903» — это 19 июля).
  • find_dates проходит по тексту слева направо и собирает все даты по порядку. Если месяц не узнан, сохраняет хотя бы год. Если есть только год («р. 1852 Т 1892»), берёт год.
Блок 3 · «своя» часть статьи: own_part, cut_relatives · промт 3
  • Если запись начинается с отсылки «— см. …» и к ней приклеена следующая статья, отсылка отбрасывается, и читается вторая статья.
  • Скобки: если внутри «кладб», «лавр», «монаст», «церк», «пуст», «собор» или после скобки ничего нет — это кладбище, дальше читать не нужно. Другие скобки («рожд. Дюлу (Бивоча)») просто выбрасываются, и чтение продолжается.
  • Родственники: текст обрезается на первом слове с заглавной буквы из списка — «Жена», «Мужъ», «Сынъ», «Дочь», «Вдова», «Мать», «Отецъ», «Съ», «Отъ», «Надпись» и др. Строчное «жена ст. сов.» относится к самому человеку и не режется.
Блок 4 · крест и «р.»: CROSS_RE, BIRTH_WORD_RE · промты 1–3

Крест — это отдельно стоящий знак (один, два или три подряд) из набора + { | } Т т 1 ф — † - и ещё нескольких, которые нашлись в данных. «Отдельно стоящий» значит, что вокруг пробелы: буква «т» внутри слова крестом не считается. «р.» ищется и в кириллице, и в латинице (OCR иногда ставит латинскую p).

Блок 5 · чья это дата: extract · промты 3, 5

Сердце программы. Для каждой найденной даты она смотрит на текст между этой датой и предыдущей:

  1. там есть «р.» → это рождение. Но если после «р.» сразу стоит крест («р. 2 + 3 апрѣля 1878»), рождение нечитаемо, и дата — смерть;
  2. там есть крест → это смерть;
  3. у первой даты нет ни «р.», ни креста, но перед следующей датой крест → первая дата — рождение («Клара, 29 октября 1821 | 17 июля 1891»);
  4. между рождением и крестом есть ещё одна дата (например, свадьба) → она пропускается, смертью берётся дата после креста;
  5. креста нет, но дата стоит сразу (не дальше 40 знаков) после рождения → это смерть с пометкой «смерть без креста».
Блок 6 · пометки: check_flags · промт 4
ПометкаКогда ставитсяСтатей
смерть без крестадата смерти определена по положению, а не по знаку228
есть год, но нет смертив «своей» части есть дата, а смерть не найдена196
возраст не совпадаетсразу после даты смерти указан возраст («на 45 г.», «63 л.»), и он отличается от разницы годов больше чем на год44
рождение позже смертигод рождения больше года смерти32
больше 110 летмежду годами больше 110 лет23
год вне диапазонагод не между 1700 и 191215
Блок 7 · SELF_TESTS и self_check — 18 примеров из промтов

Все примеры из промтов собраны в список «текст статьи → ожидаемые даты». Перед каждой обработкой программа проверяет себя на них. Если хоть один пример не прошёл, она пишет «САМОПРОВЕРКА НЕ ПРОЙДЕНА» и останавливается, не выдавая неверных результатов.

Блок 8 · main — запуск и сводка

Запускает самопроверку, читает все 13 620 статей, к каждой применяет extract, пишет dates_sonnet.csv, а помеченные статьи с текстом — в dates_sonnet_review.csv. В конце печатает сводку: сколько статей обработано, у скольких найдены даты (в процентах от всех статей вместе с отсылками), сколько каждой пометки.

code/segment.py — этапы 0–1, разбиение на статьи

Вход: data/necropol_t1.txtВыход: output/entries.csv (номер, фамилия, отсылка или нет, текст), segment_report.txt
  • Отрезает предисловие: словарь начинается со статьи «Абаза, Аггей».
  • Выбрасывает мусор (функция is_junk): номера страниц, колонтитулы, «каша» вроде «[о иваиасисивнвин…». Выброшенное сохраняется в отчёт.
  • Склеивает строки и переносы: «Але- ксандро» → «Александро».
  • Находит границы букв: раздел «Б», «В», «Г» начинается там, где пять кандидатов подряд начинаются с новой буквы. Так одна случайная строка не переключит раздел.
  • Собирает статьи: абзац — новая статья, если начинается с «Фамилия,» на букву своего раздела. Иначе это продолжение после разрыва страницы или строка эпитафии («Прохожий, чтя се…»).
  • Режет склейки (функция split_glued): «…кладбище). | Бобровъ, Яковъ…» — так нашлось 1 363 слепленные статьи.
  • Контроль: число статей по буквам и нарушения алфавитного порядка в segment_report.txt.

code/download.py, code/evaluate.py, necropol_dates.py

  • download.py скачивает источник с archive.org и проверяет, что внутри словарь (есть «Абаза, Аггей»). При сбое сервера повторяет попытку, при неудаче объясняет, как скачать вручную.
  • evaluate.py сравнивает ответы программы с ручной разметкой и считает точность и полноту отдельно для рождения и смерти, печатает каждое расхождение. Статьи ищутся по началу текста, а не по номеру: номера меняются при исправлении разбиения.
  • necropol_dates.py — те же файлы, собранные в один; ручная разметка встроена в конец. Удобно переслать: работает в любой пустой папке. Код Sonnet перенесён в него без изменений (только пути к файлам указаны через папку output), результаты совпадают до байта.

Как скачать данные и запустить

При первом запуске это займёт 10–15 минут, потом — секунды. Интернет нужен только для скачивания источника.

Шаг 1. Установить Python

macOS

«Терминал» (Программы → Утилиты), затем:

python3 --version

Нужна версия 3.10 или новее. Если нет — установщик с python.org/downloads.

Windows

Установщик с python.org/downloads, в первом окне галочка «Add python.exe to PATH». Проверка в «Командной строке»:

python --version

На Windows во всех командах пишите python вместо python3.

Шаг 2. Распаковать проект и открыть в нём терминал

Распакуйте Семинар7_практика.zip или скачайте его на сайте ztar42.github.io/necropol-seminar7. Все команды выполняются из папки practice. Исходного текста в архиве нет, чтобы он был лёгким: его скачает download.py или necropol_dates.py на шаге 3.

macOS

Правой кнопкой по папке practice → «Службы» → «Новый терминал по адресу папки». Если такого пункта нет: в Терминале наберите cd  (с пробелом), перетащите папку в окно, нажмите Enter.

Windows

Откройте папку practice, щёлкните по адресной строке, наберите cmd и нажмите Enter.

Шаг 3. Запустить

Самый короткий путь

Одна команда делает всё: скачивает источник (если его нет), разбивает на статьи, запускает код Sonnet с самопроверкой, печатает цифры проверки.

python3 necropol_dates.py

Или по этапам, как на семинаре:

python3 code/download.py
python3 code/segment.py
python3 code/dates_sonnet.py
python3 code/evaluate.py
python3 code/evaluate.py output/dates_sonnet.csv data/holdout_dates.csv
КомандаЧто должно появиться
download.py«Готово: … 3,092,966 байт» или «Файл уже есть»
segment.py«Статей: 13620», «Из них отсылок «см.»: 1290», статьи по буквам
dates_sonnet.py«Самопроверка пройдена (18 примеров).», затем сводка: «Дата смерти найдена: 11694 (85.9%)» — процент здесь от всех 13 620 статей вместе с отсылками; без отсылок это 94,8 %. «Помечено для проверки: 516» и число каждой пометки.
evaluate.pyЭталон 60: рождение 100 % / 100 %, смерть 100 % / 100 %
evaluate.py … holdoutОтложенная выборка: рождение 94 % / 100 %, смерть 97 % / 100 %, два расхождения по одной склеенной статье

Скачать источник вручную, если скрипт не работает: откройте archive.org/details/peterburgskijnekropolt1ag60 → справа «DOWNLOAD OPTIONS» → «FULL TEXT» → сохраните в practice/data как necropol_t1.txt.

Результаты: output/dates_sonnet.csv и output/dates_sonnet_review.csv. Код Sonnet сохраняет их в обычной кодировке UTF-8, поэтому в Excel открывайте через Данные → «Из текста/CSV» → кодировка UTF-8, разделитель «запятая» (двойной щелчок покажет «кракозябры»). В Google Таблицах: Файл → Импорт — работает сразу.

Если что-то пошло не так

СообщениеЧто делать
command not found: python3Python не установлен, или (Windows) нет галочки «Add to PATH». На Windows пишите python.
FileNotFoundErrorТерминал открыт не в папке practice (шаг 2) или источник не скачан. Код Sonnet ищет output/entries.csv относительно текущей папки, поэтому запускать его нужно именно из practice.
САМОПРОВЕРКА НЕ ПРОЙДЕНАКто-то изменил код, и пример из промтов перестал проходить. Верните исходный code/dates_sonnet.py из архива.
попытка 1/4 не удалась: HTTP Error 500Временный сбой archive.org. Скрипт повторит сам; если не помогло — подождите или скачайте вручную.
CERTIFICATE_VERIFY_FAILEDmacOS: Программы → Python 3.x → «Install Certificates.command», или скачайте вручную.

Почему решение устроено так

Почему регулярные выражения в коде, а не «пусть нейросеть прочитает каждую статью»? Правила видны и проверяемы, результат воспроизводим: тот же текст всегда даёт тот же ответ. 13 600 статей обрабатываются за секунды и бесплатно. ИИ использован там, где он силён: написать такую программу по описанию. Альтернатива — отправлять каждую статью в модель. Это дороже, медленнее, и ответы могут меняться от запуска к запуску.
Почему промты без технических инструкций? Так их может написать и проверить историк, а не программист. Модель достаточно сильная, чтобы понять задачу по описанию и примерам. Качество подтверждено независимой проверкой, а не «на глаз».
Почему примеры в каждом промте? Пример «текст → ответ» понятнее любого правила и сразу превращается в самопроверку. Задание требует «механизм контроля выполнения»: программа, которая не запускается при сломанном примере, — самый строгий контроль.
Почему программа помечает подозрительное, а не исправляет? «1992» могло быть и 1892, и 1882. Если исправлять наугад, ошибка спрячется в данных. Пометка оставляет решение историку. Исправляются только однозначные случаи: «т852» → 1852, год 13xx → 18xx.
Почему два эталона (60 и 40 статей)? По первым 60 статьям Sonnet на шаге 5 исправляла код, поэтому там 100 % — завышенная оценка. Последние 40 модели не показывали, их цифры (97 % / 100 %) честные.
Почему несколько скриптов и ещё один общий файл? Отдельные скрипты повторяют схему семинара «этап за этапом», и каждый можно проверить отдельно. Общий файл удобен, чтобы переслать решение и запустить одной командой. Результаты у них совпадают.
Почему только стандартная библиотека Python? Ничего не нужно устанавливать: код запустится на любом компьютере с Python, проверяющий легко повторит результат.
Почему код Sonnet сохранён без правок? Чтобы было честно: всё, что видит проверяющий, — результат промтов. Даже мелочи, которые хотелось бы поправить (кодировка для Excel), вынесены в план доработки, а не исправлены тайком.

Как шла работа

Эта история — ответ на пункт «протестируйте и отметьте доработку». После каждого промта код запускался на всём томе.

  1. Промт 1, первая версия: дата смерти у 11 319 статей (из 13 620). Sonnet сразу сделала поиск месяцев терпимым к опечаткам, поэтому даже «простая» версия нашла 83 % статей.
  2. Промт 2, искажения OCR: 11 467. Модель сама посчитала, как записан крест и месяцы, и починила годы «1336» → 1836 и «т852» → 1852.
  3. Промт 3, чьи это даты: 11 577. Даты жён и детей больше не попадают в результат, «рожд. Вердье» не считается рождением, дата без креста помечается.
  4. Промт 4, контроль: шесть видов пометок, включая сверку с возрастом из текста. 616 статей на проверку.
  5. Промт 5, сверка с эталоном: 11 694. Модель нашла пять ошибок кода — «р. 2 + 3 апрѣля» (рождение нечитаемо, дата — смерть), «5 ня», «азгуста», «19 1юля» — и исправила их. На эталоне 100 %, пометок осталось 516.
  6. Итоговая проверка на 40 статьях, которые модель не видела: смерть 97 % / 100 %, рождение 94 % / 100 %. Исправления по эталону помогли и на новых статьях: до шага 5 по смерти было 92 % / 92 %.

Вопросы и ответы

Вы сами писали код?

Отвечать честно: код этапа «Даты» написала модель Claude Sonnet по моей серии промтов, а код подготовки и проверки — Claude Opus. Это указано в декларации. Тема семинара — вайб-кодинг: оценивается умение поставить задачу, разбить её на этапы, задать механизм контроля и проверить результат. Это показано через примеры-самопроверки в промтах, эталон, отложенную выборку и разбор ошибок.

Почему у половины статей нет даты рождения?

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

Откуда уверенность, что 97 % — правда?

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

Почему в выводе программы 85,9 %, а в отчёте 94,8 %?

Программа считает процент от всех 13 620 статей, включая 1 290 отсылок вида «Аксенова — см. Анцъ», в которых дат нет по определению. В отчёте процент от 12 330 настоящих статей. Число одно и то же: 11 694 даты смерти.

Где в коде механизм контроля?

Три места в dates_sonnet.py: список SELF_TESTS и функция self_check (18 примеров из промтов, запускаются при каждом старте); функция check_flags (пометки подозрительных статей); конец main (файл на проверку и сводка). Четвёртое — отдельный скрипт evaluate.py со сверкой по эталону.

Что делать с 516 статьями на проверку?

Начать с 228 дат «без креста»: они почти всегда верны, но взяты по положению, а не по знаку, и быстро проверяются глазами. Остальные можно пройти вручную или полуавтоматически, как на семинаре со словарём исключений: программа показывает статью, человек вводит дату, ответ сохраняется.

Почему 1336 превращается в 1836?

OCR чаще всего путает 8 и 3. Во втором разряде года тройка точно ошибочна: XIV века в издании нет. Другие разряды программа не трогает, такие случаи ловят пометки.

Почему не сделаны остальные этапы?

Задание просит выбрать один этап и довести его до теста. Этапы 0–1 сделаны, потому что без них этап «Даты» не запустить. Для остальных в алгоритме описаны правила и контроль: это план.

Чем этот подход похож на семинарский?

Почти один в один. Семинар: поиск разделителя «продал» → словарь вариантов → проверка охвата файлов → словарь исключений. У нас: поиск знака † → варианты его записи в OCR → проверка покрытия и пометки → файл ручной проверки.

Как это использовать в исследовании?

Таблица дат даёт возраст смерти (медиана 56 лет), сезонность (максимум в марте, минимум в августе) и динамику по десятилетиям. С этапами «статус» и «кладбище» можно сравнивать продолжительность жизни сословий и конфессий.

Слабые места

Лучше назвать их самой, чем ждать вопроса:

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

  1. Пройти раздел «Как скачать данные и запустить» и убедиться, что цифры совпадают с отчётом.
  2. Открыть data/holdout_dates.csv и самой сверить 10 статей с текстом в output/entries.csv (поиск по фамилии). Если разметка спорная — поправить и перезапустить evaluate.py.
  3. Прочитать prompts/sonnet_prompts.md: на защите могут спросить, что именно вы просили у модели. Промты написаны обычным языком, их стоит уметь пересказать своими словами.
  4. Открыть code/dates_sonnet.py и найти глазами блоки из раздела «Что происходит в коде»: месяцы, «своя» часть статьи, роль даты, пометки, самопроверка.
  5. Прочитать декларацию ИИ в конце отчёта: пункт «Собственная доработка» заполнен, но на защите его стоит уметь пересказать своими словами.
  6. Отправить работу через форму, см. раздел «Как заполнить форму». Срок — 15 октября, 23:59.