Astreus

Graphe

Orchestration de workflows avec gestion des dépendances et exécution parallèle Découvrez les schémas de configuration, les API et les exemples pratiques...

Orchestration de workflows avec gestion des dépendances et exécution parallèle

Vue d'ensemble

Le système Graph vous permet de créer des workflows complexes en connectant des tâches et des agents avec des dépendances, des conditions et des capacités d'exécution parallèle. Il offre un moyen visuel et programmatique d'orchestrer des processus en plusieurs étapes, de gérer une logique de branchement, et de coordonner plusieurs agents travaillant ensemble.

Créer un Graph

Les graphes sont composés de nœuds (tâches ou agents) et d'arêtes (connexions entre eux) :

import { Graph } from '@astreus-ai/astreus';

// Create a workflow graph with agent reference
const agent = await Agent.create({
  name: 'ContentAgent',
  model: 'gpt-4o'
});

const graph = new Graph({
  name: 'content-creation-pipeline',
  description: 'Research and write technical content'
}, agent);  // Pass agent as second parameter

// Add task nodes
const researchNodeId = graph.addTaskNode({
  prompt: 'Research the latest TypeScript features and summarize key findings',
  model: 'gpt-4o',
  priority: 10,
  metadata: { type: 'research' }
});

const writeNodeId = graph.addTaskNode({
  prompt: 'Write a comprehensive blog post based on the research findings',
  model: 'gpt-4o',
  dependencies: [researchNodeId],  // Depends on research completion
  priority: 5,
  metadata: { type: 'writing' }
});

// Execute the graph
const results = await graph.run();

console.log('Success:', results.success);
console.log('Completed nodes:', results.completedNodes);
console.log('Failed nodes:', results.failedNodes);
console.log('Duration:', results.duration, 'ms');
console.log('Results:', results.results);

Flux d'exécution du Graph

1

Résolution des nœuds

Le Graph analyse tous les nœuds et leurs dépendances pour déterminer l'ordre d'exécution.

2

Exécution parallèle

Les nœuds indépendants s'exécutent simultanément pour une performance optimale.

3

Attente des dépendances

Les nœuds dépendants attendent que leurs prérequis se terminent avant de démarrer.

4

Collecte des résultats

Tous les résultats des nœuds sont collectés et rendus disponibles dans le résultat final.

Exemple avancé

Voici un workflow complexe avec dépendances, exécution parallèle et gestion des erreurs :

import { Graph } from '@astreus-ai/astreus';

// Create workflow graph with default agent
const agent = await Agent.create({
  name: 'OptimizationAgent',
  model: 'gpt-4o'
});

const graph = new Graph({
  name: 'code-optimization-pipeline',
  description: 'Analyze and optimize codebase',
  maxConcurrency: 3,   // Allow 3 parallel nodes
  timeout: 300000,     // 5 minute timeout
  retryAttempts: 2     // Retry failed nodes twice
}, agent);  // Pass agent as second parameter

// Add task nodes with proper configuration
const analysisNodeId = graph.addTaskNode({
  prompt: 'Analyze the codebase for performance issues and categorize them by severity',
  model: 'gpt-4o',
  priority: 10,  // High priority
  metadata: { step: 'analysis', category: 'review' }
});

const optimizationNodeId = graph.addTaskNode({
  prompt: 'Based on the analysis, implement performance optimizations',
  model: 'gpt-4o',
  dependencies: [analysisNodeId],  // Depends on analysis
  priority: 8,
  metadata: { step: 'optimization', category: 'implementation' }
});

const testNodeId = graph.addTaskNode({
  prompt: 'Run performance tests and validate the optimizations',
  model: 'gpt-4o',
  dependencies: [optimizationNodeId],  // Depends on optimization
  priority: 6,
  stream: true,  // Enable streaming for real-time feedback
  metadata: { step: 'testing', category: 'validation' }
});

const documentationNodeId = graph.addTaskNode({
  prompt: 'Document all changes and performance improvements',
  model: 'gpt-4o',
  dependencies: [analysisNodeId],  // Can run parallel to optimization
  priority: 5,  // Lower priority
  metadata: { step: 'documentation', category: 'docs' }
});

