Дайте своим агентам для программирования память, которой владеете вы
Ранее в этом году статья Программное обеспечение забывает: трассировки агентов — это память обосновывала мысль о том, что агенты для написания кода уже создают записи, которые мы постоянно теряем. Исследуя кодовую базу, пробуя разные подходы, сталкиваясь с ошибками, читая документацию и меняя направление, они оставляют подробный отчёт не только о том, что изменилось, но и о том, почему.
Хотя диагноз верен, трассировки — это лишь потенциальная память. Журналы сеансов
агента по-прежнему остаются просто архивом. Нельзя с помощью одного grep
найти ответ на вопрос «почему мы отказались от потокового парсера?» в десяти тысячах итераций. Чтобы агент мог использовать эти трассировки
во время работы, им нужны индексация, извлечение, ранжирование и точное указание происхождения.
Именно это предоставляет funes. Это долговременный слой памяти для ваших агентов (Claude Code, Codex, pi и Hermes). Он создаётся из сеансов, уже сохранённых на вашей машине. Он работает локально и становится частью обычного рабочего процесса агента с помощью одной команды. При желании память также можно отправить в принадлежащий вам датасет Hugging Face, по умолчанию закрытый.
Добавьте память к уже используемому агенту
funes — это один исполняемый файл. Его сервер вывода по умолчанию не зависит от среды выполнения ML, а встраивание и повторное ранжирование выполняются на вашей машине. Установите его:
curl -fsSL https://huggingface.co/buckets/huggingface/funes/resolve/install.sh | sh
Затем добавьте его к агенту:
funes add claude
Эта единственная команда add создаёт первый индекс, предоставляет агенту инструменты recall и get
и устанавливает автоматизацию, индексирующую каждый завершённый ход. Индексация выполняется
инкрементально: новые запуски добавляют новые ходы, а не встраивают всю историю
заново. Более старое и глубокое содержимое может заполняться фоновыми ограниченными шагами.
После этого вы просто работаете. Когда задача затрагивает принятое ранее решение, обоснование или результат,
агент сам может обратиться к recall. Вам не нужно помнить старый сеанс или
вставлять его контекст в новый.
После добавления funes извлечение происходит прямо внутри разговора. Агент сам обращается к своей памяти и называет сеанс, лежащий в основе его ответа.
recall возвращает исходный текст, а не краткое содержание, и точно показывает, откуда он взят
(агент, временная отметка, сеанс и ход). Каждый результат содержит команду get, которая
открывает полный ход и окружающий его контекст.
В основе лежит детерминированный конвейер: он разбирает каждую поддерживаемую трассировку в одинаковую структуру ходов и блоков, разбивает её на фрагменты, встраивает их с помощью закреплённой локальной модели и записывает в локальный датасет Lance. Запрос объединяет векторный поиск и поиск BM25, совмещает их результаты ранжирования, повторно ранжирует кандидатов с помощью кросс-энкодера, взвешивает их с учётом давности и добавляет соседние фрагменты.
Такая архитектура даёт funes три важных свойства:
- Единая память для всех агентов: Claude Code, Codex, pi и Hermes записывают данные в
одинаковой форме.
recallохватывает их истории, и каждый результат показывает, какой агент его создал. - Исходные свидетельства остаются нетронутыми: При записи факты не превращаются в выжимку. Результат всегда может привести обратно к ходу, в котором он был получен.
recallпо умолчанию работает локально: Учётная запись или репозиторий Hub не требуются. Размещённая модель не обрабатывает ваши сеансы для индексации; встраивание и повторное ранжирование выполняются на вашей машине, а рассуждения выполняет ваш агент для написания кода.
Проблема агента-незнакомца уже решена на одной машине. Но память становится полезнее, когда следующий агент запускается где-то ещё.
Память — это датасет, а не сервис
Чтобы память следовала за вашей работой, укажите её при добавлении funes к агенту:
funes add codex acme/funes-memory
Привязка публикует туда текущую память. Затем funes поддерживает её в актуальном состоянии, локально индексируя каждый ход и публикуя данные на границах сеансов. Агент использует её для извлечения в течение всего процесса. Запустите ту же команду на другой машине — и память последует за вами.
В основе локальная память представляет собой датасет Lance, а общая память — принадлежащий вам датасет Hugging Face (по умолчанию закрытый).
До того как что-либо попадёт на Hub, учётные данные уже удаляются во время индексации. Затем при публикации
каждый фрагмент снова проверяется, и всё, что по-прежнему похоже на секрет, не публикуется. Сканер, лежащий в основе этого процесса,
описан в SECURITY.md, включая
описание того, что он охватывает, а что нет.
Когда агент читает удалённую память, funes кэширует файлы датасета локально, поэтому после прогрева запросы возвращаются к локальной скорости. Hub предоставляет те же владение, контроль доступа, версионирование и распространение, что и для других датасетов. Ваша память не превращается в учётную запись в отдельном сервисе памяти, и вы не арендуете её обратно через API.
Сначала спросите, потом подключайте
recall разработан для агентов. Если вы хотите самостоятельно задать вопрос памяти,
используйте ask. По умолчанию он читает локальную память:
funes ask claude "what did we decide about the streaming parser"
Или укажите общую память. Мы опубликовали память разработки funes, так что вы можете спросить, почему funes работает именно так, не создавая собственную память:
funes ask claude "why is funes append-only" --memory huggingface/funes-memory
funes ask— это доступный только для чтения «собрат»funes add, предназначенный для одного вопроса. Он извлекает фрагменты, передаёт их агенту для написания кода и возвращает обоснованный ответ с указанием источников. Он не устанавливает интеграцию и не меняет постоянную настройку агента.
Неудача извлечения не маскируется. Если фрагменты не подтверждают ответ, агент так и сообщает. Вы можете переформулировать вопрос или добавить funes к агенту, чтобы тот мог итеративно искать в памяти в ходе обычной работы.
Переключайтесь между агентами, не теряя нить
Общая память не привязана к агенту или модели, которые её создали. Начните задачу в Claude Code, продолжите её в Codex на следующей неделе — и второй агент сможет вспомнить рассуждения первого. Используйте pi с локальной моделью или моделью, предоставляемой через маршрутизатор Hugging Face, а затем вернитесь к Claude.
Claude принимает решение; хук индексирует его; Codex вспоминает о нём в другом сеансе. Более старые результаты в демонстрации — это предыдущие записи того же эксперимента: память только для добавления запомнила и репетиции.
Это важно в нескольких разных масштабах:
- На разных машинах: Привяжите каждого агента к одной памяти и извлекайте историю с любого используемого хоста.
- В команде: Агент нового участника команды сможет с первого дня извлекать решения за несколько месяцев, включая тупиковые подходы и обоснования, которые так и не попали в pull request.
- Вместе с проектом с открытым исходным кодом: Мейнтейнер может опубликовать сеансы, лежащие в основе
релиза, указав их при отправке. Представьте это как доступный для поиска
CLAUDE.md, содержащий историю причин, по которым проект стал таким, какой он есть, вместо страницы, которую кто-то должен постоянно переписывать. Любой может прочитать общую память с помощью--memory.
Опубликованные воспоминания сопровождаются карточкой датасета и тегом funes, благодаря чему их можно распознать и найти на Hub. На Hub уже размещаются открытые веса и датасеты. funes добавляет открытую рабочую память. Она хранит решения, неудачные подходы и обоснования, лежащие в основе проекта, доступные для запросов другого агента и связанные с сеансами, в которых они возникли.
Самый дешёвый способ выйти из длинного сеанса
Длительное исследование раздувает сеанс до такой степени, что перенос контекста в каждом ходе обходится дороже, чем сама работа. Обычно предлагают позволить агенту сжать контекст и продолжить либо написать передачу контекста и начать заново. Извлечение — третий вариант, поэтому мы сравнили их на бенчмарке передачи контекста и извлечения : двух задачах, ответы на которые невозможно восстановить без предварительных знаний из сеанса.
Сжатие — то, что большинство агентов делают по умолчанию, и это был единственный из трёх вариантов, результат которого разделился: в одной задаче он достиг цели, а в другой — нет. Там, где он потерпел неудачу, его резюме сгладило важные результаты. Извлечение возвращает сами фрагменты, поэтому результату не нужно переживать суммаризацию.
Извлечение было самым дешёвым из трёх вариантов в обеих задачах: в одной оно оказалось в 8 раз дешевле письменной передачи контекста, а в другой — в 4 раза.
Более светлый сегмент каждого столбца — это единовременная стоимость подготовки канала, передачи контекста или сжатия, оплачиваемая до первого вопроса и учитываемая один раз. Крестик обозначает канал, который так и не достиг цели, поэтому стоимости успеха у него нет.
Перестаньте начинать с нуля
«Думать — значит забывать различия, обобщать, создавать абстракции». — Хорхе Луис Борхес, «Фунес, памятливый»
Ваши агенты уже записали историю. funes находится по адресу
github.com/huggingface/funes — одна команда отделяет
вас от превращения этой истории в память, которую сможет прочитать следующий агент на любой машине,
за которой вы окажетесь.
Построено на открытом исходном коде
funes не изобретает многое из этого. Он опирается на достаточно хорошие модели встраивания с открытым исходным кодом, способные работать локально, на датасеты Lance только для добавления с недорогими инкрементальными записями и на кэширование и дедупликацию содержимого датасетов на Hub. Основная работа заключается в том, чтобы объединить их в память, которой агент действительно сможет пользоваться.
funes тоже имеет открытый исходный код. Создайте issue, если столкнулись с чем угодно — от проблем с установкой до пропущенного результата извлечения — или если хотите, чтобы поддерживался определённый агент.
Датасеты, упомянутые в этой статье 2
Сообщество
· Зарегистрируйтесь или войдите, чтобы оставить комментарий
Датасеты, упомянутые в этой статье 2
Переведено автоматически с английского. Оригинал статьи — по ссылке ниже.



