Sim

Esquema YAML del bloque Loop

Referencia de configuración YAML para bloques Loop

Definición del esquema

type: object
required:
  - type
  - name
  - connections
properties:
  type:
    type: string
    enum: [loop]
    description: Block type identifier
  name:
    type: string
    description: Display name for this loop block
  inputs:
    type: object
    description: Optional. If omitted, defaults will be applied.
    properties:
      loopType:
        type: string
        enum: [for, forEach]
        description: Type of loop to execute
        default: for
      iterations:
        type: number
        description: Number of iterations (for 'for' loops)
        default: 5
        minimum: 1
        maximum: 1000
      collection:
        type: string
        description: Collection to iterate over (for 'forEach' loops)
        default: ""
      maxConcurrency:
        type: number
        description: Maximum concurrent executions
        default: 1
        minimum: 1
        maximum: 10
  connections:
    type: object
    properties:
      # Nested format (recommended)
      loop:
        type: object
        properties:
          start:
            type: string
            description: Target block ID to execute inside the loop
          end:
            type: string
            description: Target block ID for loop completion (optional)
      # Direct handle format (alternative)
      loop-start-source:
        type: string | string[]
        description: Target block ID to execute inside the loop (direct format)
      loop-end-source:
        type: string | string[]
        description: Target block ID for loop completion (direct format, optional)
      error:
        type: string
        description: Target block ID for error handling
    note: Use either the nested 'loop' format OR the direct 'loop-start-source' format, not both

Configuración de conexión

Los bloques de bucle admiten dos formatos de conexión:

Formato de manejador directo (alternativo)

connections:
  loop-start-source: <string>           # Target block ID to execute inside the loop
  loop-end-source: <string>             # Target block ID after loop completion (optional)
  error: <string>                       # Target block ID for error handling (optional)

Ambos formatos funcionan de manera idéntica. Usa el que prefieras.

Configuración de bloques secundarios

Los bloques dentro de un bucle deben tener su parentId configurado con el ID del bloque de bucle. La propiedad extent se establece automáticamente como 'parent' y no necesita ser especificada:

loop-1:
  type: loop
  name: "Process Items"
  inputs:
    loopType: forEach
    collection: <start.items>
  connections:
    loop:
      start: process-item
      end: final-results

# Child block inside the loop
process-item:
  type: agent
  name: "Process Item"
  parentId: loop-1                      # References the loop block
  inputs:
    systemPrompt: "Process this item"
    userPrompt: <loop.currentItem>
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'

Ejemplos

Bucle For (iteraciones fijas)

countdown-loop:
  type: loop
  name: "Countdown Loop"
  inputs:
    loopType: for
    iterations: 5
  connections:
    loop:
      start: countdown-agent
      end: countdown-complete

countdown-agent:
  type: agent
  name: "Countdown Agent"
  parentId: countdown-loop
  inputs:
    systemPrompt: "Generate a countdown message"
    userPrompt: "Count down from 5. Current number: <loop.index>"
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'

Bucle ForEach (procesamiento de colecciones)

email-processor-loop:
  type: loop
  name: "Email Processor Loop"
  inputs:
    loopType: forEach
    collection: <start.emails>
  connections:
    loop:
      start: process-single-email
      end: all-emails-processed

process-single-email:
  type: agent
  name: "Process Single Email"
  parentId: email-processor-loop
  inputs:
    systemPrompt: "Classify and respond to this email"
    userPrompt: "Email content: <loop.currentItem>"
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'

Bucle con múltiples bloques secundarios

data-analysis-loop:
  type: loop
  name: "Data Analysis Loop"
  inputs:
    loopType: forEach
    collection: <data-fetcher.records>
    maxConcurrency: 3
  connections:
    loop:
      start: validate-record
      end: generate-report
    error: handle-loop-error

