Skip to main content

Петля агента

Как Copilot CLI обрабатывает пользовательское сообщение от начала до конца: от запроса до session.idle.

Architecture

Диаграмма: Диаграмма, показывающая описанный процесс.

SDK — это транспортный слой: он отправляет ваш запрос в Copilot CLI по JSON-RPC и возвращает события обратно в приложение. CLI — это оркестратор, который запускает цикл использования агентных инструментов, выполняя один или несколько вызовов LLM API до завершения задачи.

Цикл использования инструментов

Когда вы вызываете session.send({ prompt }), CLI входит в цикл:

Диаграмма: блок-схема, показывающая описанный процесс.

Модель видит полную историю разговоров по каждому звонку — системный запрос, пользовательское сообщение и все предыдущие вызовы и результаты.

Ключевые выводы: Каждая итерация этого цикла — это ровно один вызов LLM API, видимый как одна assistant.turn_start / assistant.turn_end пара в журнале событий. Скрытых звонков нет.

Повороты — что это такое

Ход — это один вызов LLM API и его последствия:

  1. CLI отправляет историю разговоров в LLM
  2. LLM отвечает (возможно, с помощью запросов инструментов)
  3. Если инструменты запрашивались, CLI их выполняет
  4. assistant.turn_end излучается

Одно сообщение пользователя обычно приводит к нескольким ходам. Например, вопрос вроде «как работает X в этой кодовой базе?» может привести к следующему:

ПовернутьЧто делает модельtoolRequests?
1Вызовы grep и glob поиск по кодовой базе
✅ Да
2Читает конкретные файлы на основе результатов поиска
✅ Да
3Читайте больше файлов для более глубокого контекста
✅ Да
4Получает итоговый текстовый ответ
❌ Нет → концов петли

Модель решает на каждом ходу, запрашивать ли дополнительные инструменты или давать окончательный ответ. Каждый звонок видит полный накопленный контекст (все предыдущие вызовы и результаты), чтобы принять обоснованное решение о том, достаточно ли у него информации.

Поток событий для многоходового взаимодействия

Диаграмма: блок-схема, показывающая описанный процесс.

Кто запускает каждый ход?

ActorОтветственность
Ваше приложениеОтправляет первоначальный запрос через session.send()
Copilot CLIЗапускает цикл использования инструментов — выполняет инструменты и возвращает результаты в LLM на следующий ход
LLMРешает, запрашивать ли инструменты (продолжать цикл) или давать окончательный ответ (стоп)
Пакет SDKПередаёт события; не управляет циклом

CLI чисто механический: «модель запросила инструменты → выполнить → модель вызова снова». Модель принимает решение, когда остановиться.

session.idle и session.task_complete

Это два разных сигнала завершения с очень разными гарантиями:

session.idle

  • Всегда излучается , когда цикл использования инструмента заканчивается
  • Эфемерный: не сохраняется на диске, не воспроизводит при возобновлении сессии
  • Означает: «агент прекратил обработку и готов к следующему сообщению»
  • Используйте это как надёжный сигнал «готово»

Метод SDK sendAndWait() ждёт этого события:

// Blocks until session.idle fires
const response = await session.sendAndWait({ prompt: "Fix the bug" });

session.task_complete

  • Опционально излучается: требует, чтобы модель явно сигнализировала
  • Сохранено: сохранено в журнал событий сессии на диске
  • Означает: «агент считает выполненную общую задачу»
  • Несёт дополнительное summary поле
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});

Режим автопилота: CLI подталкивает к task_complete

В режиме автопилота (безголовая/автономная работа) CLI активно отслеживает, вызывала task_completeли модель . Если цикл использования инструмента заканчивается без него, CLI вводит синтетическое пользовательское сообщение, подталкивающее модель:

«Вы ещё не отметили задание как завершённое с помощью инструмента task_complete. Если вы планировали, прекратите планирование и начните внедрять. Ты не закончишь, пока полностью не выполнишь задание.»

Это фактически запускает цикл использования инструмента — модель воспринимает подталкивание как сообщение нового пользователя и продолжает работать. Подталкивание также инструктует модель не вызывать task_complete преждевременно:

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

Это создаёт двухуровневый механизм завершения в автопилоте:

  1. Модель вызывает task_complete с резюме→ CLI session.task_complete излучает → выполнено
  2. Модель останавливается, не вызывая её, → CLI подталкивает модель → продолжает или вызывает task_complete

Почему task_complete бы не появиться

В интерактивном режиме (обычный чат) CLI не подталкивает к task_complete. Модель может полностью его пропустить. Распространенные причины:

  • Разговорные вопросы и ответы: модель отвечает на вопрос и просто останавливается — нет отдельной «задачи» для выполнения
  • Дискреция модели: модель генерирует итоговый текстовый ответ без вызова сигнала завершения задачи
  • Прерванные сессии: сессия заканчивается до того, как модель достигает точки завершения

CLI всё равно излучает session.idle , потому что это механический сигнал (цикл завершился), а не семантический (модель считает, что всё сделано).

Какой из них следует использовать?

Сценарий использованияСигнал
«Жди, пока агент закончит обработку»
session.idle
«Знать, когда выполнена задача по программированию»
session.task_complete (лучшее усилие)
«Тайм-аут/обработка ошибок»
session.idle

session.error ✅ |

Подсчёт вызовов LLM

Количество assistant.turn_start / assistant.turn_end пар в журнале событий равно общему числу LLM API вызовов. Нет скрытых требований к планированию, оценке или проверке завершения.

Чтобы проверить количество ходов за сессию:

# Count turns in a session's event log
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl

Дополнительные материалы