Agentive
自動化ラボ

AIタスクの定期実行 — cron/タスクスケジューラで自動化を完結

約5分で読めます

AIタスクの定期実行

「毎時実行」「毎日実行」をOS標準機能やCI/CDサービスで実現する。AIエージェントの自動化は、定期実行の仕組みがなければ完成しない。Windowsタスクスケジューラ、Linux cron、GitHub Actions cronの3つの方法を解説する。

定期実行の選択基準

方式適用場面コスト信頼性
WindowsタスクスケジューラローカルPC常時稼働無料PCに依存
Linux cronVPS/サーバーサーバー代
GitHub Actions cronCI/CD連携無料枠あり
Cloudflare Workers cronエッジ実行無料枠あり非常に高

Windowsタスクスケジューラ

PowerShellでタスク登録

# AIボットをログオン時に自動起動
$Action = New-ScheduledTaskAction -Execute "python" -Argument "C:\bots\watchdog.py"
$Trigger = New-ScheduledTaskTrigger -AtLogOn
$Settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName "AI-Bot-Watchdog" -Action $Action -Trigger $Trigger -Settings $Settings

# 毎朝7時にレポート生成
$Action = New-ScheduledTaskAction -Execute "python" -Argument "C:\bots\daily_report.py"
$Trigger = New-ScheduledTaskTrigger -Daily -At "07:00"
Register-ScheduledTask -TaskName "AI-Daily-Report" -Action $Action -Trigger $Trigger

タスクの管理コマンド

# タスク一覧確認
Get-ScheduledTask | Where-Object { $_.TaskName -like "AI-*" }

# タスクの状態確認
Get-ScheduledTaskInfo -TaskName "AI-Bot-Watchdog"

# タスクの手動実行
Start-ScheduledTask -TaskName "AI-Daily-Report"

# タスクの停止
Stop-ScheduledTask -TaskName "AI-Bot-Watchdog"

# タスクの削除
Unregister-ScheduledTask -TaskName "AI-Bot-Watchdog" -Confirm:$false

Linux cron

crontab設定

crontab -e

# 毎時実行: スクレイピングBot
0 * * * * cd /home/user/bots && python scraper.py >> /var/log/ai-scraper.log 2>&1

# 毎朝7時: 日次レポート生成
0 7 * * * cd /home/user/bots && python daily_report.py >> /var/log/ai-report.log 2>&1

# 毎週月曜9時: 週次サマリー
0 9 * * 1 cd /home/user/bots && python weekly_summary.py >> /var/log/ai-weekly.log 2>&1

# 5分おき: ヘルスチェック
*/5 * * * * cd /home/user/bots && python health_check.py >> /var/log/ai-health.log 2>&1

cron式の読み方

分 時 日 月 曜日
*  *  *  *  *

0 * * * *     = 毎時0分
0 7 * * *     = 毎日7:00
0 9 * * 1     = 毎週月曜9:00
*/5 * * * *   = 5分おき
0 0 1 * *     = 毎月1日0:00

GitHub Actions cron

定期実行ワークフロー

name: AI Scheduled Tasks
on:
  schedule:
    - cron: "0 * * * *"
  workflow_dispatch:

jobs:
  scrape-and-report:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run AI task
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
        run: python scripts/scheduled_task.py

      - name: Commit results
        run: |
          git config user.name "AI Bot"
          git config user.email "bot@example.com"
          git add -A
          git diff --staged --quiet || git commit -m "chore: scheduled task results"
          git push

複数スケジュールの管理

on:
  schedule:
    - cron: "0 * * * *"
    - cron: "0 22 * * *"
    - cron: "0 0 * * 1"

jobs:
  dispatch:
    runs-on: ubuntu-latest
    steps:
      - name: Determine task
        id: task
        run: |
          HOUR=$(date -u +%H)
          DAY=$(date -u +%u)
          if [ "$DAY" = "1" ] && [ "$HOUR" = "00" ]; then
            echo "task=weekly" >> $GITHUB_OUTPUT
          elif [ "$HOUR" = "22" ]; then
            echo "task=daily" >> $GITHUB_OUTPUT
          else
            echo "task=hourly" >> $GITHUB_OUTPUT
          fi

      - name: Run task
        run: python scripts/${{ steps.task.outputs.task }}_task.py

Pythonでのタスクスケジューラ実装

scheduleライブラリを使った軽量スケジューラ

import schedule
import time
from datetime import datetime

def hourly_scraping():
    print("[" + str(datetime.now()) + "] スクレイピング開始")

def daily_report():
    print("[" + str(datetime.now()) + "] 日次レポート生成")

def health_check():
    print("[" + str(datetime.now()) + "] ヘルスチェック")

schedule.every().hour.at(":00").do(hourly_scraping)
schedule.every().day.at("07:00").do(daily_report)
schedule.every(5).minutes.do(health_check)

print("スケジューラ起動")
while True:
    schedule.run_pending()
    time.sleep(1)

エラーハンドリング付きスケジューラ

import traceback

def safe_run(func):
    def wrapper():
        try:
            func()
        except Exception as e:
            error_msg = traceback.format_exc()
            print("タスクエラー: " + str(e))
            send_error_notification(func.__name__, error_msg)
    return wrapper

schedule.every().hour.do(safe_run(hourly_scraping))
schedule.every().day.at("07:00").do(safe_run(daily_report))

実践パターン: Watchdogとの組み合わせ

タスクスケジューラでWatchdogを守る

# watchdog_restart.ps1
$process = Get-Process -Name python -ErrorAction SilentlyContinue |
    Where-Object { $_.CommandLine -like "*watchdog.py*" }

if (-not $process) {
    Write-Host "Watchdog停止検知。再起動します。"
    Start-Process python -ArgumentList "C:\bots\watchdog.py" -WindowStyle Hidden
}
# 5分おきにWatchdogの生存確認
$Action = New-ScheduledTaskAction -Execute "powershell" -Argument "-File C:\bots\watchdog_restart.ps1"
$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName "AI-Watchdog-Guard" -Action $Action -Trigger $Trigger

定期実行のベストプラクティス

  • ログ記録: 全タスクの実行結果をログファイルに記録する
  • エラー通知: 失敗時は即座にDiscord/Slackに通知する
  • 冪等性: 同じタスクが2回実行されても問題ない設計にする
  • タイムゾーン: GitHub Actions cronはUTCなので、JSTとの9時間差に注意
  • 実行時間制限: 各タスクにタイムアウトを設定する

関連記事

A

Agentive 編集部

AIエージェントを実際に使い倒す個人開発者。サイト制作の自動化を実践しながら、その知見を発信しています。