コンテンツにスキップ

Vault でエージェントの自走時間を延ばす 3つの工夫(HANDOFF / 疎結合 / 定期起動)

なぜ Vault と相性が良いか(一言で)

このVaultは中身が全部 markdown なので、「成果物=受け渡しファイル」になる。エージェント同士を直接つながず、ノートを置く→次が読むだけで疎結合パイプラインが組める。自走時間を延ばす=「1セッションを引き伸ばす」のではなく「短いセッションを状態ファイルで途切れず繋ぐ」。


1. HANDOFF(状態ファイル)で途切れず再開する

コンテキストが溜まって劣化する前に、今の状態を1枚のmdに書き出して新セッションで再開する。これが土台(2,3はこれが前提)。

置き場

~/yamamoto_obsidian/_handoff/<タスク名>.md

_ プレフィックスで作業用フォルダを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)

cd ~/yamamoto_obsidian
claude -p "/daily-report" --permission-mode dontAsk
  • --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 ログインKeychainClaude 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=1277日間サイレント故障し日報生成が止まった)。ラッパの resolve_claude が「CLAUDE_BIN明示 → 既知の安定パス(~/.local/bin/opt/homebrew/bin/usr/local/bin)→ PATH探索(cmux除外)」で解決する。加えて claude 不在・非0終了時は macOS 通知を出し、次はサイレントにしない。

実装は次の3点(リポジトリに同梱済み):

  1. ラッパ scripts/run-vault-command.sh … PATH補完・絶対パスclaude・_handoff/log/ へログ。
  2. LaunchAgent scripts/launchd/com.yamamoto.vault.daily-report.plist … 毎日21:30 JST に /daily-report
  3. 導入手順 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の前提なので)。

  1. ~/yamamoto_obsidian/_handoff/ を作り、今動いている1タスク(例: 修論リサーチマップ)の HANDOFF を上のテンプレで1枚書く。
  2. 次セッションから「冒頭で Read → 終了時に更新」を徹底する。これだけで再開コストが激減する。
  3. 慣れたらクリッピング処理を status 遷移(工程2)にし、最後に cron(工程3)で1日1件まわす。

やらなくていいこと(記事の過剰部分)


作成: 2026-06-27 / 最終更新: 2026-07-14