TL;DR
Toolmaker-подход — это правило разделения труда. Модель не разбирает ваши данные «глазами», а пишет код (скрипт, парсер, проверку), который разбирает их вместо неё. Этот код вы проверяете на примерах с заранее известным правильным ответом. Авторы проверили это на реверс-инжиниринге форматов данных iPhone: когда модели читали дизассемблированный код напрямую, большинство результатов содержало ошибки, а написанный Claude инструмент восстановил всё точно.
Главная боль: ошибки модели невидимы. Результат выглядит безупречно: синтаксис верный, названия правдоподобные, всё «собирается» и даже что-то декодирует. Но внутри перепутанные типы, сдвинутые номера, потерянные значения. Почти 90% неверных полей вообще не встретились в реальном трафике, поэтому проверка «прогоним на реальных данных, вроде работает» их пропустила бы. Модель не сообщает «я не уверена». Она выдаёт связную, но неверную картину.
Метод в двух частях. Первая: просите не ответ, а инструмент и проверяете его на независимых эталонах (данные с известным ответом, ранее опубликованные результаты, реальные измерения). Вторая: если всё же нужен прямой анализ большого объёма, режьте задачу на мелкие единицы и отдавайте каждую свежему агенту с чистым контекстом. Один агент на всё сломался почти полностью.
Схема метода
ЧАСТЬ A — Toolmaker (основной вывод статьи)
ШАГ 1: НЕ просить модель анализировать данные напрямую
ШАГ 2: Попросить модель написать инструмент (скрипт) → код + тесты
ШАГ 3: Собрать независимые эталоны: данные с известным ответом,
прежние результаты, внешние измерения
ШАГ 4: Требовать от инструмента точного совпадения с эталоном
ШАГ 5: Только после этого запускать на реальных данных
ЧАСТЬ B — если прямой анализ неизбежен (оригинальный промпт авторов)
ШАГ 1: Разбить задачу на единицы (один класс = одна единица)
ШАГ 2: Каждую единицу — новому агенту с чистым контекстом
ШАГ 3: В промпте: «не уверен — пометь UNRESOLVED, не угадывай»
ШАГ 4: Сверить результат с эталоном вне модели
Пример применения
Метод сильнее всего там, где результат можно проверить на заведомо известных примерах: сверки, парсинг, выгрузки, подсчёты. Он слабее там, где «правильный ответ» субъективен (тон текста, креатив): эталон для них не построить.
Задача: Финансовый менеджер селлера на Ozon получил выгрузку отчёта о реализации на 30 000 строк и выгрузку из 1С. Нужно найти расхождения по сумме. Если просто отправить обе таблицы в чат с вопросом «найди расхождения», модель выдаст правдоподобный список. Но часть расхождений она пропустит, а часть выдумает. Ты этого не заметишь.
Промпт:
Я сверяю отчёт о реализации Ozon (файл ozon.xlsx) с выгрузкой из 1С (файл 1c.xlsx).
Не анализируй данные сам. Напиши Python-скрипт reconcile.py, который:
— сопоставляет строки по номеру отправления;
— выводит расхождения по сумме, пропуски в одной из таблиц и дубли;
— сохраняет результат в mismatches.xlsx.
Затем сделай тестовый набор, в котором ответ известен заранее:
— 20 строк, где всё совпадает;
— 5 строк с расхождением в сумме (включая копейки и отрицательные суммы — возвраты);
— 3 строки, которые есть только в Ozon;
— 3 строки, которые есть только в 1С;
— 2 дубля.
Напиши заранее, какой результат должен получиться на тестовом наборе.
Запусти скрипт на тестовом наборе и покажи, совпадает ли результат с ожидаемым ровно.
Если нет — исправь скрипт и повтори.
Если какое-то правило сопоставления тебе неясно — не угадывай, а задай мне вопрос.
Только после точного совпадения запускай на реальных файлах.
Результат: Модель сначала выдаст скрипт и тестовый набор с ожидаемым ответом. Затем покажет прогон: что нашёл скрипт и что должно было получиться. Если есть расхождения, она их поправит и повторит. На реальных файлах получится таблица расхождений, которую выдал проверенный код, а не «взгляд» модели. Дополнительно возьми 10–20 расхождений из итога и проверь вручную.
Почему это работает
Слабость модели. Когда модель читает данные сама, она склонна выдавать согласованную картину. Мелкие ошибки (перепутанный тип, пропущенная строка, сдвиг номеров) не ломают общую связность и поэтому не заметны. Одна ранняя ошибка тихо портит всё, что от неё зависит. Проверка «на реальных данных вроде работает» тут ненадёжна: ошибки прячутся в редких случаях, которые реальные данные почти не задевают.
Сильная сторона. Писать код по понятной спецификации модель умеет хорошо. Инструмент детерминирован: на одних и тех же входных данных он даёт один и тот же результат, и его можно проверить. Авторы получили инструмент в 21 000 строк с тестами, написанный целиком моделью. Он дал результат, идентичный эталонному, и отработал за пару минут без обращений к модели.
Как метод обходит слабость. Он переносит доверие с модели на проверку. Вы не верите модели, вы верите совпадению с эталоном. Чем независимее эталон от самой модели, тем надёжнее проверка.
Рычаги: - Эталоны. Чем больше редких и крайних случаев в тестах, тем меньше шансов пропустить скрытые ошибки: ошибки сидят именно там. - Единица задачи. Меньше единица, чище контекст у агента. Один агент на всё провалился: он останавливался, не дойдя до большей части вложенных структур, возможно из-за переполнения контекста. - Разрешение сказать «не знаю». Явная пометка вместо догадки снижает число выдуманных значений. - Независимые источники правды. Сверка с ранее опубликованными результатами и реальными измерениями ловит то, что тесты не видят.
Шаблон промпта
A. Оригинальный промпт для агента по одной единице (по описанию авторов). Полные тексты промптов авторов лежат в их репозитории на GitHub. В статье описана логика, ниже она переведена в шаблон.
Ты разбираешь одну единицу задачи: {единица}.
Источник: {источник_данных}. Доступны только эти инструменты: {инструменты}.
Внешние подсказки, готовые ответы и поиск в интернете недоступны.
Для этой единицы восстанови: {что_восстановить_по_каждому_элементу}.
Если элемент ссылается на другую единицу — не разбирай её сам,
а верни ссылку на неё в списке «следующие единицы».
Если из источника что-то НЕ видно — пометь как
// UNRESOLVED: <причина>
Не угадывай и не придумывай.
Если элемент по своей природе простой ({простой_тип}) — оставь его простым,
не выдумывай для него сложный тип.
Верни: список элементов + список «следующие единицы».
Оркестрация: каждую единицу из списка «следующие единицы» вы отдаёте новому чату или новому агенту с этим же шаблоном. Ведёте список уже разобранных единиц, чтобы не повторять работу. В статье это делал Python-скрипт. В обычной работе можно вести общий список вручную или попросить агента с субагентами (например, Claude Code) вести его.
B. Адаптация: Toolmaker-запрос (по духу вывода статьи).
Задача: {задача_анализа}. Данные: {описание_данных}.
Не анализируй данные напрямую. Напиши инструмент: {язык_и_формат}, который {что_делает_инструмент}.
Проверка:
1. Построй тестовый набор с заранее известным ответом: {типы_случаев},
включая редкие и крайние случаи: {крайние_случаи}.
2. Сначала напиши ожидаемый результат, потом запусти инструмент.
3. Требуй точного совпадения. Если нет — исправь и повтори.
4. Если спецификация неясна — задай вопрос, не угадывай.
5. Только после совпадения запусти на реальных данных и дай мне
10 случайных результатов для ручной проверки.
Подставляйте: {задача_анализа} — что нужно получить, {описание_данных} — формат и размер, {крайние_случаи} — редкие ситуации в ваших данных (возвраты, пустые поля, дубли, нестандартные кодировки).
🚀 Быстрый старт — вставь в чат:
Вот шаблон Toolmaker-подхода. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие у тебя данные, какой результат нужен и какие редкие случаи бывают, потому что без них не построить тестовый набор с известным ответом. Она возьмёт структуру из шаблона и соберёт готовый промпт под твою задачу.
Что показали цифры
- Две модели восстанавливали схемы 17 сообщений (около 7 800 полей). Claude не справился с 1 069 полями, Codex с 1 980. Многие ошибки не были видны.
- На полях, которые встречаются в реальном трафике, точность 94–96%, на всех полях схемы 74–86%. Тест на реальных данных пропустил бы почти 90% ошибочных полей.
- Один агент на всю задачу: правильно 8,9% полей. Свежий агент на каждую единицу: заметно лучше, но дорого.
- Подход «агент на каждую единицу» потребовал около пяти суток и миллионы токенов. Инструмент справился примерно за 2 минуты без вызовов модели.
Ограничения
⚠️ Эталоны не бесплатны: Проверка инструмента требует независимого источника правды. Авторы построили эталоны в ходе собственного ручного реверс-инжиниринга. Если эталон нечем получить, подход теряет главную опору.
⚠️ Одна область: Эксперимент проведён на одной задаче: восстановление схем из бинарных файлов Apple. Перенос на ваши задачи (сверки, парсинг, выгрузки) — логичный вывод, но в статье он отдельно не проверялся.
⚠️ Субъективные критерии: Если у результата нет проверяемого правильного ответа (стиль, креатив, оценка идей), эталон не построить, и метод не поможет.
⚠️ Прямой анализ дорог и ненадёжен: Если всё же прогонять модель по большому объёму, это дорого по токенам. Один агент на весь объём почти полностью провалился.
⚠️ Тест на реальных данных обманывает: «Прогнал на живых данных, вроде работает» не доказывает корректность. Ошибки прячутся в редких случаях, которых в реальных данных мало.
⚠️ Неполный текст: Описание самого инструмента и его проверки в доступной версии обрезано, часть деталей не видна.
Ресурсы
- Decoding What iOS Location Services Send to Apple: An LLM Is an Unreliable Analyst but a Useful Toolmaker — D. J. Leith, Trinity College Dublin, Ireland.
- Инструмент (Extractor) и ios_decoder: https://github.com/doug-leith/ios-protobufdecoding
- Данные ИИ-анализа, включая использованные промпты, и сетевые измерения: https://github.com/doug-leith/ioslocation-services-study-data
