Цикл агента: модель → инструменты → снова модель
В Элис цикл разделён на две роли. ConversationRunner — режиссёр всего прогона. AgentLoop — один ход с моделью. Плюс отдельные раннеры для субагентов и eval.
Рассказываю, где с DeepSeek пришлось повозиться.
ConversationRunner собирает прогон: группа, клиент модели, реестр инструментов, бюджет, политика. Держит лимиты ходов, бюджет, прерывания, сжатие. После успеха фоном предлагает сохранить навык. Есть fixture-режим без живой модели — для дымовых тестов.
AgentLoop — один ход: стабильный системный текст + история + динамический хвост, вызов DeepSeek, затем ответ или инструменты. Прогресс и статус отделены от финального ответа.
Раннер субагента. Агент из файла в agents/ вызывается как инструмент, пишет в журнал родителя, а его бюджет не больше остатка бюджета родителя.
Раннер eval — гоняет сценарии качества.
Ключевая трудность (инженерная): reasoning round-trip и целостность пар. DeepSeek требует, чтобы рассуждения модели гонялись туда-обратно в истории. И цепочка «вызов ↔ результат» должна быть целой до следующего HTTP-запроса: у каждого вызова — ровно один результат с нужным идентификатором. Если пара порвана, это нарушение протокола и стоп, а не «как-нибудь продолжим». Отсюда правило: отказ политики, таймаут и прерывание — тоже полноценные результаты. И при сжатии истории нельзя разрезать пару посередине.
Дальше — кэш промпта и почему в префиксе нельзя писать время.