feat: кейс Primo AI Server по фреймворку STAR (страница без ссылок на сайте, noindex, только ru)

This commit is contained in:
root committed 2026-10-02 16:21:03 +02:00
1 parent a8ae6323c0
commit ac1eceefd1
3 files changed
+1837 -2

No files matched your search

+525
View File
@@ -0,0 +1,525 @@
<!DOCTYPE html>
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta
name="description"
content="Кейс по фреймворку STAR: как я упростил настройку проектов в Primo RPA AI Server и снизил порог входа для клиентов."
/>
<title>Настройка AI Server без помощи внедрения — кейс</title>
{{> head-links}}
{{> head-plyr}}
<style>
.case-article {
max-width: 48rem;
margin: 0 auto;
}
.case-article h2 {
margin: 2rem 0 0.75rem;
font-size: clamp(1.15rem, 2vw, 1.35rem);
font-weight: 700;
color: var(--text);
}
.case-article h3 {
font-size: 1.05rem;
font-weight: 600;
color: var(--text);
}
.case-article .section__prose {
margin-bottom: 0.75rem;
color: var(--text);
}
.case-article img,
.case-article video {
display: block;
max-width: 100%;
height: auto;
margin: 0.75rem 0 1rem;
}
.case-article ul,
.case-article ol {
margin: 0.5rem 0 1rem 1.25rem;
padding: 0;
}
.case-article li {
margin-bottom: 0.35rem;
}
.case-article a:not(.btn) {
color: var(--accent);
}
.case-block {
margin-top: 3rem;
padding-top: 2.5rem;
border-top: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
}
.case-block:first-of-type {
margin-top: 0;
padding-top: 0;
border-top: 0;
}
.case-facts {
margin: 1.25rem 0 0;
padding: 0;
list-style: none;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
gap: 0.75rem 1.5rem;
}
.case-facts li {
margin: 0;
}
.case-facts dt,
.case-facts__key {
display: block;
font-size: 0.78rem;
letter-spacing: 0.02em;
text-transform: uppercase;
color: var(--text-muted);
}
.case-facts__value {
display: block;
font-size: 0.95rem;
color: var(--text);
}
</style>
<script>
(function () {
try {
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
var d = document.documentElement;
var m = t.mode;
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
var eff =
m === "system"
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: m;
d.dataset.theme = eff;
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
if (h !== null) d.style.setProperty("--theme-h", String(h));
if (s !== null) d.style.setProperty("--theme-s", String(s));
if (l !== null) {
var L = Number(l);
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
}
var rad = t.radius;
if (rad === "soft" || rad === "medium" || rad === "strong") {
d.dataset.radius = rad;
} else {
d.dataset.radius = "medium";
}
var f = t.font;
if (f === "onest") f = "geologica";
if (f === "anonymous") f = "mono";
if (f === "merriweather" || f === "mono" || f === "geologica") {
d.dataset.font = f;
} else {
d.dataset.font = "merriweather";
}
var mb = t.meshBg;
if (mb === "off") {
d.dataset.meshBg = "off";
} else {
d.dataset.meshBg = "on";
}
} catch (e) {}
})();
</script>
</head>
<body data-current-case="primo-ai-server-star">
{{> header-case}}
{{> fab-stack}}
<main id="case-main" class="section section--tight">
<div class="section__inner case-article">
<p class="hero__eyebrow">Product Design · AI · STAR</p>
<h1 class="case-page__h1">AI&nbsp;Server, который настраивают без&nbsp;внедренца</h1>
<p class="case-page__sub">
Как я снизил порог входа в Primo RPA AI Server,<br />
разгрузил поддержку и отдел внедрения
</p>
<ul class="case-facts">
<li>
<span class="case-facts__key">Роль</span>
<span class="case-facts__value">UX/UI-дизайнер</span>
</li>
<li>
<span class="case-facts__key">Продукт</span>
<span class="case-facts__value">Primo RPA AI Server</span>
</li>
<li>
<span class="case-facts__key">Платформа</span>
<span class="case-facts__value">Веб, on-premise</span>
</li>
<li>
<span class="case-facts__key">Структура кейса</span>
<span class="case-facts__value">STAR</span>
</li>
</ul>
<div class="case-block" id="situaciya">
<h2>Ситуация</h2>
<p class="section__prose">
AI Server ставят на внутренние серверы клиента. Он позволяет использовать нейросети внутри контура компании: загрузил датасет своих документов, разметил поля, обучил модель, и эта модель работает в других продуктах. Качество распознавания вырастает сильно, а документы не покидают периметр компании. Позже сервис научился дообучать любую базовую модель под задачи бизнеса: файнтюнинг и скиллы на суммаризацию, извлечение, генерацию.
</p>
<p class="section__prose">
К моменту, когда меня позвали, продукт уже тестировали реальные клиенты. Собирали его разработчики своими силами, на
<a href="https://ant.design/components/overview" target="_blank" rel="noopener noreferrer">Ant Design</a> под React со стилизацией под
<a href="https://templates.iqonic.design/hope-ui/html/dist/" target="_blank" rel="noopener noreferrer">Hope UI</a>: у компании было несколько веб-продуктов и стояла задача унифицировать их вид.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/main.webp"
alt="Главная страница AI Server до редизайна"
width="2520"
height="1680"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Так сервис выглядел, когда я пришёл в проект</figcaption>
</figure>
<p class="section__prose">
Обратная связь от клиентов сходилась в одном: настройка проекта занимает слишком много шагов. Их три типа, и каждый настраивался по-своему. Между созданием проекта и его реальным использованием проходили недели, почти всегда с участием специалиста компании. Запутанная навигация и дублирующийся функционал тормозили отдел внедрения и не давали масштабировать продукт на широкую аудиторию.
</p>
</div>
<div class="case-block" id="zadacha">
<h2>Задача</h2>
<p class="section__prose">
Меня пригласили как UX/UI-дизайнера: проект делали одни разработчики, дизайнера в нём не было. Бизнес ждал, что настройку клиент сможет пройти сам, без постоянной помощи поддержки и внедрения. Моя задача звучала так: снизить порог входа, чтобы работать с сервисом могли люди без специальных знаний в ИИ и OCR.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
<div class="case-callout__content">
<p>
Порог входа, а не красота интерфейса. Это был критерий, по которому оценивали работу: клиент настраивает проект сам или всё ещё звонит в поддержку.
</p>
</div>
</aside>
<p class="section__prose">
Остановить разработку и перерисовать всё целиком было нельзя, продукт уже в эксплуатации. Значит, менять придётся по частям, вкладываясь в текущие релизы.
</p>
</div>
<div class="case-block" id="deystviya">
<h2>Действия</h2>
<h3>Погружение и разбор сценариев</h3>
<p class="section__prose">
Начал с команды: кто отвечает за продукт, кто за внедрение, как всё устроено сейчас. Разговаривал с экспертами по настройке, отделял ключевые сценарии от вспомогательных и собирал визуализацию того, как пользователь реально ходит по интерфейсу. Опыт в ИИ и в похожих веб-платформах помогал быстро понимать, о чём речь, и говорить с разработкой на одном языке.
</p>
<p class="section__prose">
Юзерфлоу оказались полезнее, чем я ожидал. Они подсветили команде конкретные места, где путь пользователя путается, и заодно вскрыли проблемы в самих процессах настройки. Часть шагов удалось автоматизировать и спрятать от пользователя: меньше рутины и меньше шансов ошибиться.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✨</span>
<div class="case-callout__content">
<p>
Схемы сценариев делались для работы, не для портфолио.
</p>
</div>
</aside>
<h3>Навигация: главная и внутри проекта</h3>
<p class="section__prose">
В сервисе стояла привычная для админок схема: слева меню, справа контент. Проблема в том, что при открытии проекта слева появлялась навигация по его разделам вперемешку с главной. Пространство под контент расходовалось плохо, а пользователь терялся в двух пересекающихся меню.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/main-new.webp"
alt="Обновлённая главная страница AI Server"
width="1920"
height="1080"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Обновлённая главная навигация: компактнее, под контент ушло заметно больше места</figcaption>
</figure>
<p class="section__prose">
Главная навигация стала компактной и осталась привычной. У проектов появилась своя, отдельная, которая не перекрывает главную. Разные типы проектов содержат разное количество пунктов, и такая схема позволяет разместить их без тесноты.
</p>
<figure class="case-media case-media-gallery case-media-gallery--wide" style="--case-gallery-cols: 2">
<div class="case-media-gallery__grid">
<div class="case-media-gallery__item">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/nav-project-nlp.webp"
alt="Навигация внутри NLP-проекта"
loading="lazy"
decoding="async"
data-image-viewer
/>
</div>
<div class="case-media-gallery__item">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/nav-project-ocr.webp"
alt="Навигация внутри OCR-проекта"
loading="lazy"
decoding="async"
data-image-viewer
/>
</div>
</div>
<figcaption>Одна и та же схема под разное число разделов: NLP-проект и OCR-проект</figcaption>
</figure>
<p class="section__prose">
Отдельно отмечу форму пунктов вторичной навигации. Стрелочная она не случайно: мягко подсказывает, что настройку удобнее проходить по шагам. При этом разделы работают как обычные табы, переключаться можно в любом порядке. Чистый визард тут не годился, пользователю всё равно нужно возвращаться назад и править результат.
</p>
<figure class="case-media case-media--content">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/nav-secondary-detail_view.webp"
alt="Вторичная навигация проекта со стрелочной формой пунктов"
width="924"
height="101"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Форма пунктов намекает на порядок, но не запирает в нём</figcaption>
</figure>
<h3>Редактор разметки датасета</h3>
<p class="section__prose">
Здесь пользователь проводит больше всего времени. Разметка полей на сотнях изображений работа монотонная, но от неё зависит, насколько качественными будут данные для обучения модели. Прежний редактор выбивался из общего стиля сервиса, выглядел перегруженно и сбивал с толку в работе с полями.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/dataset-editor-old.webp"
alt="Редактор датасета до переработки"
width="1200"
height="675"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор до переработки</figcaption>
</figure>
<p class="section__prose">
Разобрал редактор на микросценарии, выстроил их по приоритету и связям, обсудил с командой, как сделать путь пользователя ровнее. В новую структуру заложил место под функционал, которого ещё не было, и те же паттерны, что в остальном сервисе.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/dataset-editor.webp"
alt="Редактор датасета после переработки"
width="1200"
height="675"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Редактор после переработки, приведён к общей стилистике сервиса</figcaption>
</figure>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/dataset_editor-wireframe-default_mode.webp"
alt="Каркас редактора датасета, режим по умолчанию"
width="1200"
height="675"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Каркас: почти всё пространство уходит под размечаемое изображение, действия сгруппированы по панелям</figcaption>
</figure>
<p class="section__prose">
Добавил режим «Во весь экран». Продвинутые пользователи обычно прячут лишние панели и работают через горячие клавиши и нижнюю панель. Боковые панели сворачиваются, когда нужно больше места под изображение, на небольших мониторах это решает.
</p>
<figure class="case-media case-media-gallery case-media-gallery--wide" style="--case-gallery-cols: 2">
<div class="case-media-gallery__grid">
<div class="case-media-gallery__item">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/full-screen-mode-with-panels.webp"
alt="Полноэкранный режим редактора с боковыми панелями"
loading="lazy"
decoding="async"
data-image-viewer
/>
</div>
<div class="case-media-gallery__item">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/full-screen-mode-zen.webp"
alt="Полноэкранный режим редактора без панелей"
loading="lazy"
decoding="async"
data-image-viewer
/>
</div>
</div>
<figcaption>Режим «Во весь экран»: с панелями и без</figcaption>
</figure>
<figure class="case-media case-media--content">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/dataset_editor-main_toolbar.webp"
alt="Нижняя панель инструментов редактора датасета"
width="1200"
height="675"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Нижняя панель: переключение между изображениями и быстрые действия</figcaption>
</figure>
<h3>Карточки настройки обучения</h3>
<p class="section__prose">
После разметки модель можно дообучить. Сценарий разобрали с командой так же, как остальные, и сделали несколько вариантов компоновки страницы. Выбрали ленту из карточек: она оказалась самой читаемой.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/in_project-learn-overview.webp"
alt="Раздел обучения моделей в проекте"
width="1920"
height="740"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Раздел обучения: лента карточек</figcaption>
</figure>
<p class="section__prose">
В начале ленты стоит карточка с настройкой: через неё видно результат разметки активного датасета, задают параметры и запускают обучение. Отдельный блок оценки качества разметки получился одновременно наглядным и компактным.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/in_project-learn-card-new.webp"
alt="Карточка настройки обучения модели"
width="1306"
height="1104"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Карточка настройки обучения: оценка качества разметки и параметры запуска</figcaption>
</figure>
<p class="section__prose">
Под каждый запущенный процесс появляется своя карточка. Можно завести несколько процессов с разными параметрами и сравнить, какая конфигурация сработала лучше. В шапку свёрнутой карточки вынесены название и статус.
</p>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">💡</span>
<div class="case-callout__content">
<p>
Карточки придумывались под обучение, но оказались паттерном. Дальше их переиспользовали в других разделах продукта, и интерфейс стало проще держать в одном стиле.
</p>
</div>
</aside>
<h3>Настройка параметров полей</h3>
<p class="section__prose">
Одна из страниц проекта требовала настройки уникальных параметров полей для датасета. Условия жёсткие: редактору нужна большая область под скан документа, полей может быть несколько десятков, у каждого свои зависимые параметры и типы.
</p>
<figure class="case-media" style="margin: 0.85rem 0 1.2rem">
<div class="case-video-shell">
<video
controls
preload="metadata"
playsinline
poster="{{assetPrefix}}assets/ai-platform-primo-rpa/fields-maping.webp"
data-case-video-player
style="display: block; width: 100%; height: auto; margin: 0"
>
<source src="{{assetPrefix}}assets/ai-platform-primo-rpa/fields-maping.webm" type="video/webm" />
<source src="{{assetPrefix}}assets/ai-platform-primo-rpa/fields-maping.mp4" type="video/mp4" />
Ваш браузер не поддерживает видео.
</video>
</div>
<figcaption>Прототип сопоставления полей в работе</figcaption>
</figure>
<p class="section__prose">
Интерфейс получился компактным. Механика не считывается с первого взгляда, но после короткого обучения в нём работают уверенно. Это была самая длинная задача в проекте по числу черновиков: вариантов поведения перебрали много, пока не сошлись на том, что закрывает все сформулированные требования.
</p>
<h3>Долгие процессы на отдельном экране</h3>
<p class="section__prose">
Часть задач в сервисе выполняется долго, и пользователю нужно параллельно делать что-то ещё. Для таких случаев сделали отдельную страницу с модальным окном процесса.
</p>
<figure class="case-media case-media--wide">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/fullscreen_modal-import_dataset.webp"
alt="Импорт датасета в модальном окне на отдельном экране"
width="1440"
height="1024"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Импорт датасета на отдельном экране</figcaption>
</figure>
<p class="section__prose">
На странице проекта в это время стоит заглушка: процесс идёт, рядом кнопка перехода к нему. Пользователь может открыть окно с процессом в соседней вкладке и следить за прогрессом, пока в другой продолжает работать с доступными разделами.
</p>
<figure class="case-media case-media--content">
<img
src="{{assetPrefix}}assets/ai-platform-primo-rpa/fullscreen_modal-in_project-import_dataset.webp"
alt="Заглушка с процессом импорта внутри проекта"
width="1920"
height="740"
loading="lazy"
decoding="async"
data-image-viewer
/>
<figcaption>Заглушка внутри проекта: процесс виден, переход к нему в один клик</figcaption>
</figure>
<p class="section__prose">
Тут сошлись удобство и стоимость разработки. Точечно блокировать кнопки на каждой странице вышло бы дороже, чем вынести процесс на отдельный экран.
</p>
</div>
<div class="case-block" id="rezultat">
<h2>Результат</h2>
<p class="section__prose">
Настройка перестала быть набором разрозненных шагов, которые собирает специалист. Интерфейс теперь ведёт пользователя по этапам, но не ломает старые сценарии: вернуться назад и поправить результат можно в любой момент.
</p>
<p class="section__prose">
Что изменилось по сути:
</p>
<ul>
<li>порог входа снизился: работать с сервисом могут люди без знаний в ИИ и OCR;</li>
<li>часть настроек автоматизирована и спрятана от пользователя, рутины и ошибок меньше;</li>
<li>интерфейс стал консистентным, паттерны из одного раздела переезжают в другие;</li>
<li>под новые типы проектов и разделы заложено место, без переделок с нуля.</li>
</ul>
<aside class="case-callout" data-callout>
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">📌</span>
<div class="case-callout__content">
<p>
Честно про измерения: замеров я не ставил, и цифр у меня нет. Сократилось ли число обращений в поддержку и получается ли у клиентов пройти настройку самостоятельно, я как раз собирался спросить у команды, когда передавал проект.
</p>
</div>
</aside>
<p class="section__prose">
Проект вёл параллельно с другими, нагрузку приходилось распределять. В компанию взяли нового дизайнера, я вёл её в курс дела и курировал результат по задачам. После адаптации работа над сервисом полностью перешла к ней.
</p>
</div>
<div class="case-block" id="refleksiya">
<h2>Что сделал бы иначе</h2>
<p class="section__prose">
Поставил бы измерение раньше, ещё до редизайна. Сколько обращений в поддержку приходит по настройке и на каком шаге люди спотыкаются, можно было зафиксировать до изменений, тогда результат измерялся бы в цифрах.
</p>
<p class="section__prose">
И не тянул бы с юзерфлоу до середины проекта. Схемы сценариев окупились сразу, как только появились: они объясняли команде проблемы лучше любого описания.
</p>
</div>
</div>
</main>
{{> projects-related}}{{> projects-section}}
{{> contact-section}}
{{> footer}}
{{> cookie-notice}}
{{> nav-more-floating}}
<script>
document.addEventListener('DOMContentLoaded',function(){
var s=document.body.dataset.currentCase;
if(!s)return;
document.querySelectorAll('[data-related-slug="'+s+'"]').forEach(function(el){el.hidden=true;});
});
</script>
</body>
</html>