Бывало у вас такое: месяцами пилишь архитектуру, фичи летят одна за другой, тесты зелёные. Всё работает. А потом в какой-то момент ловишь себя на мысли: «Я вообще перестал понимать, как эта штука работает».

Именно это произошло со мной во время разработки PAD+ AI. После очередного раунда из миллионов тестов я осознал, что полностью потерял контроль над системой.

Проблема наблюдаемости в AI-системах

К тому моменту PAD+ AI уже умел многое: работал с памятью, пайпланами, эмоциями, Truth Loop и персонами. Результаты становились всё лучше, но вылезла неожиданная проблема.

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

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

  • какие именно компоненты участвовали в обработке;

  • в каком порядке они отрабатывали;

  • где конкретно возникла задержка или ошибка;

  • как менялось состояние системы по ходу дела.

В сложных системах это приводит к полной потере объяснимости. Я видел только вход и выход. А между ними было абсолютное чёрное пространство.

Так появилась концепция трасс

После очередной серии неудачных тестов я задал себе вопрос, который в итоге перевернул архитектуру проекта: «А что, если попробовать посмотреть на проблемы изнутри?»

Так и родилось название X-Ray. Простая аналогия: мне нужен был инструмент, который работает как рентген, показывая не просто симптом, а всю «костную структуру» процесса выполнения.

Я перестал смотреть на отдельные события и начал анализировать сам путь выполнения. Каждый пользовательский запрос превратился в отдельную Trace. Внутри неё каждая операция стала отдельным Span. В итоге получилась структура, напоминающая дерево выполнения:

Trace
├── Safety
├── Intent
├── RAG
├── Knowledge Graph
├── Semantic Memory
├── Persona
├── Generate
├── Truth Loop
└── Response Guard

Теперь можно было увидеть не только последовательность выполнения, но и время прохождения каждой фазы, взаимосвязь между этапами и полный путь обработки запроса.

Сразу проясню один момент

Давайте расставим точки над «i»: X-Ray — это не замена логам.

Логи просто кричат «тут упало» или «произошло событие X». Трасса же говорит: «вот полный путь, которым система пришла к результату, со всеми зависимостями, временными метками и контекстом». Это позволяет восстанавливать полную картину обработки запроса даже спустя недели. Именно тогда стало понятно, что мы имеем дело с совершенно другим классом инструментов.

Почему X-Ray вынесло в отдельный проект

Изначально X-Ray создавался исключительно для PAD+ AI и жил внутри его когнитивного pipeline. Но довольно быстро выяснилась интересная вещь: библиотека практически ничего не знает о когнитивной архитектуре.

Ей безразлично, что именно крутится внутри: LLM, REST API, Telegram-бот, микросервис или платёжная система. Любой процесс можно представить как последовательность связанных операций. Это означало, что X-Ray можно использовать далеко за пределами моего ИИ-проекта. Так он превратился в самостоятельную библиотеку.

Что представляет собой X-Ray сегодня

Сегодня это production-ready библиотека наблюдаемости, которую можно встроить практически в любой Python-проект. Её задача — не управлять приложением и не принимать решения, а максимально подробно фиксировать ход выполнения.

Под капотом X-Ray реализует:

  • модель Trace / Span;

  • прозрачное распространение trace_id между сервисами (propagation);

  • middleware-интеграцию (например, для FastAPI);

  • persistence — запись трасс на диск с автоматическим восстановлением после перезапуска;

  • гибкие режимы работы: live, shadow, readonly, disabled;

  • аудит целостности трасс и поиск нарушений причинно-следственных связей;

  • инструменты валидации и санитизации повреждённых данных;

  • REST API для доступа к трассам и результатам аудита.

По своей роли X-Ray можно сравнить с бортовым самописцем самолёта. Он не предотвращает ошибки и не исправляет их автоматически. Он делает гораздо более важную вещь: сохраняет полную картину произошедшего, чтобы инженер мог понять, почему система пришла именно к такому результату.

Persistence и восстановление

Каждый завершённый трейс записывается на диск в JSON. При перезапуске все трейсы восстанавливаются автоматически. Активные трейсы помечаются как interrupted, но все их спэны сохраняются.

trace_store/
├── traces/{trace_id}.json
├── spans/{trace_id}/span_{id}.json
├── index.json
├── archive/       # Архивы retention
└── quarantine/    # Повреждённые данные

Пример интеграции в FastAPI

Для подключения X-Ray к приложению на FastAPI достаточно добавить middleware и передавать идентификатор трассы между вызовами. Базовая интеграция занимает буквально несколько минут.

1. Подключение middleware:

