live · mlexi_dev · 2026-06-15

Четыре агента,
один рантайм.

chat · slides · image · search построены на общем ядре с замороженными портами: ИИ за интерфейсом AgentDriver, состояние — типизированный RunState, который течёт в браузер через change-log → SSE. Кликните любую сущность — внутри «что делает» и пошаговый механизм работы.

01

Pipeline одного запроса

Поток одинаков для всех четырёх агентов — различаются лишь набором инструментов и формой состояния. Кликайте по шагам.

02

Слои инфраструктуры

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

03

Агенты — подробно

Инструменты, режимы и форма RunState каждого продукта.

3·5

Исходники: агенты + рантайм

Буквальный код каждого агента и общего рантайма mlexi_agent (порты: AgentDriver, RunInput, Tool, StateWriter, fold_changes, …) — прямо из репозитория. Выбери вкладку и файл; путь указан над кодом, кнопкой copy можно скопировать. Большие файлы показаны фрагментами.

04

MCP-меш

Агент-продукт сам становится набором инструментов для других. Cookie сессии форвардится сервис-в-сервис для whoami-авторизации.

Продьюсеры (/mcp)

Кто что потребляет

05

Общие паттерны

На чём держатся все четыре агента.

06

Порты в коде

Реальные фрагменты из packages/python/mlexi_agent и composition root воркфлоу.

07

Как работает Opik

Opik (Comet, self-hosted, Apache-2.0) — хранилище и UI для трейсов агентов по стандарту OpenTelemetry gen_ai. Отвечает на вопрос «что именно делал агент»: какие промпты ушли в модель, что она вернула, сколько токенов, какие инструменты вызывались, сколько заняло и сколько стоило. У нас трассируются все 4 агента (chat · image · search · slides). Phoenix полностью удалён.

Конвейер трейса (в общем виде)
Спаны gen_ai — ручная разметка, без авто-инструментации

Трейс = дерево спанов; у каждого gen_ai.operation.name и атрибуты. Виды: invoke_agent агент · chat вызов модели (итерация) · execute_tool инструмент. Спаны эмитит общий PydanticAIDriver вручную (по требованию оператора — никакой авто-инструментации), одной пост-реконструкцией после прогона из result.all_messages(). У каждой итерации: точный input (история ДО ответа), output (ответ), gen_ai.usage.* токены и стоимость mlexi из gateway (mlexi.cost_credits — int-micros в usage.details, не оценка Opik). Тайминг — из таймстемпов сообщений; раскладка по проектам через Comet-Workspace+projectName.

В нашем проекте — кто и как
сервискак инструментированчто видно
chat · image · search · slides ручные gen_ai-спаны (общий PydanticAIDriver → OTLP-HTTP → Opik) chat/execute_tool-спаны с промптами, ответами, токенами, тулзами, стоимостью
codexapi не трассируется: stateless шим, не агент — роундтрип уже виден в спане агента + в gateway
gateway · identity · billing · info не трассируются (не агентные / не LLM-фреймворковые)

По проекту на продукт (chat/image/search/slides); доступ opik.mlexi.ru только админу (Caddy forward_auth → identity /internal/v1/check-admin); приём OTLP-HTTP на opik-frontend-1:5173/api/v1/private/otel/v1/traces (свой compose-стек /opt/opik); внутренний OTLP самого DBOS отключён (enable_otlp=False).

Пример дерева трейса — slides «2 слайда»
invoke_agent agent slides           service=slides · Σ cost+tokens
├─ chat iteration 1           input=[system,user] → plan_deck
│   └─ execute_tool plan_deck
├─ chat iteration 2           → create_slide / search_image
│   ├─ execute_tool create_slide
│   └─ execute_tool search_image
├─ chat iteration 3           → render_slide (vision-check)
│   └─ execute_tool render_slide
└─ chat iteration N           → финальный ответ
(у каждой итерации — реальные input/output, токены и цена mlexi из gateway)
Код — как мы это включаем
Как пользоваться