От вопроса на карте до причины сбоя

Как пользоваться Phoenix
в нашем chat-agent

Найти именно свой запрос. Понять, что сделали модель и инструменты. Разобрать ошибку, проверить время и сохранить вывод. Затем - сравнить изменение на учебных данных.

36 разделов46 иллюстраций с подписямиРеальный интерфейс и реальные traceАвтономный HTML
Начать с вопроса на картеРазобрать ошибку
01Работает сейчас

С чего начать и что Phoenix покажет

Вы задаёте вопрос на карте, агент обращается к модели и инструментам, а Phoenix собирает запись этих этапов. По ней видно, что вызвал агент, где возникла ошибка и сколько времени заняла генерация. Ответ на карте и техническое выполнение проверяем вместе.

Учебник снят с нашего Phoenix версии 20.19.0 7 октября 2026 года. Иллюстрации - настоящие снимки интерфейса с отдельным слоем подписей. Примеры для ввода выделены отдельно. Для учебника мы не отправляли новые вопросы агенту, не меняли карту и настройки сервиса, не создавали наборы данных или эксперименты.

Уже можноНужно предварительно настроить
Найти этапы по сессии и request_id, прочитать дерево, длительности, модель, токены и класс ошибки.Ручные оценки: подключить конфигурацию оценок к проекту.
Открыть Metrics, Dashboards и безопасные атрибуты.Playground, эксперименты и PXI: разрешённый доступ к модельному провайдеру. В нашей форме он пока не настроен.
Посмотреть API и политику хранения.Datasets и Evaluators: создать учебные примеры и критерии. Сейчас списки пусты.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 01 Стартовая страница проекта default. Фильтр корневых этапов нужно заменить, чтобы увидеть Agent.Нажмите на снимок, чтобы увеличить
  • 1Tracing: открыть проект
  • 2Spans: отдельные этапы
  • 3Заменить весь фильтр
  • 4Выбрать время
  1. Откройте phoenix.gis-master.ru. Если видна Signature, войдите штатным способом. Подпись и cookie для диагностики копировать не нужно.
  2. Слева нажмите Tracing. В списке проектов откройте default. Наши текущие трассы находятся в нём.
  3. Откройте вкладку Spans. В ней ищем этап chat_agent.agent и нужный бизнес-запрос.
  4. Для нового вопроса выберите Last 15 Min или Last Hour. Для примеров со снимков - период, включающий 7 октября 2026 года, 04:51-06:59, GMT+3.
  5. Читайте главы 2-11 по порядку при первой отладке. Для конкретной задачи используйте оглавление слева. Снимки увеличиваются кликом; запросы можно копировать кнопкой.

Проверка по коду: какие атрибуты разрешены в трассах.

02Работает сейчас

Задать вопрос на карте и сохранить ориентиры

Начнём с понятного учебного запроса. Он должен прочитать деморейс, показать маршрут и посчитать оставшееся время. Рейс и расчёт - демоданные, а не реальная информация о вылете.

Для деморейса TEST123 покажи маршрут до SVO и посчитай оставшееся время: 120 минут до вылета, 70 минут на дорогу, 30 минут запас.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 02 Наш интерфейс карты. Вопрос вводится в правой панели; существующее голосовое подключение на снимке не переключали.Нажмите на снимок, чтобы увеличить
  • 1Вопрос: сюда и Enter
  • 2Ответ: проверить смысл
  • 3Демоданные и планы
  • 4Связь с аудио и событиями
  1. Откройте chat-agent.gis-master.ru и нужный чат. Если панель свернута, нажмите Чат в правом нижнем углу.
  2. Для первого опыта используйте текст: вставьте пример в поле Введите сообщение... и нажмите Enter. Не запускайте параллельно несколько одинаковых вопросов - их будет сложнее сопоставлять по времени.
  3. Запишите время отправки до секунды и часовой пояс. В наших снимках Phoenix показывает GMT+3.
  4. Нажмите Ctrl+L и посмотрите адрес карты: https://chat-agent.gis-master.ru/chat/<UUID>. Часть после /chat/ - это session_id. Скопируйте только UUID. Если открыт адрес без выбранного чата, возьмите session_id из Payload запроса /core/message - путь описан в главе 5.
  5. Дождитесь ответа на карте. Проверьте маршрут, упоминание деморейса и арифметику 120 − 70 − 30 = 20 минут. Статус OK в Phoenix сам по себе не доказывает правильность результата.

Проверка по коду: как текст получает request_id и отправляется в Core.

03Работает сейчас

Выбрать период и убрать лишние этапы

В проекте смешаны HTTP-запросы, распознавание, работа модели и инструменты. Сначала сузим время и оставим верхний этап обработки вопроса.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 03 Меню времени. Для свежего вопроса нужен короткий период; для сохранённых примеров - календарь или Last 7 Days в день проверки.Нажмите на снимок, чтобы увеличить
  • 1Открыть период
  • 2Свежий запрос: 15 минут
  • 3История: 7 дней
  • 4Точные даты: календарь
  1. Нажмите период в правом верхнем углу. Выберите Last 15 Min, если вопрос только что отправлен. Если отладка заняла больше времени - Last Hour.
  2. Чтобы открыть старый случай, нажмите Pick from a calendar и задайте даты и время, включающие отправку вопроса.
  3. Вернитесь в Spans. Нажмите поле фильтра, затем Ctrl+A, чтобы выделить всё выражение.
  4. Вставьте фильтр ниже и нажмите обычный Enter. Не добавляйте его к parent_id is None: Agent часто вложен в другой span и исчезнет из такой выборки.
  5. Если таблица пуста, сначала расширьте период и проверьте синтаксис. Не считайте пустую выборку доказательством того, что агент не запускался.
name == "chat_agent.agent"
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 04 После замены фильтра остаются этапы Agent. Правые общие Stats относятся к трассам, поэтому для времени одного вопроса открываем его span.Нажмите на снимок, чтобы увеличить
  • 1Сюда: точное выражение
  • 2Открыть строку Agent

Подробнее: официальный синтаксис фильтров.

04Работает сейчас

Найти вопросы именно своего чата

Если точный request_id ещё неизвестен, ищем по сессии и времени. Это удобный путь из интерфейса карты. Он даёт кандидата для проверки; точное соответствие конкретному вопросу закрепляем идентификатором запроса.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 05 Выборка этапов Agent для одной сессии. Длительности в правых Stats могут включать долгую голосовую трассу.Нажмите на снимок, чтобы увеличить
  • 1Сессия + этап Agent
  • 2Открыть подходящий этап
  • 3Обновление / пауза
chat.session_id == "id-f9c26e6ff459" and name == "chat_agent.agent"
  1. Возьмите UUID после /chat/ в адресе своего чата; это session_id. В примере выше замените UUID в кавычках своим значением.
  2. Во вкладке Spans замените весь фильтр и нажмите Enter. Останутся только этапы этой сессии.
  3. Сопоставьте строку с временем отправки. Столбец start time может быть за правым краем таблицы: прокрутите таблицу по горизонтали или откройте строку и прочитайте дату в заголовке детали.
  4. Если строк мало, а вопроса ещё нет, дождитесь завершения ответа и обновления таблицы. Для новых данных используйте управление обновлением возле периода; не нажимайте отправку того же вопроса повторно.
  5. Откройте chat_agent.agent. В Info разверните Attributes или перейдите во вкладку Attributes. Найдите chat.session_id и chat.request_id.
  6. Проверьте сессию, время и состав инструментов. Если рядом несколько похожих ходов, возьмите request_id из Network по следующей главе: совпадение только по времени недостаточно.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 06 Карточка конкретного этапа: request_id и session_id находятся в Attributes. Длительность span справа - 463 мс; всей голосовой трассы сверху - 54 мин 47 с.Нажмите на снимок, чтобы увеличить
  • 1Здесь request_id и session_id
  • 2Время и длительность этапа
  • 3Trace ID: другая сущность
05Работает; DevTools описан по контракту

Взять точный request_id из браузера

