Как я собрал self-improving AI-ассистента за 3 месяца, не зная что такое RAG
По сути я, системный администратор без опыта в ML, собрал работающую систему с 23 компонентами, замкнутым циклом самообучения и прод-деплоем на 2 ГБ RAM. Параллельно повторил несколько идей из работ 2023 года (MemGPT, Reflexion), но нашёл и кое-что своё — например, weekly self-calibration промпта judge-LLM. Эта статья — честный разбор архитектуры, граблей и prior art.
Некоторые вводные данные:
- Стартовое окружение: VPS 1CPU, 2GB RAM, 30GB SSD
- Основная модель LLM: API GigaChat
- Embeddings: API GigaChat Embeddings
- Вспомогательные модели (fallback, Sufler): API DeepSeek, API OpenAI
Где мой проект в AI-экосистеме: Мой проект — это не конкурент LangChain или MemGPT. Это уже готовое приложение, которое использует все эти компоненты и добавляет замкнутый цикл самообучения.
Пролог: почему ChatGPT или DeepSeek меня бесили?
Я пользовался ChatGPT, потом DeepSeek примерно с момента их появления для своих нужд. И меня стабильно бесила одна вещь: «они не учатся».
Допустим, меня попросили рассчитать спецификации для производства. В понедельник спрашиваю, как правильно посчитать себестоимость шкафа-купе. Выдаёт временами ответ с галлюцинацией — путает ЛДСП и ДВП, забывает учесть кромку, считает отходы неправильно. Я ему говорю: «неверно, пересчитай». Он извиняется, даёт новый ответ — с другой галлюцинацией. В среду я спрашиваю то же самое в новом чате — он опять галлюцинирует. С тем же прайс-листом. Снова.
Для меня это было фундаментально непонятно. У человека так не работает: если я один раз понял, как считать шкаф-купе, я не забуду. А LLM — забывает всё при закрытии чата. Более того, он забывает и при следующем запросе от другого пользователя.
Я подумал: ладно, это хоть и умные модели, но общедоступные и на это, по сути, не рассчитаны, поэтому простительно. Но что если я сам соберу систему, которая будет помнить? Которая будет учиться на своих ошибках и не повторять их?
Чего я тогда не знал:
- Не знал, что такое RAG, embedding, vector database
- Не слышал про ChromaDB
- Не слышал про LangChain, LlamaIndex
- Не слышал про MemGPT
- Не слышал про Reflexion
- Не слышал про Constitutional AI
То есть я начинал с нуля — и, как выяснилось потом, шёл параллельным путём с людьми, которые делали академические работы примерно в 2023 году. Но об этом — в конце. Сначала история.
Глава 1. Точка старта: «просто чат с памятью»
Первая версия была смешной. Я взял SQLite, добавил таблицу messages, и каждый запрос пользователя отправлял в LLM вместе с последними 20 сообщениями из истории. Это и была моя «память». 200 строк кода на FastAPI. Запустил локально. Работало!
Через неделю я понял первую проблему: контекстное окно не резиновое. Если я отправлял LLM прайс-лист на 85 позиций в одном сообщении, а потом вёл диалог ещё 30 сообщений, то прайс просто выпадал из контекста. LLM его «не видел» — и галлюцинировал: «а какой у вас прайс?».
Окей, подумал я, нужно как-то помечать важные сообщения. Написал простой алгоритм: после каждого сообщения пользователя проверяю — если длина накопленного диалога > 3000 символов с прошлой «контрольной точки», ставлю новую. Сохраняю в таблицу micro_goals.
def shouldanchor(mgstack, charcount, currenttopic):
"""Решает, нужен ли новый якорь."""
if charcount - mgstack[-1].char_pos >= 3000:
return "NEW_ANCHOR"
if currenttopic != mgstack[-1].topic:
# Проверяем, не похожа ли тема
if findsimilaranchor(mgstack, currenttopic):
return "MERGE_ANCHOR"
return "NEW_ANCHOR"
return "NO_ANCHOR"
Это были мои «якоря» — точки, в которых я фиксировал «о чём мы говорим». LLM видел в system prompt:
[ТЕМЫ ДИАЛОГА: прайс-лист → расчёт себестоимости]
[ПОСЛЕДНИЕ ДАННЫЕ: ЛДСП 2.57м² × 327.39₽ = 841.39₽]
И всё. Это работало. Контекст держался на 50+ сообщений.
Я тогда ещё не знал, что в ноябре 2023 года вышла работа MemGPT с почти такой же идеей — «core memory» + «archival memory». Нашёл случайно через полгода. Но об этом, повторюсь, будет позже.
Глава 2. Стена №2: «а если LLM неправ?»
Когда ассистент начал работать стабильно на длинных диалогах, я начал замечать вторую проблему: иногда LLM выдаёт чушь, и я не понимаю, когда.
Я сделал несколько ошибок в спецификации — ассистент их пропустил. Посчитал кромку как ЛДСП. Не учёл, что у меня 4 двери, а не 2. Спрашиваю «а почему так?» — он извиняется, пересчитывает, делает другую ошибку.
Решил: мне нужен второй LLM, который проверяет первый. Написал. Назвал «Sufler» (суфлёр — тот, кто подсказывает актёру за кулисами в театре).
Инновация, обрадовался я. Однако потом нашёл Reflexion (NeurIPS 2023) — и понял, что не только я хожу в театр. Однако, архитектурно мой Sufler отличается: он — как бы это сказать — внешний и независимый по отношению к основной модели и сохраняет оценки в долговременную память, а не только в self-reflection prompt.
def evaluateandcorrect(response, userquery, context, providercfg):"""Sufler оценивает ответ и при необходимости исправляет."""
prompt = buildevaluationprompt(response, user_query, context)
evalreply = calljudgellm(prompt, providercfg)
score = parsescore(evalreply)
reasoning = parsereasoning(evalreply)
corrected = parsecorrection(evalreply)if score < 4 and corrected and corrected != response:
corrected = clean_correction(corrected)
return {
"score": score,
"reasoning": reasoning,
"corrected": corrected,
}
Глава 3. Self-improvement без учителя
Когда Sufler начал работать, появилась новая идея. Если оценка плохая (1-2), это значит: система не знает что-то. Можно это «что-то» автоматически найти в интернете и добавить в базу знаний.
Так появился ЛИКБЕЗ. Каждые 3 часа запускается скрипт:
Это замкнутый цикл: ошибка → тема → знание → меньше ошибок. Без участия разработчика.
Сейчас в моей базе ~450 тем для исследования и 1000+ статей, найденных автоматически. Многие из них — именно те, по которым система раньше галлюцинировала.
Аналог в литературе: Voyager (NVIDIA, 2023) делал похожее для Minecraft — автономное приобретение навыков через exploration. Но там не было research-фазы с поиском по интернету. И не было явного feedback loop через evaluator. Так что конкретно эта связка — мой вклад.
Глава 4. Production: что сломалось
Я развернул систему на VPS с 2 ГБ RAM — почему так мало? Просто на другое не хватило ресурсов на тот момент, что уж выпендриваться))). И пошёл бегать по граблям. Вот что я сломал себе по дороге:
Грабля №1: GigaChat отдаёт expires_at в миллисекундах
# Было (баг):if expires_at < time.time(): # 1735689600 (секунды) > 1735689600000 (ms)
refresh_token() # никогда не срабатывалоСтало:
if expiresat > 10000000000: # если > 10^10, это миллисекунды
expires_at /= 1000
Симптом: токен протухал, embeddings возвращали 401, ChromaDB сохраняла нулевые векторы. Я тогда потратил наверное часов 6 на отладку.
Грабля №2: Sufler начал льстить
После месяца работы средняя оценка Sufler по выборке 50 последних ответов выросла до 4.6. Я думал — круто, система стала лучше. Потом проанализировал распределение: 60% ответов получают 5/5, 30% — 4/5. Это явный перекос. Sufler «загрубел» — перестал ловить реальные галлюцинации.
Написал run_selfcal.py — скрипт, который раз в неделю (воскресенье, 4 утра) проверяет распределение оценок. Если среднее > 4.3 или < 2.7 — отправляет текущий промпт оценщика + статистику в LLM с просьбой перекалибровать.
Этого я нигде не видел. Ни в одной статье, ни в одном фреймворке. Если кто-то делал self-calibration для LLM-as-judge — подскажите в комментариях, буду рад почитать.
Грабля №3: GigaChat embeddings возвращают None при 401
Это уже техническая мелочь, но иллюстрация того, сколько неочевидных багов в production. После протухания токена ChromaDB сохраняла None вместо векторов. Я не сразу это заметил, потому что chromadb.add() не падал с ошибкой — молча сохранял нули. Поиск возвращал шум.
Сейчас у меня:
force_refreshна 401 + проверка наNoneперед сохранениемembeddingdimзаморожен при первом успешном вызове (если GigaChat меняет размерность, делаем pad/truncate, не меняем коллекцию)
Глава 5. Что я построил: 23 компонента
Чтобы вы понимали масштаб — вот как выглядит архитектура сейчас:
Метрики на текущий момент:
| Метрика | Значение |
|---|---|
| Строк кода | ~50 000 |
| Python | ~20 000 |
| JavaScript | ~7 500 |
| HTML | ~2 700 |
| CSS | ~20 000 |
| Компонентов | 23 |
| Записей responselog | 1 176 |
| Векторов experiencebank | 1 046 |
| Тем в researchtopics | ~450 |
| Статей в researcharticles | ~1 000 |
| Фоновых задач | 5 |
| Узлов мониторинга | 33 |
| Health-проверок | 30 |
ЧЕЛОВЕК: «Вот прайс-лист» [85 строк]СИСТЕМА: Якорь #1 — «прайс-лист: 85 позиций»
SATI: «Вижу 85 позиций. Что нужно сделать?»... 50 сообщений спустя, прайс выпал из контекста ...
ЧЕЛОВЕК: «Переведи итог в доллары»
СИСТЕМА: SEARCH_HISTORY: «прайс ЛДСП»
SQL LIKE → находит «ЛДСП 327.39 | ДВП 91 | ...»
CBR → 1 USD = 74.62₽
AI: «1 050 / 74.62 = $14.07»... через месяц, ассистент ошибается в похожем расчёте ...
Sufler: score=2 → researchsuflerfails → «почему путаются ЛДСП и ДВП»
ЛИКБЕЗ: SearXNG → 6 статей про мебельные плиты
→ ChromaDB L2 (тема: furniture)
Следующий похожий вопрос: AI не повторяет ошибку.
Глава 6. Что я узнал потом: prior art
Через пару месяцев после запуска я начал читать, что вообще происходит в индустрии. И нашёл несколько вещей:
Архитектура MemGPT (Packer et al., ноябрь 2023):
- Core memory — всегда в контексте (мой аналог: якоря STM)
- Archival memory — векторная БД (мой аналог: МНЕМОС L2)
- Recall — function call для поиска (мой аналог: SEARCH_HISTORY)
Совпадение архитектурное — почти 1:1. Различия:
- У MemGPT нет явного external evaluator (Sufler)
- У MemGPT нет автономного research (ЛИКБЕЗ)
- У меня якоря ставятся автоматически по длине диалога, у MemGPT — ручной edit
Letta (бывший MemGPT, теперь коммерческий) — прямой конкурент. Если бы я знал про них раньше, мог бы сэкономить месяц.
Reflexion
Paper от Shinn et al., NeurIPS 2023. Идея: агент рефлексирует над ошибками и пишет self-critique в память.
Мой Sufler делает похожее, но:
- Reflexion — внутренний цикл одной модели (self-reflection в prompt)
- У меня — внешний evaluator, отдельная LLM с собственной шкалой 1-5
- У меня оценки публикуются в
response_logи используются как few-shot examples для будущих ответов. У Reflexion рефлексии живут только в памяти агента.
Constitutional AI
Anthropic, декабрь 2022. LLM проверяет другой LLM по набору «принципов». Скорее философский фреймворк, чем технический. У меня — конкретная шкала 1-5 с weekly auto-calibration.
Voyager
NVIDIA, 2023. Автономный агент в Minecraft, который исследует мир, приобретает навыки, проверяет их через self-verification.
Совпадение с моим ЛИКБЕЗ — частичное:
| Voyager | Моя система |
|---|---|
| Skills library | Few-shot examples |
| Self-verification через executable code | Sufler (LLM-as-judge) |
| Curriculum-driven exploration | researchsuflerfails |
Глава 7. Что я могу назвать своим
Если убрать всё, что уже было в чужих работах, что остаётся лично моего?
Эпилог: что я вынес из этого опыта
Я не изобрёл ничего такого, чего бы не придумали в OpenAI или Berkeley до меня. Но я собрал это в работающую систему, развернул её, документировал, и собрал данные.
Уроки, которые я бы дал себе в апреле:
- Не изобретай велосипед — но и не бойся собрать свой. Если бы я сразу знал про MemGPT, я бы, наверное, не стал делать своё. Но я бы и не научился понимать, как память в LLM реально работает.
- Production учит больше, чем papers. Все мои интересные находки — это фиксы багов и оптимизации, не теория.
- Self-improvement работает, но не магически. За месяц система закрыла ~30% повторяющихся провалов. Это много. Но 70% — те, на которые нужен человек.
- Документация — это часть продукта. Я написал 9 файлов по архитектуре, и это спасло меня от выгорания: я могу перечитать и вспомнить, что я делал.
Если вы разрабатываете LLM-приложения и у вас ещё нет «judge + feedback loop» — попробуйте. Это не rocket science, и это реально улучшает качество.
Что в следующих статьях
Я планирую серию из еще 5 статей, каждая с детальным разбором каждого компонента:
1. Что такое МНЕМОС — долгосрочная память, L1/L2/L3, опыт и провалы
2. Что за связка STM + МНЕМОС — оперативная и долгосрочная память вместе
3. Замкнутый цикл обучения — Sufler → fail → ЛИКБЕЗ → знание
4. Зачем я придумал Matematicus — 3-level matching для точных расчётов
5. Что значит "интуиция" — новая идея для внедрения
В этой серии я делюсь архитектурой, граблями, рассуждениями. Если вы:
- AI-инженер и ищете похожие задачи — пишите, обсудим
- HR / рекрутер — открыт к диалогу)
- Запускаете AI-стартап или рассматриваете проект — расскажу подробнее про traction, метрики, roadmap
- Делали self-improving loop? Какой был опыт?
- Кто использовал MemGPT/Letta в проде? Стоит переходить?
- У кого есть weekly self-calibration для LLM-as-judge?
Можно цитировать, обсуждать, спорить. Если есть вопросы по конкретному компоненту — пишите в комментариях или на почту.
Если есть вопросы или хочется подробностей по конкретному компоненту — пишите в комментариях.







Комментарии
Для комментирования авторизуйтесь на сайте или используйте ВКонтакте