// Add edges (optional, as dependencies already create edges)
graph.addEdge(analysisNodeId, optimizationNodeId);
graph.addEdge(analysisNodeId, documentationNodeId);
graph.addEdge(optimizationNodeId, testNodeId);

// Execute the graph
const results = await graph.run();

console.log('Pipeline results:', results);
console.log('Completed nodes:', results.completedNodes);
console.log('Failed nodes:', results.failedNodes);
console.log('Duration:', results.duration, 'ms');

// Access individual node results
Object.entries(results.results).forEach(([nodeId, result]) => {
  console.log(`Node ${nodeId}:`, result);
});

// Check for errors
if (results.errors && Object.keys(results.errors).length > 0) {
  console.log('Errors:', results.errors);
}

Configuration du Graph

Les graphes prennent en charge diverses options de configuration :

interface GraphConfig {
  id?: string;                 // Optional graph ID (UUID)
  name: string;                // Graph name (required)
  description?: string;        // Graph description
  maxConcurrency?: number;     // Max parallel execution (default: 1)
  timeout?: number;            // Execution timeout in ms
  retryAttempts?: number;      // Retry attempts for failed nodes
  autoLink?: boolean;          // Automatically link nodes based on dependencies
  maxContextTokens?: number;   // Maximum context tokens for the graph
  contextWarningThreshold?: number; // Warning threshold for context usage (0-1, e.g., 0.8 = 80%)
  subAgentNodeTimeout?: number;     // Extended timeout for sub-agent nodes (default: 5 minutes)
  metadata?: MetadataObject;   // Custom metadata
  subAgentAware?: boolean;                           // Enable sub-agent awareness and optimization
  optimizeSubAgentUsage?: boolean;                   // Optimize sub-agent delegation patterns
  subAgentCoordination?: 'parallel' | 'sequential' | 'adaptive'; // Default sub-agent coordination
}

// Note: The default agent is passed as the second parameter to the constructor:
// new Graph(config, agent)
// The graph's defaultAgentId is automatically set from the agent's ID.

// Example with full configuration including sub-agent support
const graph = new Graph({
  name: 'advanced-pipeline',
  description: 'Complex workflow with error handling and sub-agent coordination',
  maxConcurrency: 5,
  timeout: 600000,  // 10 minutes
  retryAttempts: 3,
  subAgentAware: true,
  optimizeSubAgentUsage: true,
  subAgentCoordination: 'adaptive',
  metadata: { project: 'automation', version: '1.0' }
}, agent);  // Agent passed as second parameter

Types de nœuds et options

Nœuds de tâche

interface AddTaskNodeOptions {
  name?: string;               // Node name for easy referencing
  prompt: string;              // Task prompt (required)
  model?: string;              // Override model for this task
  agentId?: string;            // Override default agent (UUID)
  stream?: boolean;            // Enable streaming for this task
  schedule?: string;           // Simple schedule string (e.g., 'daily@09:00', 'after:5s')
  dependencies?: string[];     // Node IDs this task depends on
  dependsOn?: string[];        // Node names this task depends on (easier than IDs)
  priority?: number;           // Execution priority (higher = earlier)
  metadata?: MetadataObject;   // Custom metadata
  useSubAgents?: boolean;                        // Force enable/disable sub-agent usage for this task
  subAgentDelegation?: 'auto' | 'manual' | 'sequential'; // Sub-agent delegation strategy
  subAgentCoordination?: 'parallel' | 'sequential';      // Sub-agent coordination pattern
}

Nœuds d'agent

interface AddAgentNodeOptions {
  agentId: string;             // Agent ID (required, UUID)
  dependencies?: string[];     // Node IDs this agent depends on
  priority?: number;           // Execution priority
  metadata?: MetadataObject;   // Custom metadata
}

Options de configuration des Sub-Agents

Lors de la configuration de graphes avec support des sous-agents, vous disposez d'un contrôle complet sur la délégation et la coordination :

