Два окна главной страницы pacod-demo, светлое и тёмное, наложенные друг на друга. В каждом под шапкой объявление о сбросе, заголовок об ИИ-шлюзе, CMS и конструкторе агентов, работающих как одна платформа, и карточки pacod-gw, pacod-cms и pacod-ap; в тёмном видна и схема платформы.
Главная страница демо днём и ночью: объявление о ночном сбросе и карточка каждого продукта со ссылками на него. Запущенная на ноутбуке, как здесь, она подсказывает и как войти; на demo.pacod.io администратор не называется.

pacod-demo запускает идентификацию, AI-шлюз, платформу агентов, CMS, базу знаний и бенчмарки шлюза вместе на одной машине, из одного файла конфигурации и одной командой make. Он подключает compose-файл каждого репозитория без изменений, даёт им по одному экземпляру каждого общего компонента, знакомит продукты друг с другом и проверяет, что они работают как единое целое; каждую ночь он возвращается в известное состояние.

Весь стек

Возможности

Одна главная страница

Каждый продукт с описанием, скриншотом и ссылками на его администрирование и сайты, в дневной или ночной теме.

Один вход

Один realm pacod-id для всех продуктов. Вошли в один — вошли во все.

Один шлюз

Вызовы моделей всех продуктов идут через pacod-gw, у каждого свой ключ. Без ключа провайдера отвечает его mock-провайдер, и ничего не покидает машину.

Всего по одному

Один Caddy, один PostgreSQL, один Qdrant, один сервис эмбеддингов, один почтовый ящик для отправленных писем и один стек мониторинга, общие для всех продуктов.

Собственные файлы репозиториев

Шесть compose-файлов подключаются без изменений; небольшой overlay на репозиторий только задаёт адреса и секреты и убирает опубликованные порты.

Сброс каждую ночь

По умолчанию в 05:00 UTC данные всех продуктов возвращаются к базовому состоянию. Всё изменённое исчезает после ближайшего сброса.

Дашборды и почта

Grafana с дашбордами каждого продукта, Prometheus для ad-hoc запросов и просмотр каждого письма, которое отправляет стек.

Проверен как одна платформа

make verify проверяет точку входа, внутреннюю сеть, единый вход в пять продуктов, ключи шлюза у продуктов, базу знаний, сайты и бенчмарк.

Готов к домену

HTTPS с одним сертификатом на домен, его поддомены и домен сайтов; при публикации за пределы машины инструменты, безопасные только на ноутбуке, закрываются.

Диаграмма. Люди пользуются pacod-ap, pacod-cms и pacod-kb; все три обращаются к моделям через pacod-gw и входят через pacod-id; pacod-benchmark измеряет pacod-gw; пунктирная рамка pacod-demo охватывает всех.
Как связаны проекты. Зелёные точки: вызовы LLM, все через pacod-gw. Золотые точки: вход и роли, все через pacod-id. Серый: используется людьми. Коралловый: pacod-benchmark измеряет шлюз. pacod-demo запускает их все как одну платформу.

Скриншоты

Тёмная панель консоли pacod-gw, вход выполнен как admin@pacod.demo с ролью администратора платформы, с плитками запросов, ошибок, стоимости, токенов и задержки шлюза, графиком запросов по часам и состоянием установки ниже.
Консоль шлюза в стеке, открытая тем же входом, что и любой другой продукт. Здесь учитываются вызовы моделей всех продуктов, с токенами, стоимостью и задержкой, добавленной самим шлюзом.
Светлая главная страница сайта pacod-ap с надписью «Build and run your own AI agents», превью чата, где Starter Help-Desk Assistant отвечает на вопрос о цене со ссылкой на справочный факт, и три показателя ниже.
Собственный сайт платформы агентов, первая страница app.demo.pacod.io. Отсюда посетитель попадает в чат со стартовым агентом и в консоль администратора, где агенты создаются.
Главная страница Starward с главной статьёй «Why the stars do not twinkle in space» на фоне звёздного поля с зелёной туманностью, меню рубрик сверху и рекламой Aurelian Lines внизу.
Starward, витрина демо среди сайтов, на наборе шаблонов magazine в pacod-cms. Вымышленный журнал о космических путешествиях с фотографиями NASA и анимированной HTML5-рекламой вымышленных рекламодателей.
Светлый экран поиска pacod-kb с вопросом «How does the gateway keep provider keys?» и ранжированными фрагментами документации pacod-demo и pacod-gw ниже, у каждого оценка RRF.
База знаний отвечает на вопрос гибридным семантическим и ключевым поиском на общих для стека Qdrant и сервисе эмбеддингов. Каждый фрагмент показывает, откуда он, и свою объединённую оценку ранга.

