# v2: Todoによる構造化プランニング
**約300行。+1ツール。明示的なタスク追跡。**
v1は機能する。しかし複雑なタスクでは、モデルが見失うことがある。
「認証をリファクタリングし、テストを追加し、ドキュメントを更新して」と頼むと何が起こるか見てみよう。明示的な計画なしでは、タスク間を飛び回り、ステップを忘れ、集中を失う。
v2は1つのものを追加:**Todoツール**。エージェントの動作を根本的に変える約100行の新コード。
## 問題
v1では、計画はモデルの「頭の中」にのみ存在:
```
v1: "Aをして、次にB、次にC" (見えない)
10ツール後: "あれ、何をしていたっけ?"
```
Todoツールはそれを明示化:
```
v2:
[ ] 認証モジュールをリファクタリング
[>] ユニットテストを追加 <- 現在ここ
[ ] ドキュメントを更新
```
これであなたもモデルも計画が見える。
## TodoManager
制約のあるリスト:
```python
class TodoManager:
def __init__(self):
self.items = [] # 最大20
def update(self, items):
# バリデーション:
# - 各項目に必要: content, status, activeForm
# - Status: pending | in_progress | completed
# - in_progressは1つだけ
# - 重複なし、空なし
```
制約が重要:
| ルール | 理由 |
|--------|------|
| 最大20項目 | 無限リストを防ぐ |
| in_progressは1つ | 集中を強制 |
| 必須フィールド | 構造化出力 |
これらは任意ではない—ガードレールだ。
## ツール
```python
{
"name": "TodoWrite",
"input_schema": {
"items": [{
"content": "タスクの説明",
"status": "pending | in_progress | completed",
"activeForm": "現在形: 'ファイルを読んでいます'"
}]
}
}
```
`activeForm`は今何が起こっているかを示す:
```
[>] 認証コードを読んでいます... <- activeForm
[ ] ユニットテストを追加
```
## システムリマインダー
Todo使用を促すソフト制約:
```python
INITIAL_REMINDER = "マルチステップタスクにはTodoWriteを使用してください。"
NAG_REMINDER = "10ターン以上todoなし。更新してください。"
```
コマンドではなくコンテキストとして注入:
```python
# INITIAL_REMINDER: 会話開始時(mainで)
if first_message:
inject_reminder(INITIAL_REMINDER)
# NAG_REMINDER: agent_loop内で、タスク実行中に
if rounds_without_todo > 10:
inject_reminder(NAG_REMINDER)
```
重要な洞察:NAG_REMINDERは**エージェントループ内**で注入されるので、モデルは長時間実行タスク中にそれを見る、タスク間だけではなく。
## フィードバックループ
モデルが`TodoWrite`を呼び出すとき:
```
入力:
[x] 認証をリファクタリング (完了)
[>] テストを追加 (進行中)
[ ] ドキュメントを更新 (保留)
返却:
"[x] 認証をリファクタリング
[>] テストを追加
[ ] ドキュメントを更新
(1/3 完了)"
```
モデルは自分の計画を見る。それを更新する。コンテキストを持って続行する。
## Todoが役立つとき
すべてのタスクに必要なわけではない:
| 適切な場面 | 理由 |
|------------|------|
| マルチステップ作業 | 追跡すべき5つ以上のステップ |
| 長い会話 | 20以上のツール呼び出し |
| 複雑なリファクタリング | 複数のファイル |
| 教育 | 「思考」が可視 |
経験則:**チェックリストを書くなら、todoを使う**。
## 統合
v2はv1を変更せずに追加:
```python
# v1のツール
tools = [bash, read_file, write_file, edit_file]
# v2が追加
tools.append(TodoWrite)
todo_manager = TodoManager()
# v2は使用を追跡
if rounds_without_todo > 10:
inject_reminder()
```
約100行の新コード。同じエージェントループ。
## より深い洞察
> **構造は制約し、可能にする。**
Todo制約(最大項目数、1つのin_progress)が可能にする(可視の計画、追跡された進捗)。
エージェント設計のパターン:
- `max_tokens`は制約 → 管理可能な応答を可能に
- ツールスキーマは制約 → 構造化された呼び出しを可能に
- Todoは制約 → 複雑なタスク完了を可能に
良い制約は制限ではない。足場だ。
---
**明示的な計画がエージェントを信頼性あるものにする。**
[← v1](./v1-モデルがエージェント.md) | [READMEに戻る](../README_ja.md) | [v3 →](./v3-サブエージェント.md)