АГЕНТ 04 / 07
Структурирование
Воркер структурирования превращает извлечённые фрагменты в канонические записи — нормализованные, дедуплицированные и связанные в граф сущностей, чтобы каждый воркер опирался на единый контекст.
structuring · autonomous
01Что делает
Канонические записи из разрозненных фрагментов
Сохранять, никогда не дублировать
Записывает структурированные записи в SQLite или PostgreSQL с дедупликацией по существующим данным: одинаковый нормализованный ключ означает слияние, а не новую строку. Опциональные интеграции могут получать каноническую запись.
Модель не может забыть
Управление только через промпт может потерять передачу контекста, если модель пропустит вызов сохранения. Среда выполнения сама сохраняет метаданные от успешных инструментов извлечения и поиска, поэтому структурированные результаты сохраняются для следующего хода.
Пять таблиц — одно досье
contacts, social_profiles, companies, tags и notes — с происхождением источников, метками времени и столбцом crm_id для идемпотентной синхронизации с CRM. Режим WAL, внешние ключи, индексированные запросы.
Одно написание на контакт
normalize_email обрезает и приводит к нижнему регистру («[email protected]» → [email protected]); normalize_phone оставляет только ASCII-цифры, сохраняя их в индексируемом столбце phone_norm. Это ключи дедупликации.
Записи растут, но не разделяются
Старая запись имеет приоритет: пустые поля заполняются из новых данных, соцпрофили переносятся с дедупликацией NOT EXISTS, теги добавляются через UNIQUE(contact_id, tag), заметки накапливаются — дублирующая строка удаляется.
Сущности и связи
Сущности дедуплицируются по (name, type); типизированные связи соединяют людей, проекты, системы и организации. Многошаговый BFS до глубины 4 обеспечивает контекстно-зависимую дальнейшую работу.
02Как это работает
От вывода инструмента до канонического контакта
Триггер
Инструмент extraction или discovery возвращает структурированные метаданные с уровнем достоверности и происхождением для текущей миссии.
Автосохранение
Runtime сохраняет структурированные элементы сразу после успеха — compaction не удалит передачу, а модель не забудет результат.
Нормализация
Email приведены к нижнему регистру, телефоны — к цифрам, происхождение зафиксировано: extract_contacts:mailto link:https://acme.io.
Найти или вставить
Одна атомарная транзакция: поиск по нормализованному email, затем по phone_norm. Совпадение → слияние; нет совпадения → вставка. Параллельные воркеры не создадут дубли.
Граф
Люди, проекты, системы и организации обновляются как узлы; связи становятся типизированными рёбрами с достоверностью для контекстно-зависимой дальнейшей работы.
Синхронизация
Контакты отправляются в amoCRM, Bitrix24 или HubSpot по четыре за раз с повторами; возвращённый crm_id сохраняется, чтобы ресинхронизация обновляла, а не дублировала.
03Под капотом
Схема, ключи и правила слияния
| Схема | contacts(id, email, phone, phone_norm, name, title, company, source, crm_id, created_at, updated_at) · social_profiles · companies · tags · notes |
| Хранилище | SQLite с WAL + busy_timeout 5000 из коробки · PostgreSQL через тот же интерфейс via [contacts] pg_url |
| Ключи дедупликации | сначала нормализованный email, затем phone_norm только с цифрами · побеждает наименьший id → сохраняется самая старая запись |
| Слияние | пробелы заполнены новыми данными · соцсети перенесены через NOT EXISTS · теги INSERT OR IGNORE · заметки добавлены · временная строка удалена, одна транзакция |
| Атомарность | find-or-insert выполняется в одной заблокированной транзакции — параллельные воркеры не могут одновременно вставить одну и ту же нормализованную запись (безопасно от TOCTOU) |
| Автосохранение | срабатывает при успехе extract_contacts / find_leads независимо от модели · «[авто-сохранено N контакт(ов): X новых, Y слитых]» |
| Провенанс | Теги sources указывают породивший tool и URL источника · уверенность сохраняется как метаданные записи для ревью |
| Мягкий ввод | tags/notes принимают JSON-массив или обычную строку; «; » и переводы строк разбивают блоки — дрифт структуры LLM никогда не теряет данные |
| Дедупликация графа | entity_nodes UNIQUE(name COLLATE NOCASE, entity_type) · edges UNIQUE(from, to, relation), уверенность по умолчанию 0.8 |
| Многошаговый | Глубина BFS ограничена 1–4, только простые пути, обратный обход помечен ⁻¹ |
| Отправка в CRM | Параллелизм buffer_unordered(4) · одна попытка через 1 с · set_crm_id для идемпотентных повторных отправок |
04Инструменты
Что запускает агент
Работает на флот воркеров
Структурированный контакт — это адресат
Структурированные записи дают каждому воркеру единый надёжный субъект, ссылки на источники, теги и заметки. Задача по кодингу, исследованию или операциям может переиспользовать каноническую сущность без повторного парсинга каждого источника или создания дубликатов.
save_contacts([{
email: "[email protected]", # → [email protected]
name: "Ann Petrova",
title: "CTO",
company:"Acme",
socials:[{ platform: "linkedin", url: "…" }],
tags: ["saas", "decision-maker"]
}])
→ added: 0 · merged_with_existing: 1
# one canonical record =
# one consistent downstream handoff