Попробовать

Демо работает на demo.pacod.io, и его главная страница ведёт ко всему остальному: каждый продукт с описанием, скриншотом и ссылками на его администрирование и сайты. Каждый продукт отвечает на собственном поддомене, все за одной точкой входа:

Адрес Что
demo.pacod.io Главная страница: каждый продукт со своими ссылками
app.demo.pacod.io Платформа агентов (pacod-ap): её сайт, чат и консоль администратора
console.demo.pacod.io Консоль шлюза (pacod-gw): провайдеры, модели, ключи, потребление
gw.demo.pacod.io/v1 OpenAI-совместимый API шлюза, по ключу шлюза
studio.demo.pacod.io Студия CMS (pacod-cms)
cms.demo.pacod.io Demo Journal, сайт CMS; Demo Notes на minimal., Starward на space.
kb.demo.pacod.io База знаний (pacod-kb)
bench.demo.pacod.io Бенчмарки шлюза (pacod-benchmark): наборы, прогоны, сравнения
id.demo.pacod.io/admin Администрирование идентификации (pacod-id)
grafana.demo.pacod.io Дашборды всех продуктов
mail.demo.pacod.io Каждое письмо, которое отправляет стек
prometheus.demo.pacod.io Метрики, для ad-hoc запросов

Один вход покрывает все продукты: вошли в один — вошли во все. Самостоятельной регистрации нет: учётные записи создаёт администратор или выдают по приглашению, а без учётной записи всем открыты сайты и публичные страницы продуктов. Grafana, Prometheus и просмотр почты вместо этого спрашивают email и пароль администратора. Любое изменение отменит ближайший ночной сброс.

Зачем он нужен

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

pacod-demo устроен наоборот. Он ставит шесть продуктов на одну машину как одну платформу, с одним экземпляром каждого общего компонента, и показывает то, что появляется только при совместной работе: один вход, который признаёт каждый продукт, один шлюз, через который идёт каждый вызов модели и который их все тарифицирует, бенчмарк, который измеряет этот же шлюз, и один набор дашбордов для всего стека. Он же служит образцом того, как продукты собираются вместе: соглашению о сети и именах, на котором он держится, docs/NETWORK.md, следует каждый репозиторий.

Как он устроен

Стек — это один compose-проект, pacod-demo: 42 сервиса, два из которых выполняются один раз при старте и останавливаются (43 с необязательным ingestion).

Откуда Что работает в демо Имена
pacod-id Провайдер идентификации, с одним realm для всех продуктов pacod-id
pacod-gw Ядро, аналитика, консоль, тестер, ClickHouse, Valkey кэша ответов, mock-провайдер, а также агент и мок нагрузки его нагрузочных тестов pacod-gw, gw-*
pacod-ap API, admin API, MCP-сервер, воркеры, фронтенд, Redis и pgbouncer, общий сервис эмбеддингов и экспортёры его мониторинга ap-*, pacod-embeddings, экспортёры
pacod-cms Сайты, студия, MongoDB и Gotenberg cms-*
pacod-kb Конвейер и интерфейс kb-*
pacod-benchmark API и интерфейс bench-*
pacod-demo Caddy, PostgreSQL, Qdrant, Mailpit, Prometheus, Alertmanager, Grafana и коллектор OpenTelemetry pacod-*
  • Две сети, уникальные имена. Каждый контейнер подключается к внешней Docker-сети pacod-net под именем, уникальным во всех репозиториях: общие компоненты называются pacod-*, всё остальное несёт префикс владельца. Слушатели, до которых должны доходить только серверы, — API управления шлюза, внутренний слушатель pacod-id и API бенчмарка, — находятся во второй сети, pacod-admin-net, внутренней (без выхода наружу). Каждый привязан к псевдониму, который есть только там, и в неё входят только те, кто их вызывает.
  • Собственные compose-файлы репозиториев. Каждый репозиторий делит свою compose-настройку на app-файл со своими сервисами и standalone-файл со своими копиями общих компонентов для самостоятельного запуска. compose.yml подключает шесть app-файлов без изменений, вместе с файлами разработки и нагрузочных тестов шлюза. Небольшой overlay на репозиторий только убирает опубликованные порты, задаёт секреты и публичные адреса демо и направляет настройки на файлы демо.
  • По одному экземпляру каждого общего компонента. platform.yml не пишет ни одного с нуля: каждый расширяет (extends) определение, которое уже есть в каком-либо репозитории, и берёт вклад продуктов из их каталогов platform/: блоки сайтов Caddy, скрипты баз данных, задания, правила и дашборды Prometheus. В PostgreSQL у каждого продукта своя база данных и своя роль владельца.
  • Собственные хранилища продуктов остаются при них: ClickHouse и Valkey шлюза, MongoDB (по одной базе на сайт) и Gotenberg у CMS, Redis и pgbouncer у платформы агентов.
  • Сгенерированное состояние лежит в .state/, которое git игнорирует: секреты, созданные один раз и никогда не меняющиеся, учётные данные, которые создаёт bootstrap, и переменные каждого продукта, сгенерированные из demo.env.

