Перейти к основному содержимому

For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.

Трассировка агентов

Трассировка агентов фиксирует, кто вызвал (nvext.agent_context), что Dynamo измерил по каждому запросу к LLM (request_end), а также необязательные интервалы инструментов harness (tool_*). Контекст пассивен: он не влияет ни на маршрутизацию, ни на кэширование. Результат представляет собой профилирующие данные best-effort, а не журнал аудита.

Поток: Harness отправляет chat completions с agent_context → Dynamo публикует request_end в приемники трассировки. Harness отправляет события инструментов по ZMQ → в те же приемники.

Добавление контекста трассировки в каждый вызов LLM

Прямой вызов LLM

Внедрите agent_context в каждый запрос к LLM

{
"model": "my-model",
"messages": [{ "role": "user", "content": "..." }],
"nvext": {
"agent_context": {
"session_type_id": "deep_research",
"session_id": "research-run-42",
"trajectory_id": "research-run-42:researcher",
"parent_trajectory_id": "research-run-42:planner"
}
}
}
ПолеОбязательноЗначение
session_type_idДаКласс рабочей нагрузки (например, deep_research).
session_idДаВесь прогон агента.
trajectory_idДаОдна цепочка рассуждений/инструментов внутри прогона.
parent_trajectory_idНетРодительская траектория при использовании сабагентов.

Клиент OpenAI: объединяйте в extra_body / extra_headers:

import uuid

def instrument_llm_request(kwargs, agent_context):
body = dict(kwargs.get("extra_body") or {})
nvext = dict(body.get("nvext") or {})
nvext["agent_context"] = dict(agent_context)
body["nvext"] = nvext

headers = dict(kwargs.get("extra_headers") or {})
headers.setdefault("x-request-id", str(uuid.uuid4()))

out = dict(kwargs)
out["extra_body"] = body
out["extra_headers"] = headers
return out

x-request-id — это ваш логический идентификатор на вызов; Dynamo сохраняет его как request.x_request_id (отдельно от внутреннего request_id Dynamo). В harness не требуется импортов Dynamo. Храните контекст в contextvar, прикрепляйте его перед каждым completion и передавайте через потоки/процессы, когда эти пути вызывают модель или отправляют инструменты.

Включение вывода

Быстрый путь — одна переменная окружения:

export DYN_AGENT_TRACE=1

Это выбирает вывод jsonl_gz в /tmp/dynamo-agent-trace.*.jsonl.gz и привязывает ZMQ endpoint для событий инструментов harness к tcp://127.0.0.1:20390. Любая из переменных ниже по-прежнему имеет приоритет при явном задании, так что к ним нужно обращаться только чтобы перенести вывод, добавить stderr или настроить буферы.

Чтобы только перенести место сохранения:

export DYN_AGENT_TRACE=1
export DYN_AGENT_TRACE_OUTPUT_PATH=/mnt/captures/run-42
Все переменные окружения трассировки агентов
ПеременнаяОбязательноЗначение по умолчанию (когда DYN_AGENT_TRACE=1)Примечания
DYN_AGENT_TRACEГлавный переключательunsetИстинное значение (1, true, on, yes) включает трассировку со всеми значениями по умолчанию ниже.
DYN_AGENT_TRACE_SINKSНетjsonl_gzjsonl, jsonl_gz, stderr или список через запятую (например, jsonl_gz,stderr).
DYN_AGENT_TRACE_OUTPUT_PATHНет/tmp/dynamo-agent-traceПуть к файлу для jsonl; префикс сегмента для jsonl_gzprefix.NNNNNN.jsonl.gz.
DYN_AGENT_TRACE_CAPACITYНет1024Ёмкость trace bus.
DYN_AGENT_TRACE_JSONL_BUFFER_BYTESНет1048576Порог буфера / пакета gzip.
DYN_AGENT_TRACE_JSONL_FLUSH_INTERVAL_MSНет1000Интервал сброса.
DYN_AGENT_TRACE_JSONL_GZ_ROLL_BYTESНет268435456Роллинг сегмента gzip по несжатым байтам.
DYN_AGENT_TRACE_JSONL_GZ_ROLL_LINESНетunsetНеобязательный роллинг по числу строк.
DYN_AGENT_TRACE_REPLAY_HASHESНетonЛожное значение (0, no, …) отключает хэши replay в запросах.
DYN_AGENT_TRACE_TOOL_EVENTS_ZMQ_ENDPOINTНетtcp://127.0.0.1:20390Адрес привязки PULL для записей инструментов.
DYN_AGENT_TRACE_TOOL_EVENTS_ZMQ_TOPICНетunsetЕсли задано, первый фрейм ZMQ должен совпадать.

