Комментарии 73
Агент - это система, которая самостоятельно ставит цели, планирует, действует с помощью инструментов и оценивает результаты. Странно, что агент был такой глупенький, что забыл название проекта. Может это не агент, а чат с расширенной rag-системой? Это же база для построения агентов, и этого всё и начинается.
Формально — да, это не агент в академическом смысле. Это чат с памятью. Но давайте честно: 90% того, что сейчас называют «агентами» — это чат с инструментами. Я использую термин так, как его использует индустрия, а не учебник. А суть статьи — не в терминологии, а в архитектуре памяти. Она работает одинаково, назови хоть агентом, хоть RAG-ом, хоть Василием
Большинство всё-таки называют агентами Василича, который берет задачу, пишет код, запускает его, фиксит ошибки и коммитит. Если бы это была разровая статья - ок, но вы вроде как решили глубоко нырнуть в тему, хотелось бы в тележке получать годноту ;)
Я рекомендую вам сесть и написать агента руками - окажется что это всё тот-же чат (LLM) с инструментами и не более того
Спасибо за рекомендацию, садился, писал. Правда начал с памяти, потому что сразу понимал ограничения контекстного окна. Запуск кода, чтение ошибок и коммит - это интсрументы агента, все они бессмысленны без качественно составленного промпта. А промт - это и есть грамотное использование "памяти", с которой всё и должно начинаться.
Чат - это способ взаимодействия с ллм, когда вы скидываете несколько сообщений, в промежутках получая ответ, что формирует контекст. для следующих ответов. Не имеет смысла писать агентов на основе чатов, под капотом всё равно обработка одного запроса с заранее сформированым контекстом.
Тогда не понимаю ваш комментарий к посту, раз вы в курсе что для LLM всегда есть один запрос - один ответ и нет никакой истории, есть только аккуратно составленный запрос (контекст)
Посмотрите, как пост начинается
Три месяца назад я наблюдал, как мой агент на Llama 3.1 8B в третий раз спрашивает, как меня зовут.
Я представился в первом сообщении. Двести сообщений назад...
Агент забыл. Не потому что тупой. Потому что контекст переполнился и начало разговора уехало в никуда.
По мне это признаки не агента, который на каждое действие получает четкую инструкцию, а чата с ллм.
Зачем это нужно, когда тебе буквально иногда нужно поменять чат и очистить контекст, чтобы агент начал лучше работать
Очистить контекст — это как перезагрузить компьютер, когда тормозит. Помогает, только ты теряешь всё. Через неделю работы над проектом «поменять чат» — это потерять неделю контекста. Внешняя память, как раз, чтобы этого не делать.
@Oldweedkeeper написал про другую ситуацию, которая требует очистки контекста и нового чата. Если длительное время общаться с моделью, и при этом у модели возникла проблема с пониманием, она начинает галлюцинировать и фантазировать вместо нормальных ответов. Это периодически происходит по разным причинам, например, модель была недостаточно обучена на нужных в проекте примерах кода, или код при обучении был для другой версии, или код был другого стиля, или когда в вашем коде больше двух косвенно связанных ошибок, или контекст модели переполнили противоречивой информацией. Вы можете наблюдать это, когда агент модели начинает совершать совсем глупые логические ошибки, или начинает забивать код огромными кусками копипасты, или начинает странные правки и их отмены, или начинает вырезать без спроса важные непонятные ему куски кода, или начинает править в куче разных мест, хотя явно просили этого не делать, или начинает выдавать очень длинные рассуждения, где спорит сам с собой о приоритетах в немного противоречивых вещах, в которых запустался.
P.S.: Это не только про ту ситуацию, когда вы принудитлеьно очищаете старую память старше месяца. Таких ситуаций намного больше.
Добрый день!
А почему сделали свое решение с командами, а не воспользовались стандартным механизмом tools для LLM?
Из современных его поддерживающих локально могу выделить например Ministral 3B (да и вроде вся серия, но 3B руками пробовал)
Так много вопросов и так мало ответов... В целом если вопросы обобщить в один, то интересно зачем автор придумал RAG🤔
P.S в целом статья интересная и что-то полезное можно подчерпнуть
Не придумал. Взял стандартный RAG и разделил на три хранилища под разные паттерны доступа. Классический RAG — это «запихни всё в векторную базу и ищи». У меня факты отдельно, семантика отдельно, документы отдельно.
А что если у меня семантика хранится как документ? Т.е. у меня есть папка /decision_records/ , внутри которой я храню ISODATE_dbms_selection.md , ISODATE_language_selection.md , и так далее.
Нужно ли мне загрузить (продублировать) эти документы в векторную базу данных?
Стоит посмотреть на neo4j. И таки да, не понятно зачем писать свой велосипед, если есть mcp, через который можно цеплять тулы , в том числе и тулы для реализации памяти.
Ваш подход вполне правильный, и с взрослыми моделями работает весьма хорошо. Вместо файлов можно использовать Конфлюенс, а в инструкциях можно написать протокол работы подразумевающий регулярные обращения к внешним источникам при помощи mcp. Neo4j шикарно подходит для ведения индекса и отношений вроде "этот репозиторий относится к проекту такому-то, документация проекта там-то, страница описывающая api имеет такой то id"
Также рекомендую ознакомиться с spec подходом, это подразумевает как раз директории с md файлами, описывающими задачу, план ее решения, ограничения и прогресс выполнения. Эта механика нужна ради фокусировки на определенной задаче и возможности продолжить выполнение задачи даже если пришлось почистить контекст.
Вероятно вам стоит посмотреть на opencode, его можно подружить с ollama и mcp. И реализовать вашу схему без написания своей обертки.
Спасибо за статью, было любопытно.
spec подход хорош. В kiro , например, по дефолту. Но там очень маленькое окошко контекста в сессии. Механизм такой, что при приближении к порогу, сессия автоматически суммаризируется и отправляется в новое окно сессии. И тут часто начинается трэш. (Впрочем прерваться выполнение может и непредсказуемо)
Частично решил инструкцией в steering - в добавление к встроенному механизму чекпоинтов, приказ вести отдельный md файл для текущей сессии - где при получении промпта составить тасклист для него и при каждом действии обновлять его до и после действия.
Это спасает до того момента, пока он не начинает игнорировать эту steering инструкцию. Впрочем, можно его в это тыкать носом в каждом промпте,, хотя это и претит самой сути автоматизации.
Хороший вопрос. Tools, тут правильный путь, согласен. Делал на командах, потому что не все локальные модели на 8B адекватно работают с tool calling, галлюцинируют JSON, путают схемы. Текстовые команды в квадратных скобках парсятся надёжнее на слабых моделях. Но если модель тянет tools нормально, то конечно, лучше через них.
Текстовые команды в квадратных скобках парсятся надёжнее на слабых моделях. Но если модель тянет tools нормально, то конечно, лучше через них.
Понятно, спасибо!
1. Я все-таки рекомендую перейти не более современные варианты типа Ministral 8B - потому что современные модели ну явно лучше обрабатывают запросы, Lllama 8B ну совсем устарела (Хотя, если у вас какой-то тюн, очень подходящий под ваши задачи, предложение, конечно, неуместно)
2. А вы как-то оптимизируете контекст после запроса "read" и прочего? Потому что tools это, конечно, правильно, но долго + засоряет контекст. Если есть какой-то вариант - возможно, ваш собственный - менеджмента контекста без того, чтобы плодить допсообщения - было бы интересно ознакомиться. Если есть возможность, было бы вообще приятно увидеть код на Github.
А, и еще - если вдруг будете публиковать (да и может, для себя лично) - я бы переделал Redis тупо на локальный JSON-файл. У вас вроде фактов не тонна, доступ к файлу - миллисекунды, а зависимость убирает очень хорошо (я бы вот Докер рядом ради такой маленькой функциональности не поднимал).
Либо SQLite. Тоже быстро и тоже убирает зависимость.
Вот про JSON плюсую неистово, зависимость от Redis делает этот скрипт непереносимым, а JSON можно в Git положить и версионировать вместе с кодом
галлюцинируют JSON, путают схемы
Библиотеки для работы с ллмками давно умеют выбирать токены так, чтобы результат гарантировано соответствовал заданной формальной грамматике, в частности, json-схеме
Интересный момент, langchaingo не опирается на возможность модели звать тулы, он делает почти как вы - инструктирует модель как именно звать тулы, и ждет что модель просто родит строку с названием тула и аргументами.)
Mistral nemo 12b вполне неплохо работает в таком сценарии, особенно переученный "вихрь". Но, все равно это весьма уступает взрослым моделям в облаке, по этому локальные приколы кажутся скорее баловством для души, чем реально применимыми инструментами.
для работы с json по схеме следует использовать instructor
Да, такая вариация RAG с разделением памяти по разным типам вполне рабочий способ, чтобы контекст в сторону не уплывал, но для ответа подтягивал нужное.
Я в своем франкенштейне делал примерно так же:
Redis для conversation context - последние 20
Qdrant и PostgreSQL для долгосрочной памяти и поиска релевантных текущему запросу
Какая модель, если не секрет
32К токенов это вообще ни о чём, если нормально поработать день
У меня такое работает, называется банк памяти проектов. Данные хранятся в векторной базе, потом они извлекаются по запросу, reranker их оптимизирует, конечная llm после анализа дает красивый ответ. 32к для контекста - это крайне мало, даже ответ из rag не уместится.
Мой локальный агент помнит проект лучше меня
Примите мои соболезнования. Проблемы с памятью — это совсем не весело...
А зачем использовать Redis, если, судя по “API”, хватит обычного JSON словаря?
Ещё не понимаю, к чему модели знать имя разработчика. Для коммитов?
Ну надо ж его как-то звать. Не Шершавый Кабан же!
Доступ к внешней памяти - это входные токены и опять забитый контекст и все по кругу. Вы не пробовали Claude MCP + RAG через ChromaDB/Qdrant , как они советуют? Раз уж вы с ним работали. Интересно есть ли жизнь там)
Да все что написано можно обернуть в mcp и использовать , плюсом все файлы тоже бросить в симантику
А вы не пробовали именно через MCP claude пользоваться?
По идее у claude есть транскрипты , которые если попросить она отдаст. Там хранится вся история сообщений. Т.е. я предполагаю, внутри оно с этим транскриптом и работает через RAG какой-то внутренний, у меня эти транскрипты вообще иногда гигантские, и оно как-то ищет в них. Врядли там примитивный Ctrl-F.
Но для документации claude сам советует подключить MCP RAG . Правда не понимаю зачем этот внешний костыль через MCP, неужели нельзя было внутри это сделать, чтобы оно само индексировало и пользовалось.
Ну да, лишняя нагрузка небольшая, но это лучше чем пользователь заливает документацию под все контекстное окно .
Но тут конечно еще не понятно, что оно по токенам будет.
Или загрузить все нужное один раз прямо в контекст. Или постоянно дергать те базы данных через RAG, по сути все равно, сам RAG не панацея, он просто ищет, а потом в контекст снова летит кусок текста ...
И вот от того, как часто модель будет обращаться к этой информации зависит почти все. Тут надо еще как-то еще обучить что можно искать , а что нет и когда.
Claude любит самодеятельность и быстро засирает контекст, если его не остановить.
Иногда игнорирует инструкции и отвечает сразу.
Это вы про агента, которого реализовали? Это свойственно любой LLM, хотелось бы видеть агента, который решил эту проблему
Интересная идея.
Мне кажется, ещё можно некоторые заметки делать самому - то есть, должно быть место, где вы пишете для него заметки сами, а он читает также как остальную "память".
Добавь все инструменты в mcp и будет агент сам ходить писать и читать
Есть методы сжатия. Вооьще аы молодец! Но Америку не открыли, так работает большинство ИИ под капотом.
Я еще разработал свой метод сжати я и метод удержания контекста, сути. На 3В даже с путаными вопросами, там и программирование, и космрс, и за жизнь, 20 вопросов и оно помнит первый контекст при этом все влезло в 8к а не в 32к.
Два варианта сжатия. Первый до 95% общее знания. Второе до 70% хорошо знает код и что в нем. Но надо тестировать еще и тестировать.. Но уже работает хорошо.
У меня просто аналогично сгорел зад, контекст забило га 80к,а толку ноль, ошибок у LLM гора, воды еще больше..
Будет время, надо будет открытый какой переделать. А то горит от них люто, вреда больше чем пользы.. 😁
Это все костыли, иногда работает, иногда нет. Ждем, когда придумают нормальную память для LLM.
По работе с памятью я в конце статьи отчётливо подумал , что по завершении рабочего дня, агент может уходить в сон, в котором он перерабатывает память, проходится по воспоминаниям, что-то убирает, что-то объединяет и упрощает.
https://eu.36kr.com/en/p/3469029114074503 Классно самому доходить до каких-то идей и потом получать подтвержение им
В целом вижу у вас правильный подход. Но интересно вот что:
Когда нужно что-то вспомнить — вы ищете. Не в голове. В заметках.
Я никогда не ищу ничего ни в каких заметках. Я сразу иду в код и смотрю реализацию. И неважно, это проект, над которым я работаю сейчас, над которым я работал 7 лет назад или это проект, который я вижу впервые. Структура любого вменяемого проекта всегда иерархична и логична. Структуры проектов с использованием фреймворков ещё и стандартны к тому же. Поэтому не так уж сложно, зная одну маленькую задачу даже в огромном проекте сразу открыть нужный файл, тупо идя от корня.
Вопрос вот в чём, почему IDE умеет индексировать проект, и скажем, по клику на класс видит его предков и потомков, а ИИ для этого нужно потратить целое ведро токенов? Как бы то ни было, будущее состоит в том чтобы все вот эти агенты работали не с md-шками, а реально отсканированными AST. Грубо говоря, нужен крутой MCP для автоматического разрешения контекста.
Ты рассуждаешь как автор кода или сеньор, который проект наизусть знает, а агент это вечный джун, который проект видит первый раз. Ему нужно ведро токенов, чтобы построить ментальную модель, которая у тебя в голове годами копилась
а реально отсканированными AST. Грубо говоря, нужен крутой MCP для автоматического разрешения контекста.
мне кажется JetBrains или ещё пара около компилиторных/ide'шных компаний могут что-то такое сделать
вроде Cursor у себя похожее делал
Все только и говорят про агенты. А что насчет ассистентов? Что если я не хочу что бы ии онлайн работал по принципу "вот тебе задача, работай". Вместо этого я хочу что бы он смотрел что я уже написал, искал в этом смысл и ошибки, делал предложения что написать дальше или переписать уже написанное
У Вас реально Llama 3.1 8B выдает что-то полезное, да ещё и в кодинге? Не маловата и не старовата ли моделька..? Тут посмотришь, самые свежие модельки даже на 30B не сильно блещут умом...
Тут есть важный нюанс, человеку, который никогда не писал код, может быть сложно составить правильный запрос для ИИ.
В то же время, те, кто уже имел опыт и без ИИ ранее, смогут справиться с этой задачей легче. Даже на моделях начального уровня можно эффективно писать код, если чётко формулировать запрос.
Использование правильного агента с правильной моделью решает многие проблемы. Например, Claude code имеет историю своих сессий по задаче и может к ней возвращаться по необходимости. Если делать отдельный rag памяти агента, то ему из него достаточно вернуть "сырые" данные, которые успешно сформирует rag система без использования мощной llm. Для этого достаточно эмбидинговой и реранкер моделей, llm модель здесь не нужна, так как сам агент ее имеет по умолчанию.
Все это здорово, пока факты в Redis не начнут противоречить векторам в Chroma. Агент записал "юзаем питон", а в старых доках "юзаем го", и тут 8-ми миллиардная модель словит шизофрению, пытаясь понять, кто прав - база или кэш
Механизм инвалидации знаний - вот где настоящая засада, а не в поиске
Полностью согласен, хранить и искать гораздо проще. При интенсивной разработке с LLM инструментами зачастую огромная часть информации просто теряет актуальность, так и не смог придумать грамотный инструмент для инвалидации памяти/базы знаний. Пока спасает только общий контекст в голове и привычка вызывать тригеры на инвалидацию руками.
Разве эта фича не предлагается в виде плагинов для всех Cline/Roo кодов и тп?
Некоторые плагины вообще целиком индексируют кодовую базу нативно.
Я какое-то время пользовался памятью, в итоге понял, что от нее больше вреда, чем пользы, такой вид поиска не способен на самом деле понять контекст того, чем вы заняли. Поэтому, как только появляется малейшее легаси, ветвится функционал, появляются устаревшие описания, - все это одним скопом летит к модели и она весело крутя хвостиком переосмысляет, как работает проект.
Все же лучше потратить время, воспользоваться своей, человеческой памятью и скормить модели только то, что нужно и не каплей больше. А то человеческий мозг такая штука, утомишься, не вчитаешься, а потом тебе будет лень разбираться со всей ерундой, что ты натворил с помощью ИИ.
Несколько агентов пишут в общую базу. Учатся на опыте друг друга. Там должны быть интересные эмерджентные эффекты.
Ну да, ну да, как же :)
Эффектом будет засорение контекста друг друга. Без самоадаптации самой модели (изменения весов "нейронов"), всё это костыли.
А зачем всё это если тот же Cursor при наличии документации/заметок в репозитории на каждую новую таску первым делом grep'ает консольной командой по ключевым словам, находит и читает всё контекстное задаче?
Если это работает также как написано, то это то что я хотел реализовать очень давно, но не понимал как сделать доменную сортировку данных. По факту надо разрабатывать сложные смысловые формулы, для эффективного поиска. Советую почитать технологии на arxive, там море концепций. Большое спасибо за статью. Хейт всегда будет, и будет знание. Эмбединг лучше взять от сбербанка, он для русского языка самый лучший. А также взять реранкер для смыслового поиска. Контролировать поведение можно через ретраи, пока llm не будет писать нужную метку.
Оч круто, начал читать и сразу подумал что так и надо делать пара вопросов а) почему не MCP? б) а нормально вообще агенты работают без поисковика (подмешивания результатов в контекст)? Я сейчас с джемини подружился, такое ощущение что именно поиск дает прям буст серьезный ко всему вообще - и актуальные версии библиотек, и точность ответов - как без поиска это все работало бы непонятно.
Что-то похожее хотел реализовать. Единственная проблема - бот ведь генерирует команды, потом ждёт выполнения команды, а потом уже ему нужно второй запрос сделать с этим новым контекстом. И получается на один запрос от юзера, тратится как минимум 2 ответа нейронки. Всё правильно понимаю?
Статья с объяснением алгоритмов и кодом? Такое мы читаем
Наверняка есть подходы, о которых я не знаю.
Если я правильно понимаю, то речь идет о переходе от классического RAG с векторным хранилищем к GraphRAG и Self-RAG с дальнейшим развитием до Agentic RAG и прогрессом до идей MemGPT (разделение памяти по слоям). Но вряд ли можно сделать добротную послойку с маленькой 8B-моделью. Но некоторые идеи можно почерпнуть.
Например, если разделять хранилища для роя агентов, то можно добавить уровней:
Шаг - этап задачи.
Задача - что сейчас делается с проектом.
Проект - состояние, особенности, планы.
Общее - знания о пользователе, правилах поведения и других вещах, актуальных для каждого проекта.
Обмен - беседа с соседними агентами для координации (необязательно).
Долговременные "проект" и "общее" желательно снабдить несколькими автономными агентами для поддержания порядка (от консолидации до конфабуляции). Хотя, как лично мне кажется, это всё же место для причесывания вручную, мелкие агенты не вытягивают релевантность и связность.
Плюс можно "обмен" разделить на "сейчас", "день" и "постоянно", это будет красиво, но вряд ли практично, даже если агентов лишь несколько. Но, если я правильно понимаю, в статье речь вообще не о практичности, а о личном интересе.
Год назад пользовался Context Portal с кучей инструкций. Для Cursor других вариантов и не было особо. На RooCode это стало чуть удобней, особенно когда появился MCP conport. Но все равно пачка режимов и сидишь тыкаешь их.
А потом, с появлением Claude Code подумал, слишком много телодвижений при работе с несколькими проектами. В итоге написал API, под капот засунул эмбеддинг, прикрутил поиск. Переписал MCP (очень жирный по токена был) на навык + bash скрипт с curl запросами, добавил хуков, чтобы само работало.
С появлением Tool search снова переписал на MCP и сильно расширил функционал - помимо лога работы добавил решения, таски, хранение документов, стек проекта, связь с дочерними проектами.
Плюс, прикрутил морду, чтобы, лёжа вечером под одеялком, накидывать таски на завтра.
А утром можно сказать - сделай задачки и пойти завтракать. Дальше без меня разберутся.
Единственное, что пока автоматизировать не могу - "не знаешь - используй поиск", вот упорно сопротивляется
Попробуйте ставить временные метки на запись/чтение + Частота обращений к каждой информации в памяти, и задать правила когда информация становится не нужной
Да как идея мне понравилось, столкнулся с проблемой версий, через какое-то время однажды выбранное решение затирается новыми версиями и вдруг ты не можешь найти ту самую рабочую. А LLM теряется в огромном контексте и начинает перебор решений заново. Хочется маркировка, вот это решение предварительно хорошее, запомни, мы попробуем еще другие если что вернёмся на эту или выберем из нескольких хороших.
Рекомендую заменить Llama 3.1 на qwen 3. Отлично понимает русский и самое главное правильно следует инструкциям выдавая верный json, что в вашем случае не делала liama, ну и промт для модели лучше переводить на английский.

Мой локальный агент помнит проект лучше меня. Контекст — 32K токенов. Расскажу, как