Что делает make up

  1. Предварительная проверка. Docker и Compose 2.24 или новее, память и диск, шесть соседних репозиториев в раскладке с общей сетью, отсутствие другого стека pacod, занявшего общие имена, пароль администратора, сертификат и порты. Блокирующая проблема останавливает всё здесь.
  2. Сети и секреты. Создаёт pacod-net и внутреннюю pacod-admin-net, затем один раз генерирует каждый секрет в .state/secrets.env. Если секретов нет, а тома с данными есть, он отказывается, вместо того чтобы создать новые секреты, с которыми данные не смогут работать.
  3. Генерация. Из demo.env получаются собственные переменные каждого продукта в .state/env/<product>.env.
  4. Старт. Compose запускает проект и ждёт, пока каждый сервис не станет здоровым. Первый старт собирает каждый образ из исходников и скачивает модель эмбеддингов.
  5. Bootstrap. Он запускает собственные скрипты продуктов, bootstrap шлюза и идентификации из pacod-ap и provisioner из pacod-cms, чтобы создать ключи шлюза и служебные токены, по которым продукты обращаются друг к другу. Он также создаёт токен pacod-benchmark для API управления шлюза (администратор платформы: бенчмарк создаёт и удаляет собственную организацию для каждого прогона) и выдаёт администратору каждую недостающую роль. Сервисы, которые читают эти учётные данные, пересоздаются.
  6. Начальные данные. Таблицы платформы агентов, справочные факты стартового агента и его пользователи для разработки.
  7. Базовое состояние. На новом стеке он ждёт, пока CMS запишет три своих демо-сайта, и затем сохраняет данные как базовое состояние.
  8. Планировщик. Запускает контейнер ночного сброса, затем выводит адреса и пароль администратора.

Ночной сброс

Каждый день в DEMO_RESET_TIME (по умолчанию 05:00) в DEMO_RESET_TIMEZONE (по умолчанию UTC) демо отменяет все изменения: учётные записи, агентов, статьи, документы, ключи и настройки. Главная страница объявляет об этом в полосе под шапкой, со временем в часовом поясе посетителя и сколько осталось до следующего сброса.

  • Базовое состояние — это данные стека в один момент: то, что создал первый make up, или то, что позже сохранил make baseline. Оно включает каждый том с данными (PostgreSQL, MongoDB, Qdrant, ClickHouse, Redis, файлы базы знаний и приложения, Grafana, Alertmanager), файлы CMS и учётные данные bootstrap, в сжатом виде в Docker-томе pacod-demo-baseline.
  • Не входят: модели, метрики Prometheus, собственные данные точки входа и кэш ответов шлюза, который живёт в памяти: каждый сброс его очищает.
  • Бенчмарки тоже откатываются: прогоны и расписания pacod-benchmark, шлюзы, добавленные в его интерфейсе, и отчёты, опубликованные в консоли шлюза. Отчёт, который хочется сохранить, скачивается со страницы его прогона; консоль принимает его обратно загрузкой.
  • Как. Все сервисы, кроме точки входа, останавливаются, так что главная страница остаётся доступной, пока продукты несколько минут отвечают 502. Базовое состояние копируется обратно, стек запускается, и bootstrap выполняется снова, заодно применяя ключ провайдера, добавленный за это время. make reset делает то же самое сразу.
  • Планировщик — это контейнер pacod-demo-reset, вне compose-проекта, потому что сброс останавливает проект. Он пропускает ночь, если стек не запущен или машина спала. Пустой DEMO_RESET_TIME его выключает.

Конфигурация

