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

Паттерн персистентности Notes

Назначение

Сохранение структурированных данных, которые переживают перезапуски workflow или должны передаваться между шагами. Notes обеспечивают key-value хранилище с версионированием и тегами.

Когда использовать

СценарийПример
Восстановление сессииСохранение промежуточных результатов для продолжения после прерывания
Передача данных между шагамиПередача сложных данных между agent-directive нодами
Пользовательские настройкиЗапоминание выборов, настроек, конфигурации
Результаты анализаСохранение исследований, сравнений, рекомендаций
История выполненияОтслеживание решений во время выполнения workflow

Не используйте notes для временных вычислений (используйте context variables), данных только для следующего шага (используйте inputSchema), данных сверх действующей политики notes (используйте artifacts), бинарных данных.

Структура

[collect-data] → [write-note] → [other-steps] → [read-note] → [use-data]

Реализация

Нода write-note

Сохранение результата agent-directive ноды:

{
"id": "save-analysis",
"type": "write-note",
"key": "purchase-{{executionId}}-01-analysis",
"source": "{{analyze-step-output}}",
"tags": ["purchase-{{executionId}}", "analysis"],
"connections": {
"default": "next-step",
"error": "handle-error"
}
}

Паттерн ключа: {domain}-{{executionId}}-{sequence}-{description}

ЧастьНазначениеПример
domainОбласть workflowpurchase, research
scopeИзоляция выполнения{{executionId}}
sequenceПорядок01, 02, 03
descriptionПодсказка содержимогоuser-needs, analysis

Пакетный режим записи

Запись нескольких notes из массива:

{
"id": "save-batch",
"type": "write-note",
"source": "{{items-to-save}}",
"batchMode": true,
"connections": { "default": "next" }
}

Формат массива source:

[
{ "key": "item-001", "value": "content 1", "tags": ["batch"] },
{ "key": "item-002", "value": "content 2", "tags": ["batch"] }
]

Нода read-note

Загрузка notes в context variable:

{
"id": "load-data",
"type": "read-note",
"outputVariable": "previousData",
"filter": {
"keyPattern": "purchase-{{executionId}}"
},
"connections": { "default": "use-data" }
}

Режим single для единственной note:

{
"id": "load-preferences",
"type": "read-note",
"outputVariable": "userPrefs",
"filter": { "tag": "preferences" },
"singleMode": true,
"connections": { "default": "apply-prefs" }
}

Нода upsert-note

Обновление существующей или создание новой:

{
"id": "update-preferences",
"type": "upsert-note",
"search": {
"tag": "user-prefs",
"keyPattern": "prefs-{{userId}}"
},
"keyTemplate": "prefs-{{userId}}-new",
"value": "{{collected-preferences}}",
"tags": ["user-prefs"],
"outputVariable": "saveResult",
"connections": { "default": "confirm" }
}

Инъекция шаблонов

Прямой доступ к notes в директивах:

{
"id": "research-step",
"type": "agent-directive",
"directive": "Исследуй на основе потребностей пользователя.\n\n**Потребности:**\n{{note:purchase-{{executionId}}-01-user-needs}}\n\nОпредели основные категории.",
"completionCondition": "Исследование завершено"
}

Синтаксис: {{note:key-name}}

Содержимое note инжектируется в директиву до получения агентом.

Использование MCP Tool

Внутри agent-directive нод используйте MCP tool notes:

// Сохранить note
notes({
action: "save",
key: "user-preferences",
value: JSON.stringify({ theme: "dark", lang: "ru" }),
tags: ["preferences"],
});
// Получить note
notes({
action: "get",
key: "user-preferences",
});
// Список notes по тегу
notes({
action: "list",
tag: "preferences",
});
// Проверить квоту
notes({
action: "stats",
});

Исторический пример

Раньше Smart Purchase Assistant демонстрировал сохранение каждого этапа через write-note. Текущая production-версия в workflows/production/flows/b33e227c-cc2c-4931-ae5d-2de69932e41e.json использует один execution-correlated файловый пакет: дублирование подробного содержимого в notes и workflow variables создаёт конкурирующие источники истины. Write-note по-прежнему подходит, когда сама note является каноническим долговечным значением:

{
"id": "write-note-01",
"type": "write-note",
"key": "purchase-{{executionId}}-01-user-needs",
"source": "{{analyze-user-needs}}",
"tags": ["analysis-{{executionId}}", "research"],
"connections": { "default": "research-product-category" }
}

Лучшие практики

Стратегия тегов

  • Используйте тег выполнения: purchase-{{executionId}}
  • Используйте тег категории: research, research-flow
  • Позволяет эффективную фильтрацию и очистку

Обработка ошибок

{
"id": "write-critical",
"type": "write-note",
"key": "critical-data-{{executionId}}",
"source": "{{results}}",
"connections": {
"default": "continue",
"error": "handle-write-error"
}
}

Сериализация данных

  • Объекты и массивы автоматически сериализуются в JSON
  • Примитивные значения сохраняются как строки
  • Для больших объектов рассмотрите разбиение или artifacts

Антипаттерны

Отсутствие изоляции выполнения

// Неправильно - общий между выполнениями
{ "key": "user-analysis" }
// Правильно - изолирован по выполнению
{ "key": "user-analysis-{{executionId}}" }

Избыточное использование notes для простых данных

Не храните счётчики циклов или временные значения в notes. Используйте expression ноды или context variables.

Хранение больших бинарных данных

Notes предназначены для структурированных текстовых данных. Используйте Artifacts для HTML контента или больших файлов.

Связанные паттерны