Это самый надёжный способ связать вашу реплику с Phoenix. Идентификатор запроса создаётся ещё до отправки текста в Core. В завершённом сообщении чата он может не показываться, поэтому Network удобнее открыть заранее.

1. КартаНаписать вопрос → Enter
→
2. NetworkPOST /core/message → Payload
→
3. JSONrequest_id + session_id
→
4. PhoenixSpans → точный фильтр
  1. На странице карты нажмите F12 или Ctrl+Shift+I. В открывшихся инструментах Chrome выберите вкладку Network. Если она скрыта, найдите её в меню дополнительных вкладок ».
  2. Убедитесь, что запись Network включена: кнопка записи слева сверху красная. Выберите Fetch/XHR и в строке Filter введите /core/message.
  3. Теперь отправьте новый учебный вопрос на карте. В списке Network появится строка запроса. Нажмите её и проверьте: Request Method: POST.
  4. Откройте вкладку Payload → Request Payload. Найдите поля request_id и session_id. Скопируйте только их значения.
  5. В Response после завершения проверьте итог и ошибку, если она есть. Не используйте Copy as cURL для передачи коллегам: так можно скопировать cookie и другие заголовки доступа.
  6. Перейдите в Phoenix. Вставьте chat.request_id == "ВАШ_REQUEST_ID" в Spans, нажмите Enter и откройте Agent. Это связывает отладку именно с этой отправкой.
{
  "text": "Учебный вопрос о TEST123",
  "request_id": "<UUID запроса>",
  "turn_id": "<UUID реплики>",
  "session_id": "<UUID чата>"
}
ИдентификаторЗа что отвечает
session_idОдин чат, в нём много вопросов.
request_idОдна обработка запроса. Основной ключ поиска.
turn_idРеплика в истории. Не подставляем его вместо request_id.
trace_idТехническая цепочка OpenTelemetry. Голосовая цепочка может охватывать несколько вопросов.
span_idОдин этап внутри цепочки: Agent, модель или инструмент.

Проверка по коду: POST /core/message и разбор ответа.

06Работает сейчас

Открыть весь путь конкретного запроса

После поиска по request_id таблица может показать лишь несколько строк. Это не весь набор действий. Часть вложенных span SDK не имеет нашего бизнес-атрибута, но находится в той же трассе.

chat.request_id == "id-18139683b422"
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 07 Реальный запрос с ошибкой: фильтр нашёл Agent, voice.agent_request и два gateway-этапа LLM. Вложенные SDK-этапы раскрываются в дереве трассы.Нажмите на снимок, чтобы увеличить
  • 1Фильтр по request_id
  • 2Открыть Agent
  • 3Два вызова gateway LLM
  1. Во вкладке Spans замените весь фильтр выражением по своему request_id. В нашем историческом примере используйте UUID выше.
  2. Нажмите строку chat_agent.agent. Справа откроется дерево всей трассы и детали выбранного span.
  3. Проверьте chat.request_id и chat.session_id в Attributes. Скопируйте также Trace ID из верхнего заголовка для ссылки коллеге.
  4. В дереве найдите этот Agent по времени начала. При голосе рядом могут быть Agent других вопросов.
  5. Дальше читайте только его вложенную ветку: chat_agent.agent.pydantic, invoke_agent ..., вызовы модели и инструменты.
  6. Чтобы увидеть дочерние span, не требуйте наличия request_id у каждого. Фильтр выбрал входную точку; дерево показывает связи, даже если SDK-child не несёт бизнес-UUID.

Подробнее: что такое trace, span и вложенность.

07Работает сейчас

Прочитать дерево: кто вызвал кого

Дерево объясняет порядок исполнения. Внешний Agent владеет запросом, Pydantic AI выбирает следующий шаг, модель предлагает инструмент, а инструмент возвращает данные. Затем модель может сформировать окончательный ответ или сделать ещё один шаг.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 08 Успешная ветка запроса о деморейсе. Внешний Agent завершился за 8,9 с. В дереве видны несколько обращений к модели и последующий Code Mode.Нажмите на снимок, чтобы увеличить
  • 1Владелец этого запроса
  • 2Одна генерация модели
  • 3Code Mode: run_code
  • 4Проверить business ID
chat_agent.agentЗапрос и его результат
↓
chat_agent.agent.pydantic / invoke_agentЦикл решения задачи
↓
chat Qwen3.8-27B-FP8Одна генерация: текст либо tool calls
↓
execute_tool ...Чтение, расчёт или команда карте
  1. Нажмите нужный Agent в дереве. Заголовок справа показывает название, статус, дату начала и длительность выбранного этапа.
  2. Разверните его вложенные строки, если они свернуты. Ищите родительскую ветку по отступам, а не только по повторяющемуся названию.
  3. Нажмите chat Qwen3.8-27B-FP8. Это отдельное обращение к модели. Следующий такой же дочерний span может означать следующую генерацию после инструмента.
  4. Нажмите execute_tool flight_get или execute_tool run_code. Это исполнение инструмента, выбранного агентом.
  5. Для временных границ наведите мышь на строку дерева: всплывающая подсказка показывает начало, конец и длительность. Кнопка часов возле поиска дерева управляет отображением метрик.
  6. Не складывайте длительности родителя и его детей. Родитель уже включает ожидание дочерних этапов. Несколько nested-обёрток одного LLM-вызова тоже не являются несколькими генерациями.

Проверка по коду: где начинается ветка Pydantic AI.

08Работает сейчас

Проверить модель, генерации и токены

Если агент долго думал, сначала смотрим каждое обращение к модели. Phoenix показывает имя модели, длительность и количество токенов, когда провайдер вернул usage. Он не показывает в нашей production-настройке всю отправленную историю.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 09 Атрибуты реального LLM-span: 6004 входных, 214 выходных, 6218 токенов всего. Это один вызов модели, не весь запрос.Нажмите на снимок, чтобы увеличить
  • 1Выбран именно LLM
  • 2Вкладка Attributes
  • 3Токены этого вызова
  • 4Провайдер и модель
  1. Откройте ветку своего Agent. Выберите span chat Qwen3.8-27B-FP8, а не общий chat_agent.llm.
  2. Перейдите в Attributes. Найдите llm.model_name или gen_ai.request.model. Так проверяется фактическое имя модели в вызове.
  3. Найдите llm.token_count.prompt / gen_ai.usage.input_tokens и llm.token_count.completion / gen_ai.usage.output_tokens. Это альтернативные названия одних чисел, не два расхода.
  4. Посмотрите длительность в заголовке span. Для примера на снимке это около 4,5 с. Такое число относится к этому вызову, включая запрос к провайдеру, а не к целому голосовому сеансу.
  5. Повторите для остальных chat Qwen... в той же ветке. Считайте генерации по одному выбранному виду span, чтобы не удвоить обёртки chat_agent.agent.model.
  6. При большом input сравните число с лимитом входа 6144 токена. История и схемы инструментов занимают бюджет вместе с вопросом. Не выводите содержимое истории из одного числа токенов.

Проверка по коду: streaming-запрос, параметры и usage.

09Работает сейчас

Проверить инструменты и Code Mode

Теперь проверим, что агент действительно прочитал данные и сделал расчёт. Наличие правильного текста ответа недостаточно: нужно увидеть инструменты в ветке и результат на карте.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 10 Реальный вызов flight_get. В Info видны тип TOOL и имя инструмента; аргументы деморейса из production-трассы удалены.Нажмите на снимок, чтобы увеличить
  • 1flight_get: имя и время
  • 2Карточка инструмента
  • 3Инструмент внутри ветки
  1. В ветке Agent найдите execute_tool flight_get и нажмите строку. В Info проверьте имя и статус, в Attributes - tool.name.
  2. Найдите execute_tool run_code. Это Code Mode: модель предложила вычисление, которое выполняется в Monty.
  3. Под run_code посмотрите вызовы чтения. В снятом примере есть position_get, flight_get, weather_get и geo_distances. Их наличие доказывает обращение к данным, но сами аргументы и значения здесь скрыты.
  4. После расчёта найдите execute_tool map_show_route или map_show_points. Это отдельный native tool для изменения карты.
  5. Вернитесь на карту. Сопоставьте реально появившийся маршрут и текст ответа с задачей. Успешный tool-span означает завершение серверного действия; правильное отображение карты проверяется в интерфейсе.
  6. Если модель утверждает, что сохранила план, дополнительно проверьте карточку подтверждения и список сохранённых планов. Чтение данных или команда карты не заменяют подтверждение записи.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 11 run_code и дочерние чтения. Код вычисления и результаты данных в нашей настройке не экспортируются.Нажмите на снимок, чтобы увеличить
  • 1Выбрать run_code
  • 2Чтения внутри Code Mode
  • 3tool.name = run_code
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 12 В том же дереве наведена строка map_show_route: подсказка показывает завершившийся вызов. Деталь справа всё ещё относится к run_code.Нажмите на снимок, чтобы увеличить
  • 1Навести map_show_route
  • 2Начало, конец и длительность