Configuration des Sub-Agents au niveau du Graph

  • subAgentAware : active la détection et l'optimisation automatiques des opportunités de sous-agents à travers le graphe
  • optimizeSubAgentUsage : active la surveillance des performances en temps réel et l'ajustement automatique de la stratégie pour une meilleure efficacité
  • subAgentCoordination : définit le modèle de coordination par défaut :
    • 'parallel' : les sous-agents travaillent simultanément à travers différents nœuds
    • 'sequential' : les sous-agents travaillent dans l'ordre des dépendances, en transmettant le contexte entre les exécutions
    • 'adaptive' : choisit dynamiquement le meilleur modèle de coordination selon la complexité de la tâche et les dépendances

Configuration des Sub-Agents au niveau du nœud

Chaque nœud de tâche peut remplacer les paramètres au niveau du graphe avec un comportement spécifique de sous-agents :

  • useSubAgents : force l'activation ou la désactivation de la délégation aux sous-agents pour des nœuds spécifiques
  • subAgentDelegation : contrôle la manière dont les tâches sont distribuées aux sous-agents au niveau du nœud
  • subAgentCoordination : remplace le modèle de coordination par défaut du graphe pour des nœuds spécifiques

Workflow Graph amélioré avec des Sub-Agents

import { Graph, Agent } from '@astreus-ai/astreus';

// Create specialized sub-agents
const researcher = await Agent.create({
  name: 'DataResearcher',
  systemPrompt: 'You specialize in gathering and analyzing data from multiple sources.'
});

const analyst = await Agent.create({
  name: 'TechnicalAnalyst', 
  systemPrompt: 'You provide technical insights and recommendations.'
});

const writer = await Agent.create({
  name: 'TechnicalWriter',
  systemPrompt: 'You create clear, comprehensive technical documentation.'
});

// Main coordinator with sub-agents
const coordinator = await Agent.create({
  name: 'ProjectCoordinator',
  systemPrompt: 'You orchestrate complex projects using specialized team members.',
  subAgents: [researcher, analyst, writer]
});

// Create sub-agent optimized graph
// Note: defaultAgentId is automatically set from the coordinator agent passed as second parameter
const projectGraph = new Graph({
  name: 'Technical Documentation Pipeline',
  description: 'Automated technical documentation creation with specialized agents',
  maxConcurrency: 3,
  subAgentAware: true,
  optimizeSubAgentUsage: true,
  subAgentCoordination: 'adaptive'
}, coordinator);  // The coordinator's ID becomes the graph's defaultAgentId

// Research phase with automatic sub-agent delegation
const researchNode = projectGraph.addTaskNode({
  name: 'Market Research',
  prompt: 'Research current trends in cloud computing and serverless architecture',
  useSubAgents: true,
  subAgentDelegation: 'auto',
  priority: 10,
  metadata: { phase: 'research', category: 'data-gathering' }
});

// Analysis phase with sequential sub-agent coordination
const analysisNode = projectGraph.addTaskNode({
  name: 'Technical Analysis',
  prompt: 'Analyze research findings and identify key technical patterns',
  dependencies: [researchNode],
  useSubAgents: true,
  subAgentDelegation: 'auto',
  subAgentCoordination: 'sequential',
  priority: 8,
  metadata: { phase: 'analysis', category: 'insights' }
});

// Documentation phase with parallel sub-agent work
const docNode = projectGraph.addTaskNode({
  name: 'Documentation Creation',
  prompt: 'Create comprehensive technical documentation and executive summary',
  dependencies: [analysisNode],
  useSubAgents: true,
  subAgentDelegation: 'manual',
  subAgentCoordination: 'parallel',
  priority: 6,
  metadata: { phase: 'documentation', category: 'deliverables' }
});

// Execute the graph
const result = await projectGraph.run();

console.log('Pipeline completed:', result.success);
console.log('Node results:', result.results);

Types de réponse

L'exécution du Graph retourne des résultats complets incluant les résultats des nœuds, les statistiques d'utilisation, et les métriques de performance.

Résultat d'exécution du Graph

La méthode graph.run() retourne un GraphExecutionResult détaillé :

const result = await graph.run({ timeout: 60000 });

