Агент-инженер по репозиторию · Модуль 5 · Урок 5.5

Чекпойнт v4: трейсинг и учёт стоимости

Зачем (какую проблему чиним)

Агент дошёл до MR — но мы не видим, что он делал и сколько это стоило. Без трейсинга невозможно разобрать инцидент («почему открыл этот MR?»), без учёта токенов — невозможно управлять стоимостью. Добавляем observability: трейс каждого шага и учёт usage.

Решение и альтернативы

Решение: каждый шаг агента — спан трейса (вызов модели, исполнение инструмента, verify, создание MR) с длительностью и метаданными; в спан вызова модели кладём usage (input/output/cache токены) для подсчёта стоимости задачи. Это рабочий агент версии v4; тегируем v4.

Альтернативы: только логи fmt.Println — нет структуры, нельзя связать шаги задачи; внешний APM сразу — избыточно на этом этапе. Структурный трейс через log/slog со связкой по task_id — достаточный и дешёвый старт, расширяемый до OpenTelemetry в версии v5.

DIFF

Вводим трейсер: спаны по шагам, usage в спан вызова модели, агрегацию стоимости на задачу; собираем агент версии v4.

⚠ Безопасность

Трейс — фундамент аудита (полноценный аудит-лог записи/коммитов/MR соберём в версии v5, урок 6.4). В трейс и логи не попадают секреты и токены: пишем факты (какой инструмент, какой файл, sha коммита, URL MR, usage), но не содержимое секретов и не ключи. Учёт стоимости — ещё и предохранитель: бюджет токенов на задачу останавливает разорительные циклы.

Проверка

После задачи трейс показывает связную цепочку: план → правки → verify → MR, с длительностями; сумма usage даёт стоимость задачи. Секретов в трейсе нет. Затем git tag v4 — агент, открывающий проверенные MR с человеком в контуре и наблюдаемостью.

Глубже

Трейсинг, метрики, учёт стоимости, observability — курс «Продакшн-разработка», Модуль 5 (гл. 9) и Модуль 6 (стоимость/латентность, гл. 12).

trace.go: спаны по шагам и usage в стоимость (новый файл, фрагмент)
+package main
+
+import "log/slog"
+
+// Tracer пишет структурные спаны, связанные по task_id. Расширяется до
+// OpenTelemetry в версии v5; секреты и ключи в спаны НЕ попадают.
+type Tracer struct{ taskID string }
+
+func (t Tracer) step(name string, attrs ...any) func() {
+	slog.Info("span.start", append([]any{"task", t.taskID, "step", name}, attrs...)...)
+	return func() { slog.Info("span.end", "task", t.taskID, "step", name) }
+}
+
+// recordUsage кладёт токены вызова модели в учёт стоимости задачи.
+func (c *CostMeter) recordUsage(in, out, cacheRead int64) {
+	c.inputTokens += in
+	c.outputTokens += out
+	c.cacheReadTokens += cacheRead
+}

Anti-patterns

Грабли наблюдаемости
ГрабляПочему плохоКак правильно
Только разрозненные Println без связки по задачеНельзя восстановить ход задачи и разобрать инцидентСтруктурные спаны, связанные по task_id; шаги видны цепочкой
Логировать промпты/токены доступа/секреты в трейсУтечка секретов в системы логовПисать факты (инструмент, файл, sha, URL MR, usage), без секретов и ключей
Не учитывать usageСтоимость задачи неизвестна; нечем ограничить дорогие циклыСкладывать input/output/cache токены; бюджет на задачу как предохранитель

Практическое задание (RA-v4)

  • Добавить трейсер (спаны по шагам, связка по task_id) и учёт usage в стоимость задачи.
  • Исключить секреты/ключи из трейса и логов; ввести бюджет токенов на задачу.
  • Зафиксировать версию: git commit -m "v4: tracing and cost accounting" и git tag v4.

Проверка знаний

Что обязательно исключить из трейсов и логов агента?

  • A Идентификаторы задач
  • B Секреты и токены доступа (и сырые чувствительные данные) — писать только факты: инструмент, файл, sha, URL MR, usage
  • C Длительности шагов
  • D Номера версий