10Работает сейчас

Разобрать запрос, который завершился ошибкой

Ошибки начинаем с самого запроса, а затем идём по его дочерним этапам. Красный родитель нередко лишь передаёт исключение, которое возникло ниже.

name == "chat_agent.agent" and status_code == "ERROR"
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 13 Фильтр ошибок Agent. В снятом периоде были две строки; число на снимке не является постоянным количеством сбоев.Нажмите на снимок, чтобы увеличить
  • 1Только ERROR у Agent
  • 2Открыть конкретную ошибку
  1. Если request_id известен, ищите по нему. Если нет - примените фильтр ошибок и сузьте период до времени проблемного вопроса.
  2. Откройте chat_agent.agent. Проверьте сессию, время и request_id в Attributes, чтобы не разбирать чужой случай.
  3. Пройдите вниз по его ветке. Откройте красные дочерние этапы и сравните их время. Ошибка родителя не доказывает, что сломался именно он.
  4. Найдите error.type. На снятом запросе это RequestStopped. Такой класс используется для разных причин остановки; по одному имени нельзя объявить, что закончился deadline или упал flight_get.
  5. Вернитесь в чат и прочитайте конкретную русскую причину. Для текстового запроса также посмотрите Network → /core/message → Response: там находится штатный ответ приложения, включая ошибку.
  6. Зафиксируйте request_id, trace_id, время, самый глубокий доступный ERROR, длительности LLM/tool и видимый пользователю результат. Если подробная причина не экспортирована, так и укажите: "класс остановки найден, точная причина по этой трассе не установлена".
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 14 Запрос 8a8347…: Agent ERROR, error.type = RequestStopped. По этому набору атрибутов точную причину остановки восстановить нельзя.Нажмите на снимок, чтобы увеличить
  • 1Ошибка выбранного Agent
  • 2Проверить request_id
  • 3Класс: RequestStopped
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 15 Другой пример: красная вложенная ветка Pydantic AI. Успешный LLM-span рядом не отменяет ошибку всего Agent.Нажмите на снимок, чтобы увеличить
  • 1Идём в красную ветку
  • 2Смотрим выбранный этап

Проверка по коду: что записывается при исключении.

11Работает сейчас

Найти, где запрос потерял время

Сначала отделяем время одного вопроса от времени соединения. Затем сравниваем его последовательные генерации и инструменты. Такой порядок не даст обвинить модель из-за долгого открытого микрофона.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 16 Один живой пример разницы масштабов: вся голосовая трасса - 54 мин 47 с, выбранный Agent - 463 мс.Нажмите на снимок, чтобы увеличить
  • 1Вся голосовая трасса
  • 2Один этап: 463 мс
  1. Найдите свой request_id и Agent по разделам о сессии и точном request_id. Запишите длительность выбранного Agent справа, не верхнюю Latency всей trace.
  2. Проверьте начало Agent относительно отправки текста или ASR final. Если до Agent была пауза, поищите соседний Core/voice-этап. Не приписывайте эту паузу LLM без доказательства.
  3. Откройте каждую генерацию chat Qwen... этой ветки. Большой вход может удлинить подготовку контекста, большой выход - генерацию. Сам Phoenix здесь не разделяет внутренние GPU-этапы.
  4. Посмотрите инструменты. Если один занимает основную часть Agent, проблема может быть в ожидании данных или вычислении. Если инструмент быстрый, но генераций много - изучайте порядок выбора действий.
  5. Сравните последовательные вызовы по временным границам. Учитывайте только один уровень LLM-span: Pydantic span, NATS-обёртка и gateway могут охватывать один и тот же вызов.
  6. Для очереди, CPU, RAM и медиапоказателей нужны отдельные метрики Grafana/VictoriaMetrics и runtime. В коде есть chat_agent.queue.wait, но отсутствие соответствующего span в Phoenix не означает нулевое ожидание.
name == "chat_agent.agent" and latency_ms > 10000

Проверка по коду: раздельные метрики этапов, очередей и клиента.

12Работает сейчас

Найти голосовой запрос: PCM → ASR final → Agent

Для голоса есть два разных канала: аудио идёт через WebRTC или /audio/ws, а статусы и ответы приходят в браузер по NATS WebSocket /ws. Ошибка соединения с микрофоном может возникнуть ещё до появления Agent.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 17 На карте отдельно видны подключение аудио и события. Phoenix связывает серверные этапы, но не записывает само аудио.Нажмите на снимок, чтобы увеличить
  • 1Статус подключения
  • 2Аудио / события отдельно
  • 3Выбор аудиотранспорта
  • 4Микрофон
  1. На карте проверьте, что аудио и события подключены. При первой работе разрешите микрофон штатным способом. Для отладки существующего вопроса не меняйте транспорт и настройки задним числом.
  2. Запишите время окончания своей фразы. В Phoenix выберите ту же сессию и нужный период.
  3. В дереве ищите chat_agent.asr.final, затем следующий соответствующий voice.agent_request и chat_agent.agent. Partial - промежуточное распознавание; оно не равно отправке нового окончательного вопроса Agent.
  4. Из Agent возьмите request_id. Если в одной длинной trace несколько Agent, сверяйте время и business ID у каждого.
  5. Для точного ID из браузера откройте F12 → Network → WS. Выберите событийное соединение /ws, затем Messages. Найдите полученный JSON с request_id и session_id нужного ответа. Это внутри текстовых сообщений NATS; служебные строки INFO/PING/MSG сами по себе не являются ответом агента.
  6. Не ищите этот JSON в /audio/ws: там отправляется бинарный PCM. При проблеме с голосом разделяйте "ASR final ещё нет" и "Agent получил final, но не ответил".
  7. Если PCM/распознавание не подтверждаются нашими span, нужна диагностика владельца voice. Внутреннее выполнение Whisper на H100 не появляется автоматически в Phoenix от наличия traceparent у chat-agent.
13Работает сейчас

Info, Attributes и Events: что там читать

Деталь span состоит из удобного представления Info, списка атрибутов и событий. У нашей интеграции содержимое специально ограничено, поэтому полезно заранее понимать, какие пустые поля нормальны.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 18 Info модельного span. Output может содержать только безопасную служебную запись с именем модели; текста ответа здесь нет.Нажмите на снимок, чтобы увеличить
  • 1Info / Attributes / Events
  • 2Output: служебные данные
  • 3Annotations: ручная оценка
  1. Во вкладке Info прочитайте название, тип, статус и блоки LLM/Tool. Отсутствие текста Input/Output в текущих трассах ожидаемо.
  2. Во вкладке Attributes найдите числовые значения и безопасные ключи. Переключатель Table / JSON меняет представление тех же данных.
  3. Если таблица длинная, используйте лупу поиска атрибутов и введите token, request или error. Если поиск не включён, можно просто прокрутить таблицу.
  4. Во вкладке Events проверьте число. Текущий safe exporter удаляет события, поэтому Events 0 не доказывает отсутствие исключений или streaming.
  5. Кнопка копирования рядом с Attributes копирует этот набор атрибутов. Для передачи коллеге достаточно IDs и безопасных времён, без содержимого самого чата.
  6. Не включайте запись conversation content только ради удобства диагностики. Для проверки текста используйте интерфейс чата и контролируемые учебные примеры.