Два файла. demo.env — это конфигурация: домены, стека и сайтов, порты, сертификат, email первого администратора, время сброса, модели каждого продукта, бэкенд эмбеддингов, необязательный компонент и логирование. Git его игнорирует; первый make копирует его из шаблона в репозитории, demo.env.example, и останавливается, чтобы его можно было отредактировать. demo.local.env хранит секреты машины, пароль администратора и ключи провайдеров LLM; git игнорирует и его, а то, что в нём задано, имеет приоритет.

# demo.local.env
DEMO_ADMIN_PASSWORD=a-long-passphrase
ANTHROPIC_API_KEY=sk-...

Провайдеры LLM. Без ключа каждый вызов модели уходит к mock-провайдеру шлюза: демо работает офлайн, и make verify детерминирован, но ответы в чате заготовлены заранее. Добавьте ключ (модели платформы агентов по умолчанию — от Anthropic) и выполните make bootstrap, и шлюз настроится на реального провайдера. AP_PRIMARY_MODEL, AP_CLASSIFIER_MODEL, CMS_AI_MODEL и KB_LLM_MODEL выбирают модели, которые продукты запрашивают у шлюза.

Бэкенд эмбеддингов фиксируется при первом make up, потому что от него зависят сохранённые векторы. По умолчанию, auto, он запускает BGE-M3, когда у Docker около 8 GB памяти, а меньше — лёгкую замену; смена позже требует make clean.

Необязательный компонент ingestion запускает приём документов платформы агентов и загружает базу знаний стартового агента; без него агент отвечает только по своим справочным фактам. Его образ весит около 10 GB и может занять 7 GiB памяти, поэтому ему нужно 16 GiB для Docker.

Логи. Каждый продукт пишет логи в одном общем формате, по одному событию на строку с одинаковыми ключами везде (docs/LOGGING.md). DEMO_LOG_LEVEL и DEMO_LOG_FORMAT (text или json) настраивают их все, а также журнал запросов точки входа.

Демо-сайты CMS записываются только при первом старте студии. make cms-seed заполняет сайт без статей, а make cms-space создаёт Starward в стеке, запущенном до его появления. Для Starward и главной страницы в demo.env можно задать тег Google Analytics и подтверждение для Search Console; если оставить их пустыми, как по умолчанию, на странице нет ничего от Google.

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

  • Один опубликованный порт. Порты публикует только точка входа, pacod-caddy; все остальные сервисы доступны только в Docker-сетях. Слушатели для серверов находятся во внутренней pacod-admin-net и привязаны к псевдонимам, до которых pacod-net не дотягивается.
  • Секреты. Каждый секрет генерируется один раз на машине и никогда не попадает в репозиторий. Пароль администратора должен быть не короче 12 символов (pacod-id отклоняет более короткий); если он пуст, генерируется пароль из 24 символов.
  • Домен сайтов. Сайт CMS выполняет скрипт своего владельца, который на регистрируемом домене студии мог бы устанавливать cookies, получаемые студией и входом. Поэтому сайты получают собственный домен (DEMO_SITE_DOMAIN); на домене студии студия отказывается запускаться. DEMO_SITE_DOMAIN_SHARED=true размещает их под доменом демо — для демо, все сайты которого доверенные, и только по HTTPS. demo.pacod.io так и делает: все его сайты — его собственные.
  • При публикации за пределы машины (DEMO_BIND — не loopback-адрес) демо закрывает то, что безопасно только на ноутбуке: просмотр почты, Prometheus и Grafana спрашивают email и пароль администратора, /grafana консоли шлюза отвечает 403, главная страница не называет администратора, а токены разработки платформы агентов выключены. Собственное администрирование продуктов, как всегда, закрыто их входом.
  • Сертификаты предоставляются, а не получаются автоматически: один сертификат на домен, его поддомены и домен сайтов.

На домене или на ноутбуке

С заданными DEMO_TLS_CERT и DEMO_TLS_KEY стек отвечает по HTTPS, а обычный HTTP только перенаправляет на него. В DNS домен, его wildcard и wildcard сайтов должны указывать на сервер; до этого make hosts выводит строки для /etc/hosts, чтобы попробовать.

Шаблон в репозитории — это шаблон публичного сервера. Для демо только на одной машине в demo.env нужны пять настроек:

DEMO_DOMAIN=localhost
DEMO_TLS_CERT=
DEMO_TLS_KEY=
DEMO_HTTP_PORT=8800
DEMO_BIND=127.0.0.1

Тогда всё работает по обычному HTTP на http://<name>.localhost:8800, что браузеры разрешают без DNS (Safari может не справиться: возьмите другой браузер или make hosts).

