Перейти к содержимому

Паттерн публикации Artifacts

Публикация статического HTML контента, доступного по публичному URL. Генерация отчётов, дашбордов и документов для просмотра в браузере.

СценарийПример
ОтчётыАнализ покупок, результаты исследований, сравнительные таблицы
ДашбордыСтраницы статуса, визуализация метрик
Контент для обменаДокументы, презентации, портфолио
УведомленияГенерация отчёта + отправка URL через Telegram
Результаты для пользователяВсё, что нужно просмотреть в браузере
[generate-data] → [create-html] → [upload-artifact] → [share-url]

Когда агент генерирует HTML в памяти:

{
"id": "generate-and-upload",
"type": "agent-directive",
"directive": "Сгенерируй HTML отчёт из данных анализа.\n\n**Данные:**\n{{note:analysis-results}}\n\nСоздай адаптивный HTML с Tailwind CDN.\n\nЗагрузи:\nartifacts({ action: \"upload\", name: \"report.html\", content: \"<html>...\" })\n\nСохрани возвращённый `url` как report_url.",
"completionCondition": "Отчёт загружен и URL получен",
"inputSchema": {
"type": "object",
"required": ["report_url", "uploaded"],
"properties": {
"report_url": { "type": "string" },
"uploaded": { "type": "boolean" }
}
},
"connections": { "success": "notify-user" }
}

Когда агент сначала создаёт файлы локально:

{
"id": "upload-via-token",
"type": "agent-directive",
"directive": "Загрузи файл отчёта.\n\n1. Получи токен: artifacts({ action: \"token\", ttlMinutes: 30 })\n2. Прочитай файл из {{report_file_path}}\n3. POST на uploadUrl с контентом\n4. Сохрани url из ответа",
"inputSchema": {
"properties": {
"report_url": { "type": "string" },
"uploaded": { "type": "boolean" }
}
}
}

Маршрутизация на основе доступа агента к файлам:

{
"id": "check-file-access",
"type": "condition",
"condition": {
"operator": "eq",
"left": { "contextPath": "can_create_files" },
"right": true
},
"connections": {
"true": "generate-file-then-upload",
"false": "generate-and-upload-direct"
}
}
artifacts({
action: "upload",
name: "purchase-report.html",
content: `<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50 p-8">
<h1 class="text-2xl font-bold">Отчёт</h1>
</body>
</html>`,
executionId: "exec-123" // Опционально: связь с workflow
})

Ответ:

{
"success": true,
"data": {
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://moiraqq.com/a/a1b2c3d4...",
"name": "purchase-report.html",
"size": 1234,
"expiresAt": "2025-02-28T10:00:00.000Z"
}
}
artifacts({
action: "update",
uuid: "a1b2c3d4...",
content: "<html>...обновлённый контент...</html>",
name: "report-v2.html" // Опционально
})
artifacts({
action: "stats"
})
// Возвращает: totalArtifacts, totalSize, storageLimit, usedPercent
artifacts({
action: "list",
limit: 20
})
ЛимитЗначение
Хранилище на пользователя100 MB
Количество файлов50 artifacts
Максимальный размер файла5 MB
TTL токена1-1440 минут
Срок действия30 дней
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Контент -->
</body>
</html>
<div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<!-- Карточки -->
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-semibold">Название продукта</h3>
<p class="text-gray-600 mt-2">Описание</p>
<div class="mt-4 flex justify-between items-center">
<span class="text-2xl font-bold text-green-600">999 ₽</span>
<a href="https://store.com/product"
class="bg-blue-500 text-white px-4 py-2 rounded"
target="_blank" rel="noopener noreferrer">
Купить
</a>
</div>
</div>
<table class="w-full border-collapse">
<thead>
<tr class="bg-gray-100">
<th class="border p-3 text-left">Продукт</th>
<th class="border p-3 text-left">Цена</th>
<th class="border p-3 text-left">Рейтинг</th>
</tr>
</thead>
<tbody>
<tr class="hover:bg-gray-50">
<td class="border p-3">Продукт А</td>
<td class="border p-3">599 ₽</td>
<td class="border p-3">4.5/5</td>
</tr>
</tbody>
</table>

Комбинация с telegram-уведомлениями:

{
"id": "notify-with-link",
"type": "agent-directive",
"directive": "Отправь URL отчёта пользователю через Telegram.\n\nURL: {{report_url}}\n\nИспользуй telegram-notification для отправки ссылки.",
"connections": { "success": "end" }
}

Из workflow анализа покупок:

{
"id": "create-report",
"type": "agent-directive",
"directive": "Создай HTML отчёт с рекомендациями продуктов.\n\n**Данные анализа:**\n{{note:purchase-{{executionId}}-03-analysis}}\n\nСгенерируй адаптивный HTML:\n- Карточки продуктов с изображениями, ценами, ссылками\n- Сравнительная таблица\n- Итоговые рекомендации\n\nЗагрузи: artifacts({ action: \"upload\", name: \"purchase-{{executionId}}.html\", content: html, executionId: \"{{executionId}}\" })",
"inputSchema": {
"properties": {
"report_url": { "type": "string" },
"uploaded": { "type": "boolean" }
},
"required": ["report_url"]
}
}
// Хорошо
artifacts({ name: "purchase-analysis-2025-01-31.html" })
// Плохо
artifacts({ name: "report.html" })
artifacts({
action: "upload",
name: "report.html",
content: htmlContent,
executionId: context.executionId
})

Преимущества:

  • Отслеживание какое выполнение создало artifact
  • Запрос artifacts по выполнению
  • Очистка при архивации выполнения
{
"id": "upload-report",
"type": "agent-directive",
"directive": "Загрузи отчёт. Сначала проверь квоту. При ошибке загрузки сообщи пользователю.",
"connections": {
"success": "notify-user",
"error": "handle-upload-error"
}
}

Используйте notes для JSON данных, artifacts только для презентабельного HTML.

Всегда проверяйте stats перед большими загрузками. Обрабатывайте ошибки превышения квоты.

Используйте Tailwind или media queries. Фиксированная ширина ломается на мобильных.