🗂️

個人タスク管理を「判断は人間、更新はエージェント、計算はスクリプト」で設計する

に公開1

こんにちは。Ai Workforce事業部でAIエージェントのためのデータ基盤を開発している uphy です。業務では複数のプロジェクトを並走させているのですが、今回は個人のタスク管理についてお話しします。

タスク管理は、この5年ほどMarkdownベースでわりとライトにやってきました。プロジェクトごとにTODOリストのノートを作って、自作のObsidianプラグイン(obsidian-reminder)でアイテムに期限を付けて、毎朝daily noteに今日やる分を書き出す。期限ベースの管理としてはそれなりに回っていたんですが、期限のないタスクはずるずる後回しになるし、daily note側で付けたチェックをプロジェクト側に戻しそこねるし、忙しい日はそもそもdaily noteを作らない。真実が二重化して、じわじわ実態とズレていく運用でした。

今年に入って、LLM wikiを運用し始めてから、タスク管理ごとLLMに任せてみました。これで解決するはず、と思っていました。ところがタスクが増えるにつれて、エージェントは分かっている風なのに実は自分と全然通じていない、という状態になっていきます。原因は単純で、判断に必要な文脈をwikiに書き切れていなかったからです。エージェントが「次はこれですね」と差し出すタスクにだんだん自信が持てなくなって、そのうち人間側も全体を把握できなくなりました。

2つの失敗から、学びが2つ出てきました。1つは、構造化にはそれなりの維持コストがかかること。ライトな運用でさえチェックの書き戻しという最低限の整合性を保てなかったのに、属性の更新・親子の整合・ビューの再生成まで全部構造化して人間がメンテナンスし続けるのは、まあ無理があります。もう1つは、だからといってLLMに丸ごと任せると、今度は判断と把握を手放して崩れてしまうこと。

そこで設計し直した軸が、これです。

判断は人間、更新はエージェント、計算はスクリプト。

保守コストは機械側に分担してもらって、人間には判断だけを残す。この記事では、この分担をどう形にしたかを、タスクの持ち方・書き換えの任せ方・チームへの見せ方・日々の回し方の順に紹介します。

全体アーキテクチャ — 属性の真実はファイル、ビューは派生

タスクはすべてplain MarkdownのファイルとしてObsidianのvaultに置いています。

tasks/
  _タスク.md          ← アウトライン(木)。見出し=project、ネスト=分解
  タスクビュー.base   ← 属性ビュー(Obsidian Bases)
  ガントチャート.md   ← 派生ビュー。スクリプトが生成
  依存関係図.md       ← 派生ビュー。スクリプトが生成
  _scripts/           ← 決定論スクリプト(親属性の伝播・ビュー生成)
  items/<project>/<タスク名>.md  ← 1タスク=1ファイル。属性の真実

原則は2つです。

1つ目は1タスク=1ファイル。タスクの属性(status・期間・優先度・依存)はfrontmatterに書いて、これを唯一の真実にします。

tasks/items/顧客A案件/顧客A向け提供データ品質検証.md
---
title: 顧客A向け提供データ品質検証
project: 顧客A案件
status: todo
end: 2026-07-30
priority: Mid
estimate: 1d
depends_on:
  - "[[items/顧客A案件/顧客A向けデータ取り込みパイプライン構築|顧客A向けデータ取り込みパイプライン構築]]"
---

## 目的

取り込みパイプライン稼働後、顧客Aへ返す品質検証結果(欠損率・重複率など)を
まとめ、顧客A側との定例報告に使えるようにする。

## 完了条件

- 欠損率・重複率・フォーマット不正率の集計ロジックができている
- 直近1週間分のデータで品質レポートを1回出力できている

2つ目はビューはすべて派生。アウトラインの木、ガントチャート、依存関係図、Basesのテーブル(BasesはObsidianの機能で、ノートのfrontmatterを列にしたテーブルビューを作れます)は、どれもタスクファイルから機械的に再生成されるもので、手では編集しません。タスクファイルが更新されるとhook(詳細は後述します)がスクリプトを実行して作り直すので、「ビューが実態より古い」という状態がそもそも存在しません。

順序と分解を表す_タスク.mdも、こんな感じのただのMarkdownです(内容はサンプルです)。木に加えて、ガントチャート・依存関係図・Basesのテーブルを埋め込んでいて、これ1枚でタスク全体を見渡せます。

tasks/_タスク.md
## タスクツリー

### 社内基盤

