Реклама
Меморина
Меморина
Меморина

ИИ-агент собрал сам себя: эксперимент с LangChain4j и уроки для Java-разработчиков

ИИ-ассистент по документации LangChain4j собрал клона самого себя — и тот починил реальные баги. Разбираем эксперимент Red Hat и выясняем, почему детерминированный workflow втрое быстрее автономного супервизора.

Обложка: ИИ-агент собрал сам себя: эксперимент с LangChain4j и уроки для Java-разработчиков

Если вы строите агентные системы на Java, вот факт, о котором стоит знать: LLM уже способна по одной документации фреймворка спроектировать и написать мультиагентную систему — по сути, клона самой себя. Инженеры Red Hat Кевин Дюбуа и Марио Фуско провели такой мета-эксперимент с LangChain4j, и получившийся «самособранный» агент не только запустился, но и починил реальные баги в коде, прогнав все 11 тестов. Заодно выяснилось, что детерминированный workflow решает ту же задачу втрое быстрее автономного супервизора — два минуты против шести с лишним.

LangChain4j — это Java-фреймворк для приложений на базе больших языковых моделей, аналог LangChain из мира Python. Его модуль langchain4j-agentic позволяет описывать агентные системы декларативно: прямо в Java-интерфейсах, через аннотации. Эксперимент Дюбуа и Фуско проверял две вещи сразу: достаточно ли «читаем» API фреймворка, чтобы модель использовала его без подсказок, и как ведут себя два главных паттерна агентных систем — supervisor и workflow — на одной и той же задаче отладки кода.

Ключевые выводы

ИИ-ассистент по документации LangChain4j сам спроектировал и реализовал мультиагентного кодера — клона самого себя: супервизор плюс четыре субагента.

Собранная система починила все баги в тестовом классе Calculator: 11 тестов из 11 зелёные, сборка Maven успешна.

Модель gpt-4o провалила задачу, уйдя в цикл вызовов инструментов (сработал лимит в 100 вызовов), а более свежая gpt-5-mini справилась.

Жёсткий workflow-паттерн выполнил ту же задачу за 2 минуты против 6+ минут у supervisor-паттерна: автономная координация через LLM стоит дорого.

Новый интерфейс MonitoredAgent (langchain4j-agentic 1.12.2-beta22) показывает топологию системы и трейс вызовов агентов.

Вайбкодинг агента: промпт, который собрал агента

Идея эксперимента предельно проста: отдать код-ассистенту документацию и исходники LangChain4j и попросить собрать на их основе клона самого себя. Дословно промпт звучал так: «Изучи API и возможности агентного фреймворка LangChain4j по его документации и исходному коду и спроектируй на его основе агентного кодера, который будет клоном тебя самого».

Через несколько минут размышлений ассистент выбрал supervisor-паттерн: главный агент-координатор, который сам решает, какого субагента вызвать и с какими аргументами. Архитектура получилась такой — обратите внимание, вся система описывается одним аннотированным интерфейсом:

			public interface SupervisorCoderSystem {
   @SupervisorAgent(description = """
                   A multi-agent coding assistant that can explore codebases,
                   plan implementations, write/edit code, and run builds/tests.
                   It orchestrates specialized sub-agents to fulfill coding requests.
                   """,
           subAgents = {
               ExplorerAgent.class,
               PlannerAgent.class,
               ImplementerAgent.class,
               ExecutorAgent.class,
       })
   String code(@K(UserRequest.class) String request,
               @K(WorkingDirectory.class) String workingDirectory);
}
		

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

  • ExplorerAgent — изучает кодовую базу (получил инструмент обхода файловой системы);
  • PlannerAgent — составляет план изменений;
  • ImplementerAgent — пишет и правит код (получил редактор кода);
  • ExecutorAgent — компилирует и запускает результат.

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

Проверка боем: агент чинит баги в Calculator

Чтобы испытать собранную систему, авторы пошли от обратного: попросили ассистента написать класс Calculator с четырьмя методами, в каждом из которых спрятан классический баг. Набор получился показательный — такие ошибки джуны делают постоянно:

  • в методе sum() выход за границу списка: цикл до i <= size();
  • в average() целочисленное деление вместо дробного;
  • в max() стартовое значение 0 — ломается на списке из отрицательных чисел;
  • в factorial() цикл до i < n — факториал недосчитан на один множитель.

Дальше ассистент сгенерировал интеграционный тест: скопировать проект с багами во временную папку и натравить на него агентного кодера:

			@Test
