AIエージェント入門

Trigger.dev完全ガイド|AIエージェント長時間タスク実装

Trigger.devでAIエージェント長時間タスクをDurable Executionで実装する

この記事の結論

Trigger.devはOSS Durable ExecutionプラットフォームでAIエージェントの長時間タスク・失敗リトライ・冪等性管理を解決する。v4新機能からLLM API呼び出しのDurable化まで実装コードで解説。



この記事でわかること: Trigger.devを使うと、AIエージェントの長時間タスク・失敗リトライ・冪等性管理をコード数行で解決できます。

  • Durable Executionの設計思想と、サーバーレス環境でのタイムアウト問題を根本から解決する仕組み
  • v4(2026年GA)で追加されたWaitpoints・Run Engineの実装パターン
  • LLM APIを呼び出すタスクのDurable化コードサンプル(TypeScript・Python)

対象読者: AIエージェント・自動化ワークフローを本番運用したい開発者・PM

今日やること: npx trigger.dev@latest init でプロジェクトを初期化し、最初のタスクを5分でデプロイする

「AIエージェントのタスクが途中でタイムアウトした」「OpenAI APIがレート制限で落ちたのに、最初からやり直しになった」——こんな経験はないでしょうか。

VercelやAWS Lambdaのサーバーレス環境では、実行時間に厳しい上限があります。AIエージェントが得意とする「スクレイピング→LLM処理→データ保存」のような多段タスクを信頼性高く動かすには、既存の関数実行基盤では限界があるのが現実です。

この記事では、その問題を解決するOSSプラットフォームTrigger.devを解説します。Durable Executionの設計思想から、2026年にGAになったv4の新機能、LLM APIを呼び出すタスクの実装パターンまで、コピペ可能なコードで紹介していきます。

Trigger.devとは何か

Trigger.devは、バックグラウンドジョブ・AIエージェント・自動化ワークフローをデプロイするためのOSS Durable Executionプラットフォームです。2022年創業のアイルランド発スタートアップで、GitHubスター数は14,000以上(2026年5月時点)。ライセンスはApache 2.0で、セルフホストも可能です。

最大の特徴は「タイムアウトなしの実行」です。AWS LambdaやVercel Functionsは最大15〜900秒の制限がありますが、Trigger.devではタスクを一時停止・再開できる仕組みにより、理論上は無制限に長いタスクを走らせられます。

Durable Executionとは

Durable Execution(耐久実行)とは、タスクの実行状態をチェックポイントとして保存しておき、障害・タイムアウト・意図的な一時停止があっても、その時点から再開できる仕組みです。

Trigger.devはCRIU(Checkpoint/Restore In Userspace)技術を使い、タスクのメモリ・CPUレジスタ・ファイルディスクリプタをそのままスナップショットします。再起動後はスナップショットをロードするだけで、コードは中断した行から続きを実行します。

インストールとプロジェクト初期化

Trigger.devはCLIとSDKで構成されています。まずNode.js 18以上の環境でプロジェクトを初期化します。

# CLI初期化(既存プロジェクトに追加する場合)
npx trigger.dev@latest init

# 新規プロジェクトを作成する場合
npx trigger.dev@latest create-project --name my-agent

CLIがインタラクティブに設定をガイドします。TypeScriptプロジェクトであれば、trigger.config.tssrc/trigger/ ディレクトリが自動作成されます。

# SDKのインストール
npm install @trigger.dev/sdk@latest

# AI SDKとの統合(Vercel AI SDK v6対応)
npm install @trigger.dev/ai @ai-sdk/openai
# ローカル開発サーバーの起動
npx trigger.dev@latest dev

ローカル開発時は、CLIがトンネルを張ってTrigger.dev Cloudと接続します。本番デプロイは npx trigger.dev@latest deploy 一発です。

基本タスクの定義

Trigger.devのタスクは task() 関数で定義します。TypeScriptで書くだけで、あとは自動的にデプロイ・管理されます。

// src/trigger/hello-world.ts
import { task } from "@trigger.dev/sdk/v3";

export const helloWorldTask = task({
  id: "hello-world",
  run: async (payload: { message: string }) => {
    console.log(`受信メッセージ: ${payload.message}`);
    return { result: `処理完了: ${payload.message}` };
  },
});

タスクをトリガーするには、アプリケーションコードから trigger() を呼ぶだけです。

// Next.js API Routeやサーバーアクションから
import { helloWorldTask } from "@/trigger/hello-world";

const handle = await helloWorldTask.trigger({ message: "こんにちは" });
console.log(`Run ID: ${handle.id}`);