Проверка по коду: санитизация атрибутов, events и links.

14Работает сейчас

Почему Sessions пусто и как смотреть весь чат

Phoenix умеет собирать разговоры в Sessions, но для этого нужен стандартный атрибут сессии. У нас сейчас передаётся пользовательский ключ chat.session_id. Поэтому вкладка Sessions пуста, хотя запросы чата есть в Spans.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 19 Фактическое состояние: Sessions = 0. Это не означает, что исчезла история PostgreSQL или Agent не обрабатывает вопросы.Нажмите на снимок, чтобы увеличить
  • 1Вкладка Sessions
  • 2Сейчас сессий 0
  • 3Set up: изменение интеграции
  1. В Tracing → default откройте Sessions. Если видите пустой список как на снимке, не пытайтесь искать чат по тексту или чужому user ID.
  2. Вернитесь в Spans. Используйте фильтр по chat.session_id и name == "chat_agent.agent".
  3. Откройте вопросы этой сессии по времени и сравните последовательность инструментов. Это рабочий способ просмотра текущего чата.
  4. Историю реплик и состояние планов смотрите в chat-agent: они хранятся приложением, а не восстанавливаются из Phoenix.
  5. Кнопка Set up Sessions объясняет подключение стандартного атрибута session.id. Это задача интеграции в коде, а не кнопка, которая автоматически найдёт наши старые чаты.
chat.session_id == "id-f9c26e6ff459" and name == "chat_agent.agent"
15Нужно назначить критерий проекту

Оценить правильность ответа вручную

Технический OK говорит, что этап завершился. Ручная оценка отвечает на другой вопрос: выполнил ли агент задачу пользователя. Так можно отделить "модель ответила" от "маршрут и расчёт действительно правильные".

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 20 Общий каталог оценок. В Phoenix уже есть user_feedback, но к проекту default она пока не подключена.Нажмите на снимок, чтобы увеличить
  • 1Settings → Annotations
  • 2Готовая user_feedback
  • 3Создать свой критерий
  1. Откройте Settings → Annotations. Для простой проверки достаточно существующей user_feedback с категориями positive / negative.
  2. Если нужен свой критерий, нажмите New Configuration. В Annotation Name введите task_correctness, а в Description - Правильность выполнения учебной задачи на карте.
  3. Выберите Categorical. В Categories задайте correct со score 1 и incorrect со score 0. Для такого критерия подходит Maximize. Нажатие Create Annotation Config сохранит конфигурацию.
  4. Откройте Tracing → default → Config. В Annotation Configs поставьте галочку напротив выбранной конфигурации. Это её назначение проекту; без него span-редактор оценки не предложит категорию.
  5. Найдите свой Agent через Spans и откройте Info → Annotations. Нажмите карандаш, выберите имя критерия и категорию. Если форма предлагает explanation, кратко укажите проверяемый факт, например Маршрут показан; арифметика 120-70-30 дала 20 минут; демоданные обозначены. Сохраните оценку кнопкой формы.
  6. Вернитесь к тому же span и проверьте появившуюся оценку. Она привязана к выбранному этапу; оценка инструмента и оценка всего Agent - разные записи.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 21 Форма нового критерия. Для учебника она только открыта: конфигурация не создана.Нажмите на снимок, чтобы увеличить
  • 1Имя критерия
  • 2Тип оценки
  • 3Категория и score
  • 4Сохранить конфигурацию
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 22 Назначение конфигурации проекту: слева от user_feedback сейчас пустая галочка.Нажмите на снимок, чтобы увеличить
  • 1Открыть Config
  • 2Назначить оценку проекту

Подробнее: ручные оценки в UI.

16Запись заметки - действие пользователя

Добавить заметку и передать ссылку на случай

Заметка нужна, когда одного класса ошибки мало. В ней оставляем наблюдаемые факты и вопрос для следующего расследования. Ссылка открывает ту же трассу, но не выдаёт доступ человеку без штатной авторизации.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 23 В карточке span есть Notes, а над деревом - Share. Для коллеги важны также request_id, trace_id и время.Нажмите на снимок, чтобы увеличить
  • 1Notes: добавить факт
  • 2Share: ссылка на трассу
  • 3Ключи для сопоставления
  1. Найдите конкретный Agent и проверьте его request_id. В Info разверните Notes.
  2. Нажмите значок добавления заметки справа от Notes. Введите краткое описание: время, ожидаемый результат, видимый пользователю сбой и что уже доказано по trace. Сохраните заметку кнопкой редактора.
  3. Укажите границу знания: например Видим RequestStopped после двух LLM-вызовов. Точный код остановки в этой трассе не экспортирован.. Не записывайте предположение как установленную причину.
  4. Для ссылки нажмите Share над деревом и воспользуйтесь копированием ссылки. Можно также скопировать текущий URL страницы с выбранным span.
  5. Передайте ссылку, request_id, trace_id и время коллеге через разрешённый рабочий канал. Не добавляйте Signature, cookie, SDP, аудио и разговор в техническую заметку.
  6. Учитывайте срок хранения. Ссылка не является архивом: после очистки трассы сохранённый HTML-снимок останется, а живой trace может исчезнуть.
Случай: TEST123 / запрос <request_id>
Время: <дата, время, GMT+3>
Trace ID: <trace_id>
Ожидалось: маршрут и расчёт 20 минут
Наблюдалось: <что увидел пользователь>
Phoenix: <этап, статус, длительность, error.type>
Не установлено: <какой причины пока нет в данных>
17Работает сейчас

Посмотреть общую картину в Metrics и Dashboards

Эти экраны помогают заметить изменения потока запросов, ошибок и токенов. В нашем проекте вместе находятся разные виды trace, поэтому общий график задержки не равен скорости ответа агента.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 24 Metrics проекта default. Долгие голосовые трассы растягивают Trace latency. Cost пуст, поскольку цены нашей модели не заданы.Нажмите на снимок, чтобы увеличить
  • 1Metrics внутри проекта
  • 2Задержки целых трасс
  • 3Cost: сейчас нет данных
  1. Откройте Tracing → default → Metrics. Выберите одинаковый период при сравнении двух наблюдений.
  2. Посмотрите Traces: сколько цепочек зарегистрировано и какие статусы у них были. Это число трасс, а не гарантированное число пользовательских реплик.
  3. В Trace latency читайте p50 как середину распределения, p95/p99 - как его медленный хвост. Сначала выясните, какие trace вошли: долгий голосовой сеанс может доминировать в хвосте.
  4. Прокрутите вниз к Token usage и моделям по токенам. Сверяйте счётчики с конкретным LLM-span, если хотите понять один вопрос.
  5. Для общего экрана нажмите слева Dashboards. В Select a project выберите default. Без проекта графики не появятся.
  6. Чтобы измерить время Agent, используйте выборку Spans и длительности Agent, а для ресурсов и очередей - корпоративную Grafana. Не выдавайте общий Phoenix p99 за время ответа чата.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 25 Первое открытие Dashboards: нужно выбрать проект.Нажмите на снимок, чтобы увеличить
  • 1Открыть Dashboards
  • 2Выбрать default
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 26 После выбора default появляются встроенные графики. Это сводка проекта, а не отдельный дашборд по request_id.Нажмите на снимок, чтобы увеличить
  • 1Проверить проект
  • 2Проверить период
18Для нашей модели цена не подтверждена

Откуда берётся Cost и зачем нужен Models

