Astreus

그래프

Astreus 문서에서 그래프에 대해 알아보고, 에이전트 시스템을 구축하기 위한 설정 안내, API 패턴, 실용적인 예제를 확인하세요. 안정적인 Astreus 에이전트 시스템을 구축하는 데 필요한 설정 패턴, API, 실용적인 예제를 알아보세요.

종속성 관리와 병렬 실행을 갖춘 워크플로우 오케스트레이션

Overview

그래프 시스템을 사용하면 종속성, 조건, 병렬 실행 기능으로 작업과 에이전트를 연결해 복잡한 워크플로우를 만들 수 있습니다. 여러 단계의 프로세스를 조율하고, 분기 로직을 처리하고, 여러 에이전트가 함께 작업하도록 조정하는 시각적/프로그래밍적 방법을 제공합니다.

Creating a Graph

그래프는 노드(작업 또는 에이전트)와 엣지(노드 간 연결)로 구성됩니다.

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);

Graph Execution Flow

1

Node Resolution

그래프가 모든 노드와 그 종속성을 분석해 실행 순서를 결정합니다.

2

Parallel Execution

독립적인 노드들이 최적의 성능을 위해 동시에 실행됩니다.

3

Dependency Waiting

종속성이 있는 노드는 선행 조건이 완료될 때까지 시작을 기다립니다.

4

Result Collection

모든 노드의 출력이 수집되어 최종 결과에서 사용할 수 있게 됩니다.

Advanced Example

종속성, 병렬 실행, 오류 처리를 갖춘 복잡한 워크플로우 예제입니다.

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);
}

Graph 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

Node Types and Options

Task Nodes

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
}

Agent Nodes

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

Sub-Agent Configuration Options

서브 에이전트 지원을 갖춘 그래프를 설정할 때, 위임과 협업을 완전히 제어할 수 있습니다.

Graph-Level Sub-Agent Configuration

  • subAgentAware: 그래프 전체에서 서브 에이전트 기회를 자동으로 감지하고 최적화합니다
  • optimizeSubAgentUsage: 더 나은 효율을 위한 실시간 성능 모니터링과 자동 전략 조정을 활성화합니다
  • subAgentCoordination: 기본 협업 패턴을 설정합니다:
    • 'parallel': 서로 다른 노드에서 서브 에이전트가 동시에 작업합니다
    • 'sequential': 서브 에이전트가 종속성 순서대로 작업하며 실행 간에 컨텍스트를 전달합니다
    • 'adaptive': 작업 복잡도와 종속성에 따라 최적의 협업 패턴을 동적으로 선택합니다

Node-Level Sub-Agent Configuration

각 작업 노드는 특정 서브 에이전트 동작으로 그래프 수준 설정을 재정의할 수 있습니다.

  • useSubAgents: 특정 노드에 대해 서브 에이전트 위임을 강제로 활성화/비활성화합니다
  • subAgentDelegation: 노드 수준에서 작업이 서브 에이전트에게 분배되는 방식을 제어합니다
  • subAgentCoordination: 특정 노드에 대해 그래프의 기본 협업 패턴을 재정의합니다

Enhanced Graph Workflow with 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);

Response Types

그래프 실행은 노드 결과, 사용량 통계, 성능 지표를 포함한 종합적인 결과를 반환합니다.

Graph Execution Result

graph.run() 메서드는 상세한 GraphExecutionResult를 반환합니다.

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"]
  }
}

Graph Execution with Errors

노드가 실패하면 오류가 응답에 포함됩니다.

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: { /* ... */ }
}

Add Node Response

노드를 추가하면 노드 ID를 반환합니다 (형식: 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)

Node Usage Details

각 노드의 사용량은 개별적으로 추적됩니다.

// 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
}

Graph Usage Summary

모든 노드의 총 사용량입니다.

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
}

마지막 업데이트: 2026년 7월 6일