Skip to content

AI Agents with Trigger.dev

Trigger.dev is purpose-built for AI agent workflows — long-running, multi-step processes that use LLMs to make decisions and take actions.

Why Trigger.dev for AI Agents?

  • No timeouts — agents can run for minutes, hours, or days
  • Automatic retries — recover from LLM failures and API errors
  • Wait & resume — pause agents while waiting for human approval or external events
  • Real-time streaming — stream agent progress to your frontend
  • Parallel execution — run multiple agent workers simultaneously
  • Full observability — trace every step in the dashboard

Agent Patterns

Based on Anthropic's guide to building effective agents:

Prompt Chaining

Chain LLM calls where output from one becomes input to the next:

ts
export const generateAndTranslateTask = task({
  id: "generate-and-translate",
  run: async (payload: { topic: string; targetLanguage: string }) => {
    // Step 1: Generate content
    const content = await generateContent(payload.topic);
    // Step 2: Translate content
    const translated = await translateContent(content, payload.targetLanguage);
    return { content, translated };
  },
});

Routing

Direct requests to different models or handlers based on analysis:

ts
export const routeQuestionTask = task({
  id: "route-question",
  run: async ({ question }: { question: string }) => {
    const complexity = await analyzeComplexity(question);
    if (complexity === "simple") {
      return await gpt4oMini.generate(question);
    } else {
      return await claude.generate(question);
    }
  },
});

Parallelization

Run multiple checks or processes simultaneously using batchTriggerAndWait:

ts
export const moderateContent = task({
  id: "moderate-content",
  run: async ({ message }: { message: string }) => {
    // Simultaneously check for violence, hate speech, and spam
    const [violenceCheck, hateCheck, spamCheck] = await Promise.all([
      checkViolence.triggerAndWait({ message }),
      checkHateSpeech.triggerAndWait({ message }),
      checkSpam.triggerAndWait({ message }),
    ]);
    return { safe: !violenceCheck.flagged && !hateCheck.flagged && !spamCheck.flagged };
  },
});

Orchestrator Pattern

A parent task coordinates multiple specialized worker tasks:

ts
export const orchestratorTask = task({
  id: "fact-check-article",
  run: async ({ article }: { article: string }) => {
    const claims = await extractClaims(article);
    const verificationResults = await claimVerifier.batchTriggerAndWait(
      claims.map((claim) => ({ payload: { claim } }))
    );
    return { verified: verificationResults.filter((r) => r.output.verified) };
  },
});

Evaluator-Optimizer

Generate output, evaluate it, then refine through feedback:

ts
export const refineTranslationTask = task({
  id: "refine-translation",
  run: async ({ text, targetLanguage }: { text: string; targetLanguage: string }) => {
    let translation = await translateText(text, targetLanguage);
    let score = 0;
    let attempts = 0;

    while (score < 0.9 && attempts < 3) {
      const evaluation = await evaluateTranslation({ original: text, translation, targetLanguage });
      score = evaluation.score;
      if (score < 0.9) {
        translation = await refineTranslation({ translation, feedback: evaluation.feedback });
      }
      attempts++;
    }

    return { translation, score, attempts };
  },
});

Human-in-the-Loop

Pause an agent for human review using wait tokens:

ts
export const humanApprovalTask = task({
  id: "human-approval",
  run: async (payload) => {
    const content = await generateContent(payload.prompt);

    // Create a token and send for review
    const token = await wait.createToken({ timeout: "24h" });
    await sendForReview(content, token.publicAccessToken);

    // Wait for human to approve/reject
    const result = await wait.forToken<{ approved: boolean; feedback?: string }>(token);

    if (result.ok && result.output.approved) {
      return { content, approved: true };
    } else {
      // Revise with feedback
      return await reviseContent(content, result.output?.feedback);
    }
  },
});

Example Projects

Built from official Trigger.dev documentation