スケジュールタスク(Cron)

// src/trigger/daily-report.ts
import { scheduleTask } from "@trigger.dev/sdk/v3";

export const dailyReportTask = scheduleTask({
  id: "daily-report",
  cron: "0 9 * * 1-5",   // 平日9時に実行
  run: async (payload) => {
    // レポート生成ロジック
    const report = await generateReport(payload.lastTimestamp);
    await sendSlackNotification(report);
  },
});

Run Hierarchies — 親子タスクで複雑なフローを構成する

実際のAIエージェントでは、複数のタスクをチェーンさせることがほとんどです。Trigger.devは親タスクから子タスクを triggerAndWait() で呼び出すことで、ツリー構造のワークフローを簡単に構築できます。

// src/trigger/research-agent.ts
import { task } from "@trigger.dev/sdk/v3";
import { fetchUrlTask } from "./fetch-url";
import { summarizeTask } from "./summarize";

export const researchAgentTask = task({
  id: "research-agent",
  run: async (payload: { urls: string[] }) => {
    // 子タスクを並列実行
    const fetchResults = await Promise.all(
      payload.urls.map((url) =>
        fetchUrlTask.triggerAndWait({ url })
      )
    );

    // 全ての取得が完了してから要約
    const summaries = await Promise.all(
      fetchResults.map((r) =>
        summarizeTask.triggerAndWait({ content: r.output.content })
      )
    );

    return { summaries: summaries.map((s) => s.output) };
  },
});

triggerAndWait() は子タスクの完了を待機しますが、この「待機中」はCRIUチェックポイントが作られ、インフラリソースは消費されません。コストを抑えながら複雑なフローを書けます。

Idempotency(冪等性)とRetry戦略

AIエージェントで一番困るのが「どこまで処理したかわからなくなる」状況です。Trigger.devの冪等性キーはこれを解決します。

import { task, idempotencyKeys } from "@trigger.dev/sdk/v3";

export const processOrderTask = task({
  id: "process-order",
  retry: {
    maxAttempts: 5,
    factor: 2,
    minTimeoutInMs: 1000,
    maxTimeoutInMs: 30000,
  },
  run: async (payload: { orderId: string }) => {
    // 冪等性キーを設定 — 同じキーで2回呼ばれても1回しか実行しない
    const key = await idempotencyKeys.create(payload.orderId);

    const paymentResult = await chargePaymentTask.triggerAndWait(
      { orderId: payload.orderId },
      { idempotencyKey: key }
    );

    // 失敗した場合、retry設定に従って自動でリトライ
    if (!paymentResult.ok) {
      throw new Error(`Payment failed: ${paymentResult.error}`);
    }

    return paymentResult.output;
  },
});

失敗が起きても、冪等性キーのおかげでリトライ時に決済が2重実行される心配がありません。

LLM API呼び出しのDurable化パターン

AIエージェント開発でもっとも実用的なパターンです。OpenAI APIの呼び出しをDurableにラップすることで、レート制限・ネットワーク障害・タイムアウトから安全に保護できます。

// src/trigger/llm-pipeline.ts
import { task } from "@trigger.dev/sdk/v3";
import OpenAI from "openai";

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export const llmAnalysisTask = task({
  id: "llm-analysis",
  retry: {
    maxAttempts: 10,
    // OpenAIのレート制限に合わせた指数バックオフ
    factor: 2,
    minTimeoutInMs: 2000,
    maxTimeoutInMs: 120000,
  },
  run: async (payload: { documents: string[] }) => {
    const results = [];

    for (const [index, doc] of payload.documents.entries()) {
      // 各ドキュメントを冪等性キーで保護
      const key = await idempotencyKeys.create(`doc-${index}-${doc.slice(0, 50)}`);

      const response = await openai.chat.completions.create({
        model: "gpt-4o",
        messages: [
          { role: "system", content: "あなたは文書分析の専門家です。" },
          { role: "user", content: doc },
        ],
      });

      results.push({
        index,
        analysis: response.choices[0].message.content,
      });
    }

    return { results };
  },
});

このパターンにより、100件のドキュメントを処理中にAPIエラーが起きた場合も、50件目から再開できます。

Vercel AI SDKとの統合(v6対応)

import { task } from "@trigger.dev/sdk/v3";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

export const aiPipelineTask = task({
  id: "ai-pipeline",
  run: async (payload: { prompt: string }) => {
    const { text } = await generateText({
      model: openai("gpt-4o"),
      prompt: payload.prompt,
    });
    return { text };
  },
});

Waitpoints — 人間のレビューを挟むHITL対応