В Models хранится сопоставление имени модели с ценой токенов. Это справочник расчёта стоимости в Phoenix. Он не устанавливает модель на H100 и не меняет выбор модели нашего Agent.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 27 Справочник Models. На снимке встроенные тарифные записи Phoenix; они не являются стоимостью нашей Qwen на собственном сервере.Нажмите на снимок, чтобы увеличить
  • 1Settings → Models
  • 2Поиск точного имени
  • 3Цена входа и выхода
  • 4Add Model: новая запись
  1. Откройте Settings → Models. В поиске введите Qwen3.8-27B-FP8.
  2. Проверьте наличие правила и его match pattern. Сопоставление должно подходить фактическому имени из LLM-span.
  3. Если записи нет, Phoenix не знает согласованную цену этой модели. Наличие чужих built-in записей не решает этот вопрос.
  4. Для расчёта владелец может нажать Add Model, задать имя/шаблон, цену prompt и completion за миллион токенов и дату начала. Для собственного H100 нужны утверждённые внутренние ставки; не подставляйте облачный тариф другой модели.
  5. После настройки проверьте расчёт в конкретном span и периоде Dashboards. Отдельно учитывайте ресурсы сервера - этот справочник не даёт CPU/RAM и фактическую себестоимость.
19Форма доступна; набор не создан

Собрать учебные случаи в Dataset

Dataset - набор одинаковых входов и ожидаемых результатов. Он нужен, чтобы сравнивать варианты на одних и тех же задачах. Для начала достаточно трёх синтетических арифметических примеров, без истории production-чата.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 28 Текущий список Datasets пуст. New Dataset открывает мастер создания.Нажмите на снимок, чтобы увеличить
  • 1Datasets & Experiments
  • 2Новый набор
  1. Откройте слева Datasets & Experiments, затем нажмите New Dataset.
  2. На вкладке From scratch укажите имя chat-agent-demo-arithmetic. В Description напишите Синтетические проверки арифметики, без production-разговоров.
  3. В metadata можно записать {"scope":"synthetic","purpose":"tutorial"}. Это служебное описание набора.
  4. Нажмите Create Dataset, если хотите создать пустой набор. После создания отдельно нужно добавить примеры: само имя Dataset не создаёт тестовые строки.
  5. Для первого законченного опыта удобнее путь From file в следующей главе: он сразу импортирует три подготовленных примера.
  6. При использовании production-span не рассчитывайте автоматически получить исходный вопрос и ответ: они удалены из экспортированных данных. Для оценки качества нужны разрешённые входы и эталоны.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 29 Создание пустого Dataset. Имя, описание и metadata задаются здесь; примеры добавляются отдельно.Нажмите на снимок, чтобы увеличить
  • 1From scratch
  • 2Имя набора
  • 3Описание и metadata
  • 4Создать пустой набор

Подробнее: создание и импорт Dataset.

20Импорт описан; не выполнен

Импортировать готовые примеры из файла

Этот путь превращает учебные фразы в повторяемый набор. Inputs хранит вопрос, Outputs - ожидаемый результат, Metadata - признаки случая. Ожидаемый ответ - эталон для сравнения, а не уже полученный ответ модели.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 30 From file принимает CSV или JSONL. Лимит формы - 100 МБ; наш учебный JSONL содержит только три строки.Нажмите на снимок, чтобы увеличить
  • 1From file
  • 2Выбрать учебный файл

  1. Нажмите кнопку скачивания выше. Она создаёт файл из встроенных синтетических примеров прямо в браузере; запросов к сервисам не делает.
  2. В Phoenix откройте Datasets & Experiments → New Dataset → From file. Нажмите область загрузки или перетащите phoenix-demo.jsonl.
  3. В предварительном просмотре проверьте три строки. Если мастер предлагает сопоставление, назначьте inputs входами, outputs эталонными выходами, metadata служебными данными. Точные подписи следующего шага зависят от распознанного формата.
  4. Назовите набор chat-agent-demo-arithmetic и завершите импорт кнопкой создания в мастере.
  5. Откройте созданный набор и проверьте количество примеров: 3. В каждой строке должен быть inputs.question и эталон outputs.expected.
  6. Если импорт сообщает ошибку, сначала проверьте структуру JSONL: одна самостоятельная JSON-запись в строке, без общего массива. Не запускайте эксперимент по пустому или неправильно сопоставленному набору.
{"inputs": {"question": "До вылета 120 минут. На дорогу 70 минут, запас 30 минут. Сколько останется?"}, "outputs": {"expected": "20 минут"}, "metadata": {"case": "margin_20", "synthetic": true}}
{"inputs": {"question": "До вылета 90 минут. На дорогу 50 минут, запас 30 минут. Сколько останется?"}, "outputs": {"expected": "10 минут"}, "metadata": {"case": "margin_10", "synthetic": true}}
{"inputs": {"question": "До вылета 60 минут. На дорогу 50 минут, запас 30 минут. Объясни результат."}, "outputs": {"expected": "Не хватает 20 минут"}, "metadata": {"case": "negative_margin", "synthetic": true}}
21Запуск требует разрешённого провайдера

Подготовить модель для Playground

Чтение production-трасс и запуск нового модельного запроса - разные возможности. Agent уже работает через свой gateway, но Phoenix не наследует его credentials и доступ автоматически.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 31 AI Providers: у ключевых провайдеров not configured. Ollama не требует ключа по протоколу, но это не доказывает доступ к нашему endpoint.Нажмите на снимок, чтобы увеличить
  • 1Settings → AI Providers
  • 2Состояние подключения
  • 3Настройка провайдера
  1. Откройте Settings → AI Providers. Проверьте состояние выбранного провайдера и наличие согласованного custom provider.
  2. Для нашей Qwen нужен разрешённый доступ из Phoenix к существующему vLLM requester. Сам факт, что ваш Chrome авторизован через Slim Auth, не выдаёт серверу Phoenix такой доступ.
  3. Перед запуском попросите владельца настроить разрешённое подключение. Не переносите cookie, Signature или ключ нашего Agent в поле API Keys.
  4. Откройте Playground. Выбор gpt-5.6-luna на снимке - значение формы, а не доказательство настроенного провайдера и не модель текущего chat-agent.
  5. После разрешённой настройки откройте параметры выбранной модели: API Type - Chat Completions, Model Name - Qwen3.8-27B-FP8, Base URL - https://nats-proxy-vllm.gis-master.ru/v1. Согласуйте доступ до запуска, потому что наличие URL не доказывает доступ из Phoenix.
  6. Для сопоставимости с Agent используйте temperature 0, Max Completion Tokens 2048 и в Extra Body {"chat_template_kwargs":{"enable_thinking":false}}. Параметры формы не применяются к production-Agent.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 32 Параметры модели в Playground. На снимке ещё Responses и gpt-5.6-luna; для нашей Qwen после настройки нужен Chat Completions.Нажмите на снимок, чтобы увеличить
  • 1Открыть параметры
  • 2Имя модели
  • 3API: Chat Completions
  • 4Base URL провайдера

Проверка по коду: параметры production-запроса Qwen.

Подробнее: подключение совместимого провайдера.

22Нужен провайдер; запуск не выполняли

Проверить один промпт в Playground

Playground помогает проверить, как модель ответит на заданный текст. Он не воспроизводит весь Agent: без отдельной интеграции здесь нет нашей истории, снимка карты, NATS, Monty и сохранения плана.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 33 Редактор Playground. System задаёт правило ответа, User - шаблон, Inputs - значение переменной, Run - запуск через настроенный провайдер.Нажмите на снимок, чтобы увеличить
  • 1System: правило ответа
  • 2User: {{question}}
  • 3Ввести question
  • 4Run после настройки
  1. Убедитесь, что провайдер настроен по предыдущей главе. Откройте Playground и проверьте модель и параметры.
  2. В сообщении System замените учебное правило на Отвечай по-русски. Посчитай остаток времени. Если остаток отрицательный, явно скажи, сколько минут не хватает..
  3. В сообщении User укажите {{question}}. Оставьте формат Mustache: это переменная шаблона.
  4. В блоке Inputs → question введите До вылета 120 минут. Дорога 70 минут, запас 30 минут. Сколько останется?.
  5. Нажмите Run. В Output проверьте, что модель получила вопрос и рассчитала 20 минут. При ошибке доступа сначала исправляется штатное подключение провайдера, а не меняется защита endpoint.
  6. Для следующего опыта поменяйте только question. Если хотите сравнить промпты, сохраните вход одинаковым и переходите к следующей главе.
  7. Кнопка запуска из production-LLM-span не восстановит отсутствующий Input. Наш safe exporter удаляет содержание, поэтому для replay нужно вручную создать разрешённый синтетический пример.

