「この課題進めておいてね」「環境構築しておいてね」と指示をもらったとき、「あれ、何から順番に手を付ければいいんだっけ…?」 と一瞬迷ったり、「タスクが大きすぎて、何から手をつければいいか分からずフリーズする」 ことありませんか?

そこで、大雑把な課題を入力するだけで、AIが勝手に15分以内の「小さいアクション」に分解し、1番目のタスクが一番上に来るよう見やすく並べてGoogle ToDo リストに自動登録してくれる「タスク自動分解エージェント」 を作りました!

作ったものの概要

ターミナルで「研修リポジトリを使って開発環境を構築しないといけない」と大雑把に入力するだけで、AIが自律的に以下を実行します。

  1. タスクの自動分解: 15分以内で終わる具体的な小アクション3〜5個に分解(一歩目は「Terminalで ls コマンドを叩いてフォルダの存在を確認する(3分)」など、今すぐできる超簡単なもの)。

  2. Google ToDo リストへの自動整列登録: 1番目のタスクがリストの一番上に来るよう、AIが自律的に【最後のタスク ➔ 1番目のタスク】の逆順でツールを連続実行してGoogle ToDo リストへ追加。

  3. 対話型CLI: 実行しっぱなしで、何度でも続けてタスクを投げられる(q で終了)。

技術スタックとアーキテクチャ

  • 言語: Python 3.12

  • LLM: Gemini API (google.genai SDK / gemini-3.6-flash)

  • 外部API: Google Tasks API (googleapiclient)

  • 認証: OAuth 2.0 (Google Cloud Console / credentials.json)

  • 主要概念: Function Calling (Tools)

ポイント:Function Calling

AIに「単に文章を返させる」のではなく、Pythonで書いた add_google_task という関数(Google ToDo リストにタスクを登録する処理)をAIに「道具(Tool)」として持たせています。 AI自身が「このタスクを登録するために関数を呼び出そう」と判断し、必要な引数(タイトルや詳細)を生成して実行してくれる仕組みです。

開発環境と再現手順

1. ディレクトリ構造

task-agent フォルダを作成し、以下のようにファイルを配置します。

task-agent/
├── .env              # Gemini APIキーを保持
├── credentials.json  # Google Cloud ConsoleからダウンロードしたOAuthクライアント情報
├── token.json        # ログイン後に自動生成されるOAuth認証トークン
└── agent.py          # エージェント本体のプログラム

2. 事前準備(APIキーと認証情報の取得)

  1. Gemini APIキー: Google AI Studio で作成してコピー。

  2. Google Cloud認証情報: Google Cloud Consoleで「Google Tasks API」を有効化し、デスクトップアプリ用のOAuth 2.0 クライアントIDを作成して credentials.json としてダウンロード。

.env に以下を記述します。

GEMINI_API_KEY=あなたのGemini APIキー

3. コード(agent.py)

必要なライブラリをインストールします。

Bash

pip install google-genai google-api-python-client google-auth-httplib2 google-auth-oauthlib python-dotenv

以下の完成版コードを agent.py に保存します。

Python

import os
import json
from dotenv import load_dotenv
from google import genai
from google.genai import types
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

# 1. 環境変数の読み込み (.env から APIキーを取得)
load_dotenv()
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")

# Google Tasks API の権限スコープ
SCOPES = ['https://www.googleapis.com/auth/tasks']

def get_tasks_service():
    """Google Tasks APIへアクセスするための認証を行い、サービスオブジェクトを返す"""
    creds = None
    if os.path.exists('token.json'):
        creds = Credentials.from_authorized_user_file('token.json', SCOPES)
    
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.json', 'w') as token:
            token.write(creds.to_json())

    return build('tasks', 'v1', credentials=creds)

def add_google_task(title: str, notes: str = "") -> str:
    """
    Google ToDo リスト (Tasks) に新しいタスクを追加する関数。
    
    Args:
        title: タスクのタイトル(例: 「資料作成の目次を作成する」)
        notes: タスクの詳細・補足(例: 「所要時間: 15分」)
    """
    try:
        service = get_tasks_service()
        task = {
            'title': title,
            'notes': notes
        }
        result = service.tasks().insert(tasklist='@default', body=task).execute()
        return f"タスク『{title}』をGoogle ToDo リストに正常に追加しました。(ID: {result['id']})"
    except Exception as e:
        return f"タスク追加時にエラーが発生しました: {str(e)}"