void workflow_should_fix_buggy_calculator() throws Exception {
   var coder = CoderAgenticSystem.supervisorCoder(coderModel());

   Path source = Path.of("src/test/resources/buggy-project");
   Path workDir = Path.of("/tmp/buggy-calculator");

   String result = coder.code(
           "The tests are currently failing because Calculator.java has bugs. "
           + "Fix all bugs so all tests pass.",
           workDir.toAbsolutePath().toString());

   assertThat(result).isNotBlank();
}
		

Первая попытка: gpt-4o уходит в цикл

Первый прогон делали на gpt-4o — это модель по умолчанию в LangChain4j, и она поддерживает вызов инструментов. Результат: через несколько минут система упала с ошибкой. LLM застряла в цикле вызовов инструментов, и фреймворк прервал её на лимите в 100 последовательных вызовов:

			dev.langchain4j.agentic.agent.AgentInvocationException:
Failed to invoke agent method: ImplementerAgent.implement(...)
Caused by: java.lang.RuntimeException:
Something is wrong, exceeded 100 sequential tool invocations
		
Полезно знать: лимит в 100 вызовов инструментов подряд — дефолт LangChain4j. Он настраивается методом maxToolCallingRoundTrips() в AiServices, но дефолт вполне разумный: здоровому агенту столько вызовов не нужно, а беззащитный цикл сожжёт бюджет на токены.

Вторая попытка: gpt-5-mini чинит всё

Авторы уже сталкивались с таким поведением у старых моделей, поэтому просто заменили модель на gpt-5-mini — и тот же самый агентный дизайн отработал чисто. Система нашла все четыре бага, переписала методы (for-each вместо индексного цикла, приведение к (double) в среднем, инициализация максимума первым элементом, включительная граница в факториале) и отчиталась:

  • mvn package — BUILD SUCCESS;
  • mvn test — 11 тестов, 0 падений, 0 ошибок;
  • финальный вердикт агента: «All tests in CalculatorTest.java pass (11/11)».

Это важный практический вывод, который часто недооценивают: агентная архитектура неотделима от модели, на которой она работает. Один и тот же дизайн на одной модели захлёбывается в tool-calling цикле, а на другой решает задачу. Прежде чем переписывать оркестрацию, попробуйте сменить модель.

Смотрим под капот: MonitoredAgent

Когда один ИИ собирает другого ИИ, вопрос «а что там внутри происходит» перестаёт быть риторическим. В версии 1.12.2-beta22 модуля langchain4j-agentic появился интерфейс MonitoredAgent: достаточно унаследовать от него корневой интерфейс системы, и фреймворк сам зарегистрирует монитор — можно распечатать отчёт о вызовах агентов и топологию системы:

			public interface SupervisorCoderSystem extends MonitoredAgent {
   @SupervisorAgent(description = "...")
   ...
}
		

По такому отчёту видно, какой агент когда вызывался и как система фактически связана в граф — без ручного сбора листенеров и регистрации AgentMonitor.

Supervisor против workflow: автономия или скорость

Автономность супервизора имеет скрытую цену: каждый шаг координации — это дополнительный вызов LLM, который «придумывает», кого вызвать дальше и с какими аргументами. Чтобы измерить эту цену, авторы попросили ассистента перепроектировать систему в детерминированном виде — только на workflow-паттернах LangChain4j.

Получилась строгая последовательность из пяти шагов: те же четыре роли плюс отдельный SummarizerAgent, который забрал у супервизора функцию финального отчёта. Шаги планирования и исполнения оформлены как циклы с самопроверкой:

			public interface WorkflowCoderSystem extends MonitoredAgent {

   @SequenceAgent(
           description = "A workflow-based coding pipeline: explore, plan "
                   + "(with review loop), implement, execute (with evaluation "
                   + "and refactoring loop), then summarize",
           typedOutputKey = Summary.class,
           subAgents = {
               ExplorerAgent.class,
               PlanReviewLoop.class,
               ImplementerAgent.class,
               ExecutionLoop.class,
               SummarizerAgent.class
           })
   String code(@K(UserRequest.class) String request,
               @K(WorkingDirectory.class) String workingDirectory);
}
		

Цикл исполнения устроен как связка «исполнитель → оценщик → рефактор»: итерации продолжаются, пока оценка качества не достигнет 0.8, но не дольше 5 итераций — защита от бесконечного сжигания токенов:

			public interface ExecutionLoop {

   @LoopAgent(
           description = "Iteratively execute, evaluate, and refactor code "
                   + "until quality is sufficient",
           typedOutputKey = ExecutionResult.class,
           maxIterations = 5,
           subAgents = {ExecutorAgent.class, EvaluatorAgent.class,
                        RefactorAgent.class})
   String executeAndRefine(
           @K(ImplementationResult.class) String implementationResult,
           @K(WorkingDirectory.class) String workingDir);

   @ExitCondition(description = "evaluation score >= 0.8")
   static boolean exit(@K(EvaluationScore.class) double score) {
       return score >= 0.8;
   }
}
		