v4で追加されたWaitpointsは、タスクを外部イベント・人間の承認待ちで一時停止させる仕組みです。AIエージェントと人間のコラボレーション(HITL: Human-in-the-Loop)を実装するのに最適です。

import { task, wait } from "@trigger.dev/sdk/v3";

export const contentModerationTask = task({
  id: "content-moderation",
  run: async (payload: { content: string; reviewerEmail: string }) => {
    // AIによる一次スクリーニング
    const aiResult = await screenContentWithAI(payload.content);

    if (aiResult.requiresHumanReview) {
      // レビュアーにメール通知
      await sendReviewEmail(payload.reviewerEmail, payload.content, aiResult);

      // 人間の判断を最大24時間待機
      // この間はインフラリソースを消費しない
      const approval = await wait.forEvent<{ approved: boolean; reason: string }>(
        "human-review-complete",
        {
          timeout: { hours: 24 },
          filter: { contentId: payload.content.slice(0, 20) },
        }
      );

      if (!approval.output?.approved) {
        return { status: "rejected", reason: approval.output?.reason };
      }
    }

    return { status: "approved", content: payload.content };
  },
});

スケジューラ — CronエージェントとEvent Trigger

定期実行のcronエージェントと、WebhookやAPIからのイベントトリガーを組み合わせることで、完全自律のエージェントループを実装できます。

// イベントトリガー付きのエージェントループ
import { task, eventTrigger } from "@trigger.dev/sdk/v3";

export const webhookProcessorTask = task({
  id: "webhook-processor",
  trigger: eventTrigger({
    name: "github.push",
  }),
  run: async (payload: { repository: string; commits: string[] }) => {
    // GitHubのpushイベントを受け取ったら自動実行
    const analysis = await analyzeCommits(payload.commits);
    await postSlackSummary(payload.repository, analysis);
    return { processed: payload.commits.length };
  },
});

セルフホスト vs Cloud

Trigger.devはApache 2.0ライセンスで、CloudとセルフホストどちらでもOKです。

項目 Trigger.dev Cloud セルフホスト
無料枠 月5,000ラン 無制限
並列実行 Free: 20 / Pro: 200 インフラ依存
ログ保持 Free: 1日 / Pro: 14日 自由設定
セットアップ CLI 1コマンド Docker / Kubernetes
データ主権 Trigger.devサーバー 自社インフラ
料金 Pro $50/月〜 インフラコストのみ

個人・スタートアップはCloudの無料枠から始めて、月5,000ランを超えたらProへ移行するのが合理的です。GDPRや社内コンプライアンスで自社インフラ必須の場合はDockerセルフホストが現実的な選択肢です。

# Dockerでセルフホストする場合
docker compose up -d

# 設定ファイル(docker-compose.yml)の主要環境変数
# TRIGGER_SECRET_KEY=your-secret-key
# DATABASE_URL=postgresql://...
# REDIS_URL=redis://...

Inngest・Temporalとの比較

項目 Trigger.dev v4 Inngest Temporal
言語 TypeScript/Node.js, Python TypeScript/Node.js 多言語(Go, Java, TS, Python)
セルフホスト 可(Apache 2.0) 不可 可(MIT)
設計哲学 DX重視、AIネイティブ イベント駆動 エンタープライズ耐久性
学習コスト 低(TypeScript関数を書くだけ) 低〜中 高(Workflow概念の習得必要)
HITL対応 v4 Waitpoints waitForEvent Signal/Query
AIエージェント向け 公式サポート済み フレームワーク連携 手動実装が必要
無料枠 月5,000ラン 月10,000ラン なし(セルフホストのみ)

2026年時点での使い分けを端的に言うと、「AIエージェント・TypeScript中心ならTrigger.dev、イベント駆動アーキテクチャのWebアプリならInngest、巨大エンタープライズで運用コストを厭わないならTemporal」です。Inngest比較の詳細はVercel AI SDK・Inngest・Mastra 比較記事もあわせて参照ください。

実用パターン4選

1. バッチLLM処理

export const batchLlmTask = task({
  id: "batch-llm",
  run: async (payload: { items: { id: string; text: string }[] }) => {
    const results = [];
    for (const item of payload.items) {
      const key = await idempotencyKeys.create(item.id);
      const res = await analyzeWithLLM.triggerAndWait(
        { text: item.text },
        { idempotencyKey: key }
      );
      results.push({ id: item.id, analysis: res.output });
    }
    return { results, total: results.length };
  },
});

2. Webhook受信+非同期処理