- [[items/社内基盤/バッチ実行基盤の権限設計|バッチ実行基盤の権限設計]]
	- [[items/社内基盤/バッチ実行基盤のIAMロール定義|バッチ実行基盤のIAMロール定義]]
	- [[items/社内基盤/バッチ実行基盤の監査ログ設計|バッチ実行基盤の監査ログ設計]]
- [[items/社内基盤/社内ダッシュボードの応答速度改善|社内ダッシュボードの応答速度改善]]

### 顧客A案件

- [[items/顧客A案件/顧客A向けデータ取り込みパイプライン構築|顧客A向けデータ取り込みパイプライン構築]]
- [[items/顧客A案件/顧客A向け請求書突合ロジック実装|顧客A向け請求書突合ロジック実装]]
- [[items/顧客A案件/顧客A向け提供データ品質検証|顧客A向け提供データ品質検証]]

## ビュー

### ガントチャート

![[ガントチャート.md]]

### 依存関係図

![[依存関係図.md]]

### タスクリスト

![[タスクビュー.base]]

Obsidian上ではこう見えます。木のレンダリング、スクリプトが生成したガントチャートと依存関係図、Basesのテーブル。どれもタスクファイルからの派生です。


_タスク.md 1枚に、木・ガントチャート・依存関係図・Basesのテーブルがすべて揃う

なぜNotionやJiraではなくローカルのMarkdownなのか

最初に浮かぶ疑問だと思います。答えは「エージェントを働かせる場所としては、ローカルのテキストファイルが圧倒的にやりやすいから」です。

一番大きい理由は、この後説明する「計算はスクリプト」「実行契機はhook」が、ローカルファイルだからこそ成立することです。全タスクを対象にした集計はPython数行で書けますし、hookはファイルへの書き込みにそのまま反応します。SaaSのAPI越しに同じことをやろうとすると、認証・rate limit・pagination・スキーマ変換が漏れなく付いてきて、とてもこの軽さにはなりません。ローカルであることは、好みというより、この設計の成立条件だと思っています。

あと、コーディングエージェントにとってplain textはホームグラウンドです。読む・書く・検索するっていう、エージェントが一番慣れている操作だけで完結します。gitで履歴とdiffとrollbackがタダで付いてくるのも効いていて、エージェントに書き込み権を渡す以上「壊しても戻せる」は前提だと思っています。一括リネームがワンライナーで済むこと、知識ノートと同じvaultに置くとタスクと設計メモがリンクで繋がることも、地味ですがちょいちょい効きます。

分担の設計 — 判断は人間、更新はエージェント、計算はスクリプト

ここがこの仕組みの中心です。方針を一言でいうと、仕事をいちばん信頼できる実行者に降ろして、LLMは翻訳が必要なところにだけ使う、という感じです。

状態を書き換えるのはサブエージェント一本だけ

タスクファイルを書き換える経路は、task-managerという専用のサブエージェント一本に絞っています。定義の骨格を要約するとこんな感じです。

.claude/agents/task-manager.md
---
name: task-manager
description: タスクシステムを書き換える唯一のwriter。作成・更新・close・
  並べ替えを不変条件を守って原子的に実行し、結果を構造化して報告する。
---

あなたはタスクシステム唯一のwriterである。

- 書き換えてよいのは tasks/ 配下のみ。1タスク=1ファイル、木はリンクと順序だけを持つ
- 不変条件: ファイル名=title、frontmatterスキーマ、statusの遷移規則、木とファイルの整合
- 優先度・done充足・closeの是非は判断しない。指示が曖昧なら確認事項として差し戻す
- 操作後は「何をどう変えたか」を構造化して報告する

実際の定義はこの要約ではなくて、約240行あります。不変条件は10個(属性はファイルのみ、順序は木のみ、作成とcloseはファイルと木を同一操作で、など)、タスクの命名規約、createやcloseといった操作ごとの手順、報告フォーマットまで、仕様としてがっつり書き切ってあります。「更新はエージェント」は丸投げという意味ではなくて、何をどう書き換えていいかの仕様を書き切るコストを払って初めて成立する分担だ、というのが正直なところです。

ポイントは、サブエージェントに判断をさせないことです。タスクの優先度をどうするか、完了条件を満たしたと言えるか、closeしていいか。このあたりは毎回人間が決めます。サブエージェントがやるのは、自然言語の指示を具体的なファイル操作に翻訳して、不変条件を守って原子的に実行して、何をどう変えたかを報告するところまで。判断に迷う指示が来たら、推測で進めずに確認事項として差し戻します。

