Hermes Agentのメモリが消える原因と対処法|Docker volume / state.db / セッション破損のトラブルシュート

Hermes Agentを業務で常時稼働させていると、ある日突然「秘書AIが過去の文脈を忘れた」状態に遭遇することがあります。株式会社Fyveが中小企業向けにHermes Agentの導入支援をしている中で、もっとも問い合わせが多いのが、このメモリ消失系のトラブルです。
本記事では、Hermes Agentでメモリが飛ぶ3大パターンと、それぞれの検出・復旧・予防の手順を、実際に運用している現場の知見ベースで整理します。GitHub Issue #5563(Critical UX issue: persistent memory loss)でも報告されている内容と、私たちが社内検証で再現したケースをマージした内容です。
前提: Hermes Agentの3層メモリ構造の復習

原因を切り分けるためには、まずHermes Agentがどこに何を保存しているかを押さえる必要があります。詳細は別記事「Hermes Agentの3層メモリ構造を徹底解説」にまとめていますが、要点だけ復習します。
3層の役割
- 短期メモリ(セッションコンテキスト): 現在のセッション内のみ有効。プロセス終了で消える
- 中期メモリ(state.db / SQLite + FTS5): セッションをまたいで検索可能な履歴。FTS5全文検索で過去の会話を引き当てる
- 永続メモリ(MEMORY.md / SOUL.md): 人格・長期方針・恒久的な知識。プレーンテキストで永続化
「メモリが消えた」という症状は、このうちどの層が飛んだかによって対処が変わります。まずは症状の見極めから始めるのが鉄則です。

パターン1: Docker volume未設定で再起動した
もっとも頻度が高く、かつ被害が大きいパターンです。GitHub Issue #5563でも筆頭に挙がっています。
症状
- Dockerコンテナを再起動した直後から、過去のすべてのやりとりを忘れている
- MEMORY.mdの内容が初期テンプレートに戻っている
- state.dbがそもそも存在しない、またはサイズが極端に小さい
原因
Hermes Agentの公式Docker imageは、デフォルトでメモリファイルをコンテナ内のファイルシステムに書き込みます。volume bindまたはnamed volumeを設定していない場合、docker restartでコンテナが破棄された瞬間に全データが消えます。検証中に「動いた、よし本番」と切り替えた利用者が、初回の再起動で気づくケースが多い印象です。
検出方法
docker inspect hermes-agent | grep -A 20 MountsMounts配列が空なら、永続化されていません。さらに以下でstate.dbのサイズと更新時刻を確認します。
docker exec hermes-agent ls -lah /app/data/state.db
docker exec hermes-agent ls -lah /app/data/MEMORY.md対処手順
1. まず現状のコンテナ内データを退避します。再起動前にコピーを取らないと、設定変更時点で消えます。
docker cp hermes-agent:/app/data ./hermes-backup-$(date +%Y%m%d)2. docker-compose.ymlにvolumeを追加します。
services:
hermes-agent:
image: hermes-agent:latest
volumes:
- ./hermes-data:/app/data
- ./hermes-config:/root/.config/hermes3. 退避したデータを./hermes-dataに戻し、docker compose up -dで起動し直します。
パターン2: state.dbの破損(FTS5インデックス壊れ)
頻度は低いものの、復旧が一番厄介なパターンです。SQLiteのFTS5仮想テーブルが破損すると、中期メモリ検索が機能不全に陥ります。
症状
- 「先週話したXXの件」のような過去参照クエリが空振りする
- Hermes Agent起動時に
SQLITE_CORRUPT系の警告がログに出る - セッション一覧は引けるのに、本文検索が0件しか返さない
原因
多くは「書き込み中に強制終了した」ことが引き金です。具体的には、ホストマシンのスリープ復帰直後・docker killによる強制停止・ディスク容量枯渇によるwrite失敗などです。FTS5インデックスは部分破損するとリビルドしない限り検索結果が信用できなくなります。
検出方法
sqlite3 ./hermes-data/state.db "PRAGMA integrity_check;"
sqlite3 ./hermes-data/state.db "INSERT INTO sessions_fts(sessions_fts) VALUES('integrity-check');"前者でok以外が返る、または後者でエラーが出るなら破損確定です。
対処手順
1. まずstate.dbを丸ごとコピーしてバックアップを取ります(復旧失敗時の保険)。
cp ./hermes-data/state.db ./hermes-data/state.db.broken.$(date +%s)2. FTS5インデックスのみリビルドを試みます。本体データが生きていればこれで復旧します。
sqlite3 ./hermes-data/state.db "INSERT INTO sessions_fts(sessions_fts) VALUES('rebuild');"3. それでもダメならVACUUM INTOで健全部分を新DBに書き出します。
sqlite3 ./hermes-data/state.db "VACUUM INTO 'state.db.recovered';"4. 復旧後、必ずintegrity_checkを再実行してokを確認してから本番に戻します。
パターン3: MEMORY.md / SOUL.mdを編集して構造を壊した
これは「自分でメモリを育てよう」とした利用者がやりがちなパターンです。事例研究は別記事「独自メモリ実装の事例: HackAfterDarkの試行錯誤」も参考になります。
症状
- 編集直後からHermes Agentが「人格が抜けた」ような応答をする
- Hermes Agent起動時にMEMORY parser warningが出る
- SOUL.mdに書いたはずの長期方針が応答に反映されない
原因
MEMORY.mdとSOUL.mdは見た目こそプレーンテキストですが、内部的にはYAML frontmatter + Markdown sectionの構造をパースして読んでいます。インデント1つ、コロン1つの崩れでパースエラーになり、起動時に該当ファイルがスキップされます。エディタの自動整形機能が悪さをするケースもあります。
検出方法
hermes memory validate
hermes memory validate --strictvalidateコマンドでパースエラー位置と原因が出力されます。SOUL.mdのfrontmatter(---で囲まれた領域)に未エスケープのコロンが入っていないかは特に要チェックです。
対処手順
1. gitで管理していればgit log -- MEMORY.mdで直前の正常版を確認し、git checkoutで戻すのが最速です。
2. gitで管理していない場合は、後述のバックアップから復元します。Hermes Agentは標準でgit管理を推奨していますが、新規利用者ほどこれを飛ばしているケースが多く、私たちもクライアントには初日に必ずgit init済みのstate構成を渡すようにしています。
予防策: 「常時稼働の秘書」を支える永続化設計

