# Supabase — AI Tooling Engineer — Эссе Q2 (Docs / interfaces / tooling for agents)

## Метаданные

- **Компания:** Supabase
- **Роль:** AI Tooling Engineer
- **Канал подачи:** ashbyhq, через careers-page Supabase
- **Дата подачи:** 29 мая 2026
- **CV использовано:** CV-A (oleg_proskurin_ai_engineer_fullstack_cv.md), pdf-вариант `oleg_proskurin_ai_engineer_fullstack_cv.pdf`
- **Статус:** подано, ожидаем ответа

## Вопрос (дословно)

> How would you design docs, product interfaces, or developer tooling so agents can use them effectively?

## Выбранный угол

**Knowledge representation deep-dive.** Сознательно отказались от двухполушарной структуры (MCP interface + knowledge representation), хотя она ровно матчила формулировку JD. Решили: один глубокий разворот сильнее, чем два поверхностных. MCP оставлен на интервью.

Сердце ответа — компактный реестр компонентов: minified rendering functions (8KB → 700B на компонент), compact notation для пропсов (1.5KB → 300B из Zod-схем), extended schemas с descriptions и стилями (1.5KB на компонент в итоговом виде).

## Финальный текст ответа (English, как подано)

> The actual problem I faced in PrimeUI was how to pass our component library to the page generation LLM so it can properly use it. Let me highlight the issues with the original source first:
>
> - each component has React component code, TypeScript props, and an additional Zod schema. On top of that each one has a markdown file with description, functionality, "where to use", style details, etc.
> - dependencies. Many files have imported components.
> - huge length of definition: component code is big plus types, schemas, and description. Consumes a lot of tokens if passed raw.
> - the amount of components started from 100 and grew to 200.
> - even with Zod schemas we can't fully rely on them, because we have a lot of semantic and design-driven requirements. E.g. number of words in titles, discrete number of cards, capitalization styles, etc.
> - component code actually repeats in many components. Has a lot of functionality that isn't useful for an LLM. Too noisy to detect the look and feel of a component, its purpose.
>
> Having that I realized we can't just pass component code to a model. First attempt was a RAG system over component code, but it still faced the problem that component structure isn't visible because of the noise from classes, functionalities, tons of HTML tags etc. While the goal was to select each component wisely.
>
> The solution I proposed and implemented is creating a special components registry. The essential parts of which:
>
> - minified reduced functions instead of real components. It just outputs simplified HTML code with rendered props. This is enough to understand the structure of an actual component and easy to render existing content during the generation loop. Reduced code size from around 8KB per component to around 700B.
> - special compact notation schema describing component props. I created a syntax that allows describing not only formal requirements but also LLM-important relationships and styles. Managed to reduce from around 1.5KB in zod files to around 300B.
> - extended compact schemas also with component descriptions and visual styles. Finally one component definition in the registry takes approx 1.5K and provides LLM-friendly information about component functionality and usage.
>
> The total component registry was compact enough to put into the model's context window. I selected Gemini Flash 2.5 after some tests across Anthropic, OpenAI, and Gemini models, as a good candidate because of good performance, speed, and caching support. The biggest part of the context is our registry, which is always the same across all client projects and pages, so it always gets cached. Up to 77% cache hit, with reasonable generation speed.
>
> The registry generation is our own internal AI flow involving a few AI agents and deterministic code. It lets any engineer on our team add and update components in PrimeUI. For clients, when they export their project, we provide a production-ready Next.js codebase with the selected components and their props: it works like a usual project.

## Источники материала

- Драфт Олега в этой подаче (написан с нуля под этот вопрос, не из других чатов)
- `cv-master-extended.md` — Block 1 (RAG / Retrieval facts) для контекста про переход от RAG к cached registry
- Уточнения по числам: 77% cache hit (тут vs 73% в CV — Олег подтвердил 77%), 8KB→700B, 1.5KB→300B, total ~1.5K per component, registry started from 100 grew to 200

## Ключевые приёмы (что делает эссе сильным)

1. **Структура «проблема изнутри → решение через данные».** Список конкретных issues с реальной кодовой базой → реализованное решение с числами. Не теоретизирование «как бы я спроектировал», а «я столкнулся, я решил так».
2. **Числа per-component compression на каждом пункте решения.** 8KB→700B, 1.5KB→300B, итог 1.5K. Это редкий уровень детализации. Любая компания с eval-first культурой считывает зрелость по таким цифрам.
3. **First attempt → solution.** RAG-первая-попытка показана как тупик, после неё — финальное решение. Это сильнее, чем сразу выложить решение. Показывает инженерный путь, а не готовую теорию.
4. **77% cache hit как закрывающий числовой anchor.** Связывает выбор модели (Gemini Flash 2.5) с инструментацией (registry в кэше) и продуктовым следствием (reasonable speed).
5. **Сознательный отказ от MCP-половины.** На этапе финальной редактуры обсуждали: добавлять ли абзац про MCP server, чтобы закрыть второй буллет JD. Решили — нет: глубокий ответ на одну половину сильнее поверхностного на обе. MCP держим на интервью.
6. **Voice signatures сохранены:** `Having that I realized`, `While the goal was to select each component wisely`, постпозиционные `from`, длинные комма-цепочки, фраза-заголовок + двоеточие, drop -s в `that match`, drop article в bullet points.

## Что вырезано / не делали

- MCP-абзац (см. п.5 выше)
- pgvector mention (был nice-to-have в JD, но решили не натягивать — реальный реестр в JSON, не в pgvector)
- Промежуточные эксперименты с другими моделями названы не были — оставлено как «after some tests across Anthropic, OpenAI, and Gemini models»

## Что можно адаптировать для других подач

- **Spine «issues with original source → first attempt → solution with numbers»** — переносимая структура для любого вопроса вида «как бы вы спроектировали X для агентов». Реальный кейс всегда сильнее гипотетического.
- **Числа compression (8KB→700B, 1.5KB→300B, 77% cache)** — все проверенные, можно реюзать буквально.
- **Если в другой подаче нужен MCP-угол** — он есть в `cv-master-extended.md` Block 2 (25 tools, official SDK, 6 хостов). Можно собрать отдельное эссе или короткий абзац к этому.