validate-record:
  type: function
  name: "Validate Record"
  parentId: data-analysis-loop
  inputs:
    code: |
      const record = <loop.currentItem>;
      const index = <loop.index>;
      
      // Validate the record
      if (!record.id || !record.data) {
        throw new Error(`Invalid record at index ${index}`);
      }
      
      return {
        valid: true,
        recordId: record.id,
        processedAt: new Date().toISOString()
      };
  connections:
    success: analyze-record
    error: record-error

analyze-record:
  type: agent
  name: "Analyze Record"
  parentId: data-analysis-loop
  inputs:
    systemPrompt: "Analyze this data record and extract insights"
    userPrompt: |
      Record ID: <validaterecord.recordId>
      Data: <loop.currentItem.data>
      Position in collection: <loop.index>
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'
  connections:
    success: store-analysis

store-analysis:
  type: function
  name: "Store Analysis"
  parentId: data-analysis-loop
  inputs:
    code: |
      const analysis = <analyzerecord.content>;
      const recordId = <validaterecord.recordId>;
      
      // Store analysis result
      return {
        recordId,
        analysis,
        completedAt: new Date().toISOString()
      };

Bucle de procesamiento concurrente

parallel-processing-loop:
  type: loop
  name: "Parallel Processing Loop"
  inputs:
    loopType: forEach
    collection: <start.tasks>
    maxConcurrency: 5
  connections:
    loop:
      start: process-task
      end: aggregate-results

process-task:
  type: api
  name: "Process Task"
  parentId: parallel-processing-loop
  inputs:
    url: "https://api.example.com/process"
    method: POST
    headers:
      - key: "Authorization"
        value: "Bearer {{API_TOKEN}}"
    body: |
      {
        "taskId": "<loop.currentItem.id>",
        "data": "<loop.currentItem.data>"
      }
  connections:
    success: task-completed

Ejemplo de formato de manejador directo

El mismo bucle puede escribirse usando el formato de manejador directo:

my-loop:
  type: loop
  name: "Process Items"
  inputs:
    loopType: forEach
    collection: <start.items>
  connections:
    loop-start-source: process-item      # Direct handle format
    loop-end-source: final-results       # Direct handle format
    error: handle-error

process-item:
  type: agent
  name: "Process Item"
  parentId: my-loop
  inputs:
    systemPrompt: "Process this item"
    userPrompt: <loop.currentItem>
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'

Ejemplo de bucle mínimo (usando valores predeterminados)

Puedes omitir completamente la sección inputs, y se aplicarán los valores predeterminados:

simple-loop:
  type: loop
  name: "Simple Loop"
  # No inputs section - defaults to loopType: 'for', iterations: 5
  connections:
    loop-start-source: process-step
    loop-end-source: complete

process-step:
  type: agent
  name: "Process Step"
  parentId: simple-loop
  inputs:
    systemPrompt: "Execute step"
    userPrompt: "Step <loop.index>"
    model: gpt-4o
    apiKey: '{{OPENAI_API_KEY}}'

Este bucle ejecutará 5 iteraciones por defecto.

Variables de bucle

Dentro de los bloques secundarios del bucle, estas variables especiales están disponibles:

# Available in all child blocks of the loop
<loop.index>                    # Current iteration number (0-based)
<loop.currentItem>              # Current item being processed (forEach loops)
<loop.items>                    # Full collection (forEach loops)

Referencias de salida

Después de que un bucle se completa, puedes hacer referencia a sus resultados agregados:

# In blocks after the loop
final-processor:
  inputs:
    all-results: <loop-name.results>    # Array of all iteration results
    total-count: <loop-name.count>      # Number of iterations completed

Mejores prácticas

  • Establece límites de iteración razonables para evitar tiempos de ejecución largos
  • Usa forEach para procesar colecciones, bucles for para iteraciones fijas
  • Considera usar maxConcurrency para operaciones limitadas por E/S
  • Incluye manejo de errores para una ejecución robusta del bucle
  • Usa nombres descriptivos para los bloques secundarios del bucle
  • Prueba primero con colecciones pequeñas
  • Monitorea el tiempo de ejecución para colecciones grandes