In the world of artificial intelligence, training a new machine learning model can feel like conducting a complex, multi-stage orchestra. You have to source and prepare the data, configure the training environment, run the job, validate the results, and finally, deploy the model. Each step depends on the last, and a failure at any point can bring the entire process to a screeching halt, leaving you to sift through logs to find the single point of failure.
This complexity is a major hurdle in scaling AI development. Monolithic scripts and brittle pipelines are difficult to debug, impossible to reuse, and a nightmare to maintain. But what if we could approach this differently? What if we could break down that entire orchestra into individual musicians, each playing their part perfectly and independently?
This is the philosophy behind action.do—the fundamental building block of modern automation. By breaking down complex processes like model training into discrete, atomic actions, we can build robust, scalable, and manageable agentic workflows.
At its core, action.do represents a single, executable step. Think of it as the smallest, indivisible unit of work in your system. It's not a whole script; it's a single, focused task:
This principle of atomicity is what makes action.do so powerful. When an action has one job, it becomes incredibly reliable, easy to test, and simple to debug. You're no longer hunting for a bug in a 500-line script; you're examining a single, isolated unit of logic.
By defining these simple, powerful actions as code, you begin to build a library of reusable capabilities—turning your unique business logic into composable Business as Code.
Defining an action is straightforward. Using the .do SDK, you provide a unique ID, a description, and the core execution logic.
Let's look at a simple example: an action to send a welcome email to a new user.
import { action } from '@do-sdk/core';
// Define an action to send a welcome email
const sendWelcomeEmail = action.create({
id: 'send-welcome-email',
description: 'Sends a welcome email to a new user.',
execute: async ({ email, name }) => {
// Your email sending logic via an external API
console.log(`Sending welcome email to ${name} at ${email}...`);
// Example: await emailProvider.send({ to: email, ... });
return { success: true, messageId: 'xyz-123' };
}
});
// Execute the action
const result = await sendWelcomeEmail.execute({
email: 'jane.doe@example.com',
name: 'Jane Doe'
});
console.log(result); // { success: true, messageId: 'xyz-123' }
This code encapsulates one specific task. The execute function contains the logic, which could be anything from making an API call to running a shell script. The key is that it's self-contained. Now, imagine creating similar actions for our AI model training pipeline: fetch-training-data, preprocess-images, or deploy-model-to-staging. The structure remains the same, providing a consistent, predictable pattern for all your automated tasks.
A single action.do is a building block. The true power emerges when you chain them together inside a workflow.do to deliver valuable Services-as-Software.
A workflow.do orchestrates multiple actions, passing the output of one step as the input to the next, handling errors, and managing conditional logic. It's the conductor that brings all the individual musicians together to perform a symphony.
Let's map our AI model training process to a conceptual workflow composed of atomic actions:
In this model, if the preprocess-data step fails, the entire workflow halts there. You know exactly which atomic unit failed and why, without affecting any other part of the system. Each action can be tested in isolation and reused in other workflows, drastically accelerating development.
By embracing these principles, you move away from tangled, monolithic processes and towards a modular, resilient, and scalable system for automation. Whether it's a complex AI pipeline or a simple user-onboarding sequence, the approach is the same: break it down into atomic steps and build up from there.
Q: What is an 'atomic action' in the context of .do?
A: An atomic action is the smallest, indivisible unit of work in a workflow. It performs a single, specific task, like 'send an email' or 'update a database record', ensuring that operations are reliable, testable, and easy to debug.
Q: How does an action.do differ from a workflow.do?
A: An action.do represents a single step, while a workflow.do orchestrates multiple actions to achieve a larger business outcome. You build powerful workflows by composing a series of simple actions.
Q: Can I create my own custom actions?
A: Yes. The .do platform is designed for extensibility. You can define your own custom actions using our SDK, encapsulating your specific business logic and integrating any third-party API to make them available in any workflow.
Q: Are actions stateful?
A: No, actions are stateless by design. They receive input, perform their task, and produce output without retaining memory of previous executions. State management is handled at the workflow level, ensuring actions are reusable and predictable.