// Response structure:
{
  graph: {
    id: "graph-uuid-123",
    defaultAgentId: "agent-uuid",  // Set from the agent passed to constructor
    config: {
      name: "code-optimization-pipeline",
      description: "Analyze and optimize codebase",
      maxConcurrency: 3,
      timeout: 300000,
      retryAttempts: 2
    },
    nodes: [ /* GraphNode[] */ ],
    edges: [ /* GraphEdge[] */ ],
    status: "completed",  // 'idle' | 'running' | 'completed' | 'failed' | 'paused'
    startedAt: Date('2024-01-15T10:00:00Z'),
    completedAt: Date('2024-01-15T10:12:30Z'),
    executionLog: [ /* GraphExecutionLogEntry[] */ ],
    usage: { /* GraphUsage */ },
    createdAt: Date('2024-01-15T09:55:00Z'),
    updatedAt: Date('2024-01-15T10:12:30Z')
  },
  success: true,                // Overall success status
  completedNodes: 5,            // Number of successfully completed nodes
  failedNodes: 0,               // Number of failed nodes
  duration: 12500,              // Total execution time in milliseconds
  results: {
    "node_abc12345-...": "Analysis complete: Found 15 performance issues categorized by severity...",
    "node_def67890-...": "Optimization implemented: 40% performance improvement...",
    "node_ghi11111-...": "Tests passed: All optimizations validated...",
    "node_jkl22222-...": "Documentation updated with all changes...",
    "node_mno33333-...": "Final review completed..."
  },
  errors: {},  // Empty if all nodes succeeded
  usage: {
    totalPromptTokens: 1500,
    totalCompletionTokens: 3000,
    totalTokens: 4500,
    totalContextTokens: 500,
    totalCost: 0.045,
    nodeUsages: {
      "node_abc12345-...": {
        promptTokens: 200,
        completionTokens: 400,
        totalTokens: 600,
        contextTokens: 100,
        model: "gpt-4",
        cost: 0.012
      },
      "node_def67890-...": {
        promptTokens: 300,
        completionTokens: 600,
        totalTokens: 900,
        contextTokens: 150,
        model: "gpt-4",
        cost: 0.018
      }
      // ... more node usages
    },
    modelsUsed: ["gpt-4", "gpt-3.5-turbo"]
  }
}

Exécution du Graph avec erreurs

Lorsque des nœuds échouent, les erreurs sont incluses dans la réponse :

const result = await graph.run();

// Response with failures:
{
  graph: { /* ... */ },
  success: false,
  completedNodes: 3,
  failedNodes: 2,
  duration: 8500,
  results: {
    "node_abc12345-...": "Successfully completed...",
    "node_def67890-...": "Partial completion...",
    "node_ghi11111-...": "Task completed..."
  },
  errors: {
    "node_jkl22222-...": "Error: Timeout exceeded after 5000ms",
    "node_mno33333-...": "Error: Dependency node_jkl22222-... failed, skipping execution"
  },
  usage: { /* ... */ }
}

Réponse Add Node

Ajouter des nœuds retourne l'ID du nœud (format : node_<uuid>) :

const nodeId = graph.addTaskNode({
  name: "Analyze Data",
  prompt: "Analyze the following data...",
  model: "gpt-4",
  priority: 10
});

// Response: "node_a1b2c3d4-e5f6-7890-abcd-ef1234567890" (node ID string)

Détails d'utilisation par nœud

L'utilisation de chaque nœud est suivie individuellement :

// Access individual node usage from result
const nodeUsage = result.usage.nodeUsages["node_abc12345-..."];

// Structure:
{
  promptTokens: 200,
  completionTokens: 400,
  totalTokens: 600,
  contextTokens: 100,      // Optional: tokens from context/memory
  model: "gpt-4",
  cost: 0.012              // Optional: calculated cost
}

Résumé d'utilisation du Graph

Utilisation totale à travers tous les nœuds :

const totalUsage = result.usage;

// Structure:
{
  totalPromptTokens: 1500,        // Sum of all prompt tokens
  totalCompletionTokens: 3000,    // Sum of all completion tokens
  totalTokens: 4500,              // Total tokens used
  totalContextTokens: 500,        // Total context tokens loaded
  totalCost: 0.045,               // Total estimated cost
  nodeUsages: { /* ... */ },      // Per-node breakdown
  modelsUsed: ["gpt-4", "gpt-3.5-turbo"]  // All models used in execution
}

Dernière mise à jour : 6 juillet 2026