判断させないのは、LLMを信頼していないからじゃありません。冒頭に書いた2つ目の失敗で分かったのは、判断に必要な文脈(案件の温度感や口頭で決まったこと、自分の中の優先順位あたり)を、wikiに書き切ることはできない、ということでした。文脈が揃っていない場所に判断を置くと、「分かっている風」の判断が返ってきます。だから判断は、文脈が全部揃っている唯一の場所である人間に置く。これは書き切れなさの問題なので、モデルが賢くなっても変わらない構造だと思っています。

経路を一本に絞るのは一貫性のためです。複数の経路がそれぞれの解釈でファイルを触ると、命名規約や木とファイルの整合はどこかで必ず破れます。「タスク追加して」「これcloseして」みたいな日常の指示は、薄いskillがこのサブエージェントの操作に翻訳して渡します。skill自身はファイルを触りません。

計算できることはスクリプトへ

サブエージェント自身にも、やらせないことがあります。親タスクの期日を子の最遅日に引き上げる、見積もりを子の合計に集計する、ガントや依存図を生成する。こういう計算できる処理は、決定論のPythonスクリプトに寄せました。

第一の理由は精度です。計算と整合チェックは、LLMにやらせるより決定論のコードの方が確実です。もう一つはトークンコストで、全タスクファイルをLLMに読ませて集計させるのは、スクリプトなら一瞬で終わる処理に毎回コストを払うことになります。「LLMにやらせないことを決める」のが、この仕組みの信頼性の要でした。

実行のタイミングもエージェントから外す

実は最初、スクリプトの実行はサブエージェントの仕事でした。「タスクを更新したらスクリプトを実行せよ」とpromptに書いてあったんです。これでも動くんですが、実行し忘れの可能性が構造的に残ります。

なので今は、Claude CodeのPostToolUse hookでタスクファイルへの書き込みに反応して、スクリプトが自動実行される形にしました。効果は2つあって、1つはビューの再生成をエージェントの善意に頼らなくなったこと。もう1つはサブエージェントのpromptから実行手順の記述を丸ごと消せたことです。「LLMにやらせない」の範囲を、計算の中身から実行のタイミングにまで広げた、という感じですね。

この分担はClaude Code公式のガイダンスと同じ形をしている

この分担、実はAnthropicが公式に推奨している形とほぼ同じでした。Claude Codeのベストプラクティスには、こう書かれています。

Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens.

Claude Code Best Practices

指示(CLAUDE.md)は助言であって、毎回確実に起きてほしいことはhookにせよ、という整理です。肥大化した指示への処方箋としても「消すか、hookに変換せよ(delete it or convert it to a hook)」と書かれています。Agent Skillsの公式記事も、決定論が必要な処理はコードに任せると明言しています。

Beyond efficiency concerns, many applications require the deterministic reliability that only code can provide.

Equipping agents for the real world with Agent Skills

私はここに一つ補助線を引いています。LLMの周りに組む仕組みには2種類あると思っていて、モデルの能力不足を補うための仕組みは、モデルの進化とともに要らなくなって、作り込むほど負債になります。一方で、精度とコストの保証のための仕組みは、モデルがどれだけ賢くなっても「計算は決定論の方が確実で安い」が変わらない以上、剥がす理由がありません。このシステムの決定論化は後者なので、モデルの進化に賭けつつ、安心して作り込めます。

ついでに言うと、この線引きは私の本業そのものでもあります。私が関わっているAi Workforceという業務向けのエージェント製品でも、決まりきった業務フローは決定論的なworkflow(低コストで精度が安定します)で固めて、動的な判断が要るところにだけエージェントを差し込む、という同じ使い分けをしています。この記事の「計算はスクリプト、更新はエージェント」も同じ発想の縮小版で、業務でもプライベートでも、エージェントにどこまで任せてどこを固めるかの工夫を考えるのは、やっぱり面白いですね。

チームへの見せ方

チームの進捗管理はNotionにあります。手元のタスクを全部そっちに載せると、今度は「個人の作業分解がチームのボードを埋め尽くす」問題が起きるので、ここでも同じ責務分担を当てはめました。何をチームに見せるかの方針は人間が決めて、同期の実行と対象の算出は機械がやります。

同期はproject単位のopt-inで、チーム側にはマイルストーン相当の粗いタスクだけを載せます。手元で切った細かい分解を同期対象から外す仕組みがちょっと面白いところで、除外したいサブツリーの根にだけフラグを立てて、除外集合は木の構造から機械的に算出します。子タスクに1個ずつフラグを立てる方式にすると絶対に立て忘れるので、除外の意思はfrontmatterで一度だけ表明して、その波及は木の構造から計算させる、という分担です。後からそのサブツリーに子タスクを足しても、自動的に除外側に入ります。