Подробнее: Playground и сравнение вариантов.

23Нужны Dataset и провайдер

Сравнить два варианта и запустить Experiment

Сравнение имеет смысл, если вопросы одинаковые. Тогда меняем только правило ответа или модель и смотрим, улучшились ли результаты. Dataset задаёт входы, Experiment сохраняет результаты одного прогона.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 34 Compare находится вверху Playground, Test over a dataset - в Inputs. Сейчас Dataset ещё нет; успешного эксперимента на снимке нет.Нажмите на снимок, чтобы увеличить
  • 1Добавить вариант B
  • 2Выбрать Dataset
  • 3Запустить выбранные варианты
  1. Создайте учебный Dataset по разделам "Собрать учебные случаи в Dataset" и "Импортировать готовые примеры" и настройте провайдера. Вернитесь в Playground.
  2. В варианте A оставьте исходное правило. Нажмите Compare, чтобы добавить вариант B. В B измените только System, например добавьте требование проверять знак результата.
  3. Убедитесь, что в обоих вариантах одинаковые question, модель и параметры, если сравнивается именно промпт. Если сравниваются модели, одинаковым должен остаться промпт.
  4. В Inputs нажмите Test over a dataset. Выберите chat-agent-demo-arithmetic и нужную версию набора. Переменная question должна брать inputs.question каждого примера.
  5. Перед Run проверьте число строк и выбранные варианты. Запуск создаёт модельные запросы и результаты эксперимента - это не просто открытие страницы.
  6. После завершения откройте Datasets & Experiments → свой Dataset → список его Experiments. Выберите завершившийся прогон; сравните ответы по одним и тем же строкам, ошибки и оценки.
  7. Сначала исправьте неудачные строки, затем сравните сводную оценку. Три учебных примера показывают работу процедуры, но не доказывают общее качество всего голосового агента.
24Критерии ещё не созданы

Поставить автоматическую оценку

Evaluator превращает правило проверки в повторяемую оценку. Для арифметики лучше начать с точного правила, а не просить вторую модель судить первую. Но простая проверка наличия "20" легко пропустит неправильный смысл.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 35 Текущий раздел Evaluators объясняет две группы: Code и LLM. Пока список пуст; первый критерий добавляется к Dataset.Нажмите на снимок, чтобы увеличить
  • 1Раздел Evaluators
  • 2Code: формальная проверка
  • 3LLM: оценка моделью
  • 4Начать с Dataset
  1. Создайте Dataset и откройте его. В его разделе Evaluators нажмите Add Evaluator. Корневой пустой экран на снимке сначала предлагает View Datasets.
  2. Выберите тип проверки. Для строгого формата удобно Exact Match; для небольшого признака - Contains или Regex. Для содержательного ответа по-русски одного совпадения строки недостаточно.
  3. Задайте имя margin_correct и сопоставьте фактический output с ответом Experiment, а reference - с outputs.expected примера. Не подставляйте входной вопрос вместо ответа модели.
  4. Для code evaluator выберите разрешённую sandbox-конфигурацию. В следующей главе показаны доступные профили; они не меняют Monty внутри нашего Agent.
  5. Для LLM evaluator отдельно выберите настроенного судью и задайте критерии: правильный остаток, явный дефицит при отрицательном результате, отсутствие выдуманных фактов. Это создаёт дополнительные модельные вызовы.
  6. Сохраните evaluator и запустите новый Experiment с выбранным критерием. В результатах проверьте не только score, но и строки с ошибками оценки и explanation, если он доступен.
  7. Вручную просмотрите хотя бы случаи с нулевым/отрицательным остатком. Если evaluator ошибается, исправляйте критерий; нельзя объявлять Agent правильным только по красивой средней оценке.

Подробнее: настройка server-side evaluators.

25Профили включены; исполнение не тестировали

Различать песочницу Phoenix и Monty нашего Agent

В Phoenix тоже есть Monty. Но это отдельное выполнение для оценок и служебных операций Phoenix. Настройки этой страницы не меняют лимиты run_code нашего chat-agent.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 36 Состояние Sandboxes: локальные Deno, Monty и WebAssembly включены. У готовых профилей указан timeout 300 с; hosted-провайдеры требуют доступа.Нажмите на снимок, чтобы увеличить
  • 1Settings → Sandboxes
  • 2Локальные провайдеры
  • 3Готовые профили
  • 4Hosted требует доступа
  1. Откройте Settings → Sandboxes. В верхней карточке смотрите provider, язык и состояние Enabled / Authentication required.
  2. В нижней карточке Sandbox Configurations найдите готовый профиль нужного языка. На снимке есть default-monty-python, default-wasm-python и default-deno-typescript.
  3. При создании code evaluator выберите подходящую конфигурацию. Статус Enabled показывает настройку, но не заменяет успешный тест вашего evaluator.
  4. Для простой арифметики/JSON используйте локальную изолированную проверку. Внешний runtime, сеть и secrets для такого примера не нужны.
  5. Не меняйте timeout Phoenix, чтобы починить run_code в Agent. У Agent отдельный бюджет: Monty 10 с вычислений, 64 МиБ и общий ограниченный запрос. Для его диагностики смотрите tool-span и код chat-agent.

Подробнее: назначение sandbox-профилей.

26Форма доступна; промпт не сохранён

Сохранить промпт и работать с версиями

Сохранённый промпт позволяет вернуться к точному варианту после эксперимента. Важно не путать эту библиотеку с развертыванием нашего Agent: сохранение в Phoenix не переписывает системный промпт приложения.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 37 Форма сохранения из Playground. Можно создать имя или новую версию существующего промпта и назначить tag.Нажмите на снимок, чтобы увеличить
  • 1Prompt: открыть сохранение
  • 2Имя / существующий промпт
  • 3Tag версии
  • 4Сохранить в Phoenix
  1. Подготовьте вариант в Playground. Нажмите кнопку Prompt с иконкой сохранения рядом с выбором сохранённого промпта.
  2. В поле Prompt введите новое имя demo-time-margin или выберите существующее, чтобы сохранить следующую версию.
  3. В Description объясните изменение, например Явно сообщает дефицит при отрицательном остатке. В Metadata можно хранить имя учебного набора и цель опыта.
  4. Если нужен tag, выберите development для учебного варианта. Tags production / staging / development - указатели версий, а не команды CI/CD.
  5. Нажмите Create Prompt. Затем откройте слева Prompts, найдите имя и проверьте сохранённую версию, сообщения и параметры.
  6. Для следующего изменения загрузите нужный вариант в Playground, измените правило и сохраните новую версию. Сравнивайте её на той же версии Dataset.
  7. Чтобы перенести удачное изменение в chat-agent, нужна отдельная правка кода/интеграции и штатная поставка. Наша текущая реализация не читает автоматически Phoenix tag production.

Подробнее: версионирование промптов.

27Нужен настроенный провайдер PXI

Попросить PXI объяснить span или trace

PXI - помощник внутри Phoenix. Он может помочь прочитать цепочку и предложить направление проверки, но не заменяет доказательства в span. Это отдельный агент, а не наш агент на карте.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 38 Первое открытие PXI: Explain this span / Debug this span / Explain this trace и уведомление о работе с данными. Запрос помощнику не отправляли.Нажмите на снимок, чтобы увеличить
  • 1Объяснить выбранный этап
  • 2Ознакомиться с условиями
  • 3Запись трасс отключена
  • 4Первый вход: Acknowledge
  1. Откройте нужный Agent/span в Phoenix. Нажмите Ask PXI справа сверху.
  2. На первом открытии прочитайте сообщение о данных. Если вы решаете использовать помощника, нажмите Acknowledge. В нашем снимке запись полных session traces отключена системными настройками; не включайте её ради отладки.
  3. Проверьте модель и доступ: Settings → Assistant и AI Providers. Выбранный по умолчанию claude-opus-4-6 не доказывает наличие credentials. В текущей проверке запросы PXI не запускались.
  4. После разрешённой настройки нажмите Explain this span для выбранного этапа либо Debug this span. Для общей цепочки используйте Explain this trace.
  5. Если открылась строка сообщения, задайте конкретный вопрос: Разбери выбранный Agent: какие этапы самые долгие, какие ERROR видны, а каких данных не хватает для причины? Ничего не меняй..
  6. Сверьте ответ помощника с временем, атрибутами и business ID. Для нашего RequestStopped PXI тоже не получает скрытый текст исключения и не должен выдавать догадку за точный код причины.
  7. Если помощник предлагает изменение данных или настроек, сначала рассмотрите действие. Для чтения трассы такие изменения не обязательны.
Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 39 Настройки PXI: отдельно выбираются модель, инструменты, права и работа с данными. Они относятся к Phoenix Assistant, а не к карте.Нажмите на снимок, чтобы увеличить
  • 1Settings → Assistant
  • 2Права: manual approval
  • 3Модель помощника