Без DYN_AGENT_TRACE=1 трассировка выключена; остальные переменные начинают действовать только после включения мастер-переключателя.

События инструментов (ZMQ)

Формат передачи: [topic, seq_be_u64, msgpack(AgentTraceRecord)]. Чтобы публиковать в Dynamo, используйте фоновый publisher, ограниченную очередь, монотонную последовательность и PUSH с HWM. Конечные строки tool_end / tool_error должны содержать тайминги (started_at_unix_ms, ended_at_unix_ms, duration_ms), даже если tool_start был потерян.

Используйте тот же agent_context, что и у окружающих вызовов LLM; tool_call_id должен быть уникален в пределах одной траектории. Объединяйте офлайн по session_id, trajectory_id, tool_call_id.

Пример tool_end:

{
"schema": "dynamo.agent.trace.v1",
"event_type": "tool_end",
"event_time_unix_ms": 1777312801500,
"event_source": "harness",
"agent_context": {
"session_type_id": "deep_research",
"session_id": "research-run-42",
"trajectory_id": "research-run-42:researcher"
},
"tool": {
"tool_call_id": "call-abc",
"tool_class": "web_search",
"status": "succeeded",
"started_at_unix_ms": 1777312801080,
"ended_at_unix_ms": 1777312801500,
"duration_ms": 420.5
}
}

Необязательные ключи tool: output_tokens, output_bytes, tool_name_hash, error_type (полезно для tool_error). Значения статуса: running, succeeded, error, cancelled; синонимы ok/success, failed, timeout/canceled тоже десериализуются.

Запись Dynamo request_end

Публикуется после завершения потока ответа или после его сброса. Пропущенные ключи на этом пути не записывались; полный Rust-схемы см. в AgentTraceRecord / AgentRequestMetrics в lib/llm/src/agents/trace/types.rs.

{
"schema": "dynamo.agent.trace.v1",
"event_type": "request_end",
"event_time_unix_ms": 1777312801000,
"event_source": "dynamo",
"agent_context": {
"session_type_id": "deep_research",
"session_id": "research-run-42",
"trajectory_id": "research-run-42:researcher",
"parent_trajectory_id": "research-run-42:planner"
},
"request": {
"request_id": "dynamo-request-id",
"x_request_id": "llm-call-42",
"model": "my-model",
"output_tokens": 16,
"finish_reason_metadata": {
"finish_reason": "tool_calls",
"backend_finish_reason": "stop",
"stop_reason": "END",
"tool_calls": [
{
"choice_index": 0,
"tool_call_index": 0,
"id": "call-abc",
"name": "web_search"
}
],
"choices": [
{
"choice_index": 0,
"finish_reason": "tool_calls",
"backend_finish_reason": "stop",
"stop_reason": "END"
}
]
},
"replay": {
"trace_block_size": 64,
"input_length": 128,
"input_sequence_hashes": [14879255164371896291, 274632075616497421]
}
}
}

finish_reason_metadata необязателен. backend_finish_reason и stop_reason поступают из пути остановки backend/token; finish_reason — это финальная OpenAI-compatible причина завершения после переписывания парсером, например tool_calls. Поля завершения верхнего уровня суммируют типичный случай с одним выбором; choices сохраняет поля завершения для каждого варианта, когда n > 1. Метаданные tool-call содержат только id и имена; аргументы намеренно не сохраняются в agent traces. Для chat streams финальные метаданные завершения записываются после переписывания parser/jail; completion streams записывают финальную OpenAI-compatible причину завершения из choices ответа completion.

По умолчанию мы не сохраняем входные/выходные payload'ы. Чтобы увидеть их, используйте встроенную функцию Dynamo audit_sink.

Audit side-by-side (тот же механизм gzip/jsonl):

# enable agent trace sinks
export DYN_AGENT_TRACE_SINKS=jsonl_gz
export DYN_AGENT_TRACE_OUTPUT_PATH=/tmp/dynamo-trace
# enable audit sinks
export DYN_AUDIT_SINKS=jsonl_gz
export DYN_AUDIT_OUTPUT_PATH=/tmp/dynamo-audit
export DYN_AUDIT_FORCE_LOGGING=true

После прогона сопоставьте по id:

gzip -cd /tmp/dynamo-audit.*.jsonl.gz | jq -c '.event' > /tmp/audit.jsonl
gzip -cd /tmp/dynamo-trace.*.jsonl.gz | jq -c '.event' > /tmp/trace.jsonl
jq -s 'group_by(.request_id // .request.request_id)' /tmp/audit.jsonl /tmp/trace.jsonl

Результат — файл JSONL, где каждая строка оборачивает запись:

