Skip to main content

Agent Workflows

Workflows let you orchestrate multiple Agents in complex pipelines. Chain Agents sequentially, run them in parallel, or route to different Agents based on conditions.

Sequential Agent Pipeline

import { Agent, Workflow } from 'praisonai';

const researcher = new Agent({
  name: 'Researcher',
  instructions: 'Research topics and gather information.'
});

const writer = new Agent({
  name: 'Writer',
  instructions: 'Write clear, engaging content.'
});

const editor = new Agent({
  name: 'Editor',
  instructions: 'Review and improve writing quality.'
});

// Chain Agents in a workflow
const contentPipeline = new Workflow('content-creation')
  .step('research', async (topic) => {
    return await researcher.chat(`Research: ${topic}`);
  })
  .step('write', async (research) => {
    return await writer.chat(`Write an article based on: ${research}`);
  })
  .step('edit', async (draft) => {
    return await editor.chat(`Edit and improve: ${draft}`);
  });

const { output } = await contentPipeline.run('AI in healthcare');
// Output: Polished article that went through research → writing → editing

Parallel Agent Execution

Run multiple Agents simultaneously:
import { Agent, parallel } from 'praisonai';

const sentimentAgent = new Agent({
  name: 'Sentiment Analyzer',
  instructions: 'Analyze sentiment of text.'
});

const summaryAgent = new Agent({
  name: 'Summarizer',
  instructions: 'Create concise summaries.'
});

const keywordAgent = new Agent({
  name: 'Keyword Extractor',
  instructions: 'Extract key topics and keywords.'
});

// All three Agents run concurrently
async function analyzeDocument(document: string) {
  const [sentiment, summary, keywords] = await parallel([
    async () => sentimentAgent.chat(document),
    async () => summaryAgent.chat(document),
    async () => keywordAgent.chat(document)
  ]);
  
  return { sentiment, summary, keywords };
}

const analysis = await analyzeDocument('Long document text...');
// All three analyses complete in parallel

Agent Router Workflow

Route to different Agents based on conditions:
import { Agent, route } from 'praisonai';

const techAgent = new Agent({
  name: 'Tech Support',
  instructions: 'Handle technical issues.'
});

const billingAgent = new Agent({
  name: 'Billing Support',
  instructions: 'Handle billing inquiries.'
});

const generalAgent = new Agent({
  name: 'General Support',
  instructions: 'Handle general questions.'
});

const classifierAgent = new Agent({
  name: 'Classifier',
  instructions: 'Classify queries as: technical, billing, or general. Return only the category.'
});

async function routeQuery(query: string) {
  // First, classify the query
  const category = await classifierAgent.chat(query);
  
  // Route to appropriate Agent
  return await route([
    {
      condition: () => category.includes('technical'),
      execute: async () => techAgent.chat(query)
    },
    {
      condition: () => category.includes('billing'),
      execute: async () => billingAgent.chat(query)
    }
  ], async () => generalAgent.chat(query)); // Default
}

await routeQuery('My payment failed'); // → Billing Agent
await routeQuery('App keeps crashing'); // → Tech Agent

Agent Loop (Iterative Refinement)

Have an Agent iterate until satisfied:
import { Agent, loop } from 'praisonai';

const writerAgent = new Agent({
  name: 'Writer',
  instructions: 'Write content based on feedback.'
});

const reviewerAgent = new Agent({
  name: 'Reviewer',
  instructions: 'Review content. Return "APPROVED" if good, or specific feedback for improvement.'
});

async function iterativeWriting(topic: string) {
  let draft = await writerAgent.chat(`Write about: ${topic}`);
  
  const finalDraft = await loop(
    async (iteration) => {
      const review = await reviewerAgent.chat(`Review this draft:\n${draft}`);
      
      if (review.includes('APPROVED')) {
        return { draft, approved: true };
      }
      
      // Refine based on feedback
      draft = await writerAgent.chat(`Improve this draft based on feedback:\nDraft: ${draft}\nFeedback: ${review}`);
      return { draft, approved: false };
    },
    (result, iteration) => !result.approved && iteration < 5 // Max 5 iterations
  );
  
  return finalDraft[finalDraft.length - 1].draft;
}

Multi-Agent Workflow with Context

Share context between Agents in a workflow:
import { Agent, Workflow } from 'praisonai';

const dataAgent = new Agent({
  name: 'Data Analyst',
  instructions: 'Analyze data and extract insights.'
});

const strategyAgent = new Agent({
  name: 'Strategist',
  instructions: 'Create strategies based on data insights.'
});

const reportAgent = new Agent({
  name: 'Report Writer',
  instructions: 'Write executive reports.'
});

const analysisWorkflow = new Workflow('business-analysis')
  .addStep({
    name: 'analyze',
    execute: async (data, context) => {
      const insights = await dataAgent.chat(`Analyze: ${JSON.stringify(data)}`);
      context.set('insights', insights);
      return insights;
    }
  })
  .addStep({
    name: 'strategize',
    execute: async (insights, context) => {
      const strategy = await strategyAgent.chat(`Create strategy for: ${insights}`);
      context.set('strategy', strategy);
      return strategy;
    }
  })
  .addStep({
    name: 'report',
    execute: async (strategy, context) => {
      const insights = context.get('insights');
      return await reportAgent.chat(`
        Write executive report:
        Insights: ${insights}
        Strategy: ${strategy}
      `);
    }
  });

const { output, context } = await analysisWorkflow.run(salesData);

Conditional Agent Steps

Skip Agents based on conditions:
import { Agent, Workflow } from 'praisonai';

const translatorAgent = new Agent({
  name: 'Translator',
  instructions: 'Translate content to English.'
});

const processorAgent = new Agent({
  name: 'Processor',
  instructions: 'Process the content.'
});

const workflow = new Workflow('conditional-processing')
  .addStep({
    name: 'translate',
    condition: (context) => context.metadata.language !== 'en',
    execute: async (input) => translatorAgent.chat(`Translate to English: ${input}`)
  })
  .addStep({
    name: 'process',
    execute: async (input) => processorAgent.chat(input)
  });

// Translation step skipped for English content
await workflow.run('Hello world', { metadata: { language: 'en' } });

// Translation step runs for non-English
await workflow.run('Bonjour le monde', { metadata: { language: 'fr' } });

Agent Workflow with Error Handling

Handle Agent failures gracefully:
import { Agent, Workflow } from 'praisonai';

const primaryAgent = new Agent({
  name: 'Primary',
  instructions: 'Handle requests.'
});

const fallbackAgent = new Agent({
  name: 'Fallback',
  instructions: 'Handle requests when primary fails.'
});

const resilientWorkflow = new Workflow('resilient')
  .addStep({
    name: 'primary',
    execute: async (input) => primaryAgent.chat(input),
    onError: 'skip',
    maxRetries: 2
  })
  .addStep({
    name: 'fallback',
    condition: (context) => context.get('primary') === undefined,
    execute: async (input) => fallbackAgent.chat(input)
  });

Workflow Patterns

PatternUse Case
SequentialResearch → Write → Edit
ParallelAnalyze sentiment + Extract keywords + Summarize
RouterRoute to Tech/Billing/General support
LoopIterative refinement until quality threshold
ConditionalSkip translation for English content