1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code Routinesは、なぜ毎回「初めまして」なのか ― gitリポジトリを"記憶"にして朝刊メールを動かした話

1
Posted at

「AIエージェントの記憶」を扱った記事はすでにたくさんあります。ただ、その多くは汎用的な設計論か、mem0・Zepみたいなメモリライブラリの比較が中心でした。この記事はそのどちらでもなく、Claude Code Routinesという具体的な機能の制約の上で、実際に毎朝動いているものの中身を書きます。

TL;DR

  • Claude Code Routinesは実行のたびにまっさらなコンテナでリポジトリをcloneし直す。前回のことは何も覚えていない
  • なので「次回に必要な情報は全部gitリポジトリにコミットしておく」という前提で組み直した
  • 記憶は2種類に分けている。人間が書き換える設定と、エージェント自身が読み書きする作業記憶
  • 「考える(AI)」と「送る(決定論的スクリプト)」を工程として分け、無人実行でも事故らないようにした
  • 承認プロンプトが出ない無人実行だからこそ、コネクタの書き込み権限は最初から最小に絞った

対象読者

  • Claude Code RoutinesやGitHub Actions連携で「毎朝◯◯する」系の自動化を組みたい人
  • Routineを触ってみて、「毎回リセットされる」問題にどう対処すればいいか迷っている人
  • AIエージェントに外部送信やカレンダー操作を任せるとき、どこまで権限を渡していいか知りたい人

Routineの始め方自体(トリガーの種類やコネクタの繋ぎ方)はここでは触れません。すでに良い入門記事がいくつもあるので、その一歩先の「記憶をどう設計するか」だけに絞って書きます。


なぜ作ったか

朝起きて、カレンダー・天気・通勤経路の運行情報・気になるニュース・締切もの・今日やること……これを確認するためだけに、アプリを5個くらい開く。毎朝これをやるのが地味にだるくて、それなら1通のメールにまとめて、起きたら読むだけにしよう、と思ったのがきっかけです。

やりたいことはシンプルでした。毎朝決まった時間に、自分向けにパーソナライズされた「朝刊」を1通のメールで受け取る。Claude Code Routinesはこれにちょうどよさそうに見えました。プロンプトもリポジトリもコネクタもトリガーもセットで保存できて、PCを閉じていてもクラウド側で勝手に動いてくれます。

ただ、実際に動かしてみるとすぐに壁にぶつかりました。


最大の壁:Routineは毎回「初めまして」を繰り返す

動かし始めてすぐ気づいたのが、同じニュースが2日連続で出てくること。しかも「昨日もう扱いました」と自分で書いたはずの話題を、次の日にまた律儀に取り上げてきたりします。原因は単純で、Routineは前回のやり取りを一切覚えていないからです。

Routineの実行モデル自体はシンプルです。

毎回まっさらなコンテナでcloneし直すので、「昨日この話題を読んだ」「この締切はもう扱った」みたいな記憶は、明示的にリポジトリへ書き戻さない限り残りません。ローカルで動かす常駐プロセスとは違って、セッションをまたいだ暗黙の共有状態はない、くらいに考えておいたほうが安全です。

なので設計の出発点は、「このエージェントは記憶を持たない」というのをまず受け入れることでした。


記憶をリポジトリに切り出す ― 2種類に分けて考える

「リポジトリに書けば残る」というのは分かっても、何でもかんでも1つのファイルにベタ書きすると、わりとすぐに崩壊します。人間が意図的に変えたい情報と、AIが日々勝手に更新する情報が混ざると、後から見て「これどっちが書き換えたやつ?」が分からなくなるからです。

なので、記憶を性質で2種類に分けています。

種類 更新する人 役割 具体例
設定(人間が書く) 自分 AIの前提や方針を変える プロフィール、締切カレンダー、関心の重み
作業記憶(AIが書く) AI 日々の実行結果を持ち越す 既読URL一覧、続報待ちリスト、当日のログ

この線引きをしておくと、「今日の出力なんか変だな」となったとき、設定側を疑うのか作業記憶側を疑うのか、すぐに見当がつきます。ここから、作業記憶まわりで実際にやってよかった工夫を3つほど紹介します。

関心の重みで、読まない話題を勝手に沈める

全部の話題を平等に扱うと、興味のないジャンルの記事が毎朝紛れ込んできます。かといって毎回フィルタ条件を細かく手で調整するのも面倒なので、話題ごとに「重み」を持たせるだけの簡単な仕組みにしました。

{
  "topics": {
    "frontend": { "weight": 1.0 },
    "crypto":   { "weight": 0.2 }
  }
}

読まないジャンルに気づいたら、月1くらいのペースで重みを手で下げるだけです。クリックログを自動で集めるような凝った仕組みはあえて作らず、人間が気づいたときに数字を1つ書き換える、くらいにとどめています。自動化しすぎず、フィードバックの主導権はこっちに残しておく感じです。

見た記事は30日だけ覚えておく

同じニュースが2日連続で出てくると、それだけで一気に「使えないな」という印象になります。なので、扱ったURLを記録しておいて、しばらくは再掲しないようにしています。

{
  "https://example.com/article-a": "2026-08-20",
  "https://example.com/article-b": "2026-08-22"
}