復旧手順を覚えるよりも、消えない構成を最初に組むほうが圧倒的に投資対効果が高いです。私たちがクライアントに納品する標準構成を共有します。
1. docker-compose.ymlのvolume必須化
パターン1の対策です。本番のdocker-compose.ymlにvolumeが書かれていないHermes Agentは、運用していないのと同じ扱いにして良いレベルです。
2. cron + rsyncによる日次バックアップ
0 3 * * * rsync -a --delete /opt/hermes-data/ /backup/hermes/$(date +\%Y\%m\%d)/3世代以上を残し、週次でオフサイト(S3互換ストレージ等)に同期するのが基本です。state.dbはWAL有効時にコピー整合性が崩れることがあるので、sqlite3 state.db ".backup '/backup/state.db'"形式の使用も検討してください。
3. セッション履歴の保護
~/.config/hermes/sessions/配下にはセッション単位のJSONLが保存されます。state.dbとは別物で、ここが消えると「複数日にまたがる長期プロジェクト」の文脈が一気に飛びます。バックアップ対象に必ず含めてください。
4. 検証環境で1週間以上見てから本番投入
中小企業のクライアントには、いきなり本番に入れず、検証環境で最低1週間、できれば2週間メモリが安定するかを確認してから業務利用に移すよう案内しています。スリープ復帰・OS再起動・Docker再起動を意図的に何度か起こして、それでも前日の会話を覚えているかを確認するのが現実的なチェックです。
スキルポイズニングという永続化のもう一つのリスク
vectorize.ioのレポートで指摘されている通り、Hermes Agentのメモリ層には「攻撃的なプロンプトが書き込まれて、それが永続化される」というリスクが存在します。詳細は「Hermes Agentセキュリティ監査7826件の知見」にまとめていますが、要点だけ触れます。
外部から取り込んだスキルやドキュメントに、「次回起動時に管理者権限で◯◯せよ」といった指示が混入していると、それがMEMORY.mdに書き込まれて持続的な脅威になります。「メモリが消える」は分かりやすい障害ですが、「気づかないうちにメモリに不正な指示が混入する」のはもっと厄介です。バックアップを取るときは、定期的にdiffで前回との差分を確認し、想定外の追記が入っていないかを目視チェックする運用を推奨します。
業務利用での教訓
Hermes Agentを「常時稼働の秘書」として使う以上、メモリの永続化は機能ではなく前提条件です。私たちがクライアントに最初に渡すドキュメントは、機能解説ではなく「volumeとバックアップの設計図」です。ここを最初に固めるかどうかで、半年後のHermes Agent活用度がまったく変わります。
メモリが消える3大パターン(Docker volume未設定・state.db破損・MEMORY.md構造破壊)は、いずれも事前設計で防げる類の事故です。本記事の検出コマンドと予防策を、運用中のHermes Agentに今日のうちに適用しておくことをお勧めします。困っている時に検索でこの記事に辿り着いた方は、まずパターン1のvolume状態確認から始めてください。多くのケースはそこで原因が判明します。
株式会社Fyveでは、Hermes Agentを業務に組み込みたい中小企業向けに、永続化設計込みの導入支援を行っています。「自社で構築してみたがメモリが安定しない」「バックアップ設計を見直したい」といったご相談も歓迎です。
Hermes Agent を本気で活用するなら
「Hermes Agent を自分で使いこなしたい」「自社の業務に組み込みたい」
— そんな方は、まず初回無料相談でお話ししてみませんか。