Building Basic Graphs in Astreus
Learn how to create workflow graphs in Astreus with task dependencies and sequential execution. Master the fundamentals of Agent.create(), Graph construction, and addTaskNode() for multi-step AI workflows.
Workflow graphs in Astreus let you orchestrate multi-step processes by defining tasks and their dependencies. Instead of running everything sequentially in code, you model the relationships between tasks and let the framework handle execution order.
Setting Up Your Environment
First, install the Astreus package:
Bashnpm install @astreus-ai/astreus
Create a .env file in your project root with your API credentials:
EnvOPENAI_API_KEY=sk-your-openai-api-key-here DB_URL=sqlite://./astreus.db
The OpenAI API key enables model access, while the database URL specifies where Astreus stores execution history. SQLite is the simplest option for getting started.
Creating Your First Agent
Every graph needs an agent to execute its tasks. Use Agent.create() to initialize one:
JavaScriptimport { Agent, Graph } from '@astreus-ai/astreus'; const agent = await Agent.create({ name: 'WorkflowAgent', model: 'gpt-4o' });
The agent acts as the worker that processes each task in your graph. The name parameter helps identify the agent in logs, while model specifies which LLM to use.
Initializing a Graph
With an agent created, you can construct a graph:
JavaScriptconst graph = new Graph({ name: 'research-workflow' }, agent);
The graph constructor takes two arguments: a configuration object with a name, and the agent instance. This binds the agent to the graph so it knows which worker will execute tasks.
Adding Task Nodes
Use addTaskNode() to define individual tasks within your graph:
JavaScriptconst research = graph.addTaskNode({ prompt: 'Research artificial intelligence trends' });
Each task node has a prompt that tells the agent what to do. The method returns a reference to the node, which you'll use when defining dependencies.
Creating Dependencies Between Tasks
Pass dependent nodes in an array to establish execution order:
JavaScriptconst summary = graph.addTaskNode({ prompt: 'Summarize the research findings', dependencies: [research] });
Now the summary task will only run after the research task completes. Dependencies ensure tasks have access to the outputs they need before starting.
Running Your Graph
Execute the entire workflow with the run() method:
JavaScriptconst results = await graph.run();
Astreus analyzes your graph structure, determines the correct execution order, and runs each task. The returned results object contains outputs from all completed nodes.
Accessing Task Results
Results are stored in a keyed object where each key matches a task node:
JavaScriptif (results.success && results.results[summary]) { const summaryResult = JSON.parse(results.results[summary]); console.log(summaryResult.response); }
Check results.success to verify the workflow completed without errors. Each result is a JSON string that needs parsing before you can access the response content.
Building a Multi-Step Workflow
Here's a complete example with multiple dependent tasks:
JavaScript
This creates a linear pipeline where each task depends on the previous one. The research informs the outline, which guides the draft writing.
Understanding Sequential Execution
When you define dependencies, Astreus guarantees execution order. A task will never start until all its dependencies finish:
JavaScriptconst taskA = graph.addTaskNode({ prompt: 'First task' }); const taskB = graph.addTaskNode({ prompt: 'Second task', dependencies: [taskA] }); const taskC = graph.addTaskNode({ prompt: 'Third task', dependencies: [taskB] });
This creates a chain: taskA runs first, then taskB, then taskC. Each task receives the output from its dependency as context.
Error Handling
Always check if the graph execution succeeded before accessing results:
JavaScriptconst results = await graph.run(); if (!results.success) { console.error('Workflow failed'); return; } // Safe to access results here const output = JSON.parse(results.results[myTask]);
If any task in the graph fails, results.success will be false. This prevents you from trying to parse results that don't exist.
Practical Example: Data Analysis Pipeline
Here's a real-world workflow that analyzes data and generates insights:
JavaScript
Each task builds on the previous one, creating a clear pipeline from raw data to actionable insights.
Working with Node References
The references returned by addTaskNode() are essential for building dependencies:
JavaScriptconst step1 = graph.addTaskNode({ prompt: 'First step' }); const step2 = graph.addTaskNode({ prompt: 'Second step' }); // Both steps must complete before final step const final = graph.addTaskNode({ prompt: 'Combine results from previous steps', dependencies: [step1, step2] });
You can reference multiple nodes in the dependencies array. The final task will wait for all of them to complete.
Getting Started with the Examples Repository
Astreus provides a complete working example you can clone and run:
Bashgit clone https://github.com/astreus-ai/basic-graphs cd basic-graphs npm install
This repository contains production-ready code demonstrating all the concepts covered here. Use it as a starting point for your own workflows.
Best Practices
Keep task prompts focused and specific. Each task should have a clear, single purpose that makes its role in the workflow obvious.
Use descriptive names for your graphs and agents. When debugging or monitoring execution, clear names make it easier to understand what's happening.
Structure your graphs to model actual task dependencies, not just the order you want things to run. This creates more maintainable workflows.
Common Patterns
Linear pipelines are the simplest pattern, where each task depends on exactly one previous task. This works well when each step requires the complete output of the previous step.
When multiple tasks can share a common starting point, create one initial node and have multiple tasks depend on it. This reduces redundant work.
Next Steps
Once you're comfortable with basic graphs, explore more advanced features like parallel execution and complex dependency structures. The foundation you've built here scales to much more sophisticated workflows.
Experiment with different task granularities to find what works for your use case. Sometimes many small tasks provide better flexibility, while other times fewer large tasks are more efficient.
This experiment is written for Astreus v0.5.37. Please ensure you are using a compatible version.