ФОРС – Центр разработки
Москва, Трифоновский тупик, д. 3
Москва, Графский переулок, д. 14, корп. 2
Новости и события
В ходе работы над одним из наших проектов встала задача разобраться , как в существующей системе загружаются данные в несколько сотен таблиц — какие-то совсем простые, какие-то сложные. И все процессы образуют длинные цепочки из более двух десятков таблиц: данные из источника загружаются в таблицу, потом преобразуются и загружаются в следующую, преобразуются и загружаются в следующую, преобразуются и загружаются в следующую… И чтобы было не слишком скучно, все имена таблиц и полей — это коды, а не привычные имена.
Документации на все загрузки нет, спросить не у кого. Единственное, что остаётся — это брать имеющиеся процессы и делать их реверс-инжиниринг и реализацию на новой платформе.
В такой ситуации LLM инструменты (Claude в нашем случае, но всё описанное применимо и к, например, Codex) сияют в полный рост. Есть большой массив текста — исходных кодов на одном языке, надо сделать новый массив текста — новых исходных кодов на другом языке. Large Language Models буквально созданы для этого.
Естественно, если бы это была задача уровня «Claude, сделай хорошо и положи результат туда, а я пока кофе попью», я бы не писал сейчас эту статью. А, может, писал бы, но с другой подводкой. И даже в такой ситуации требуется непрерывно проверять и контролировать, что делается, как делается, принимать решения о том, по какому пути идёт процесс. Будущее наступило, но пока не полностью.
И раз уж поручить агенту всю работу не получится и надо управлять результатом, то приходится как-то отслеживать три существенных момента:
Мы говорим про более чем тысячу шагов перекладки данных и эти процессы не линейные. Из таблицы A данные попадают в таблицу B, из B в C и D, C объединяется с E из другой цепочки, потом результат объединения фильтруется и загружается в…(см. Рис. 1)
Каждая стрелочка — это какой-то процесс обработки, и каждым из них могут заниматься разные люди. Думаю, тут проблема понятна — нужен инструмент для отслеживания зависимостей и статусов.
Со статусами можно было бы решить эту проблему вручную — завести в SVN или в Confluence файлик или страничку, куда записывать эту информацию. Это возможно, но любой, кто этим хоть раз занимался, сразу увидит проблему — подавляющее большинство людей не любит писать такие статусы и еще меньше любит их читать. Это вопрос только времени, когда статус начнёт отличаться от реальной жизни настолько, что его все начнут игнорировать. Нужно что-то настолько простое, чтобы поддержание его в актуальном состоянии не выглядело задачей, которую всегда хочется отложить на потом.
С отслеживанием зависимостей проблема другого характера. Сделали файл в Excel, который показывает, какая таблица зависит от какой.
У этого способа есть как свои плюсы (простота хранения и обмена), так и свои минусы. Самый неприятный минус в том, что проследить все цепочки загрузки в некоторые таблицы очень тяжело. Фильтруем таблицу по получателю, который нам нужен. Потом добавляем в фильтр все его источники, чтобы узнать источники второго порядка. И потом их источники. Иногда это занимает непростительно много времени. А потом одно неловкое действие, и все фильтры сбросились.
Для понимания, мы говорим о цепочках примерно такого размера:
И у каждой цепочки свой статус и свой владелец и свои проблемы.
Естественно, это не все сложности и проблемы проекта. Я попытался рассказать, какие именно из них мы пытались решить при помощи MCP инструментов.
Любой, кто использовал LLM через клиенты (Claude Code, Codex и так далее), а не в виде чата в браузере, уже знаком с работой этих инструментов. В каждом из них уже присутствуют десятки, если не сотни других встроенных инструментов, которые могут выполнять различные действия. Они могут быть как очень простыми типа выполнения команд операционной системы, так и более сложными типа доступа к почтовому клиенту, мессенджерам, внешним облачным системам и так далее.
Когда мы просим LLM прочитать или записать локальный файл, поискать информацию в интернете, и тому подобное, клиент обращается к соответствующим инструментам.
И хорошая новость состоит в том, что мы можем очень легко добавлять свои собственные инструменты. Еще одна хорошая новость состоит в том, что это не проприетарная технология одного из вендоров, а открытый стандарт. Инструменты, которые сделаны для одного клиента, могут быть перенесены и использованы в другом клиенте, хотя процесс их подключения и настройки может немного различаться.
Я не буду пытаться переписать сюда всю документацию или давать полностью рабочее финальное решение и просто постараюсь описать основные моменты, чтобы было понятно, что это за технология, какие задачи с её помощью можно решать, какие преимущества она дает.
MCP инструмент (MCP — Model Context Protocol), упрощая — это процесс, который умеет общаться с агентом. Язык, на котором реализован этот процесс, совершенно не важен, важно чтобы он понимал и реагировал на три основные типа сообщений:
Например, для отслеживания статусов реализации процессов нам бы очень хотелось иметь возможность делать следующие вещи: записывать текущий статус в реестр и считывать текущий статус из реестра. А чтобы сделать процесс более гибким, неплохо бы уметь добавлять комментарии без изменения статуса и еще получать список разрешенных статусов, чтобы разные агенты не начали изобретать свои.
Дальше реестры статусов надо как-то хранить и синхронизировать между разными людьми. Желательно, чтобы можно было отследить историю изменений. Тут можно придумать разные варианты, можно использовать настоящую базу данных типа Postgres и писать в неё. Можно завести какой-нибудь файл и сохранять его в системе контроля версий. Я сделал папку в системе контроля версий, для каждой таблицы один yaml файл, в котором есть все необходимые поля.
object: "A"
pg_object: "tbl_a"
status: "finished"
owner: "andrew"
claimed_at: "2026-06-25T16:20:39+03:00"
notes:
- "таблица - источник для цепочки данных о …"
- "код построен на основе SAP"
- "результат не проверялся на реальных данных"
Такие файлы легко читаются и пишутся, они хорошо версионируются, по ним можно автоматически строить статистику. Иными словами, YAML это стильно, модно, молодёжно.
Ладно, может не очень молодёжно, но два из трёх — это тоже неплохо.
Оба инструмента написаны на Python, потому что Python это тоже стильно и модно. А еще потому, что это язык, на котором я могу не только читать без словаря, но и писать. Но об этом позже.
Ведение истории и координация между несколькими исполнителями держится на SVN. Перед чтением скрипт делает svn update, чтобы видеть актуальное состояние. При записи: lock (если файл существует) → запись файла → add (если файл новый) → commit. Так несколько человек работают с одним реестром, не мешая друг другу. Если бы в процессе участвовали десятки человек, и они выбирали бы объекты для работы случайным образом, то это могло бы оказаться «узким» местом, но в нашем случае проблемы нет.
Отслеживание цепочек загрузки — это просто скрипт, который читает Excel файл с зависимостями. Необходимо найти источники таблицы, потом найти источники источников и так продолжать до тех пор, пока не придём к таблицам, у которых нет источников. Затем следует вернуть всю цепочку. Это простейшая задача на десять минут кодинга и отладки.
Прелесть работы с этим состоит в том, что интерфейс — это просто чат с моделью. Когда человек хочет узнать статус по конкретной таблице, то он не идёт искать файл среди сотен похожих. Когда хочется увидеть цепочку загрузки, не надо сидеть в Excel и фильтровать таблицу. Достаточно просто спросить у LLM:
Видно, что для ответа на этот вопрос были использованы инструменты (Used 2 tools). LLM для ответа на вопрос обратилась к инструменту, инструмент прочитал Excel файл и нашел предков нужной таблицы, потом предков предков, и так далее.
Можно комбинировать инструменты для выполнения более комплексных задач.
Один инструмент прочитал Excel файл со списком зависимостей, другой — выполнил svn update, потом нашел нужные файлы ([a-f].yaml), прочитал их по полям и вернул ответ.
Фиксация результата работы — это просто короткое сообщение в чате. Я ни на что не намекаю, но иногда хочется описать результат (особенно негативный) эмоционально и нажать enter, но не хочется, чтобы это кто-то потом прочитал именно в том виде, как оно было написано.
Наверно, можно было бы достичь того же или близкого результата и без кастомных инструментов. Можно проинструктировать LLM писать и читать файлы в определённой папке. Описать их формат. Сказать выполнять команды svn update и svn add|commit. И это бы даже работало. Но помимо потери дешевизны и скорости работы инструментов (сотни токенов и десятки секунд), приходилось бы постоянно надеяться, что LLM не придумает свой собственный статус или формат, что она не решит, что можно вообще ничего и не читать из файла, а просто придумать. Или что можно удалить все файлы в svn просто потому что, почему бы и нет. И когда будет поймана на этом, то просто извинится.
Таким образом, можно делать инструменты, которые могут работать с какими-то системами без того, чтобы давать им полный доступ к этим системам. Например, если надо чтобы LLM читала данные из какой-то БД, то не надо давать ей логин и пароль в базу. Можно сделать инструмент, который будет принимать на вход название таблицы и параметры, проверять, что там нет SQL-инъекций и DDL, читать таблицу, возвращая данные в LLM.
Делать свои инструменты проще, чем кажется. Особенно учитывая то, что у нас в руках инструмент, который может писать код по спецификации. Я не писал всё сам. Я придумал, что такой инструмент должен делать и как работать. А потом объяснил это LLM. Осталось только проверить, что результат соответствует ожиданиям. И да, он полностью соответствует.
Москва, Трифоновский тупик, д. 3
Москва, Графский переулок, д. 14, корп. 2
Москва, Графский переулок, д. 14, корп. 2
Москва, ул. Авиамоторная, д. 8, стр. 12, 5 этаж
Москва, Трифоновский тупик, д. 3
Москва, Графский переулок, д. 14, корп. 2
Москва, Графский переулок, д. 14, корп. 2
Москва, ул. Авиамоторная, д. 8, стр. 12, 5 этаж
Благодарим за ваш запрос.
Мы обязательно
свяжемся с вами!
Благодарим Вас!
Регистрация
прошла успешно.