AI Agent Global Variable Pool & Memory Mechanisms: A Practical Guide to Workflow Node Data Passing
AI Agent Global Variable Pool & Memory…
A comprehensive guide to designing global variable pools and memory mechanisms for AI Agent workflows.
This article explores the design and implementation of global variable pools in AI Agent workflow engines. It covers three types of AI memory (in-memory, global, and persistent), variable scope division, node execution architecture abstraction using strategy patterns, and placeholder-based variable replacement. Practical applications in AI orchestration platforms like Dify and Coze, low-code tools, and automation workflows are also discussed.
Introduction
In AI Agent development, "memory" is the core factor that determines the intelligence level of the entire system. When building a workflow editor, how nodes pass data to each other and how AI "remembers" contextual information during execution — all of this depends on the design and implementation of a variable pool. This article starts with the classification of AI memory, dives deep into the operational logic of global variable pools, and explains how to implement variable parsing and replacement in a frontend workflow editor.
Three Types of AI Memory
In AI Agent architecture design, memory mechanisms are typically divided into three layers. This layered design draws inspiration from cognitive science research on human memory systems — human memory is divided into sensory memory, short-term memory (working memory), and long-term memory. The in-memory, global, and persistent memory types in AI systems correspond to these respectively. This biomimetic design enables AI Agents to process and retain information across different time scales, achieving intelligent behavior closer to human cognition.
In-Memory (Volatile) Memory
In-memory memory is the most lightweight type, with data stored in runtime memory and a lifecycle tied to the application process. It's suitable for storing temporary context during execution, such as intermediate states of the current conversation, parameters passed between nodes, etc. This type of memory features fast read/write speeds, but data disappears once the process ends.
Technically, in-memory memory is typically stored as key-value pairs in the process's heap memory. In a Node.js environment, this might be a simple JavaScript object or Map structure. In distributed scenarios, in-memory databases like Redis can be used to achieve cross-process "in-memory" memory sharing, but its essence remains volatile storage.
Global Memory
Global memory is a variable space accessible throughout the entire workflow execution. Regardless of which node is currently executing, data can be read from or written to global memory. This is exactly the functionality carried by the "global variable pool" we'll focus on today.
Global memory design needs to consider concurrency safety. When parallel branches exist in a workflow, multiple nodes may simultaneously read and write the same global variable, requiring lock mechanisms or immutable data structures to avoid race conditions. In JavaScript's single-threaded environment, this problem is relatively simplified due to the event loop's characteristics, but it still requires careful handling in multi-Worker or distributed execution scenarios.
Persistent Memory
Persistent memory requires external storage, typically involving vector databases. The core principle of vector databases is converting unstructured data like text and images into high-dimensional vectors (usually 768 or 1536 dimensions) through Embedding models, then using Approximate Nearest Neighbor (ANN) algorithms (such as HNSW, IVF, etc.) for efficient similarity search. Common choices include:
- pgvector: A vector extension for PostgreSQL, suitable for teams with existing PG infrastructure. Its advantage lies in combining vector search with traditional relational queries for hybrid retrieval
- Qdrant: A dedicated vector search engine with excellent performance. Written in Rust, it supports rich filtering conditions and payload storage
- Milvus: An open-source large-scale vector database suitable for enterprise applications. Supports distributed retrieval of trillion-scale vectors
Persistent memory essentially falls under the domain of RAG (Retrieval-Augmented Generation). RAG technology addresses issues like knowledge cutoff and hallucination in large language models by introducing external knowledge retrieval during the generation phase. Its typical workflow includes: document chunking → vectorized storage → retrieving relevant chunks at query time → injecting retrieval results as context into the prompt. The choice of chunking strategy (fixed-length splitting, semantic splitting, recursive character splitting, etc.) directly impacts retrieval quality and is an independent and complex technical domain.
Design Philosophy of the Global Variable Pool
What Is a Global In-Memory Variable Pool
A global in-memory variable pool, as the name suggests, is a global data container that exists in memory throughout the entire workflow execution. Its core purpose is: enabling data produced by upstream nodes to be consumed and used by any downstream node.
From a data structure perspective, a global variable pool is essentially a flat or nested key-value store. In simple scenarios, it can be an object of type Record<string, any>; in complex scenarios, it may need to support namespaces to avoid variable name conflicts between different node outputs, for example using nodeId.variableName for addressing.
Here's a simple example: suppose the global variable pool stores a name field that comes from an upstream node's output. When a downstream AI prompt node needs to use this name, it simply references it through the placeholder {{name}} in the template, and the system automatically retrieves the value from the variable pool and replaces it during execution.
Variable Scope Division
In a real workflow editor, variable scope is typically divided into two levels:
- Global Scope: A shared variable space across the entire workflow, readable and writable by any node
- Node Scope: A private variable space for each node, valid only during that node's execution, which can also be passed downstream as the node's output
This design is consistent with the scope concept in programming languages, ensuring both global data accessibility and avoiding variable naming conflicts. In JavaScript, this is similar to the relationship between global variables and function-local variables. In more complex workflow systems, closure-like mechanisms may also be introduced — sub-workflows can access parent workflow variables, but parent workflows cannot directly access sub-workflow internal variables.
Some mature workflow platforms also introduce a third level — Environment Variables — for storing API keys, service endpoints, and other configuration information. These variables are determined at workflow definition time and cannot be modified at runtime.
Architectural Abstraction of Node Execution
Design Evolution: From Unified to Separated
In the initial design of a workflow engine, we might use a single unified executeNode function to handle all node execution. But as business complexity grows, different node types (start nodes, end nodes, AI nodes) have fundamentally different execution logic, and unified handling leads to bloated and hard-to-maintain code.
This evolution is very common in software engineering, reflecting the balance between "premature abstraction" and "timely refactoring." The "Rule of Three" mentioned by Martin Fowler in Refactoring applies here as well: when you encounter similar but different logic for the third time, it's the optimal moment to extract an abstraction.
Therefore, a better approach is to perform further low-level abstraction, splitting the execution logic into:
executeStartNode: Handles start nodes, initializes the global variable pool, receives external input parametersexecuteEndNode: Handles end nodes, collects final output, cleans up the execution contextexecuteAINode: Handles AI prompt nodes, performs variable replacement and model invocation, processes streaming responses
This separation embodies an important architectural principle: true design and architecture are incremental. When you find that a unified abstraction can no longer meet differentiated requirements, it's time for the next level of abstraction.
Switch-Case Based Node Routing
In the execution engine, a switch-case statement dispatches to the corresponding execution function based on node type:
switch (element.type) {
case 'start':
nodeData = executeStartNode(element);
break;
case 'end':
nodeData = executeEndNode(element);
break;
case 'ai_prompt':
nodeData = executeAINode(element);
break;
}
Each execution function returns processed nodeData, which replaces the original element.data and becomes the actual data used in subsequent processes.
It's worth noting that while the Switch-Case pattern is intuitive, as node types continue to grow, it faces challenges with the Open-Closed Principle (OCP) — every new node type requires modifying the routing logic. A more elegant alternative is the Strategy Pattern, which associates node types with corresponding executors through a registration mechanism:
// Strategy registry
const executorRegistry = new Map();
executorRegistry.set('start', executeStartNode);
executorRegistry.set('end', executeEndNode);
executorRegistry.set('ai_prompt', executeAINode);
// Dynamic lookup at execution time
const executor = executorRegistry.get(element.type);
if (executor) {
nodeData = executor(element);
}
This approach eliminates the need to modify core routing logic when adding new node types — you simply register a new executor, aligning with plugin-based architecture design principles.
Implementation of Variable Replacement
Placeholder Parsing and Replacement Flow
The core variable replacement flow can be summarized in three steps:
- Define placeholders: In node configurations (such as the
labelordescriptionfields of an AI prompt), use specific syntax to mark variable positions, e.g.,{{name}} - Look up variable values: At execution time, look up the corresponding variable values from the global variable pool
- Perform replacement: Replace placeholders with actual variable values to generate the final execution parameters
This placeholder syntax (double curly braces) has a long history in the frontend world. The Mustache template language was the first to adopt this syntax ("Mustache" means a mustache in English, and the shape of double curly braces resembles a sideways mustache), later widely adopted by frameworks like Vue.js and Angular. In workflow scenarios, variable replacement is typically implemented via regular expressions:
const replaceVariables = (template, variables) => {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return variables[key] !== undefined ? variables[key] : match;
});
};
In production environments, additional edge cases need to be considered: nested variable references ({{user.{{field}}}}), filter support ({{name | uppercase}}), default value syntax ({{name || 'Anonymous User'}}), etc.
Taking an AI prompt node as an example, suppose the original prompt template is:
Hello, {{name}}, please help me complete the following task...
When name = "Miaoma" in the global variable pool, the replaced actual prompt becomes:
Hello, Miaoma, please help me complete the following task...
Asynchronous Execution and Data Backfill
In a real workflow engine, node execution is typically asynchronous. By using await new Promise to wait for node execution to complete, the returned data is then backfilled into the execution context. This process ensures that variable replacement occurs at the right moment — before the node actually executes, all placeholders have already been replaced with actual values.
The choice of asynchronous execution model directly impacts the workflow engine's performance and reliability. In a Node.js environment, common implementation approaches include:
- Serial execution: Using
for...of+awaitto execute nodes one by one — simple but less efficient - Parallel execution: For nodes with no dependencies in the DAG, using
Promise.allfor parallel execution to improve throughput - Streaming execution: For LLM calls, using Server-Sent Events (SSE) or WebSocket for streaming output to improve user experience
Additionally, production-level concerns such as timeout handling, retry mechanisms, and error propagation need to be considered. When a node fails, whether to terminate the entire workflow, skip the node and continue, or follow a predefined error-handling branch — these are all design trade-offs in workflow engine development.
Practical Application Scenarios
The design patterns of global variable pools and workflow editors have broad applications in the current technology ecosystem:
- AI Orchestration Engines: Platforms like Dify and Coze center their workflow orchestration around data flow between nodes and variable management. Dify is an open-source LLM application development platform whose workflow engine supports serial, parallel, conditional branching, looping, and other execution modes, with a variable system supporting strings, numbers, arrays, objects, and other data types. Coze (under ByteDance) offers a richer plugin ecosystem and multimodal capabilities. These platforms share the common trait of abstracting complex AI orchestration logic into visual node-and-wire operations, lowering the barrier to AI application development
- Low-Code Platforms: Data binding and state management in visual building tools are essentially applications of variable pools. For example, platforms like Alibaba's Yida and Tencent's Weida rely on similar variable parsing mechanisms for form linkage, conditional visibility, and other features
- Automation Workflows: Tools like n8n and Zapier similarly rely on variable mechanisms for data passing between nodes. n8n uses an expression-based variable reference approach (e.g.,
{{$node["HTTP Request"].json["body"]}}), supporting more complex data path access
From a tech stack perspective, the frontend implementation of workflow editors typically relies on the following technologies:
- React Flow / Vue Flow: Providing foundational capabilities like node dragging, connecting, and canvas zooming
- Zustand / Pinia: Managing the editor's global state, including node data, connection relationships, variable pools, etc.
- Monaco Editor: Providing code editing and IntelliSense capabilities for variable expressions
For frontend developers, mastering workflow editor development not only addresses AI Agent-related business requirements but also offers high reuse value in low-code and process automation domains.
Summary
The global variable pool is core infrastructure in an AI Agent workflow engine. The fundamental problem it solves is: how to enable various nodes in a workflow to share and consume data. From in-memory variable pools to persistent storage, from global scope to node scope, each layer of design serves different business scenarios. Understanding these concepts and being able to implement them in real projects is an essential skill for AI Agent developers.
From a broader perspective, the design philosophy of the global variable pool shares remarkable similarities with state management in reactive programming (such as Redux's Store and MobX's Observable) — they all address the core problem of "how to achieve predictable data flow in complex systems." Mastering this mental model will help developers navigate various complex system designs with confidence.
Key Takeaways
Related articles

Claude Code for Test Development in Practice: An AI Programming Workflow That Doubles Your Efficiency
A practical guide to Claude Code for test development: auto-generating test scripts, Plan Mode workflows, MCP + Playwright integration, and Subagent parallel tasks to build systematic AI-assisted workflows.

Hermes Agent Hands-On Review: An AI Efficiency Revolution for Indie Game Developers
Indie game developer reviews Hermes Agent vs OpenClaude: intelligent context compression, real-time Memory, remote control via Telegram, and practical use cases in game dev, social media, and email.

Vibe Coding Beginner's Guide: Tool Selection Across Three Categories with Practical Examples
A comprehensive guide to Vibe Coding's three tool categories: Agent frameworks, CLI Coding, and IDE tools, with practical examples including Snake game and data analysis workbench.