書き戻しにも安全規則を入れています。自分がownerのタスクだけをローカルSSoTとしてNotionへ書き戻して、他のメンバーが主導しているタスクは読み取り専用として扱います。あと、closeしたタスクもNotion側は削除せずDoneに更新して残します。ローカルから消えた履歴をチーム側が保持してくれるので、週次の報告素材はそこから拾えます。

日々の回し方

日々の運用は、次の4つのモードで回していて、どれも同じwriter経路の上に乗っています。

  • バックログ操作 — タスクの追加・変更・close
  • 計画 — 週次計画と朝の計画、日報
  • タスク消化のループ — 「次のタスクやって」で日中を回す
  • 日次メンテ — 棚卸しと整合の確認

計画も日報も、タスクの状態を触るときは必ずtask-managerサブエージェント経由です。朝の計画はコマンド一発で下書きが出てきて、あとは微調整して数分で終わります。

日中は「次のタスクやって」と言うと、依存と優先度を踏まえた次の一手が差し出されるループで進めます。このループには個人的な動機があって、自分に不足しがちな一歩引いた視点を保つために、日々の作業を常にエンジニアリングマネージャーの視点で見ていたい、というのが出発点でした。自分がメンバーとして手を動かして、エージェントがマネージャーみたいに次の一手を差し出してくる、という構図です。

ただ、ここでも判断は人間に残ります。差し出された一手をやるかどうか、優先を入れ替えるか、closeしていいか。決めるのは毎回自分です。責務分担は運用のリズムの中でも崩れません。

3週間運用してみての振り返り

振り返ると、5年続けたMarkdownベースのライトな運用は整合の保守で崩れて、LLMへの丸投げは判断と把握を手放して崩れました。土台は5年前から変わらずMarkdownのままで、今回変えたのは、保守コストを誰が払うかと、判断をどこに置くか、この2つだけです。

移行後、この記事を書いている時点で運用23日目です。タスクファイルは100件(closed 49 / todo 47 / in_progress 4)、projectは9本になりました。ビューは常に実態と一致していて、朝の計画は数分で終わります。

3週間はまだ「定着した」と言える長さじゃありません。ただ、過去の2つの方式と決定的に違う点があります。第1期を壊した書き戻し漏れとビューのズレは、書き換え経路の一本化とhookの再生成で仕組み上起こり得なくなりました。第2期を壊した文脈不足の判断は、判断を人間に残したことで発生しません。破綻の原因を、続ける意思ではなく仕組みの側で潰せたので、今回はわりと続く見込みに根拠があると感じています。

それを一言にしたのが、この記事のタイトルです。判断は人間、更新はエージェント、計算はスクリプト。 人間に残っているのが判断だけだから、続けられる。

冒頭に書いたとおり、私は普段、AIエージェントのためのデータ基盤をやっています。複数の顧客案件を並走させる中で自分の頭では管理しきれなくなったのが、この仕組みを組んだきっかけでした。で、組んでみて気づいたのは、ここで使った考え方が、本業でエージェントの基盤を設計するときの判断とまったく同じだったことです。仕事はいちばん信頼できる実行者に降ろす、LLMにやらせないことを先に決める、破綻は意思ではなく仕組みで防ぐ。個人のタスク管理は、この原則を毎日試せる小さな実験場になっています。

同じように「タスク管理ツールを乗り換え続けている」人は、ツールじゃなくて責務分担から設計してみると、ちょっと違う景色が見えるかもしれません。

最後に少しだけ。私はLayerXで、この記事で書いた「決定論とLLMの線引き」を、個人のタスク管理ではなく業務が回る精度で作り込むデータ基盤を、AIエージェント向けに設計しています。いままさにこの領域を一緒に作るシニアデータエンジニアを募集中なので、面白そうと思ってくれた方はぜひ募集要項をのぞいてもらえたら嬉しいです。

https://open.talentio.com/r/1/c/layerx/pages/109629

LayerX

Discussion

Tatsuya ShimomotoTatsuya Shimomoto

決定論とLLMの線引き、興味深いですね。
私もAIエージェントを設計しているのですが、
設計を作りこんでいくほど、意外とLLMに任せるよりもスクリプトのほうが、
再現性やデバッグ可能性も高いので、どんどんLLMの領域が縮小していきます。
この辺りはみんなベストプラクティスを模索中だと思うので、今後の展開に期待しています。

1