Что ему нужно

  • Docker с Compose 2.24 или новее и make. Всё остальное, от секретов до проверок, работает в контейнерах.
  • Шесть репозиториев продуктов, склонированных рядом с этим.
  • Около 8 GB памяти для Docker. Весь стек с настоящей моделью эмбеддингов занимал около 5 GiB при измерении, до того как к нему присоединился pacod-benchmark; бенчмарк с агентом и моком нагрузки шлюза добавляет в покое меньше 100 MiB. С лёгкой заменой — около 4 GiB.
  • Около 30 GiB диска для образов. Первый make up собирает каждый образ из исходников: три Rust-workspace, одну сборку Maven, несколько образов Python и три приложения SvelteKit, — и занимает от 30 до 60 минут. Последующие запуски занимают около двух минут.

make down останавливает стек и сохраняет данные; make clean удаляет всё, что создало демо. После получения новых версий make build пересобирает образы (make up собирает только недостающие), а make reset и затем make baseline делают перенесённые данные новым базовым состоянием.

Что проверено и где его пределы

make verify проверяет работающий стек от начала до конца и завершается с кодом 1, если что-то не прошло:

Часть Что проверяется
Docker По одному экземпляру каждого общего компонента, порт публикует только точка входа, ни один сервис не остановлен и не нездоров, pacod-admin-net внутренняя и в ней только те, кто вызывает слушателей
Точка входа и здоровье Адрес и health-эндпоинт каждого продукта, каждая цель Prometheus доступна, правила и дашборды шлюза и приложения загружены
Единый вход Администратор входит один раз и без повторного входа попадает в приложение, консоль шлюза, студию, базу знаний и бенчмарк, и у него есть каждая положенная роль
Шлюз Ключи платформы агентов, CMS и базы знаний каждый выводят список моделей и завершают чат; повторный вызов получает ответ из кэша ответов
Продукты Потоковый ход чата через шлюз (только на ноутбуке); документ, принятый, найденный и удалённый в базе знаний; Demo Journal отображается, а Starward — на наборе magazine
Бенчмарк Его токен — администратор платформы шлюза, и шлюз принимает его отчёты

Его пределы:

  • Агент нагрузки бенчмарка работает на той же машине, что и шлюз: его цифры показывают, как ведёт себя шлюз, а не его пропускную способность.
  • Цифры памяти измерены до того, как pacod-benchmark вошёл в стек.
  • Сброс делает продукты недоступными на несколько минут, а планировщик пропускает ночь, когда машина спала.
  • Без ключа провайдера каждый ответ — от мока; с ключом вызовы настоящие и стоят денег.
  • Стеку, запущенному до появления Starward или с его прежней версией, нужен ручной шаг, чтобы его получить; README описывает его, вместе с полным списком настроек и таблицей решения проблем.

Быстрый старт

Склонируйте семь репозиториев рядом друг с другом

mkdir pacod && cd pacod
for r in pacod-demo pacod-id pacod-gw pacod-ap pacod-cms pacod-kb pacod-benchmark; do git clone https://github.com/pacod22/$r.git; done

Настройте его только для этой машины

cd pacod-demo
cp demo.env.example demo.env
printf '%s\n' DEMO_DOMAIN=localhost DEMO_TLS_CERT= DEMO_TLS_KEY= DEMO_HTTP_PORT=8800 DEMO_BIND=127.0.0.1 >> demo.env

Соберите, запустите и проверьте стек

make up
make verify
open http://localhost:8800

Работает с

  • pacod-id: Единственный провайдер идентификации в стеке, с одним realm, через который входит каждый продукт; bootstrap даёт администратору роль каждого продукта.
  • pacod-gw: Единственный шлюз в стеке, запущенный с включённым кэшем ответов; bootstrap даёт каждому продукту собственный ключ шлюза.
  • pacod-ap: Запускает стартового агента, небольшую вымышленную службу поддержки, с его сайтом, чатом и консолью администратора.
  • pacod-cms: Запускает студию с её AI-помощью при написании и три демо-сайта, Demo Journal, Demo Notes и Starward.
  • pacod-kb: Запускает базу знаний на общих Qdrant, PostgreSQL и сервисе эмбеддингов.
  • pacod-benchmark: Измеряет собственный шлюз стека с помощью агента нагрузки и мока шлюза; его отчёты видны в консоли шлюза.

В репозитории pacod-demo пока нет файла лицензии. У каждого продукта, который он запускает, своя лицензия, указанная в его репозитории и на его странице.