(更新: 2026.04.08)

AI駆動タスク自動振り分け:DASH(Daily Action System by Hero)の実装

はじめに

複数のアカウント・チーム・プロジェクトを管理していると、「このタスクはどこに属するか?」の判断が面倒になります。この記事では、AIが自動でタスクを振り分ける DASH システムの実装を紹介します。

DASHの設計思想

雑な投げかけを歓迎

ユーザーは細かい分類を気にせず、タスクを投げるだけ:

  • 「これやらな」
  • 「あれ忘れてた」
  • 「明日までに〇〇」

AIがアカウント・チーム・優先度を自動判定します。

判定ロジック

タスクテキストから以下を抽出・推論します:

  1. アカウント判定: クロスリンク vs プログラミングスクール
  2. チーム判定: learning / seo / recruitment / kansai / nagoya_school など
  3. 優先度判定: high / medium / low
  4. 期限抽出: 「明日まで」「3/30」などから due_date を推定

実装:LLMベース判定

プロンプト設計

TASK_CLASSIFICATION_PROMPT = """
以下のタスクテキストから情報を抽出し、JSON形式で返してください。

タスク: {task_text}

【判定基準】
- account: "crosslink" or "programming_school"
  - クロスリンク: ラーニング講座、SEO記事、求人関連
  - プログラミングスクール: 体験会、座席表、シフト管理

- team: "learning" / "seo" / "recruitment" / "kansai" / "tokai" / "nagoya_school" / "general"

- priority: "high" / "medium" / "low"
  - high: 至急、締切間近、重要
  - medium: 通常業務
  - low: 後回し可能

- due_date: YYYY-MM-DD形式(今日は{today})
  - 「明日」→ {tomorrow}
  - 「今週金曜」→ 次の金曜日
  - 「3/30」→ 2026-03-30

【出力JSON】
{{
  "account": "...",
  "team": "...",
  "priority": "...",
  "due_date": "...",
  "estimated_minutes": 数値
}}
"""

判定関数

import anthropic
from datetime import datetime, timedelta

def classify_task(task_text):
    today = datetime.now().strftime('%Y-%m-%d')
    tomorrow = (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d')

    prompt = TASK_CLASSIFICATION_PROMPT.format(
        task_text=task_text,
        today=today,
        tomorrow=tomorrow
    )

    client = anthropic.Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))

    message = client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": prompt
        }]
    )

    response_text = message.content[0].text

    # JSON抽出
    import json
    import re

    json_match = re.search(r'\{.*\}', response_text, re.DOTALL)
    if json_match:
        return json.loads(json_match.group())

    return None

タスク登録

def add_task_auto(task_text):
    """
    タスクテキストを受け取り、自動分類してtasks.jsonに追加
    """
    classification = classify_task(task_text)

    if not classification:
        print("⚠️ 分類失敗。デフォルト値で登録します。")
        classification = {
            "account": "crosslink",
            "team": "general",
            "priority": "medium",
            "due_date": None,
            "estimated_minutes": 30
        }

    task_id = f"task-{datetime.now().strftime('%Y%m%d-%H%M%S')}"

    task = {
        "id": task_id,
        "title": task_text,
        "account": classification["account"],
        "team": classification["team"],
        "priority": classification["priority"],
        "status": "todo",
        "due_date": classification.get("due_date"),
        "estimated_minutes": classification.get("estimated_minutes", 30),
        "source": "telegram",
        "created_at": datetime.now().isoformat(),
        "notes": ""
    }

    # tasks.json に追加
    tasks = load_tasks()
    tasks["tasks"].append(task)
    save_tasks(tasks)

    print(f"✅ タスク登録: {task['title']}")
    print(f"   アカウント: {task['account']}")
    print(f"   チーム: {task['team']}")
    print(f"   優先度: {task['priority']}")
    if task['due_date']:
        print(f"   期限: {task['due_date']}")

    return task

実例:判定精度

テストケース1: クロスリンク系

入力:

「サンヴァーテックス様 アンケートフォーム送付」

AI判定:

{
  "account": "crosslink",
  "team": "learning",
  "priority": "high",
  "due_date": null,
  "estimated_minutes": 25
}

✅ 正解。クライアント名からクロスリンク・ラーニングチームと判定。

テストケース2: プログラミングスクール系

入力:

「ココグラム名古屋校 座席表作成」

AI判定:

{
  "account": "programming_school",
  "team": "nagoya_school",
  "priority": "high",
  "due_date": "2026-03-28",
  "estimated_minutes": 30
}

✅ 正解。「ココグラム」から名古屋校と判定。毎週土曜の定期タスクのため due_date も推定。

テストケース3: 期限付き

入力:

「明日までにブログ記事5件作成」

AI判定:

{
  "account": "crosslink",
  "team": "seo",
  "priority": "high",
  "due_date": "2026-03-30",
  "estimated_minutes": 60
}

✅ 正解。「明日まで」を日付に変換。ブログ→SEOチームと判定。

改善:コンテキスト学習

過去タスクからの学習

過去の分類結果を参照し、判定精度を向上させます。

def classify_task_with_history(task_text):
    # 過去の類似タスクを検索
    similar_tasks = find_similar_tasks(task_text, limit=5)

    # 類似タスクのアカウント・チーム分布
    context = f"""
    過去の類似タスク:
    {format_similar_tasks(similar_tasks)}
    """

    # プロンプトにコンテキスト追加
    prompt = TASK_CLASSIFICATION_PROMPT + "\n" + context

    return classify_task(task_text, prompt)

ユーザーフィードバック

誤判定があった場合、ユーザーが修正できます。

def correct_task_classification(task_id, corrections):
    """
    ユーザーの修正を記録し、次回の判定に反映
    """
    task = get_task(task_id)

    # 修正履歴を記録
    feedback = {
        "original": {
            "account": task["account"],
            "team": task["team"],
            "priority": task["priority"]
        },
        "corrected": corrections,
        "task_text": task["title"]
    }

    save_feedback(feedback)

    # タスクを更新
    task.update(corrections)
    save_task(task)

Google Calendar統合

分類されたタスクを自動的にGoogle Calendarに登録します。

def sync_task_to_calendar(task):
    """
    アカウントに応じた Google Calendar に登録
    """
    account_calendar_map = {
        "crosslink": "work@example.com",
        "programming_school": "school@example.com"
    }

    calendar_email = account_calendar_map[task["account"]]

    event = {
        "summary": task["title"],
        "description": f"チーム: {task['team']}\n優先度: {task['priority']}",
        "start": {
            "date": task["due_date"]
        },
        "end": {
            "date": task["due_date"]
        }
    }

    service = build_calendar_service(calendar_email)
    service.events().insert(calendarId='primary', body=event).execute()

    print(f"📅 {calendar_email} のカレンダーに登録完了")

まとめ

LLMベースのタスク分類により、ユーザーは細かい指定をせず雑にタスクを投げるだけで、自動的に適切なアカウント・チーム・期限が設定されます。過去の分類履歴やユーザーフィードバックを活用することで、判定精度を継続的に向上できます。

関連記事:
– Google Calendar統合でタスク管理を進化
– Gmail重要メール監視システム構築
– OpenClaw Cronジョブ活用術