{
"timestamp": 1234,
"event": { "schema": "dynamo.agent.trace.v1", "...": "..." }
}

timestamp — это elapsed ms относительно sink; для порядка по реальному времени используйте event.event_time_unix_ms.

Просмотр трассировок в Perfetto

Чтобы визуализировать и оптимизировать ваш agentic graph, мы предоставляем утилиту для преобразования agent trace JSONL-файлов в trace-файл Perfetto. Мы считаем это крайне полезным для pipeline-агентов, которые пишет наша команда!

uv run --no-project python benchmarks/agent_trace/convert_to_perfetto.py \
"${DYN_AGENT_TRACE_OUTPUT_PATH}".*.jsonl.gz \
--output "${DYN_AGENT_TRACE_OUTPUT_PATH}.perfetto.json"

Откройте в Perfetto UI. Флаги: --include-markers, --no-stages, --separate-stage-tracks.

Срезы запросов включают сглаженные метаданные завершения, если они присутствуют, например finish.finish_reason, finish.backend_finish_reason, finish.stop_reason, finish.tool_call_count, finish.tool_call_names и сводки по каждому выбору, такие как finish.choice_finish_reasons.

[Экспериментально] Повтор agent traces с помощью agentic Mooncake replay

Вы можете преобразовать собранный agent trace в trace agentic Mooncake и воспроизвести его с помощью python -m dynamo.replay. Конвертер использует строки Dynamo request_end для таймингов запросов, длины токенов, размещения worker'ов и replay hashes. Он также использует конечные строки инструментов harness (tool_end / tool_error), чтобы сохранить время ожидания инструментов между зависимыми запросами LLM.

Replay игнорирует не относящиеся к replay поля запроса, такие как finish_reason_metadata; используйте представление Perfetto выше, когда нужно посмотреть финальные причины завершения, backend stop сигналы или полные метаданные tool-call внутри trace.

cargo run -p dynamo-bench --bin agent_trace_to_mooncake -- \
--agentic \
--input-path "${DYN_AGENT_TRACE_OUTPUT_PATH}".*.jsonl.gz \
--output-file /tmp/dynamo-agent-trace.agentic-mooncake.jsonl

Бинарник выводит trace_block_size. Используйте именно это значение для replay, чтобы сегментация хэшей совпадала с тем, что записал Dynamo. Согласуйте размер блока mock engine с тем же числом в --extra-engine-args.

TRACE_BLOCK_SIZE=128
uv run --no-sync python -m dynamo.replay /tmp/dynamo-agent-trace.agentic-mooncake.jsonl \
--trace-format agentic_mooncake \
--trace-block-size "${TRACE_BLOCK_SIZE}" \
--replay-mode offline \
--router-mode kv_router \
--num-workers 4 \
--extra-engine-args "{\"block_size\":${TRACE_BLOCK_SIZE}}" \
--report-json /tmp/dynamo-agent-trace.replay-report.json

kv_router требует как минимум двух mock workers; для smoke test с одним worker используйте --router-mode round_robin --num-workers 1.

Строки Agentic Mooncake сохраняют:

  • request_id: идентичность строки запроса LLM.
  • session_id: Dynamo trajectory_id.
  • wait_for: id запросов, которые должны завершиться, прежде чем эта строка станет доступной.
  • branches: дочерние id запросов, порождённых этой строкой.
  • prefix_reset: первый запрос в траектории.
  • delay: задержка не из-за инструментов после завершения зависимостей.
  • tool_wait_ms: время инструментов после завершения зависимостей с учётом параллельности (объединение перекрывающихся интервалов, а не их сумма).
  • tool_events: интервалы по каждому инструменту, привязанные к этому запросу LLM, каждый содержит tool_call_id, tool_class, status, started_at_unix_ms, ended_at_unix_ms, duration_ms, а также необязательные output_bytes / output_tokens / error_type.
  • hash_ids, input_length и output_length: данные о prompt-prefix и длине для replay через mocker.

Строки без wait_for используют свой timestamp как время начала replay. Строки с зависимостями ждут, пока завершатся все перечисленные запросы, затем ждут delay + tool_wait_ms перед отправкой. Дополнительные флаги и настройки engine см. в DynoSim Runs.

Согласование ATIF

Dynamo выпускает dynamo.agent.trace.v1, а не полные ATIF-логи, но идентификаторы совпадают с ATIF / Harbor, так что вы можете объединять траектории harness со строками Dynamo по session_id + trajectory_id. Dynamo намеренно не включает разговорные данные.

DynamoРоль
session_idОбщий id прогона
trajectory_idВетвь внутри прогона
parent_trajectory_idСвязь с сабагентом
session_type_idПрофиль / тип нагрузки