Vault でエージェントの自走時間を延ばす 3つの工夫(HANDOFF / 疎結合 / 定期起動)¶
なぜ Vault と相性が良いか(一言で)¶
このVaultは中身が全部 markdown なので、「成果物=受け渡しファイル」になる。エージェント同士を直接つながず、ノートを置く→次が読むだけで疎結合パイプラインが組める。自走時間を延ばす=「1セッションを引き伸ばす」のではなく「短いセッションを状態ファイルで途切れず繋ぐ」。
1. HANDOFF(状態ファイル)で途切れず再開する¶
コンテキストが溜まって劣化する前に、今の状態を1枚のmdに書き出して新セッションで再開する。これが土台(2,3はこれが前提)。
置き場¶
_ プレフィックスで作業用フォルダを1つ作る(タスクごとに1ファイル)。
テンプレート¶
---
task: 修論リサーチマップの精緻化
status: in_progress # in_progress | blocked | done
updated: 2026-06-27
---
## ゴール(このタスクの完了条件)
- 受け入れ条件を1〜3行で
## 完了したこと
- [x] 〜
- [x] 〜
## 次の1ステップ(最優先・これだけやる)
- 〜(具体的に。曖昧にしない)
## 未解決・人間の判断待ち
- 〜(あれば。無ければ「なし」)
## 関連ファイル(絶対 or Vault相対パス)
- 02_research/02-1_main_research/research_plan/xxx.md
運用ルール¶
- セッション終了時に必ず HANDOFF を更新してから終わる(「次の1ステップ」を必ず埋める)。
- 新セッションは冒頭で HANDOFF を Read してから着手する。
- 1ファイル=1タスク。終わったら
status: doneにして_handoff/done/へ移す。 - コンテキストが重くなったら、続きを書かず HANDOFF 更新→新セッション(記事の「
/compactか HANDOFF+新規セッション」)。
2. markdown 成果物経由で疎結合にする(工程を frontmatter status で表す)¶
エージェント/ステップは1ノートを出力するだけ。次段はそのノートの status やフォルダで拾う。1体が落ちても他は止まらない=全体の自走時間が延びる。
やり方: status 遷移でパイプライン化¶
各ノートの frontmatter に工程を持たせる(02_research で導入済みの status 運用を全工程に拡張)。
例: Zotero クリッピング処理パイプライン
raw(04_clippings に投下)
↓ 要約ステップ: status:raw を1件探して要約 → status:summarized
summarized
↓ 整理ステップ: 06_zotero/02_research へ配置・タグ付け → status:linked
linked(完成)
各ステップの指示はこれだけ:
「
status: rawのノートを1件だけ探し、要約してstatus: summarizedに更新せよ。1件処理したら終了。」
ポイント¶
- ステップ間で会話状態を共有しない。ファイルが唯一の真実(再実行・再開が楽)。
- 1回の実行は1件だけ・冪等に。失敗しても次回が同じノートを拾える。
- 「どれを処理するか」は status とフォルダで決まるので、人間が割り振らなくてよい。
3. 定期起動でループ化する(人の起動をスケジュールに置き換える)¶
「人間が起動」を「スケジュールが起動」にすると自走時間は実質無限。1回を短く冪等にしておけば、失敗しても次回拾える。
Vault の定期タスク候補¶
- 日報の下書き: 毎朝、各リポの
git log(JST正規化)+予定から01_daily_reports/に下書き生成 - クリッピング棚卸し:
status: rawを1件要約(=工程2のループ駆動) - リンク切れ・孤立ノート検出: 週次で
[[...]]切れと被リンク0ノートを一覧化 - research 棚卸し:
status: ideaのテーマを月次で再評価
最小コマンド(headless Claude Code)¶
--permission-mode dontAsk: 無人実行用(確認を出さず、allowlist 外は尋ねず拒否=deny安全網が効く)。allowlistの網羅性がそのまま実行可否になる点に注意。実際、初回はbash scripts/gather-git-activity.shが allowlist 外で実行できず、claude がgit logに自動フォールバックした。テスト済みスクリプトを確実に使わせるにはBash(bash scripts/...:*)を allow に足す。
macOS では cron ではなく launchd(重要・実測)¶
headless claude -p の認証は macOS ログインKeychain(Claude Code-credentials)経由。
- cron は不可: 非Aquaセッションで走るためログインKeychainに確実にアクセスできず
Not logged inになる(env -iでの再現も同様)。 - launchd は可: LaunchAgent はユーザーのGUI(Aqua)セッションで走るのでKeychainにアクセスでき、認証が通る(
claude -pが launchd 経由でPONGを返すことを実測確認)。 - 使う claude は 安定版。GUIアプリ同梱版(cmux等)は Keychain 認証が通らないので cron/launchd 用に使わない。
- claude のパスをハードコードしない(実測:
run-vault-command.shが/opt/homebrew/bin/claude固定だったため、2026-07-07 に claude が~/.local/bin〈ネイティブインストーラ版〉へ migration した瞬間からexit=127で7日間サイレント故障し日報生成が止まった)。ラッパのresolve_claudeが「CLAUDE_BIN明示 → 既知の安定パス(~/.local/bin→/opt/homebrew/bin→/usr/local/bin)→ PATH探索(cmux除外)」で解決する。加えて claude 不在・非0終了時は macOS 通知を出し、次はサイレントにしない。
実装は次の3点(リポジトリに同梱済み):
- ラッパ
scripts/run-vault-command.sh… PATH補完・絶対パスclaude・_handoff/log/へログ。 - LaunchAgent
scripts/launchd/com.yamamoto.vault.daily-report.plist… 毎日21:30 JST に/daily-report。 - 導入手順
scripts/launchd/README.md。
# 導入
cp scripts/launchd/com.yamamoto.vault.daily-report.plist ~/Library/LaunchAgents/
launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.yamamoto.vault.daily-report.plist
# 今すぐ動作確認
launchctl kickstart -k "gui/$(id -u)/com.yamamoto.vault.daily-report"
- 前提: Mac が起動・ログイン中(スリープ中は発火しない)。
- Claude Code 内の
scheduleスキルはクラウド実行なので、ローカルの~/配下リポジトリを走査する日報用途には使えない。複数リポ横断の重い処理は Temporal(temporal_活用事例と導入設計)。
始め方(最小構成で1個だけ)¶
いきなり全部やらない。まず1のHANDOFFだけ導入する(2,3の前提なので)。
~/yamamoto_obsidian/_handoff/を作り、今動いている1タスク(例: 修論リサーチマップ)の HANDOFF を上のテンプレで1枚書く。- 次セッションから「冒頭で Read → 終了時に更新」を徹底する。これだけで再開コストが激減する。
- 慣れたらクリッピング処理を status 遷移(工程2)にし、最後に cron(工程3)で1日1件まわす。
やらなくていいこと(記事の過剰部分)¶
- ディスプレイ6面・スパコン・モバイルバッテリーは「人間が同時に何個見れるか」の話で、エージェントの自走時間とは無関係。Vault運用には不要。
- 「トークン消費量」を成果指標にしない(../../03-2_notes/architecture/AI支出を横ばいに保つ_デフォルト_ルーティング_キャッシング)。全工程を最上位モデルに振らず、要約・巡回など軽い工程は安いデフォルトで。
作成: 2026-06-27 / 最終更新: 2026-07-14