Та же задача с багами в Calculator — тот же результат: все тесты зелёные, финальная оценка качества 0.8. Но по времени картина разительно другая: две минуты у workflow против более чем шести у supervisor. Втрое быстрее — при большем числе агентов в системе. Вся разница — устранение координационных вызовов LLM: в workflow каждый следующий шаг известен заранее и «мнения» модели на этот счёт не требуется.

Это не означает, что supervisor не нужен. Выбор зависит от природы задачи:

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

Что это значит на практике

Эксперимент Дюбуа и Фуско красиво подтверждает рекомендации, которые Anthropic сформулировала в гайде по эффективным агентам: начинайте с простейшего детерминированного пайплайна и добавляйте автономность только там, где без неё никак. Каждый «свободный» шаг координации — это лишний вызов модели: и по деньгам, и по латентности, и по шансу уйти в цикл. Замер в статье (3x на одной тривиальной задаче) — хорошая иллюстрация того, во что это превращается в проде.

Второй урок — про «вайбкодинг» агентных систем. То, что LLM собрала рабочую мультиагентную систему по документации, говорит больше о качестве API LangChain4j, чем о магии моделей: аннотации @SupervisorAgent, @SequenceAgent и @LoopAgent читаются как обычный декларативный дизайн, и модели это по зубам. Для Java-команд это практический повод присмотреться к фреймворку: порог входа в агентные системы здесь заметно ниже, чем кажется.

И третье: отлаживайте агентов как распределённую систему. Трейс вызовов и топология из MonitoredAgent — это тот же распределённый трейсинг, к которому вы привыкли в микросервисах, только спаны здесь — вызовы LLM. Без него вы не узнаете, что система половину бюджета потратила на «размышления» супервизора.

Часто задаваемые вопросы
1
Что такое LangChain4j?

Java-фреймворк для приложений на базе LLM, аналог LangChain из экосистемы Python. Модуль langchain4j-agentic позволяет описывать агентные системы декларативно — аннотациями в Java-интерфейсах, с поддержкой workflow-паттернов, супервизоров и мониторинга.

2
Чем supervisor-паттерн отличается от workflow?

Supervisor — автономный координатор: LLM на каждом шаге сама решает, какого агента вызвать и с какими аргументами. Workflow — заранее заданная последовательность шагов с циклами самопроверки. В эксперименте workflow оказался втрое быстрее: 2 минуты против 6+, потому что не тратит вызовы модели на координацию.

3
Почему gpt-4o не справилась с задачей?

Модель ушла в бесконечный цикл вызовов инструментов, и LangChain4j прервал её на дефолтном лимите в 100 последовательных вызовов. Тот же агентный дизайн на более свежей gpt-5-mini выполнил задачу успешно: качество tool-calling у современных моделей заметно выше.

4
Можно ли повторить эксперимент самостоятельно?

Да: исходники обеих реализаций (supervisor и workflow) вместе с тестом на багах Calculator выложены в открытый репозиторий mariofusco/langchain4j-agentic-coder на GitHub. Понадобятся JDK, Maven и ключ OpenAI API — модель задаётся в коде теста.

Выводы

Выбирайте workflow, когда критичны скорость, предсказуемость и цена выполнения. Выбирайте supervisor, когда автономность и гибкость важнее скорости — но помните, что свобода координации оплачивается токенами и временем.
Кевин Дюбуа и Марио Фускоинженеры Red Hat, авторы эксперимента

Самособирающийся агент — пока эксперимент, а не продакшн-практика. Но три вывода из него применимы уже сегодня. Первый: хорошо спроектированный декларативный API читаем не только для людей, но и для моделей — и это становится критерием качества фреймворка. Второй: детерминированный workflow на предсказуемых задачах даёт троекратный выигрыш во времени — автономию стоит включать точечно. Третий: агентная система наследует слабости своей модели, поэтому мониторинг и лимиты вызовов — не опция, а необходимость.

Источники: оригинальная статья — The Self-Building Agent: A LangChain4j Experiment (InfoQ); код эксперимента — репозиторий langchain4j-agentic-coder; документация — Agentic Systems в LangChain4j.

Если строите агентные системы на Java — возьмите репозиторий, прогоните тест на своей модели и сравните supervisor с workflow на своих задачах. Цифры могут удивить.