// Next.js API Route (WebhookからTrigger)
export async function POST(req: Request) {
  const payload = await req.json();

  // すぐ200を返し、処理はバックグラウンドへ
  const handle = await processWebhookTask.trigger(payload);

  return Response.json({ runId: handle.id });
}

3. Pythonとの組み合わせ(データパイプライン)

# Python SDKでの利用
# pip install triggerdotdev

from triggerdotdev import TriggerClient

client = TriggerClient(api_key="your-api-key")

# TypeScriptで定義したタスクをPythonからトリガー
handle = client.trigger(
    task_id="llm-analysis",
    payload={"documents": ["doc1", "doc2", "doc3"]}
)
print(f"Run started: {handle.id}")

4. cronエージェント(毎日レポート生成)

export const dailyAgentTask = scheduleTask({
  id: "daily-agent",
  cron: "0 8 * * 1-5",  // 平日の朝8時
  run: async (payload) => {
    // 1. データ収集(複数ソース)
    const data = await collectDailyData();

    // 2. LLMで分析
    const analysis = await llmAnalysisTask.triggerAndWait({ documents: data });

    // 3. Slackへ通知
    await notifySlack(analysis.output);

    return { date: payload.timestamp, itemsProcessed: data.length };
  },
});

よくある失敗パターン4選

失敗1: タスクIDの重複

// ❌ 同じIDを複数のタスクに使うとデプロイ時にエラー
export const task1 = task({ id: "my-task", ... });
export const task2 = task({ id: "my-task", ... }); // ID重複エラー

// ✅ IDはプロジェクト全体でユニークに
export const task1 = task({ id: "user-analysis-task", ... });
export const task2 = task({ id: "report-generation-task", ... });

失敗2: retry設定なしでLLM APIを呼ぶ

// ❌ retryなしだと1回の失敗でタスクが完全停止
export const noRetryTask = task({
  id: "fragile-llm",
  run: async (payload) => {
    const result = await openai.chat.completions.create(...); // 失敗で終了
  },
});

// ✅ retryを設定してLLM APIエラーを自動リカバリー
export const robustLlmTask = task({
  id: "robust-llm",
  retry: { maxAttempts: 5, factor: 2, minTimeoutInMs: 1000 },
  run: async (payload) => {
    const result = await openai.chat.completions.create(...);
  },
});

失敗3: 環境変数の管理ミス

# ❌ ローカルのみの.envを本番に反映し忘れる

# ✅ Trigger.dev CLIで環境変数を安全に管理
npx trigger.dev@latest env set OPENAI_API_KEY sk-xxx --env prod
npx trigger.dev@latest env list --env prod

失敗4: 子タスクを awaithなしで呼ぶ

// ❌ triggerAndWaitを使わないと結果を待てない
childTask.trigger(payload);           // 結果が取れない
const res = await childTask.trigger(payload); // これも非推奨

// ✅ 結果を待つなら triggerAndWait()
const res = await childTask.triggerAndWait(payload);
console.log(res.output);

まとめ:今日から始める3つのアクション

  1. 今日やること: npx trigger.dev@latest init で既存プロジェクトに組み込み、最初のタスクをCloudにデプロイしてみる
  2. 今週中: 既存のLambda・Vercel FunctionsのうちタイムアウトしているAPIコールをTrigger.devタスクに移行し、retry設定を追加する
  3. 今月中: 複数ステップのAIエージェントをRun Hierarchiesで構成し、WaitpointsによるHITLフローを実装する

Trigger.devはAIエージェントが抱える「タイムアウト」「重複実行」「リトライの複雑さ」という三大問題を一気に解決します。v4でセルフホストも大幅に改善されたため、本番運用のハードルは下がっています。


あわせて読みたい:

この記事を読んでAIエージェントの本番導入イメージが固まってきた方へ

UravationではAIエージェント導入の研修・コンサルを行っています。Trigger.devを含むエージェント基盤の設計から実装まで、貴社の状況に合わせたサポートが可能です。

参考・出典


著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー10万人超。
100社以上の企業向けAI研修・導入支援。著書累計3万部突破。
SoftBank IT連載7回執筆(NewsPicks最大1,125ピックス)。
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。

Need help moving from reading to rollout?

この記事を読んで導入イメージが固まってきた方へ

Uravationでは、AIエージェントの要件整理、PoC設計、社内導入、研修まで一気通貫で支援しています。

この記事をシェア

X Facebook LINE

※ 本記事の情報は2026年5月時点のものです。サービスの料金・仕様は変更される可能性があります。最新情報は各サービスの公式サイトをご確認ください。

関連記事