TypeScriptで自己実行するAIタスクを構築する方法(クーロン不要)
サポートチケットを要約するAIがあります。次は、それを毎時間実行させる必要があります。
本当にcronジョブを設定しますか?Nodeスクリプトを書きますか?エラーを処理しますか?リトライを設定しますか?ログを作りますか?失敗を監視しますか?
より良い方法があります。
旧来の方法:Cron+スクリプト+つらさ
スケジュールされたAIタスクを従来の方法で作ると、こんな感じになります:
// scripts/ticket-summarizer.ts
import { OpenAI } from 'openai';
import { writeFileSync } from 'fs';
const openai = new OpenAI({ apiKey: process.env.OPENAI_KEY });
async function summarizeTickets() {
try {
const tickets = await fetchOpenTickets();
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: `Summarize: ${tickets}` }]
});
await postToSlack(response.choices[0].message.content);
writeFileSync('/var/log/ai-runs.json', JSON.stringify({ success: true, time: Date.now() }));
} catch (err) {
// 指数バックオフ付きのリトライロジック?
// 誰かにアラートする?
// 部分的な失敗はどうする?
console.error('Failed:', err);
process.exit(1);
}
}
summarizeTickets();
そしてcrontabを追加します:
0 * * * * * cd /app && npx ts-node scripts/ticket-summarizer.ts 2>&1 | tee -a /var/log/cron.log
でも待ってください—必要なのは:
- 指数バックオフ付きのリトライロジック
- 一時的な失敗と恒久的な失敗を区別するエラーハンドリング
- ジョブが本当に動いているかを確認する方法
- 3回連続で失敗したときの監視
- crontabを編集せずに一時停止する手段
- 再起動時に消えないログ
あなたがやりたかったのは、AIタスクを毎時間実行することだけでした。なのに、いまインフラを管理しています。
NeuroLinkのやり方:TaskManager
NeuroLink v9.41.0ではTaskManagerが導入されました。これは、SDKに直接組み込まれたスケジュール済みの自己実行型AIタスクです。cron不要。別ワーカー不要。インフラの悩み不要。
import { NeuroLink } from '@juspay/neurolink';
const neurolink = new NeuroLink();
返却形式: {"translated": "翻訳されたHTML"}// それだけです。関数を1回呼び出すだけ。
const task = await neurolink.tasks.create({
name: 'ticket-summarizer',
prompt: 'これらのサポートチケットを要約し、緊急の問題を強調してください',
schedule: {
type: 'cron',
expression: '0 * * * *', // 毎時間
timezone: 'America/New_York'
},
mode: 'isolated',
provider: 'openai',
model: 'gpt-4o-mini', // 要約用の低コストモデル
// 組み込みのリトライ(再試行)ロジック
retry: {
maxAttempts: 3,
backoffMs: [30000, 60000, 300000] // 30秒、1分、5分
},
// 結果のコールバック
onSuccess: (result) => {
if (result.output?.includes('URGENT')) {
sendPagerDutyAlert(result.output);
}
},
onError: (err) => {
console.error(`Run ${err.runId} failed:`, err.error);
}
});
console.log(`Task scheduled: ${task.id}`);
// タスクは自動的に実行されます。プロセスは稼働したままになります。
それだけです。タスク:
- ✅ 毎時間自動で実行されます
- ✅ 一時的な失敗(レート制限、タイムアウト)に対して再試行します
- ✅ 実行のたびにタイムスタンプ付きでログを残します
- ✅ プロセスの再起動にも耐えます(Redisバックエンドを使用)
- ✅ API経由で一時停止、再開、削除ができます
- ✅ 結果をコールバックに送信します
Three Practical Examples
ここでは、実際に動く自己実行型AIタスクを3つ作りましょう。
1. 時間ごとのサポートチケット要約
import { NeuroLink } from '@juspay/neurolink';
const neurolink = new NeuroLink({
tasks: {
backend: 'bullmq', // 本番用:Redisで支えられています
redis: { url: process.env.REDIS_URL }
}
});
const ticketTask = await neurolink.tasks.create({
name: 'hourly-ticket-summary',
prompt: `過去1時間のオープンなサポートチケットを取得します。
要約してください:
- 合計数と優先度の内訳
- よくあるテーマと繰り返し発生する問題
- すぐにエスカレーションが必要なチケット
Slackでそのまま使えるメッセージとしてフォーマットしてください。`,
schedule: {
type: 'cron',
expression: '0 * * * *', // 毎時の頭に実行
timezone: 'America/New_York'
},mode: 'isolated', // 各実行ごとに新しいコンテキスト
provider: 'openai',
model: 'gpt-4o-mini', // 要約のための費用対効果が高い
// ツールを有効にして、AIがチケットを自分で取得できるようにする
tools: true,
onSuccess: async (result) => {
await fetch(process.env.SLACK_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: ` チケット要約
${result.output}`
})
});
}
});
なぜこれが機能するのか:
-
isolatedモードは、各実行が独立していることを意味します。つまり、コンテキストの混入(汚染)がありません -
gpt-4o-miniは、高頻度の実行に対してコストを低く抑えます - ツールを有効化しているため、AIがあなたのチケットAPIを直接呼び出せます
2. デイリー・コードレビュー・ボット(継続モード)
ここからが面白いところです。継続モードでは、AIが過去の実行を記憶できます。
const codeReviewBot = await neurolink.tasks.create({
name: 'daily-code-review',
prompt: `昨日マージされたPRをレビューしてください。各PRについて:
1. 潜在的なバグやセキュリティ上の問題を特定する
2. 追加されていないテストやドキュメントがないか確認する
3. PR間でのパターンをメモする(例:繰り返されるミス)
過去のレビューと比較してください。同じ問題が再発していますか?`,
schedule: {
type: 'cron',
expression: '0 9 * * 1-5' // 平日の9:00
},
mode: 'continuation', // AIが昨日のレビューを記憶する
provider: 'anthropic',
model: 'claude-sonnet-4-6',
maxRuns: 30, // 1か月後に自動停止
onSuccess: (result) => {
// チームの #code-reviews チャンネルに投稿する
postToSlack(result.output);
// 致命的な問題が見つかった場合はエスカレーション
if (result.output?.includes('CRITICAL')) {
notifyTechLead(result.output);
}
}
});
継続モードはどのように機能するか:
- 実行1:「3つのPRが見えます。PR #42 には、潜在的なヌルポインタ問題があります。」
- 実行2:「PR #45 もヌルポインタ問題があります。今週2回目です。optional chaining に関するチーム研修をおすすめします。」
- 実行3:「今日はヌルポインタ問題はありません。前回までのパターンは解消されたようです。」
あなた側でDBコードを書くことなく、AIが時間の経過とともに理解を積み上げます。
3. 週次レポートジェネレーター
const weeklyReport = await neurolink.tasks.create({
name: 'weekly-executive-summary',
prompt: `リーダーシップ向けのエグゼクティブサマリーを作成してください:
含める指標:
- APIの稼働率とエラー率(モニタリングから取得)
- サポートチケットの件数と解決までの時間
- デプロイ頻度とインシデント数
- 主要な顧客フィードバックのテーマ
フォーマット:
- 1ページのエグゼクティブサマリー
- 補足データ付きで3つの重要な洞察
- 来週に向けた2つの提案`,
返却形式: {"translated": "翻訳されたHTML"}schedule: {
type: 'cron',
expression: '0 8 * * 1' // 毎週月曜の8 AM
},
mode: 'isolated',
provider: 'openai',
model: 'gpt-4o', // 役員向けレポートの品質を向上
timeout: 300_000, // 5分(レポート生成には時間がかかります)
onSuccess: async (result) => {
// Notionに保存
await saveToNotion({
title: `Weekly Report - ${new Date().toISOString()}`,
content: result.output
});
// 経営陣にメール送信
await sendEmail({
to: 'exec-team@company.com',
subject: 'Weekly Executive Summary',
body: result.output
});
},
onError: (err) => {
// レポート生成に失敗した場合にアラート
if (!err.willRetry) {
pagerDuty.trigger({
severity: 'warning',
summary: 'Weekly report failed after all retries'
});
}
}
});
TaskManagerの機能を理解する
実行モード
| モード | 挙動 | 向いている用途 |
|---|---|---|
| isolated | 実行のたびに新しいAIコンテキスト | 単発タスク、モニタリング、レポート |
| continuation | 前回の実行内容をAIが保持 | トレンド分析、段階的なワークフロー |
スケジュールの種類
// Cron(最も柔軟)
schedule: { type: 'cron', expression: '0 9 * * 1-5', timezone: 'America/New_York' }
// Interval(シンプル)
schedule: { type: 'interval', every: 5 * 60 * 1000 } // 5分ごと
// ワンショット(特定の時刻に1回実行)
schedule: { type: 'once', at: '2026-04-01T14:00:00Z' }
内蔵のリトライ(再試行)ロジック
TaskManagerはエラーを自動的に分類します:
一時的(再試行されます):
- レート制限が超過しました
- ネットワークのタイムアウト
- 5xxのサーバーエラー
恒久的(タスク失敗):
- 無効なAPIキー
- モデルが見つかりません
- 不正な設定
デフォルトのリトライ:指数バックオフ付きで3回(30秒 → 1分 → 5分)
タスクの管理
// すべてのタスクを一覧表示
const tasks = await neurolink.tasks.list();
const active = await neurolink.tasks.list({ status: 'active' });
// スケジュール外で今すぐ実行
await neurolink.tasks.run('task_abc123');
返却形式: {"translated": "翻訳されたHTML"}// 一時停止して再開
await neurolink.tasks.pause('task_abc123');
await neurolink.tasks.resume('task_abc123');
// 更新
await neurolink.tasks.update(' task_abc123', {
prompt: '新しいプロンプトのテキスト',
schedule: { type: 'interval', every: 10 * 60 * 1000 }
});
// 削除
await neurolink.tasks.delete(' task_abc123');
// 実行履歴の表示
const runs = await neurolink.tasks.runs(' task_abc123', { limit: 20 });
本番環境での考慮事項
バックエンドを選ぶ
BullMQ(Redis)— 本番環境
const neurolink = new NeuroLink({
tasks: {
backend: 'bullmq',
redis: { url: process.env.REDIS_URL },
maxConcurrentRuns: 5 // 同時実行数を制限
}
});
- ✅ 再起動に耐える
- ✅ 複数プロセスで安全
- ✅ ファイルI/Oなし(コンテナ向け)
NodeTimeout — 開発
const neurolink = new NeuroLink({
tasks: { backend: 'node-timeout' } // 依存関係なし
});
- ✅ Redis不要
- ✅ 人が読めるJSONファイル
- ⚠️ 再起動時にタイマーは失われる(タスクはディスクから自動的に再スケジュールされる)
監視
// イベントを購読する
neurolink.on('task:started', (task, runId) => {
metrics.increment('task.started', { task: task.name });
});
neurolink.on('task:completed', (result) => {
metrics.timing('task.duration', result.durationMs);
console.log(`✅ ${result.taskId}: ${result.output?.slice(0, 100)}`);
});neurolink.on('task:failed', (error) => {
metrics.increment('task.failed', { task: error.taskId });
console.error(`❌ ${error.taskId}: ${error.error}`);
});
デーモンとして実行
# PM2 を使用
pm2 start src/tasks.ts --name ai-tasks
# systemd を使用
# (完全な systemd ユニットファイルについては NeuroLink ドキュメントを参照)
# もしくは Node プロセスを単に動かし続ける
npx ts-node src/tasks.ts
CLI の代替手段
コードを書きたくないですか? CLI を使いましょう:
# タスクを作成
neurolink task create \
--name "hourly-ticket-summary" \
--prompt "Summarize open support tickets" \
--cron "0 * * * *" \
--provider openai \
--model gpt-4o-mini
# タスクを管理
neurolink task list
neurolink task pause <task-id>
neurolink task resume <task-id>
neurolink task logs <task-id> --limit 50
何が違うのか?
| 機能 | 従来の Cron + スクリプト | NeuroLink TaskManager |
|---|---|---|
| セットアップ | 5 つ以上のファイル、インフラ | SDK の呼び出し 1 回 |
| リトライ | 自分で書く | バックオフ付きで組み込み |
| エラーハンドリング | 手動の分類 | 一時エラー vs 恒久エラーを自動判定 |
| 監視 | カスタムログ | イベント + 実行履歴 |
| コンテキストのメモリ | データベース + コード | mode: 'continuation' |
| スケーリング | より多くのインフラ | Redis バックエンド |
| AI が自己スケジュールできる | 不可能 | 組み込みのツール |
はじめに
# インストール
npm install @juspay/neurolink
# セットアップウィザードを実行
npx @juspay/neurolink setup
# 最初のスケジュール済みタスクを作成
import { NeuroLink } from '@juspay/neurolink';
const neurolink = new NeuroLink();
await neurolink.tasks.create({
name: 'hello-world',
prompt: 'Say hello and mention what time it is',
schedule: { type: 'interval', every: 60000 },
onSuccess: (r) => console.log(r.output)
});
// プロセスを生かし続ける
setInterval(() => {}, 1000);
結論
AI タスクをスケジュール実行するために、cron ジョブ、ワーカキュー、そしてカスタムのリトライロジックは不要です。TaskManager は次を提供します:
- Cron、interval、ワンショットのスケジューリング
- 指数バックオフ付きの組み込みリトライ
- 分離または継続(continuation)実行モード
- Redis またはファイルベースの永続化
- 監視のためのイベントとコールバック
- CLI および SDK インターフェース
すべてを 1 つの TypeScript SDK に集約。
インフラ管理をやめましょう。自走する AI の構築を始めましょう。
NeuroLink は Juspay の TypeScript-first AI SDK—13 のプロバイダー、100+ のモデル、一つに統一された API。



