| name | extract-sparse-data |
| description | Извлечение DN-релевантной информации из больших внешних Telegram-чатов и каналов (emigrantista, immigrazia_IT, rutoitaly, rutoitalychat), где лишь ~1% сообщений касается визы цифрового кочевника. Используй этот скил когда пользователь просит: обработать внешние чаты, извлечь данные из emigrantista/rutoitaly/ immigrazia_IT/rutoitalychat, найти DN-информацию в сторонних чатах, обработать разреженные данные. Также триггерь когда пользователь упоминает папки этих чатов в .datasource/ или говорит об извлечении DN-тематики из больших дампов. НЕ триггерь на основной DN-чат (nomadvisaitaly) — для него есть скил update-guide.
|
Извлечение DN-информации из внешних чатов
Ты обрабатываешь большие дампы Telegram-чатов и каналов общей тематики (эмиграция, Италия), в которых лишь ~1% сообщений касается визы цифрового кочевника (DN). Задача — найти эти сообщения, восстановить контекст и извлечь полезную информацию.
Ключевой принцип: НЕ читай дамп целиком. Работай через поиск по ключевым словам -> расширение контекста -> верификация DN-релевантности -> извлечение.
Входные данные
Дампы в .datasource/YYYY-MM-DD/:
.datasource/2026-04-06/
emigrantista_answers_2026-04-06/ <- канал Q&A по эмиграции
immigrazia_IT_2026-04-06/ <- канал про иммиграцию в Италию
rutoitaly_2026-04-06/ <- канал про жизнь в Италии
rutoitalychat_2026-04-06/ <- чат (supergroup) с тредами
Два типа источников:
| Тип | type в JSON | Треды | Размер |
|---|
Канал (public_channel) | Нет reply_to_message_id | Посты от авторов | <10K сообщений |
Чат (public_supergroup) | Есть reply_to_message_id | Живые обсуждения | >10K сообщений |
Поле text может быть строкой ИЛИ массивом (при форматировании). Для поиска используй оба поля: text и text_entities.
Алгоритм работы
Шаг 1: Поиск сообщений-кандидатов
Для каждого result.json ищи по трём уровням триггеров:
Tier 1 — Прямые упоминания DN (безусловный триггер):
| Паттерн | Что покрывает |
|---|
номад | номад, номада, номады, номадов... |
кочевни | кочевник, кочевника, кочевники... |
цифров.{0,5}кочевни | цифровой кочевник... |
digital.?nomad | digital nomad, digital-nomad |
nomad[ie]\s*digital[ie] | nomade digitale, nomadi digitali |
nomad.?visa | nomad visa |
виз\S*\s+(?:DN|номад|кочевни) | виза DN, визу номада |
(?:DN|ND)\s+виз | DN виза, ND виза |
Tier 2 — Контекстные (требуют проверки контекста ±5 сообщений):
| Паттерн | Типичные false positives |
|---|
удал[её]н | «сообщение удалено», «удалённое место» |
lavorator[ie]\s*(?:da\s*)?remoto | — |
lavoro\s*(?:da\s*)?remoto | — |
lavoro\s*autonomo | ОЧЕНЬ ШУМНЫЙ — общий ИП-контекст |
фрилан[сз] | фриланс без DN |
самозанят | самозанятость без DN |
remote\s*work | — |
работа.{0,10}из.?за\s*рубеж | — |
relocat\S*.*(?:ital|итал) | общая релокация |
Tier 3 — Юридические (редкие, но точные):
| Паттерн | Что покрывает |
|---|
27[\s.-]*ter | статья 27-ter (правовая основа DN) |
decreto.*nomad|nomad.*decreto | decreto nomadi digitali |
visto.*nomad|nomad.*visto | visto per nomadi |
permesso.*nomad|nomad.*permesso | permesso per nomade digitale |
Tier 4 — Составные (2+ слова рядом в одном сообщении или ±3 по ID):
ВНЖ + удалён / фриланс / номад
partita\s*iva + номад / кочевни / digital nomad
forfettari + номад / кочевни
квестур + номад / кочевни
Шаг 2: Расширение контекста
Для чатов (supergroup):
- Тред назад:
reply_to_message_id рекурсивно до корня
- Тред вперёд: все сообщения с
reply_to_message_id на любое сообщение в цепочке (транзитивно)
- Соседи: ±15 сообщений по ID, в пределах 30 минут, тематически связанные
- Дедупликация: объединить, убрать дубликаты по ID, сортировать по дате
Для каналов:
- ±5 сообщений по ID
- Собрать части длинного поста (несколько сообщений от одного автора подряд)
- Отметить
forwarded_from если есть
Шаг 3: Верификация DN-релевантности (ОБЯЗАТЕЛЬНЫЙ)
Без этого шага Tier 2 триггеры дают ~50% ложных срабатываний. На rutoitalychat (103K сообщений) без верификации — 529 дискуссий, после — 269.
Для каждой собранной дискуссии проверь: содержит ли объединённый текст ВСЕХ сообщений хотя бы одно DN-специфичное слово?
DN_VERIFY_RE = re.compile(
r'номад|кочевни|digital[\s._-]?nomad|nomad[\s._-]?visa'
r'|nomad[ie]\s*digital|\bdn\b|виз\S*\s+dn|dn\s+виз'
r'|27[\s.-]*ter|decreto.*nomad|цифров\S*\s+кочевни',
re.IGNORECASE
)
Правило: нет совпадения DN_VERIFY_RE по всему тексту дискуссии -> дискуссия отсеивается.
Почему это работает:
- Tier 1 проходит автоматически — триггер уже содержит DN-слово
- Tier 2 проходит, только если в расширенном контексте кто-то упомянул DN
\bdn\b ловит аббревиатуру «DN» — покрывает «подавался на DN в Белграде»
Что НЕ является DN-контекстом:
- «виза D» — общая категория (lavoro subordinato, autonomo, studio, famiglia, elective residence...)
- «lavoro autonomo» без «номад»/«DN»/«кочевник» — обычная фрилансерская виза
- «partita IVA», «ВНЖ», «квестура» сами по себе — общая иммиграция
Шаг 4: Извлечение информации
Из каждой подтверждённой дискуссии извлеки:
| Категория | Примеры | Приоритет |
|---|
| Конкретные кейсы | «подал DN в Белграде, получил за 3 недели» | Высший |
| Изменения процедур | «теперь для номадов квестура Милана требует X» | Высший |
| Документы и требования | «для DN-визы нужен апостиль на DDV» | Высший |
| Сроки и стоимость | «перевод стоил 5000р», «ждал 45 дней» | Высший |
| Сравнения с другими визами | «DN vs наёмный — разница в сроках» | Высокий |
| Контакты и ресурсы | переводчики, консультанты, ссылки | Средний |
| Общие рассуждения без конкретики | | Игнорировать |
Обязательный контекст: источник — кликабельная markdown-ссылка с URL: [emigrantista #1234](https://t.me/emigrantista_answers/1234) / [rutoitalychat #5678](https://t.me/rutoitalychat/5678) / [rutoitaly #1234](https://t.me/rutoitaly/1234) / [immigrazia_IT #1234](https://t.me/immigrazia_IT/1234), город/консульство/квестура, тип занятости, дата. НЕ писать [rutoitaly #1234] без (https://t.me/...).
Кейсы: даже если сообщение не проходит полный DN_VERIFY, но содержит личный кейс подачи/получения — вставить в 18-cases.md (кейс ценен сам по себе). Полная библиотека regex-паттернов для поиска кейсов: ../update-guide/references/case-patterns.md.
Шаг 5: Формирование выхода
Сохрани в ту же папку где исходник, с префиксом extracted_:
.datasource/2026-04-06/emigrantista_answers_2026-04-06/
result.json <- исходник
extracted_emigrantista_answers.json <- результат
Формат JSON:
{
"source": "emigrantista_answers_2026-04-06",
"extraction_date": "2026-04-06",
"discussions": [
{
"discussion_id": 1,
"trigger_messages": [1234, 1235],
"all_message_ids": [1230, 1231, 1234, 1235, 1236, 1240],
"topic": "Краткое описание",
"messages": [
{"id": 1234, "date": "2026-03-15T10:30:00", "from": "Имя", "text": "текст"}
],
"extracted_facts": [
{
"fact": "Квестура Милана для DN требует справку X",
"category": "Изменения процедур",
"confidence": "yellow (из опыта)",
"context": "квестура Милана, ИП",
"date": "2026-03-15",
"source_ids": [1234, 1235],
"guide_section": "12-first-steps.md"
}
]
}
],
"stats": {
"total_messages_scanned": 50000,
"trigger_matches": 150,
"discussions_found": 25,
"discussions_after_filtering": 18,
"facts_extracted": 42
}
}
Обработка ссылок
- Пересланные сообщения (
forwarded_from) — учитывай как источник, отмечай оригинальный канал
- Официальные источники (консульства, integrazionemigranti.gov.it, законодательство) -> переходи и верифицируй, маркировка 🟢
- Другие Telegram-каналы -> отметь как потенциальный источник для будущей обработки
Маркировка достоверности
- 🟢 Официально — законодательство, сайты консульств
- 🟡 Из опыта — реальные кейсы (из внешних чатов = независимый источник, особо ценно)
- 🔴 Спорно — противоречит основному гайду или другим источникам
Факты из внешних чатов, подтверждающие основной DN-чат — независимая верификация. Отмечай такие случаи.
Стратегия по размеру источника
- Каналы (<10K сообщений): grep + ручной просмотр. Верификация обычно не отсеивает — авторы пишут целевые посты.
- Чаты (>10K сообщений): Python-скрипт с индексацией и DN_VERIFY_RE. Без верификации — ~50% мусора.
Референсные Python-скрипты для обработки больших чатов: references/scripts.md.
Чеклист перед финализацией