def main():
    client = genai.Client(api_key=GEMINI_API_KEY)
    
    system_instruction = """
    あなたは大雑把なタスクを分解して自動実行するタスク管理エージェントです。
    ユーザーから大きなタスクが入力されたら、以下の手順で実行してください。

    1. タスクを『15分以内で完了できる具体的で小さなアクション』3〜5個に分解する。
    2. 1つ目のアクションは、3分以内でできる超簡単な一歩目にする。
    3. 1番目のタスクがリストの先頭に来るよう、分解した【最後のタスクから逆順(例: 4→3→2→1)】に `add_google_task` ツールを呼び出して登録する。
    4. 登録がすべて完了したら、分解したタスク一覧と「最初の一歩のアドバイス」をユーザーに報告する。
    """

    print("🤖 タスク分解エージェントが起動しました!(終了するには 'q' を入力してください)\n")

    while True:
        try:
            user_input = input("📌 分解したいタスクを入力してください: ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\n終了します。")
            break

        if not user_input:
            continue
            
        if user_input.lower() in ['q', 'quit', 'exit']:
            print("エージェントを終了します。お疲れ様でした!")
            break

        print(f"\nAIが「{user_input}」を分解し、Google ToDoに自動登録中...\n")

        try:
            response = client.models.generate_content(
                model='gemini-3.6-flash',
                contents=user_input,
                config=types.GenerateContentConfig(
                    system_instruction=system_instruction,
                    tools=[add_google_task],
                    temperature=0.2,
                )
            )

            print("=== エージェントからの回答 ===")
            print(response.text)
            print("\n" + "-"*40 + "\n")
        except Exception as e:
            print(f"エラーが発生しました: {e}\n")

if __name__ == "__main__":
    main()

実際にターミナルで動かしてみた!

1. エージェントの起動

プロジェクトディレクトリ(task-agent)に移動し、以下のコマンドを実行します。

Bash

python3 agent.py

実行すると、プロンプトが立ち上がり入力待ち状態になります。

🤖 タスク分解エージェントが起動しました!(終了するには 'q' を入力してください)

📌 分解したいタスクを入力してください: 

※ 初回実行時のみブラウザが自動的に開き、Googleアカウントのアクセス許可画面が表示されます。「詳細」➔「Task Agentに進む」➔「続行」をクリックしてアクセスを許可すると、token.json が生成されて連携が完了します。

2. タスクを入力して分解実行

「環境構築の手順を分解して」と入力してみます。

📌 分解したいタスクを入力してください: 環境構築の手順を分解して

AIが「環境構築の手順を分解して」を分解し、Google ToDoに自動登録中...

Direct use of automatic function calling (AFC) in Models.generate_content is not recommended. Instead, we recommend to use AFC in Chat.send_message. Similarly, direct use of AFC in Models.generate_content_stream is not recommended. Instead, we recommend to use AFC in Chat.send_message_stream.
⚙️ [Tool実行] Google ToDoに追加中: 依存関係をインストールし、動作確認(開発サーバーの起動など)を行う
⚙️ [Tool実行] Google ToDoに追加中: プロジェクトのリポジトリをクローンし、設定ファイル(.env等)を用意する
⚙️ [Tool実行] Google ToDoに追加中: 必要なソフトウェア(Node.js/Python/Dockerなど)をインストールする
⚙️ [Tool実行] Google ToDoに追加中: 環境構築に必要なツールとドキュメントのURLを確認する

AIが自律的にツール(add_google_task)を何度も連続呼び出し、バックグラウンドでGoogle Tasks API経由でタスクを追加していきます。

3. Google ToDo リストの確認

ブラウザで Google カレンダーや Gmail を開き、右サイドバーの ToDo リスト(チェックマークの青いアイコン) を確認します。

画面を見ると、分解された15分以内のタスクが「1番目の手順が一番上」に来る綺麗な順番でバッチリ登録されていました!

終わったらターミナルで q と入力すれば、いつでも安全にエージェントを終了できます。

苦労したポイントと解決プロセス

1. APIキー認証エラー(API_KEY_INVALID)の罠

プログラムを実行すると何度も 400 INVALID_ARGUMENT エラーが発生。 原因は .env ファイルにコピーしたAPIキーの末尾に「見えない全角スペース」が入っていたり、画面上の表示にあった ...(省略記号)まで貼り付けていたことでした。

  • 学び: 環境変数はスペース1文字で壊れる。Pythonを使って .env を直接生成・上書きすることで手動コピペミスを防止するように改善!

2. モデル名の指定ミス(404エラー)

認証が通ったと思ったら、次は 404 NOT_FOUND。 gemini-2.5-flash を指定していたところ、「そのモデルは利用できません」とAPIに弾かれました。

  • 学び: エラーログをしっかり読み、推奨されている最新モデル(gemini-3.6-flash)にコードを一括置換して無事解決!

3. Google ToDo リストでの「逆順登録(4→3→2→1)」の罠

無事にタスクが追加されたものの、ToDo画面を見ると「タスク4」が一番上に表示され、手順1が一番下に行ってしまう事態が発生。 Google Tasks APIは「最新に追加されたものが先頭に来る」仕様のため、AI側のプロンプト(system_instruction)で「最後のタスクから逆順(4→3→2→1)にツールを実行して」と指示を調整し、画面上で手順1が一番上に来るUIを実現!

まとめ

今回は、大きな課題を入れるだけで「3分でできる超かんたんな作業」まで勝手に細かく砕いてToDoリストに入れてくれるAIを作ってみました!

AIに「1個目は3分でできる超かんたんな作業にして!」と頼んでおくことで、リストを見た瞬間に「これならすぐできる!」と手が動く仕組みにできたのが、一番よかったポイントだと感じています✨

「何から手をつければいいか分からなくて手が止まっちゃう」という方は、ぜひ試してみてください!