主要データ構造マップ
このページへ戻るべき場面
主要な record 構造を横断的に見直すための資料です。
agent 学習でいちばん迷いやすいのは、機能の多さそのものではなく、
「今の状態がどの record に入っているのか」が見えなくなることです。
この文書は、主線章と bridge doc に繰り返し出てくる record をひとつの地図として並べ直し、
読者が system 全体を「機能一覧」ではなく「状態の配置図」として理解できるようにするための資料です。
どう使うか
この資料は辞書というより、state map として使ってください。
- 単語の意味が怪しくなったら
glossary.mdへ戻る - object 同士の境界が混ざったら
entity-map.mdを開く TaskRecordとRuntimeTaskStateが混ざったらs13a-runtime-task-model.mdを読む- MCP で tools 以外の layer が混ざったら
s19a-mcp-capability-layers.mdを併読する
最初にこの 2 本だけは覚える
原則 1: 内容状態と制御状態を分ける
内容状態とは、system が「何を扱っているか」を表す状態です。
例:
messagestool_result- memory の本文
- task の title や description
制御状態とは、system が「次にどう進むか」を表す状態です。
例:
turn_counttransitionhas_attempted_compactmax_output_tokens_overridepending_classifier_check
この 2 つを混ぜると、読者はすぐに次の疑問で詰まります。
- なぜ
messagesだけでは足りないのか - なぜ control plane が必要なのか
- なぜ recovery や compact が別 state を持つのか
原則 2: durable state と runtime state を分ける
durable state は、session をまたいでも残す価値がある状態です。
例:
- task
- memory
- schedule
- team roster
runtime state は、system が動いている間だけ意味を持つ状態です。
例:
- 現在の permission decision
- 今走っている runtime task
- active MCP connection
- 今回の query の continuation reason
この区別が曖昧だと、task・runtime slot・notification・schedule・worktree が全部同じ層に見えてしまいます。
1. Query と会話制御の状態
この層の核心は:
会話内容を持つ record と、query の進行理由を持つ record は別物である
です。
Message
役割:
- user と assistant の会話履歴を持つ
- tool 呼び出し前後の往復も保存する
最小形:
message = {
"role": "user" | "assistant",
"content": "...",
}
agent が tool を使い始めると、content は単なる文字列では足りなくなり、次のような block list になることがあります。
- text block
tool_usetool_result
この record の本質は、会話内容の記録です。
「なぜ次ターンへ進んだか」は Message の責務ではありません。
関連章:
s01s02s06s10
NormalizedMessage
役割:
- さまざまな内部 message を、model API に渡せる統一形式へ揃える
最小形:
message = {
"role": "user" | "assistant",
"content": [
{"type": "text", "text": "..."},
],
}
Message と NormalizedMessage の違い:
Message: system 内部の履歴 record に近いNormalizedMessage: model 呼び出し直前の入力形式に近い
つまり、前者は「何を覚えているか」、後者は「何を送るか」です。
関連章:
CompactSummary
役割:
- context が長くなり過ぎたとき、古い会話を要約へ置き換える
最小形:
summary = {
"task_overview": "...",
"current_state": "...",
"key_decisions": ["..."],
"next_steps": ["..."],
}
重要なのは、compact が「ログ削除」ではないことです。
compact summary は次の query 継続に必要な最小構造を残す record です。
最低でも次の 4 つは落とさないようにします。
- task の大枠
- ここまで終わったこと
- 重要な判断
- 次にやるべきこと
関連章:
s06s11
SystemPromptBlock
役割:
- system prompt を section 単位で管理する
最小形:
block = {
"text": "...",
"cache_scope": None,
}
この record を持つ意味:
- prompt を一枚岩の巨大文字列にしない
- どの section が何の役割か説明できる
- 後から block 単位で差し替えや検査ができる
cache_scope は最初は不要でも構いません。
ただ、「この block は比較的安定」「この block は毎ターン変わる」という発想は早めに持っておくと、system prompt の理解が崩れにくくなります。
関連章:
PromptParts
役割:
- system prompt を最終連結する前に、構成 source ごとに分けて持つ
最小形:
parts = {
"core": "...",
"tools": "...",
"skills": "...",
"memory": "...",
"dynamic": "...",
}
この record は、読者に次のことを教えます。
- prompt は「書かれている」のではなく「組み立てられている」
- stable policy と volatile runtime data は同じ section ではない
- input source ごとに責務を分けた方が debug しやすい
関連章:
s10
QueryParams
役割:
- query 開始時点で外部から受け取る入口入力
最小形:
params = {
"messages": [...],
"system_prompt": "...",
"user_context": {...},
"system_context": {...},
"tool_use_context": {...},
"fallback_model": None,
"max_output_tokens_override": None,
"max_turns": None,
}
ここで大切なのは:
- これは query の入口入力である
- query の途中でどんどん変わる内部状態とは別である
つまり QueryParams は「入る前に決まっているもの」、QueryState は「入ってから変わるもの」です。
関連章:
QueryState
役割:
- 1 本の query が複数ターンにわたって進む間の制御状態を持つ
最小形:
state = {
"messages": [...],
"tool_use_context": {...},
"turn_count": 1,
"max_output_tokens_recovery_count": 0,
"has_attempted_reactive_compact": False,
"max_output_tokens_override": None,
"pending_tool_use_summary": None,
"stop_hook_active": False,
"transition": None,
}
この record に入るものの共通点:
- 対話内容そのものではない
- 「次をどう続けるか」を決める情報である
初心者がよく詰まる点:
messagesが入っているので「全部 conversation state に見える」- しかし
turn_countやtransitionは会話ではなく control state
この record を理解できると、
- recovery
- compact
- hook continuation
- token budget continuation
がすべて「同じ query を継続する理由の差分」として読めるようになります。
関連章:
TransitionReason
役割:
- 前ターンが終わらず、次ターンへ続いた理由を明示する
最小形:
transition = {
"reason": "next_turn",
}
より実用的には次のような値が入ります。
next_turntool_result_continuationreactive_compact_retrymax_output_tokens_recoverystop_hook_continuation
これを別 record として持つ利点:
- log が読みやすい
- test が書きやすい
- recovery の分岐理由を説明しやすい
つまりこれは「高度な最適化」ではなく、
継続理由を見える状態へ変えるための最小構造です。
関連章:
2. Tool 実行・権限・hook の状態
この層の核心は:
tool は
name -> handlerだけで完結せず、その前後に permission / runtime / hook の状態が存在する
です。
ToolSpec
役割:
- model に「どんな tool があり、どんな入力を受け取るか」を見せる
最小形:
tool = {
"name": "read_file",
"description": "Read file contents.",
"input_schema": {...},
}
これは execution 実装そのものではありません。
あくまで model に見せる contract です。
関連章:
s02s19
ToolDispatchMap
役割:
- tool 名を実際の handler 関数へ引く
最小形:
dispatch = {
"read_file": run_read_file,
"write_file": run_write_file,
}
この record の仕事は単純です。
- 正しい handler を見つける
ただし実システムではこれだけで足りません。
本当に難しいのは:
- いつ実行するか
- 並列にしてよいか
- permission を通すか
- 結果をどう loop へ戻すか
です。
関連章:
ToolUseContext
役割:
- tool が共有状態へ触るための窓口を持つ
最小形:
context = {
"workspace": "...",
"permission_system": perms,
"notifications": queue,
"memory_store": memory,
}
この record がないと、各 tool が勝手に global state を触り始め、system 全体の境界が崩れます。
つまり ToolUseContext は、
tool が system とどこで接続するか
を見える形にするための record です。
関連章:
s02s07s09s13
ToolResultEnvelope
役割:
- tool 実行結果を loop が扱える統一形式で包む
最小形:
result = {
"tool_use_id": "toolu_123",
"content": "...",
}
大切なのは、tool 結果が「ただの文字列」ではないことです。
最低でも:
- どの tool call に対する結果か
- loop にどう書き戻すか
を持たせる必要があります。
関連章:
s02
PermissionRule
役割:
- 特定 tool / path / content に対する allow / deny / ask 条件を表す
最小形:
rule = {
"tool": "bash",
"behavior": "deny",
"path": None,
"content": "sudo *",
}
この record があることで、permission system は次を言えるようになります。
- どの tool に対する rule か
- 何にマッチしたら発火するか
- 発火後に何を返すか
関連章:
s07
PermissionDecision
役割:
- 今回の tool 実行に対する permission 結果を表す
最小形:
decision = {
"behavior": "allow" | "deny" | "ask",
"reason": "...",
}
これを独立 record にする意味:
- deny 理由を model が見える
- ask を loop に戻して次アクションを組み立てられる
- log や UI にも同じ object を流せる
関連章:
s07
HookEvent
役割:
- pre_tool / post_tool / on_error などの lifecycle event を統一形で渡す
最小形:
event = {
"kind": "post_tool",
"tool_name": "edit_file",
"input": {...},
"result": "...",
"error": None,
"duration_ms": 42,
}
hook が安定して増やせるかどうかは、この record の形が揃っているかに大きく依存します。
もし毎回適当な文字列だけを hook に渡すと:
- audit hook
- metrics hook
- policy hook
のたびに payload 形式がばらけます。
関連章:
s08
ToolExecutionBatch
役割:
- 同じ execution lane でまとめて調度してよい tool block の束を表す
最小形:
batch = {
"is_concurrency_safe": True,
"blocks": [tool_use_1, tool_use_2],
}
この record を導入すると、読者は:
- tool を常に 1 個ずつ実行する必要はない
- ただし何でも並列にしてよいわけでもない
という 2 本の境界を同時に理解しやすくなります。
関連章:
TrackedTool
役割:
- 各 tool の lifecycle を個別に追う
最小形:
tracked = {
"id": "toolu_01",
"name": "read_file",
"status": "queued",
"is_concurrency_safe": True,
"pending_progress": [],
"results": [],
"context_modifiers": [],
}
これがあると runtime は次のことを説明できます。
- 何が待機中か
- 何が実行中か
- 何が progress を出したか
- 何が完了したか
関連章:
queued_context_modifiers
役割:
- 並列 tool が生んだ共有 state 変更を、先に queue し、後で安定順に merge する
最小形:
queued = {
"toolu_01": [modifier_a],
"toolu_02": [modifier_b],
}
ここで守りたい境界:
- 並列実行してよい
- しかし共有 state を完了順でそのまま書き換えてよいとは限らない
この record は、parallel execution と stable merge を切り分けるための最小構造です。
関連章:
3. Skill・memory・prompt source の状態
この層の核心は:
model input の材料は、その場でひとつの文字列に溶けているのではなく、複数の source record として存在する
です。
SkillRegistry
役割:
- 利用可能な skill の索引を持つ
最小形:
registry = [
{"name": "agent-browser", "path": "...", "description": "..."},
]
これは「何があるか」を示す record であり、skill 本文そのものではありません。
関連章:
s05
SkillContent
役割:
- 実際に読み込んだ skill の本文や補助資料を持つ
最小形:
skill = {
"name": "agent-browser",
"body": "...markdown...",
}
SkillRegistry と SkillContent を分ける理由:
- registry は discovery 用
- content は injection 用
つまり「見つける record」と「使う record」を分けるためです。
関連章:
s05
MemoryEntry
役割:
- 長期に残すべき事実を 1 件ずつ持つ
最小形:
entry = {
"key": "package_manager_preference",
"value": "pnpm",
"scope": "user",
"reason": "user explicit preference",
}
memory の重要境界:
- 会話全文を残す record ではない
- durable fact を残す record である
関連章:
s09
MemoryWriteCandidate
役割:
- 今回のターンから「long-term memory に昇格させる候補」を一時的に保持する
最小形:
candidate = {
"fact": "Use pnpm by default",
"scope": "user",
"confidence": "high",
}
教学 repo では必須ではありません。
ただし reader が「memory はいつ書くのか」で混乱しやすい場合、この record を挟むと
- その場の conversation detail
- durable fact candidate
- 実際に保存された memory
の 3 層を分けやすくなります。
関連章:
s09
4. Todo・task・runtime・team の状態
この層が一番混ざりやすいです。
理由は、全部が「仕事っぽい object」に見えるからです。
TodoItem
役割:
- 今の session 内での短期的な進行メモ
最小形:
todo = {
"content": "Inspect auth tests",
"status": "pending",
}
これは durable work graph ではありません。
今ターンの認知負荷を軽くするための session-local 補助構造です。
関連章:
s03
PlanState
役割:
- 複数の
TodoItemと current focus をまとめる
最小形:
plan = {
"todos": [...],
"current_focus": "Inspect auth tests",
}
これも基本は session-local です。
TaskRecord と違って、再起動しても必ず復元したい durable board とは限りません。
関連章:
s03
TaskRecord
役割:
- durable work goal を表す
最小形:
task = {
"id": "task-auth-migrate",
"title": "Migrate auth layer",
"status": "pending",
"dependencies": [],
}
この record が持つべき心智:
- 何を達成したいか
- 依存関係は何か
- 今どの状態か
ここで大切なのは、task は goal node であって、今まさに走っている process ではないことです。
関連章:
s12
RuntimeTaskState
役割:
- いま動いている 1 回の execution slot を表す
最小形:
runtime_task = {
"id": "rt_42",
"task_id": "task-auth-migrate",
"status": "running",
"preview": "...",
"output_file": ".runtime-tasks/rt_42.log",
}
TaskRecord との違い:
TaskRecord: 何を達成するかRuntimeTaskState: その goal に向かう今回の実行は今どうなっているか
関連章:
NotificationRecord
役割:
- background 実行や外部 capability から main loop へ戻る preview を持つ
最小形:
note = {
"source": "runtime_task",
"task_id": "rt_42",
"preview": "3 tests failing...",
}
この record は全文ログの保存先ではありません。
役割は:
- main loop に「戻ってきた事実」を知らせる
- prompt space を全文ログで埋めない
ことです。
関連章:
s13
ScheduleRecord
役割:
- いつ何を trigger するかを表す
最小形:
schedule = {
"name": "nightly-health-check",
"cron": "0 2 * * *",
"task_template": "repo_health_check",
}
重要な境界:
ScheduleRecordは時間規則TaskRecordは work goalRuntimeTaskStateは live execution
この 3 つを一緒にしないことが s14 の核心です。
関連章:
s14
TeamMember
役割:
- 長期に存在する teammate の身元を表す
最小形:
member = {
"name": "alice",
"role": "test-specialist",
"status": "working",
}
TeamMember は task ではありません。
「誰が長く system 内に存在しているか」を表す actor record です。
関連章:
s15
TeamConfig
役割:
- team roster 全体をまとめる
最小形:
config = {
"team_name": "default",
"members": [member1, member2],
}
この record を durable に持つことで、
- team に誰がいるか
- 役割が何か
- 次回起動時に何を復元するか
が見えるようになります。
関連章:
s15
MessageEnvelope
役割:
- teammate 間の message を、本文とメタ情報込みで包む
最小形:
envelope = {
"type": "message",
"from": "lead",
"to": "alice",
"content": "Review retry tests",
"timestamp": 1710000000.0,
}
envelope を使う理由:
- 誰から誰へ送ったか分かる
- 普通の会話と protocol request を区別しやすい
- mailbox を durable channel として扱える
関連章:
s15s16
RequestRecord
役割:
- approval や shutdown のような構造化 protocol state を持つ
最小形:
request = {
"request_id": "req_91",
"kind": "plan_approval",
"status": "pending",
"payload": {...},
}
これを別 record にすることで、
- ただの chat message
- 追跡可能な coordination request
を明確に分けられます。
関連章:
s16
ClaimPolicy
役割:
- autonomous worker が何を self-claim してよいかを表す
最小形:
policy = {
"role": "test-specialist",
"may_claim": ["retry-related"],
}
この record がないと autonomy は「空いている worker が勝手に全部取りに行く」設計になりやすく、
race condition と重複実行を呼び込みます。
関連章:
s17
WorktreeRecord
役割:
- isolated execution lane を表す
最小形:
worktree = {
"path": ".worktrees/wt-auth-migrate",
"task_id": "task-auth-migrate",
"status": "active",
}
この record の核心:
- task は goal
- runtime slot は live execution
- worktree は「どこで走るか」の lane
関連章:
s18
5. MCP・plugin・外部 capability の状態
この層の核心は:
外部 capability も「ただの tool list」ではなく、接続状態と routing を持つ platform object である
です。
MCPServerConfig
役割:
- 外部 server の設定を表す
最小形:
config = {
"name": "figma",
"transport": "stdio",
"command": "...",
}
これは capability そのものではなく、接続の入口設定です。
関連章:
s19
ConnectionState
役割:
- remote capability の現在状態を表す
最小形:
state = {
"status": "connected",
"needs_auth": False,
"last_error": None,
}
この record が必要な理由:
- 外部 capability は常に使えるとは限らない
- 問題が tool schema なのか connection なのか区別する必要がある
関連章:
CapabilityRoute
役割:
- native tool / plugin / MCP server のどこへ解決されたかを表す
最小形:
route = {
"source": "mcp",
"target": "figma.inspect",
}
この record があると、
- 発見
- routing
- permission
- 実行
- result normalization
が同じ capability bus 上で説明できます。
関連章:
s19
最後に、特に混同しやすい組み合わせ
TodoItem vs TaskRecord
TodoItem: 今 session で何を見るかTaskRecord: durable work goal と dependency をどう持つか
TaskRecord vs RuntimeTaskState
TaskRecord: 何を達成したいかRuntimeTaskState: 今回の実行は今どう進んでいるか
RuntimeTaskState vs ScheduleRecord
RuntimeTaskState: live executionScheduleRecord: いつ trigger するか
SubagentContext vs TeamMember
SubagentContext: 一回きりの delegation branchTeamMember: 長期に残る actor identity
TeamMember vs RequestRecord
TeamMember: 誰が存在するかRequestRecord: どんな coordination request が進行中か
TaskRecord vs WorktreeRecord
TaskRecord: 何をやるかWorktreeRecord: どこでやるか
ToolSpec vs CapabilityRoute
ToolSpec: model に見せる contractCapabilityRoute: 実際にどこへ routing するか
読み終えたら言えるべきこと
少なくとも次の 3 文を、自分の言葉で説明できる状態を目指してください。
messagesは内容状態であり、transitionは制御状態である。TaskRecordは goal node であり、RuntimeTaskStateは live execution slot である。TeamMember、RequestRecord、WorktreeRecordは全部「仕事っぽい」が、それぞれ actor、protocol、lane という別層の object である。
一文で覚える
どの record が内容を持ち、どの record が流れを持ち、どれが durable でどれが runtime かを分けられれば、agent system の複雑さは急に読める形になります。