from fastapi import FastAPI, Request
from aethon.xray.http_propagation import fastapi_extract_xray

app = FastAPI()

@app.middleware("http")
async def xray_middleware(request: Request, call_next):
    headers = fastapi_extract_xray(request)
    trace_id = headers.get("trace_id", "")
    response = await call_next(request)
    if trace_id:
        response.headers["X-Trace-Id"] = trace_id
    return response

Нюанс: fastapi_extract_xray возвращает не скаляр, а словарь из 5 полей: trace_id, span_id, parent_span_id, logical_ts, causal_depth. Это необходимо для полной поддержки propagation-контекста между сервисами.

2. Обёртка внешних вызовов:

from aethon.xray import start_span, SpanKind

async def call_provider():
    span = start_span(kind=SpanKind.EXTERNAL, name="provider_call")
    try:
        result = await provider.call()
        span.end(success=True)
        return result
    except Exception:
        span.end(success=False)
        raise

3. Конфигурация persistence (в коде):

from aethon.xray.trace_store import store

# Включение записи трейсов на диск
store.configure_persistence("./data/trace_store")

4. Проверка работоспособности:

GET /health                → {"status": "ok", "mode": "live", "trace_store": true}
GET /xray/audit/{trace_id} → {"trace_id": "...", "all_passed": true}
GET /xray/traces           → {"traces": [...]}

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

Где X-Ray уже работает

X-Ray не остался на бумаге. Сегодня он работает в продакшене как часть приложения PAD+ AI, развёрнутого на Render.

? PAD+ AI на Render

Что можно увидеть в реальном времени:

Pasted image 20260716230033.png

Каждый запрос, проходящий через PAD+, оставляет за собой полную трассу, и за этим можно наблюдать в реальном времени:

? Live-режим через WebSocket. Специальный endpoint /api/v1/xray/ws отправляет события trace_event на фронтенд. Вы видите, как запрос проходит через все стадии pipeline: Safety → Intent → Retrieve → Persona → Generate → Verify → Remember → Emit. Каждая стадия подсвечивается, показывается время выполнения и статус. Это как смотреть на ЭКГ в реальном времени.

? Визуализация pipeline. Фронтенд-компонент XRayPipeline.jsx показывает активную стадию, завершённые этапы и общее время обработки.

? История трейсов. Через endpoint GET /api/v1/xray/recent?limit=50 можно получить последние 50 завершённых сессий с деталями: user_message, start_time, events, metadata, stage_times и total_time_ms. Компонент TraceHistory.jsx позволяет искать и фильтровать их по статусу.

? Детальный просмотр и экспорт. Через GET /api/v1/xray/sessions/{session_id} можно получить полную информацию о конкретной сессии и экспортировать данные в JSON или CSV для внешнего анализа.

? Персистентность. В памяти хранятся последние 100 сессий, а завершённые трейсы сохраняются на диск.

Область применения

После отделения от PAD+ AI оказалось, что X-Ray можно использовать для микросервисной архитектуры, AI-приложений с несколькими LLM-провайдерами, Telegram- и VK-ботов, систем обработки документов, RAG-приложений, платёжных шлюзов и распределённых API.

Фактически, любая программа, в которой важно понимать не только итог работы, но и путь, которым система к нему пришла, может использовать X-Ray.

Но на этом история не закончилась

После появления X-Ray произошло ещё одно неожиданное открытие. Система действительно научилась видеть всё, что происходит внутри: каждую фазу, каждую ошибку, каждое отклонение и деградацию.

И однажды возник следующий вопрос: если система уже умеет видеть собственные проблемы… почему она не может начать исправлять их самостоятельно?

Именно этот вопрос позже привёл к созданию ещё одного независимого проекта — HEALER. Но это уже совсем другая история.


Ссылки и материалы

? PAD+ AI v4.0: исследовательская когнитивная архитектура поверх LLM — первая статья о проекте, для которого изначально создавался X-Ray. Рекомендую начать с неё, чтобы понять контекст.

? GitHub: xray-integration-kit — исходный код библиотеки. Репозиторий пока приватный, но если хотите изучить архитектуру, предложить улучшения или просто обсудить трассировку — пишите, открою доступ заинтересованным.

? PAD+ AI на Render — живое демо, где можно увидеть работу X-Ray в реальном времени.

? https://github.com/Ovladimirovich/xray-integration-kit/blob/master/docs/xray/INSTALL.ru.md — полное руководство по установке и настройке X-Ray: минимальная интеграция за 5 минут, описание режимов работы, структура persistence и production-чеклист.

? Telegram: @padplusai — для вопросов, предложений и запросов на доступ к репозиторию.


Комментарии (0)