Notes Persistence Pattern
Purpose
Section titled “Purpose”Persist structured data that survives workflow restarts or needs to be shared between workflow steps. Notes provide key-value storage with versioning and tagging.
When to Use
Section titled “When to Use”| Use Case | Example |
|---|---|
| Session recovery | Store intermediate results for resume after interruption |
| Cross-step data sharing | Pass complex data between agent-directive nodes |
| User preferences | Remember choices, settings, configuration |
| Analysis results | Store research findings, comparisons, recommendations |
| Execution history | Track decisions made during workflow execution |
Structure
Section titled “Structure”[collect-data] → [write-note] → [other-steps] → [read-note] → [use-data]Implementation
Section titled “Implementation”Write Note Node
Section titled “Write Note Node”Store output from an agent-directive node:
{ "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" }}Key pattern: {domain}-{{executionId}}-{sequence}-{description}
| Part | Purpose | Example |
|---|---|---|
domain | Workflow area | purchase, research |
scope | Execution isolation | {{executionId}} |
sequence | Ordering | 01, 02, 03 |
description | Content hint | user-needs, analysis |
Batch Write Mode
Section titled “Batch Write Mode”Write multiple notes from an array:
{ "id": "save-batch", "type": "write-note", "source": "{{items-to-save}}", "batchMode": true, "connections": { "default": "next" }}Source array format:
[ { "key": "item-001", "value": "content 1", "tags": ["batch"] }, { "key": "item-002", "value": "content 2", "tags": ["batch"] }]Read Note Node
Section titled “Read Note Node”Load notes into context variable:
{ "id": "load-data", "type": "read-note", "outputVariable": "previousData", "filter": { "keyPattern": "purchase-{{executionId}}" }, "connections": { "default": "use-data" }}Single mode for exactly one note:
{ "id": "load-preferences", "type": "read-note", "outputVariable": "userPrefs", "filter": { "tag": "preferences" }, "singleMode": true, "connections": { "default": "apply-prefs" }}Upsert Note Node
Section titled “Upsert Note Node”Update existing or create new:
{ "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" }}Template Injection
Section titled “Template Injection”Access notes directly in directives:
{ "id": "research-step", "type": "agent-directive", "directive": "Research based on user needs.\n\n**User needs:**\n{{note:purchase-{{executionId}}-01-user-needs}}\n\nDetermine main categories.", "completionCondition": "Research completed"}Syntax: {{note:key-name}}
The note content is injected into the directive before the agent receives it.
MCP Tool Usage
Section titled “MCP Tool Usage”Within agent-directive nodes, use the notes MCP tool:
// Save a notenotes({ action: "save", key: "user-preferences", value: JSON.stringify({ theme: "dark", lang: "en" }), tags: ["preferences"]})
// Get a notenotes({ action: "get", key: "user-preferences"})
// List notes by tagnotes({ action: "list", tag: "preferences"})
// Check quotanotes({ action: "stats"})Real Example
Section titled “Real Example”From smart-purchase-assistant.json:
{ "id": "write-note-step-1", "type": "write-note", "key": "purchase-{{executionId}}-01-user-needs", "source": "{{step-1-identify}}", "tags": ["purchase-{{executionId}}", "smart-purchase"], "connections": { "default": "step-2-research" }}Later in the workflow:
{ "directive": "Create final purchase report.\n\n**User needs:**\n{{note:purchase-{{executionId}}-01-user-needs}}\n\n**Research results:**\n{{note:purchase-{{executionId}}-02-research}}"}Best Practices
Section titled “Best Practices”Tag Strategy
Section titled “Tag Strategy”- Use execution-specific tag:
purchase-{{executionId}} - Use category tag:
smart-purchase,research-flow - Enables efficient filtering and cleanup
Error Handling
Section titled “Error Handling”{ "id": "write-critical", "type": "write-note", "key": "critical-data-{{executionId}}", "source": "{{results}}", "connections": { "default": "continue", "error": "handle-write-error" }}Data Serialization
Section titled “Data Serialization”- Objects and arrays auto-serialize to JSON
- Primitive values stored as strings
- For large objects, consider chunking or artifacts
Anti-patterns
Section titled “Anti-patterns”Not Using Execution Isolation
Section titled “Not Using Execution Isolation”// Wrong - shared across executions{ "key": "user-analysis" }
// Right - isolated per execution{ "key": "user-analysis-{{executionId}}" }Overusing Notes for Simple Data
Section titled “Overusing Notes for Simple Data”Don’t store loop counters or temporary values in notes. Use expression nodes or context variables instead.
Storing Large Binary Data
Section titled “Storing Large Binary Data”Notes are for structured text data. Use Artifacts for HTML content or large files.
Related Patterns
Section titled “Related Patterns”- Artifacts Publishing - For HTML content with public URLs
- Workspace - For organized file structures