保持期間はざっくり30日で区切って、期限切れのものは定期的に棚卸しして間引いています。作業記憶を無限に太らせないためのTTL設計は、この手のリポジトリ永続化パターン全般で効いてくる考え方だと思います。

日をまたぐ「宿題」を持ち越す

「まだ確定してないけど、明日には分かりそうな話」って、その日だけで判断せずに翌日以降も追いたくなりますよね。これも同じで、状態ファイルに「継続確認中」として書き出しておいて、次回の実行時にちゃんと読み込むようにしています。人間から見ると、AIが昨日の宿題を律儀に覚えていてくれる、みたいな形になります。


「考える」と「送る」を分ける

もう1つこだわったのが、AIに外部送信そのものを任せないことです。

AI側の仕事は、その日の本文をリポジトリにコミットするところまでで終わりです。実際にSMTPに繋いでメールを送る処理は、挙動が変わらないただのPythonスクリプトが、GitHub Actions経由で担当します。

理由は単純で、毎回プロンプトの解釈が微妙にブレるかもしれない相手に、取り返しのつかない外部送信という操作を直接持たせたくないからです。AIの仕事は「良い本文を作る」ところに閉じておいて、「決まったフォーマットのメールを決まった宛先に送る」という機械的な部分は決定論側に寄せる。これは朝刊に限らず、送信・投稿・決済みたいな外部アクションをAIエージェントに絡めるときに、わりと汎用的に効く分け方だと思います。

副産物として、リポジトリに毎日の本文がそのままログとして残ります。「今日のメール、なんか内容おかしかったな」となったとき、AI側の判断がおかしかったのか送信スクリプト側の問題なのか、ログを見るだけで切り分けられるのも地味に助かっています。


無人実行だからこその権限設計

Routineの実行は、普段のインタラクティブなセッションと違って承認プロンプトが一切出ません。設定したコネクタの権限の範囲で、完全に自律的に動きます。つまり「怪しい操作の直前に人間が止める」という最後の砦がない前提で、権限を考える必要があります。

なので、繋ぐコネクタと許す操作は、動かす前にできるだけ絞り込みました。

コネクタ 用途 許す操作
カレンダー 今日・明日の予定を読む/確実な予定だけ登録 読み取り+作成のみ(変更・削除は禁止)
メール 直近の受信を要約に使う 読み取りのみ(送信・下書き・ラベル変更は禁止)

「読み取りだけで十分なはずの用途」に、うっかり書き込み系のスコープまで持つコネクタを繋いでしまうと、無人実行中はそれを止める手立てがありません。繋ぐコネクタは「その朝刊に本当に必要な最小セット」まで絞っておくのをおすすめします。

カレンダーへの自動登録も、日時がはっきり書いてある確実な情報だけに限定していて、曖昧なものは本文中に「追加候補」として出すだけにしています。判断が怪しいものを機械的に確定させない、というのも無人実行では大事な線引きです。


地味だけど刺さった落とし穴

許可ドメインに入れても403で弾かれることがある

検索自体は通っても、原典ページの取得(WebFetch)は許可ドメインの外だと弾かれます。ここまでは想定内だったんですが、許可ドメインに追加しても、サイト側のボット対策でずっと弾かれ続けるケースがありました。特に交通系・地図系のサイトはボット遮断がわりと厳しい印象で、この手のサイトから情報を取りたい場合は、許可ドメインに入れるだけでは解決しないこともある、と知っておくと調査の時間を節約できると思います。

CIが緑でも「成功」とは限らない

GitHub Actionsの実行結果が緑でも、それは「インフラ的なエラーなく終わった」ことしか意味しません。AIの判断ミスで本文がスカスカだったり、そもそも送るべき内容がなかったりしても、ワークフロー自体は正常終了扱いになります。成否は、リポジトリにその日のログファイルが増えたかどうかで判断する、くらいに割り切ったほうが運用が楽です。


記憶を持たせるときのチェックリスト

このパターンは朝刊に限らず、Routine全般に使えると思っています。何かをリポジトリに永続化しようとするとき、次の4つを自分に聞くと、設計がそんなにブレなくなります。

  1. その情報は、次回の実行に本当に必要か? 必要ならリポジトリへ。いらないなら書かない
  2. 誰が更新する情報か? 人間が変えるものとAIが変えるものは、最初からファイルレベルで分けておく
  3. その処理は、やり直しがきかない一発勝負か? きかないなら、AIに直接やらせず決定論的なスクリプトに逃がす
  4. 無人実行中にこの権限が暴走したら、最悪何が起きるか? 起きてほしくないなら、書き込み権限は最初から渡さない

まとめ

  • Routineはステートレス。記憶が欲しいなら、リポジトリへのコミットとして自分で設計するしかない
  • 記憶は「人間が書く設定」と「AIが書く作業記憶」を分けると事故が減る
  • 「考える」と「外部に送る」は工程として分けて、取り返しのつかない操作は決定論側に寄せる
  • 無人実行では承認プロンプトが出ないので、コネクタの権限は動かす前に最小化しておく

同じような「毎朝◯◯する」系のRoutineを組む人の参考になれば嬉しいです。


参考

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?