Подробнее: возможности PXI.

28Запуск требует провайдера

Чем Chat в Phoenix отличается от карты

Раздел Chat отправляет сообщения напрямую выбранной модели через провайдера Phoenix. Это быстрый способ проверить модельный ответ, но у него нет нашей бизнес-логики и инструментов карты.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 40 Phoenix Chat: system prompt слева, сообщение и выбор модели снизу. Сам интерфейс предупреждает, что разговор не сохраняется после ухода.Нажмите на снимок, чтобы увеличить
  • 1System prompt модели
  • 2Ввести учебное сообщение
  • 3Выбрать модель
  • 4Отправить
  1. После настройки разрешённого провайдера откройте слева Chat.
  2. В нижнем выборе модели установите нужный провайдер/модель. Имя в пустом поле на снимке - default формы, не модель chat-agent.
  3. В System prompt напишите учебное правило. При необходимости задайте Temperature и Max output tokens слева.
  4. В нижнем поле напишите синтетический вопрос и отправьте стрелкой. Проверьте ответ и доступность модели.
  5. Для повторяемого сравнения переносите пример в Dataset/Playground. Страница предупреждает: разговоры этого Chat не сохраняются после выхода.
  6. Проверку маршрута, approval или голоса выполняйте на карте chat-agent. Отсутствие этих действий в Phoenix Chat - ожидаемая граница этого режима.
29Работает сейчас

Проверить срок хранения трасс

Трасса - временная запись выполнения. История чата и сохранённые планы живут в БД приложения отдельно. Удаление старой trace не удаляет их и не означает, что запрос не выполнялся.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 41 Settings → General: версия сервера и максимальный возраст trace 7 дней. Расписание очистки видно в Config проекта.Нажмите на снимок, чтобы увеличить
  • 1General
  • 2Версия 20.19.0
  • 3Хранение: 7 дней
  1. Откройте Settings → General. Проверьте Hostname и Platform Version, чтобы понимать, с каким Phoenix работаете.
  2. Прочитайте Maximum Trace Retention in Days. В нашей настройке - 7. Здесь значение только просмотрено.
  3. Откройте Tracing → default → Config → Data Retention. В нашем UI указана политика Default: удаляются traces старше 7 дней, расписание - воскресенье 00:00 UTC.
  4. Для разбора недавнего сбоя сохраните ссылку, IDs и снимок выбранного этапа. Ссылка после очистки не является долговечным архивом.
  5. Не увеличивайте retention самостоятельно только потому, что старый пример пропал. Владелец должен согласовать хранение и объём, а для учебника уже встроены изображения исторических случаев.

Проверка по коду: версия Phoenix, внутренняя БД, retention и OAuth ingress.

30Схема доступна; автоматизация требует доступа

Посмотреть REST API без изменения сервиса

REST API нужен для разрешённой автоматизации чтения и оценок. Схема показывает доступные операции именно установленной версии. Цветные POST/PUT/DELETE - реальные изменения данных, а не учебные кнопки.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 42 Встроенная REST-схема Phoenix. Для знакомства раскрываем GET и читаем параметры/ответы; изменения не выполняем.Нажмите на снимок, чтобы увеличить
  • 1REST API
  • 2GET: описание чтения
  • 3POST / PUT / DELETE меняют данные
  1. Нажмите слева REST API. Откроется схема Arize-Phoenix REST API.
  2. Раскройте нужный GET, например /v1/annotation_configs. Прочитайте query/path parameters и формат ответа, прежде чем вызывать endpoint.
  3. Для связи запроса с трассой пользуйтесь именами и IDs из Phoenix. request_id приложения не является универсальным ID любого объекта REST API.
  4. Если вам нужен только просмотр структуры, не нажимайте Try it out / Execute. Для программного чтения сначала нужен штатный доступ, согласованный для клиента; браузерная Signature не равна API credentials.
  5. Учтите внешний Slim Auth. В нашей конфигурации встроенная Phoenix-auth отключена за защищённым ingress, поэтому обычная инструкция Phoenix по API keys не описывает весь корпоративный доступ.
  6. При 401/403 или блокировке клиента остановите этот путь и используйте разрешённый UI/обратитесь к владельцу доступа. Не копируйте браузерные cookie в скрипт как обход.

Проверка по коду: граница встроенной авторизации и Slim Auth.

31Работает сейчас

Сделать безопасный запрос чтения в GraphQL

GraphQL позволяет выбрать нужные поля из схемы Phoenix. Для первого знакомства достаточно запроса, который возвращает имя корневого типа. Он ничего не записывает и не раскрывает разговоры.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 43 Реально выполненный query { __typename }: справа получен ответ Query. Комментарии стартового редактора не влияют на выполнение.Нажмите на снимок, чтобы увеличить
  • 1Ввод query слева
  • 2Выполнить чтение
  • 3Результат справа
  • 4Документация схемы
query { __typename }
  1. Откройте слева GraphQL. На странице GraphiQL нажмите левый редактор Query.
  2. Нажмите Ctrl+A внутри редактора и замените содержимое выражением выше. Не вводите mutation для знакомства: оно может изменить данные.
  3. Нажмите розовый треугольник либо Ctrl+Enter. Справа должен появиться JSON {"data":{"__typename":"Query"}}. Такой результат действительно получен в этой проверке.
  4. Чтобы изучить прикладной query, откройте Documentation Explorer слева сверху. Ищите тип Query и доступные поля текущей схемы, затем их аргументы и возвращаемые поля.
  5. Не придумывайте запрос по request_id, не проверив схему. Это атрибут span нашего приложения; путь фильтрации GraphQL определяется схемой Phoenix.
  6. Для первой отладки пользовательского запроса удобнее Spans и готовые фильтры учебника. GraphQL оставьте для разрешённой автоматизации, когда формат действительно нужен.
32Служебная настройка; для чтения не нужна

Зачем в Phoenix Secrets

Secrets - служебное хранилище для поддерживаемых интеграций Phoenix. Это не место для копирования Signature пользователя или credentials chat-agent при обычной отладке.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 44 Фактическое состояние Secrets: No secrets. Никакие значения в этой проверке не просматривались и не вводились.Нажмите на снимок, чтобы увеличить
  • 1Settings → Secrets
  • 2Список сейчас пуст
  • 3New Secret: отдельная настройка
  1. Откройте Settings → Secrets. Посмотрите названия записей, если они есть; для чтения trace этот раздел не нужен.
  2. Если evaluator или провайдер требует secret, сначала определите, кто владеет интеграцией и какой доступ ей разрешён. Новая запись не создаёт сетевой доступ сама по себе.
  3. Настройку выполняет владелец через штатный механизм. Не помещайте значения в заметки, Dataset, промпт, учебник или снимок экрана.
  4. При разборе ошибки доступа фиксируйте имя интеграции и статус, а не значение секрета. В текущем учебном пути достаточно настроить разрешённого провайдера через владельца.
33Сервер включён; внешний клиент не проверен

Что означает MCP и почему это отдельный доступ

MCP даёт внешнему агенту возможность обращаться к операциям Phoenix. Он может облегчить поиск trace и работу с экспериментами, но подключение клиента не выполнено в рамках этого учебника.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 45 Phoenix показывает MCP server: enabled и Code mode: enabled. Это состояние самого сервера; успешный доступ внешнего клиента здесь не проверен.Нажмите на снимок, чтобы увеличить
  • 1Settings → MCP
  • 2Сервер включён
  • 3Адрес MCP
  • 4Инструкции по клиентам
  1. Откройте Settings → MCP. Прочитайте состояния сервера и Code mode. На снимке они enabled, URL - https://phoenix.gis-master.ru/mcp.
  2. Не трактуйте надпись "Authentication is disabled" как открытый публичный доступ. Она относится к встроенной авторизации Phoenix; снаружи наш домен защищает Slim Auth.
  3. Для подключения внешнего клиента сначала согласуйте штатный машинный доступ и область операций. Готовые команды этой страницы не проверяют совместимость с корпоративным ingress.
  4. После разрешённого подключения начните с чтения проекта и trace. Операции создания/редактирования/удаления datasets, prompts и annotations имеют побочные эффекты и требуют отдельного намерения.
  5. Code mode MCP работает с операциями Phoenix. Он не вызывает автоматически инструменты карты и не заменяет run_code в chat-agent. Для обычной отладки хватит Spans без установки клиента.

Подробнее: встроенный MCP Phoenix.

34Панель доступна; конвертацию не проверяли

Получить фильтр из обычной фразы

AI Query помогает составить выражение поиска. Это отдельная функция редактора фильтра, а не новая генерация нашего Agent. Для точной диагностики безопаснее сохранять и проверять итоговое выражение.

Снимок рабочего интерфейса хранится в исходном архиве.
Рис. 46 Панель AI Query: выбран Gemini Nano. Преобразование фразы в этой работе не запускалось; вручную проверенные фильтры приведены в учебнике.Нажмите на снимок, чтобы увеличить
  • 1Звёздочки / настройки
  • 2Модель фильтра
  • 3Generative AI settings
  1. В Spans нажмите звёздочки Plain-English query рядом со строкой фильтра. Для выбора модели откройте соседнюю шестерёнку AI query settings.
  2. Прочитайте выбранную модель и состояние в её настройках. На снимке выбран Gemini Nano; это не Qwen нашего Agent. Выбор в форме не заменяет проверку доступности конвертации.
  3. Если функция готова и её использование разрешено, замените строку описанием, например Show spans named chat_agent.agent with error status. Для преобразования используйте действие AI Query / указанное сочетание Ctrl+Enter. Обычный Enter применяет готовый фильтр.
  4. Прочитайте получившееся выражение: имя должно быть chat_agent.agent, статус ERROR, а поля должны относиться к spans. Только затем применяйте фильтр.
  5. Если конвертация недоступна или дала неверный фильтр, вставьте готовое выражение ниже и нажмите обычный Enter. Для нашей задачи помощь модели необязательна.
  6. Не вводите сюда текст разговора для поиска: наша production-трасса его не содержит. Формулируйте условие по имени этапа, status, session_id, request_id или длительности.
name == "chat_agent.agent" and status_code == "ERROR"
35Работает сейчас

Если что-то не видно или выглядит странно

Эти ситуации встречаются раньше, чем настоящая поломка модели. Проверяем их в этом порядке, чтобы не искать ошибку в неправильном запросе или периоде.

Что вижуЧто проверитьЧто это пока не доказывает
Нет Agent в спискеSpans, период, полностью заменить parent_id is None фильтром Agent.Что запрос не выполнялся.
По request_id лишь 3-4 строкиОткрыть Agent и всё дерево его trace. SDK-child может не иметь business ID.Что было только 3-4 действия.
Trace длилась почти часВыбрать span конкретного Agent и сверить его request_id/время.Что ответ занимал час.
Sessions = 0Использовать chat.session_id в Spans.Что история чатов потеряна.
Input/Output пусто, Events 0Учесть safe exporter; смотреть текст в чате, безопасные атрибуты в Phoenix.Что не было prompt, ответа или исключения.
OK, но ответ неверныйПроверить инструменты, карту и арифметику; поставить ручную оценку.Что задача решена правильно.
RequestStoppedПроверить штатный ответ UI/Network и вложенные ERROR.Конкретную причину: deadline, отмену или неверный tool.
UNSET / unknownПосмотреть статус и kind выбранного span, а не считать слово unknown ошибкой.Неуспешное выполнение.
Cost пуст / $0Проверить Models и match pattern, согласованную цену Qwen.Бесплатность H100.
Playground 401/403Проверить разрешённого провайдера и доступ из Phoenix.Что сломался production-Agent.
Старый пример исчезПериод, retention 7 дней и плановая очистка. Снимок в учебнике остаётся.Что такой запрос никогда не существовал.
Нет внутреннего Whisper/GPUПроверить границу экспортирующих сервисов и обратиться к владельцу voice.Что GPU не выполнял распознавание.
  1. Вернитесь к своей реплике: session_id, request_id, время и ожидаемый результат.
  2. Убедитесь, что рассматриваете его Agent, затем выбранную дочернюю ветку.
  3. Отделите подтверждённые факты от отсутствующих данных. Для неустановленной причины оставьте точное описание пробела.
  4. Если нужен коллега, передайте безопасную ссылку и краткую заметку по главе 16. Не снимайте защиту и не запускайте повторный production-сценарий только ради красивого trace.
36Работает сейчас

Короткий маршрут от вопроса до вывода

Для ежедневной работы достаточно этого порядка. Остальные разделы нужны, когда вы переходите от разбора одного случая к оценке изменения.

  1. На карте отправить один учебный вопрос; сохранить время, session_id и request_id из Network, если нужен точный ключ.
  2. Phoenix → Tracing → default → Spans → правильный период.
  3. Ctrl+A в фильтре → chat.request_id == "ВАШ_ID" → Enter → открыть Agent.
  4. Проверить session_id, request_id и начало выбранного Agent. Смотреть его длительность, а не всей голосовой trace.
  5. Пройти по его ветке: LLM → tools / run_code → map tool → итог. Для ошибки - вложенные ERROR и error.type.
  6. Сверить результат на карте. OK в Phoenix и правильный пользовательский ответ - разные проверки.
  7. Сохранить заметку/ссылку и оценку. Для сравнения изменений создать синтетический Dataset и разрешённый Experiment.
name == "chat_agent.agent"

chat.request_id == "ВАШ_REQUEST_ID"

chat.session_id == "ВАШ_SESSION_ID" and name == "chat_agent.agent"

name == "chat_agent.agent" and status_code == "ERROR"

name == "chat_agent.agent" and latency_ms > 10000

name == "execute_tool flight_get"

Два реальных случая со снимков

СлучайКлючиЧто действительно видно
Успешный деморейс / расчётrequest_id = id-c6d770439429
trace_id = 09827560b569665617a71cb45167f78e
07.10.2026 04:51:23, GMT+3
Agent 8,9 с; flight_get, run_code, чтения и map_show_route. Точный исходный текст не экспортирован.
Остановленный запросrequest_id = id-18139683b422
trace_id = 15bd3a8e95843122a9953e02713f6907
07.10.2026 06:17:45, GMT+3
Agent ERROR 2,4 с; RequestStopped; два gateway LLM этапа. Точная причина остановки в этом наборе атрибутов отсутствует.

Старые живые trace могут быть удалены политикой хранения. Их снимки встроены в этот файл, поэтому учебник открывается автономно.

На чём основан учебник

Пути кнопок и состояние настроек проверены в Phoenix 20.19.0. Контракт приложения сверён с исходниками 7747c4c3. Это ссылка на проверенную версию кода, а не самостоятельное подтверждение SHA каждого работающего контейнера. Поздние изменения основного потока в этот снимок не включены.

Наш Phoenix · Карта chat-agent · Официальная документация Phoenix

Основные кодовые источники: безопасный экспорт, этапы и ошибки, ID текстового запроса, инструментирование Agent, вызов модели, размещение и защита Phoenix.

↑
Оригинальный снимок с подписями. Прокрутка - внутри окна; Esc - закрыть.

Служебные вложения доступны в исходном архиве.