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?

「ドメイン移管が失敗した理由を調べて」を Discord に投げてAIにやってもらう

1
Last updated at Posted at 2026-08-31

「ドメイン移管が失敗したので、原因を調べて」

外出先でこれを投げたいとき、どこに投げるか。

ChatGPT に投げると、一般論は返ってきます。ただ whois を実際に叩いて、移管元が何を理由に弾いたのかまで特定してくることは期待しにくいです。手が無いからです。

Claude Code なら手はあります。ただし PC の前に座ってターミナルを開く必要があります。

そして、どちらで調べても結果は自分の画面の中で閉じます。チームでやっているなら、そこからもう一度共有し直すことになります。

私はこれを Discord に投げています。OpenClaw が受けて、自宅のマシンでコマンドを打ち、結果をそのスレッドに書きます。この記事は、なぜその形にしているのかという話です。

実際にこの調査で何が必要だったか

さっきのドメイン移管の件、エージェントが出してきた結論はこれでした。

移管リクエストがレジストリに受理されていない。受理されれば必ず約5日間 pendingTransfer が付く。それが一度も無い=レジストラが投げた EPP transfer request が即時拒否された(典型は EPP 2202 Invalid authorization information)。

そこに至るまでに踏んだ手順です。

  1. レジストリの WHOIS(whois.verisign-grs.com)を引いて Domain Status: ok を確認。ロックは解除済み
  2. Updated Date がロック解除の瞬間から1秒も動いていないことに気づく
  3. 毎時実行の監視 cron を仕掛けて、31時間ぶんのログを取る
  4. その31時間、一度も pendingTransfer になっていないことを確認
  5. レジストラ側の WHOIS(whois.porkbun.com:43)に接続を試みるが拒否、RDAP エンドポイントも見つからず、「ここから先は管理画面を目で見るしかない」と判断
  6. レジストラ提示のチェックリスト(ロック未解除 / 期限切れ / 60日ルール / 承認メール期日切れ)を1つずつ実測で潰し、残る候補を2つに絞る

ポイントは 3番目 です。「監視を仕掛けて31時間待つ」は、チャット UI に手が無いと成立しません。ChatGPT に「1時間おきに whois を叩いて状態変化を教えて」と頼んでも、その cron はどこにも存在しません。

そして 6番目。「ロックは解除済みだから、この候補は消える」という消去法は、実測値がないと書けません。推測で候補を並べるだけなら誰でもできますが、それは調査ではなく作文です。

Claude Code ならこれは全部できます。私も普段は使っています。ただこの件、私は外にいました。

OpenClaw とは

OpenClaw は、Discord・Slack・Telegram・LINE・iMessage といったメッセージングチャネルと AI エージェントをつなぐ、セルフホストのゲートウェイです1。非営利の OpenClaw Foundation が開発していて、ライセンスは MIT です。

エージェント本体はクラウドではなく自分のマシンで動きます。なので git も DB も Prometheus も、ローカルにあるものはそのまま触れます。チャネルは入口として被せるだけ、という構造です。

ここから、実際に使い分けている理由を順に書きます。

理由1: コマンドが打てる

ChatGPT や Claude のアプリで詰まるのは、たいてい「実測しないと判定できないこと」を頼んだときです。冒頭のドメイン移管がまさにそれで、必要なのは知識ではなく whois の出力でした。

OpenClaw でツールを解放しておくと、エージェントは Bash を持ちます。tools.profile: "coding" を入れるだけです2。あとは普通のシェルなので、whois でも curl でも gh でも psql でも動きます。

実際に外から投げて返ってきたものの例です。

  • 本番 DB(Supabase)の全面バックアップ。roles.sql / schema.sql / データに加えて、Storage の実ファイル 2,100件・約 2.77GB まで
  • GA4 を引いて「直近5日の本番セッションが全部 Direct、engaged もほぼゼロ、国の散らばり方からしてボット中心」という判定
  • Google Search Console のサイトマップ登録状況の確認
  • Google Ads の予算・入札のガードスクリプトの運用

どれも API キーとコマンドがあれば済む話です。逆に言うと、API キーとコマンドが無いと1つもできません。 ここが最初の分かれ目になります。

理由2: PC の前にいなくても打てる

Claude Code には手があります。ただし起動するのに PC が要ります。

OpenClaw は Gateway が常駐しているので、入口が Discord のメンションになります。移動中でも、寝る前でも、外で飯を食っているときでも投げられます。私の場合、思いつくタイミングと PC の前にいるタイミングが噛み合わないので、ここが効きました。

さらに、常駐しているということは こちらが話しかけていないときにも動ける ということでもあります。私は15分ごとに自分のターンを起こす cron を1本置いていて、寝ている間も動いています。

やっている中身はこうです。

  1. 使用率ゲートを叩く(後述)。SKIP なら何もせず終わる
  2. 作戦盤(PLAN.md)と決定台帳(DECISIONS.md)を読む
  3. open な PR を確認して、CI 全緑・コンフリクト無しならマージする
  4. 手が空いていれば次のタスクを起票して投げる
  5. 報告は原則しない(NO_REPLY を返して黙る)

5番目が肝です。15分ごとに報告されたら通知地獄になるので、報告してよい条件を4つ(本番が壊れた / お金が出ていく判断 / 外部への連絡 / 法務)だけに絞っています。それ以外は自分で決めて PLAN.md に書いて黙って進める、というルールです。

ある1日のログから、実際にこのループがやっていたことを拾うと、

  • CI 8本の head_sha が PR の head と一致していることまで確認してから PR をマージ、develop → main のリリースまで実行
  • リリース後に本番 URL を叩いて壊れていないか確認
  • レビュアーとワーカーの主張が食い違ったので、どちらも信じずに再実測を指示して決着
  • 起票しかけた作業について「もう実装済みではないか」を先に grep で確認したら実装済みで、発注を取りやめ(ワーカーのセッション1本ぶん、実測で約 $6 が浮きました)

理由3: チームに共有しなくても、チームと文脈が共有されている

ここが一番でかいと思っています。

ChatGPT でも Claude Code でも、やりとりは自分の画面の中で閉じます。チームで動いているとき、その中身は必ずどこかで共有し直すことになります。要約して貼る、スクショを撮る、口で説明する。この工程は AI を使う量に比例して増えます。

OpenClaw をチームがいる Discord サーバーに置くと、ここが丸ごと消えます。人も Bot も同じ場所を読んでいるからです。

  • 私がスレッドで投げた指示は、そのままチームにも見えている
  • エージェントの回答も、そのままチームにも見えている
  • 逆に、チームメンバーがスレッドで話したこともエージェントが読める

「さっき AI に聞いた話」を人に説明し直す、という工程が要りません。共有するのではなく、最初から共有された場所で作業している という違いです。

設定としては、サーバー横断で入れておくのが効きます。

"guilds": {
  "*": {
    "requireMention": true,
    "roles": ["<許可するロールID>"]
  }
}

"*" にすると、チャンネルを増やすたびに設定を足す必要がなくなります。新しく立てたスレッドでいきなり相談できる、というのが実運用ではかなり大きいです。当然リスクは上がるので、requireMention: true でメンション時だけ反応させ、roles で開放範囲を絞っています。

加えて tools.sessions.visibility: "all" を入れると、別スレッドで何が起きているかをエージェントが横断的に読めます2。複数の作業が並行しているとき、片方のスレッドで「あっちはどうなってる?」と聞けば答えます。

理由4: 記憶の仕組みを自分でいじれる

ChatGPT も、過去のやりとりを踏まえた前提つきで答えてはくれます。ただしそれは自動で管理されていて、中の仕組みには手が入りません。 何を覚えているのか、なぜそれを思い出したのか、いつ忘れるのかが見えません。

OpenClaw の記憶は全部ファイルと設定です。

  • 何を覚えるか — memory/YYYY-MM-DD.md(日次の生ログ)と MEMORY.md(選別済み)に分かれていて、書き方は AGENTS.md に自分で書きます
  • どこから引くか — memory.search.sources で memory と sessions を選べます。sessions を入れると Discord のログそのものが検索対象になります
  • どう引くか — 埋め込みプロバイダを選べます。OpenAI・Gemini・Voyage・Ollama・LM Studio、そして API キー不要のローカル(llama.cpp)まで3
  • いつ忘れるか — 日付付きの日次メモは30日半減期で減衰し、MEMORY.md のような選別済みファイルは減衰しません。この式は公開されています4

私はローカル埋め込みにしています。常駐させると記憶ファイルは毎日増えるので、インデックス更新のたびに API 課金が乗るのは相性が悪いのと、中身が業務の生データそのものなので外に出さずに済むならそのほうがいい、という2点です。

そのうえで、sessions をソースに入れて Discord の発言を検索対象にしてあるので、「あのとき決めたやつ」と聞けば当時のスレッドから拾ってきます。ここが ChatGPT の記憶と一番違うところで、拾ってくる元が自分たちの Discord そのもの です。

夜間には dreaming という機能が走って、短期の記録を長期記憶へ昇格させます5。昇格した項目には出典(ファイル名と行番号)が付くので、後から「なぜこれを覚えているのか」を辿れます。仕組みも閾値も設定ファイルに書いてあります。

技術的な設定は記事の後半にまとめます。

理由5: 開発エージェントと繋がる

もう1つ、これは私の環境固有の話です。

OpenClaw とは別に、C-lord という自作の OSS を同じ Discord サーバーに置いています。Discord のスレッドごとに Claude Code セッションを立てて、それぞれを git worktree に隔離し、共有ラウンジ経由で互いに衝突しないよう調整する、というものです(MIT・claude-code-discord-bridge がベースです)。

つまりこうなっています。

OpenClaw 側は、スレッドを立てて発注文を流し、返ってきた PR をマージするかどうかを判断します。実際の発注はスクリプト1本にまとめてあって、チャンネルには短い1行だけ残し、詳細は立ったスレッドへ投げる形にしています。

重要なのは、この一連が全部 Discord 上で起きている ことです。だから OpenClaw は開発側の文脈を知った状態でいられます。私が「あの件どうなった?」と聞けば、開発側スレッドの結果を汲んだうえで答えが返ってきます。私がスレッドを1つずつ開いて読み、要約して OpenClaw に貼り直す、という作業は要りません。

理由3と同じ話が、人だけでなくエージェント同士にも効いている、という形です。


ここから下は設定まわりです。

openclaw.json の要点

設定は $OPENCLAW_CONFIG_DIR/openclaw.json です。全体は Configuration にあるので、ここでは実運用で効いたところだけ書きます。

インスタンスを分ける

設定ディレクトリとポートを変えるだけです。

export OPENCLAW_CONFIG_DIR=$HOME/.openclaw-pm
openclaw gateway --port 23789

私は用途とモデルを変えて何本か立てています。

用途 モデル thinkingDefault
事業まわりの判断と自律ループ Claude Opus max
込み入った調査・切り分け Claude Opus xhigh
ちょっとした調べもの Claude Sonnet minimal
セカンドオピニオン OpenAI Codex —
上限に達したときの退避先 Gemini Flash(無料枠) —

Discord Bot をインスタンスごとに作るので、Discord 上では別 Bot として並びます。同じ質問を別モデルに投げて突き合わせるのが楽なので、この形に落ち着きました。

ただし インスタンスを分けても Claude のサブスク枠は共有 です。分けても capacity は増えません。並列度を上げる目的で増やしても、ホストの負荷が上がるだけでした(実際に一度ホストを落としました)。1インスタンス内で役割を分けたいだけなら agents.entries で分けるほうが素直です6。

ツールの解放範囲

{
  "tools": {
    "profile": "coding",
    "alsoAllow": ["message"],
    "web": {
      "search": { "enabled": true, "provider": "duckduckgo" }
    },
    "sessions": { "visibility": "all" }
  }
}
  • tools.profile — ツールのベース許可セット。coding で Bash やファイル操作系が入ります。理由1で書いた「手」はこれです
  • tools.alsoAllow — プロファイル外を個別に足す。message を足すと、エージェント自身が別チャンネルへ投げられます
  • tools.web.search — API キー不要の duckduckgo が手軽です。これが無いエージェントは、詰まったときに手詰まりになります
  • tools.sessions.visibility — 他セッションの参照範囲。既定は tree で、all にすると横断的に読めます

エージェントの挙動

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "anthropic/claude-opus-5",
        "fallbacks": ["anthropic/claude-sonnet-5"]
      },
      "modelPolicy": {
        "allow": ["anthropic/claude-sonnet-5", "anthropic/claude-opus-5"]
      },
      "workspace": "/home/yousan/.openclaw-pm/workspace",
      "thinkingDefault": "max",
      "timeoutSeconds": 1800,
      "maxConcurrent": 16,
      "subagents": { "maxConcurrent": 8, "archiveAfterMinutes": 60 },
      "contextPruning": { "mode": "cache-ttl", "ttl": "1h" },
      "heartbeat": { "every": "1h" },
      "compaction": { "mode": "safeguard" }
    }
  }
}
  • model.fallbacks — 主モデルが上限や障害で落ちたときの退避先。常駐させるならほぼ必須です
  • modelPolicy.allow — 使えるモデルの明示的な許可リスト。事故で高いモデルを踏まないための蓋です
  • thinkingDefault — off 〜 max。役割ごとに変えます
  • timeoutSeconds — 1ターンの上限。重い調査をさせるなら 1800 秒くらい要ります
  • contextPruning — cache-ttl にするとプロンプトキャッシュの TTL に合わせて刈ります
  • compaction.mode — safeguard は溢れそうなときだけ動きます

Discord チャネル

{
  "channels": {
    "discord": {
      "enabled": true,
      "token": "<bot token>",
      "groupPolicy": "open",
      "allowFrom": ["<自分の Discord ユーザーID>"],
      "guilds": {
        "*": { "requireMention": true, "roles": ["<許可するロールID>"] }
      },
      "replyToMode": "off",
      "autoPresence": { "enabled": true },
      "streaming": {
        "progress": { "narration": false, "maxLines": 3, "maxLineChars": 100 }
      }
    }
  },
  "commands": {
    "ownerAllowFrom": ["discord:<自分の Discord ユーザーID>"]
  }
}

権限まわりが紛らわしいので整理しておきます。

  • allowFrom — このチャネルでエージェントに話しかけられるユーザー
  • guilds.*.requireMention — サーバー全体で有効にしつつ、メンションされたときだけ反応させる
  • guilds.*.roles — 特定ロールを持つ人だけに開放する
  • commands.ownerAllowFrom — /restart などオーナー限定コマンドを打てる人。allowFrom とは別物です

通知を鳴らすのは1ターンに1回だけ

常駐させると必ずぶつかるのが通知です。途中経過のたびに鳴ると、「呼ばれた」と思って開くのに中身がありません。かといって全部切ると完了に気づけません。

replyToMode を off にすると発言が引用返信になりません7。引用返信でなければ通知も飛ばないので、何もしなければ全部「独り言」 になります。そのうえで、最終回答の本文先頭に [[reply_to_current]] を置いたときだけ引用返信になります8。このタグは送信前に取り除かれるので表には出ません。

AGENTS.md にはルールだけでなく理由も書いています。

理由: 途中経過で通知が鳴ると「呼ばれた」と思って見に行くのに中身が無い。
逆に完了は静かに終わるので気づけない。鳴らすタイミングを完了の1回に集約する。

理由が書いてあると、明記していないケースに当たったときに正しく類推します。ルールだけ書いていた頃は、中間報告にもタグを付けてきていました。

プレゼンスに状態を出す

autoPresence を使うと、稼働状況が Discord のプレゼンス(オンライン / 退席中 / 取り込み中)にマップされます9。文言も上書きできます。

"autoPresence": {
  "enabled": true,
  "intervalMs": 60000,
  "minUpdateIntervalMs": 15000,
  "healthyText": "稼働中 🔧",
  "degradedText": "⚠️ 接続/動作が不安定 ({reason})",
  "exhaustedText": "⛔ Claude上限到達 — 復活待ち(5時間枠/週次で変動)"
}

これを入れる前は、返事が来ないときに「落ちてるのか、上限なのか、単に長考しているのか」を確かめるために毎回ログを見に行っていました。いまはメンバー一覧を見れば済みます。チームで使っているなら、他のメンバーにも状態が見えるという意味もあります。

AGENTS.md に何を書くか

ワークスペース直下の AGENTS.md は起動時のコンテキストとして読まれます10。運用ルールの本体はここです。効いたものを挙げます。

記憶の書き方

## Memory

あなたは毎セッション、まっさらな状態で目を覚まします。以下が連続性です。

- **日次メモ:** `memory/YYYY-MM-DD.md` — 何が起きたかの生ログ
- **長期記憶:** `MEMORY.md` — 選別済みの記憶

### 書き留めること

「頭の中のメモ」はセッション再起動を生き延びません。ファイルは生き延びます。

- 「これ覚えといて」と言われた → `memory/YYYY-MM-DD.md` を更新する
- 教訓を得た → `AGENTS.md` か該当スキルを更新する
- 失敗した → 未来の自分が繰り返さないように書き残す

「失敗したら書き残す」を明示しておくと、自分の失敗をかなり素直に記録します。

既存解の事前チェック

## Existing Solutions Preflight

独自のシステム・機能・ツール・連携・自動化を提案または構築する前に、
すでにそれを十分に解決している OSS・メンテされているライブラリ・
既存の OpenClaw プラグイン・無料のプラットフォームがないか短く確認すること。

これを入れる前は、張り切って車輪の再発明をしがちでした。1段落で抑制されます。

グループでいつ黙るか

**話すとき:** 直接メンションされた/質問された、本当に価値を足せる、
重要な誤情報の訂正、頼まれた要約。

**黙るとき:** 人間同士の雑談、すでに誰かが答えた、
返答が「そうですね」程度にしかならない、会話が問題なく流れている。

チームのサーバーに常駐させるなら必須です。全メッセージが見えている状態で、全部に反応されると邪魔になります。

cron(automations)で自律ループを組む

OpenClaw の cron は「エージェント自身のターンを起こす」形をとります11。ジョブの実体は、間隔・プロンプト・許可ツール・配信先のセットです。

{
  "name": "pm-loop",
  "enabled": true,
  "schedule": { "kind": "every", "everyMs": 900000 },
  "pacing": { "min": "10m", "max": "6h" },
  "sessionTarget": "current",
  "payload": {
    "kind": "agentTurn",
    "message": "PMループ。……(手順書本文)",
    "timeoutSeconds": 900,
    "toolsAllow": ["automations", "sessions", "terminal", "message", "..."]
  },
  "delivery": {
    "mode": "announce",
    "channel": "discord",
    "to": "channel:<チャンネルID>"
  }
}

引っかかったのは3点です。

sessionTarget: "current" にするとループが既存の会話セッションの続きとして走ります。 これで Discord で私が話した内容がループにも見えます。切り離したければ別セッションにします。

手順書は cron の payload 側に書きます。 運用ルールを PLAN.md にだけ書いて payload を直し忘れ、17時間ぶんループの挙動が変わらなかったことがあります。payload に書いてある文章がループの本体です。

automations ツールを許可しておくと、エージェントが自分で次回実行を先送りできます。 後述の使用率ゲートはこれと組み合わせて成立しています。

使用率ゲート

自律ループの実害は、放っておくと枠を食いつぶすことです。ループの冒頭に、起動可否だけを判定するシェルスクリプトを挟んでいます。

# 出力は1行だけ: "GO <理由>" / "SKIP <interval> <理由>"
$ ~/.openclaw/workspace/bin/pm-gate.sh
GO 5h 15% / 7d 71%

SKIP が返ったら、automations ツールで次回チェックを先送りして NO_REPLY だけ返して終わります。

最初は ccusage の値を使っていたのですが、これは失敗でした。ccusage が出すのは「過去実績の最大値を100%とした相対値」で、分母の窓集合に直近7日自身が含まれるため、使用量が伸びている限り7日値が永久に100%へ張り付きます。閾値をいくら上げても SKIP し続けました。実測すると、旧指標が 5h 9% / 7d 100% と言っているときの実際の値は 5h 23% / 7d 76% でした。加えて2回の呼び出しに最大300秒かかっていて、それだけでループが1本潰れます。

いまはプランの実使用率(絶対値)を自前で Prometheus に出しています。Claude Code の OpenTelemetry には レートリミットの使用率を表すメトリクスが無い12 ので、ccstatusline のステータスライン出力(Session: xx% / Weekly: xx%)を5分ごとにパースして、Prometheus のテキストファイル形式で書き出しています。

# HELP claude_code_rate_limit_used_percentage Rate limit percentage used
# TYPE claude_code_rate_limit_used_percentage gauge
claude_code_rate_limit_used_percentage{window="five_hour"} 69
claude_code_rate_limit_used_percentage{window="seven_day"} 54

メトリクス名は自作です。リセット時刻も同じ経路で取れるので、「あと何時間で戻るか」もゲートの判断材料に使えます。

罠: cron + toolsAllow でツールがゼロになる

これは丸1日溶かしました。

automations ツールで cron を作ると、自動で toolsAllow が付きます(toolsAllowIsDefault: true)。そして toolsAllow が付いたランは「制限付きラン」になります。ドキュメントにはこう書かれています13。

Restricted runs such as cron jobs with toolsAllow require an exact backend-owned translation. The bundled claude-cli backend disables Claude's native tools and user, project, and local customizations, including hooks, plugins, agents, skills, and CLAUDE.md. … Backends without an exact translation still fail closed.

claude-cli バックエンドは、制限付きランでは Claude 側のネイティブツール(Bash / Read など)を全部無効化して、代わりに OpenClaw 側のツールを loopback MCP 経由で渡す設計です。この翻訳が成立しないと fail closed、つまりツールゼロで起動 します。

「cron を作ったら、そのジョブだけ何もできない」という症状が出たらここを疑ってください。cron ブロックは strict で、このツールキャップを外すような設定キーは存在しません14。ジョブ定義側の toolsAllow を直すのが対処になります。

メモリ: ローカル埋め込みと dreaming

理由4で書いた「記憶を自分で組める」の具体です。

ローカル埋め込みに切り替える

OpenClaw には公式の llama.cpp プロバイダプラグインがあり、API キーなしのローカル埋め込みに切り替えられます3。

openclaw plugins install @openclaw/llama-cpp-provider
{
  "memory": {
    "search": {
      "enabled": true,
      "provider": "local",
      "sources": ["memory", "sessions"],
      "rememberAcrossConversations": true,
      "cache": { "enabled": true },
      "experimental": { "sessionMemory": true }
    }
  },
  "plugins": {
    "allow": ["memory-core", "llama-cpp", "active-memory"],
    "entries": {
      "llama-cpp": { "enabled": true, "config": {} },
      "active-memory": { "enabled": true, "config": {} },
      "memory-core": { "config": {} }
    }
  }
}

provider: "local" にすると GGUF モデル(約 0.6GB)が自動でダウンロードされ、埋め込み専用のワーカープロセスが立ちます。ps で見るとこれです。

node .../openclaw/dist/memory-core-local-embedding-worker.js

Gateway 本体とは別プロセスで常駐します。sources に sessions を入れているのがポイントで、これで Discord のログそのものが検索対象になります。

検索はベクトル + BM25

memory_search はベクトル検索と BM25 キーワード検索を並列に走らせてマージします3。

これは実用上そこそこ効きます。エラー文字列・設定キー名・Issue 番号のような「そのままの文字列」は BM25 が拾い、「あのとき決めたやつ」みたいな曖昧な言い回しはベクトルが拾います。片方だけだと必ずどちらかを取り落とします。

ランキングは決定論的です。

hybrid relevance × recency decay × importance multiplier

日付付きの日次メモは30日半減期で減衰し、MEMORY.md や USER.md のような選別済みファイルは減衰しません。古い生ログは自然に沈み、選別された記憶は沈まない、という設計です。Generative Agents 論文の relevance / recency / importance を、クエリ時のモデル呼び出しなしで実装したものだと明記されています4。

この式が公開されていること自体が、私にとっての選択理由です。 思い出し方が気に入らなければ、減衰も重みも自分で変えられます。

dreaming — 夜間に記憶を組み直す

memory-core には dreaming という機能があり、既定で毎日 3:00 に走ります5。睡眠の段階になぞらえた3フェーズです。

フェーズ やること MEMORY.md へ書くか
Light 直近の短期記憶・日次メモ・セッション記録を仕分けして候補を staged にする いいえ
REM テーマや繰り返し出てくる概念を要約する いいえ
Deep 候補をスコアリングして、閾値を越えたものだけ昇格させる はい

Deep のランキングは6つの重み付きシグナルです。

シグナル 重み 内容
Relevance 0.30 平均的な検索ヒット品質
Frequency 0.24 短期シグナルの蓄積量
Query diversity 0.15 何種類の文脈で浮上したか
Recency 0.15 時間減衰つきの新しさ
Consolidation 0.10 複数日にまたがる再出現の強さ
Conceptual richness 0.06 概念タグの密度

実際の出力(memory/dreaming/light/2026-08-26.md)はこうなっています。

# Light Sleep

- Candidate: 発注前に自分で実測した2件(ワーカーに探させない): …
  - confidence: 0.62
  - evidence: memory/2026-08-25.md:110-113
  - recalls: 0
  - status: staged

候補に evidence: としてファイル名と行番号が付くのが良くて、昇格した記憶を後から辿れます。昇格の受け入れ条件も厳しめです5。

  • 既存エントリを一定割合以上失わないこと(既定 0.25)
  • 昇格した候補すべてに Source: path#Lx-Ly の参照が含まれること
  • ファイルサイズ予算に収まること

書き換え前の MEMORY.md は SQLite に保存されるので、変な書き換えが入っても戻せます。長期記憶ファイルを AI に自動で書き換えさせるという操作を、監査可能かつ可逆にしてあるのは実用的だと思います。この設計は sleep-time compute の研究(arXiv:2504.13171)を参照していると明記されています15。

なお、うちの Deep は昇格0件の日がそこそこあります。

# Deep Sleep

- Repaired recall artifacts: rewrote recall store.
- Ranked 0 candidate(s) for durable promotion.
- Promoted 0 candidate(s) into MEMORY.md.

閾値(minScore / minRecallCount / minUniqueQueries)を全部通らないと昇格しないので、こうなります。recalls: 0 の候補が並んでいるのは、staged した内容が一度も検索で引かれていないということなので、ここは調整の余地がありそうです。

セッション横断の記憶

rememberAcrossConversations: true を入れると、同じエージェントの他のプライベート会話から関連する断片を引けます16。境界は固定で、緩められません。

  • プライベート DM 同士は互いに参照できる
  • グループ・チャンネルは参照元にも参照先にもならない
  • 他のエージェントの記録は対象にならない

チームのサーバーに置いている以上、ここが固定されているのは重要です。1対1で話した内容がグループに漏れる経路が仕様として塞がれています。

そのほか

決定は台帳に、その場で書く

失敗談です。

ある日、私が広告の日予算の増額を承認しました。エージェントはそれを作戦盤ファイル(PLAN.md、当時 16,681行)の履歴セクションに記録しました。ファイルの84%地点です。

3日後、別のループが「支出は必ず確認する」というルールを読み、予算変更の記録を探し、見つけられず、「無断変更だ」と判定して予算を元に戻しました。

エージェントは忘れたわけではありません。自分のルールを正しく守った結果、間違えました。承認は履歴に落ちて、台帳には昇格せず、台帳は「履歴より台帳が勝つ」と正しく宣言していた、という噛み合い方です。

対策として、決定台帳を PLAN.md から DECISIONS.md に切り出しました。足したルールは1つです。

承認・判断をもらった瞬間に、その場で台帳に1行書く。
「あとで PLAN に書く」は履歴行きであって、台帳には永久に載らない。

長いファイルの中ほどに書いた情報は読まれません。冒頭 240行しか読まないと自分で書いていたのに、6917行目に置いた台帳を参照させようとしていた私の設計ミスでした。

設定のバックアップを習慣にする

openclaw.json を触るたびに、変更内容をファイル名にしたバックアップを残しています。

_backup-local-embed-20260820-095000-openclaw.json
_backup-sessionmemory-20260820-101312-openclaw.json
openclaw.json.last-good

常駐エージェントは設定ミスで静かに壊れます(「反応はするけどツールが使えない」など)。last-good を置いておくと復帰が速いです。

成果物を URL で返させる

エージェントが生成したファイルは絶対パスで返ってくるとスマホから開けません。これは Tailscale + Caddy で tailnet 限定の静的配信を立てて解決しました。別記事に書いています。

公開まわり

エージェントは自分のマシンでシェルを叩けます。Gateway をリモートに晒す前に Security と Gateway exposure runbook は読んでおいたほうがいいです。私は mode: "local" のまま、外から触るときは Tailscale 経由にしています。

まだ解けていないこと

うまくいっていないところも書いておきます。

  • 「進捗どう?」が完全には消えない。 直近2週間のログを分析させたら、私の「どうなった?」系の発言13件はすべて直前のエージェント発言から中央値 4.2時間あいていました(最長25.6時間)。不安ではなく、返ってこないから聞いていた。未決テーブルを足して頻度は減りましたが、エージェント側の自己申告に依存していて仕組みで強制できていません
  • Deep の昇格が0件の日が多い。 閾値を調整していないので、staged された候補が溜まる一方です
  • インスタンスを増やしすぎました。 用途で分けたつもりが、枠は共有なので単に管理対象が増えただけのものもあります
  • cron の payload と手順書ファイルの二重管理。 payload に書くのが正解だと分かったものの、長い手順を JSON の文字列に埋めるのは編集しづらいです

まとめ

ChatGPT も Claude Code も普通に使っています。そのうえで、日常の仕事の入口を OpenClaw に寄せている理由は4つ + 1つでした。

  1. コマンドが打てる — 実測が要る仕事は、手が無いと結論まで行けません
  2. PC の前にいなくても打てる — 常駐しているので、外から投げられるし、こちらが黙っていても動けます
  3. チームに共有しなくても、チームと文脈が共有されている — 共有するのではなく、最初から共有された場所で作業している
  4. 記憶の仕組みを自分でいじれる — 何を覚え、どう引き、いつ忘れるかが全部ファイルと設定です
  5. (おまけ)開発エージェントと繋がる — 同じ Discord にいるので、文脈を渡し直す必要がありません

3番目が一番でかいと思っています。AI を使う量が増えるほど「AI に聞いた話を人に説明し直す」工程が効いてくるので、そこがゼロになるのは効き方が違います。

参考リンク

  1. 出典: OpenClaw README「OpenClaw is a personal AI assistant that learns and grows with you, running on your own devices — developed in the open by the OpenClaw Foundation, a non-profit.」およびドキュメントの説明「Self-hosted gateway that connects Discord, Google Chat, iMessage, Matrix, Microsoft Teams, Signal, Slack, Telegram, WhatsApp, Zalo, and more to AI coding agents.」ライセンスは MIT です。 ↩

  2. 出典: Configuration: tools。tools.profile は tools.allow / tools.deny の前に適用されるベース許可セットで、ローカルのオンボーディングでは未設定時に coding が既定になります。tools.sessions.visibility の既定は tree です。 ↩ ↩2

  3. 出典: Memory search。「For local embeddings with no API key, install the official llama.cpp provider plugin and set provider: "local"」。プロバイダ一覧の表では local は「GGUF model, ~0.6 GB auto-download」「Needs API key: No」と記載されています。選択できるプロバイダは bedrock / deepinfra / gemini / github-copilot / local / lmstudio / mistral / ollama / openai / openai-compatible / voyage です。検索はベクトル検索と BM25 を並列に走らせて重み付きマージします。 ↩ ↩2 ↩3

  4. 出典: Memory search「This follows the relevance, recency, and importance result in Generative Agents (arXiv:2304.03442) without adding a query-time model call.」日付付き日次メモは30日半減期で減衰し、MEMORY.md / USER.md は減衰しません。 ↩ ↩2

  5. 出典: Dreaming。「Dreaming runs three cooperative phases per sweep, in order: light -> REM -> deep.」既定のスケジュールは dreaming.frequency = 0 3 * * * で、既定で有効です。Deep フェーズのみが MEMORY.md へ書き込みます。昇格の受け入れ条件(phases.deep.maxPriorEntryLossFraction 既定 0.25、Source: path#Lx-Ly 参照の必須化、ブートストラップ予算内に収まること)、閾値ゲート(minScore / minRecallCount / minUniqueQueries を全て通過する必要がある)、書き換え前の MEMORY.md を SQLite に保存する点も同ドキュメントに記載されています。 ↩ ↩2 ↩3

  6. 出典: Configuration: agents。agents.entries.<id> で、ワークスペース・モデル・thinkingDefault などをエージェント単位に分けられます。 ↩

  7. 出典: Configuration: channels。replyToMode は off | first | all | batched を取り、グループでの引用返信の戦略を決めます。 ↩

  8. 出典: Rich output protocol および Discord channel。[[reply_to_current]] / [[reply_to:<id>]] は返信メタデータを指定する配信ディレクティブで、送信前にテキストから取り除かれます。 ↩

  9. 出典: Configuration: channels「channels.discord.autoPresence maps runtime availability to bot presence (healthy => online, degraded => idle, exhausted => dnd) and allows optional status text overrides.」healthyText / degradedText / exhaustedText({reason} プレースホルダ対応)で文言を上書きできます。 ↩

  10. 出典: Agent workspace および OpenClaw 同梱の既定 AGENTS.md。起動時のコンテキストには AGENTS.md / SOUL.md / USER.md / 直近の日次メモ / MEMORY.md(メインセッションのみ)が含まれ得ます。 ↩

  11. 出典: Scheduled tasks (cron)。 ↩

  12. 出典: Claude Code: Monitoring usage。CLAUDE_CODE_ENABLE_TELEMETRY(必須)を有効にすると OpenTelemetry でメトリクスとイベントを出力できます。エクスポートされるメトリクスは claude_code.session.count / claude_code.lines_of_code.count / claude_code.pull_request.count / claude_code.commit.count / claude_code.cost.usage / claude_code.token.usage / claude_code.code_edit_tool.decision / claude_code.active_time.total で、レートリミットや残枠の割合を表すメトリクスは含まれていません(2026-08 時点の同ドキュメントで確認)。本文の claude_code_rate_limit_used_percentage は筆者が自前で定義した gauge です。 ↩

  13. 出典: CLI backends「Restricted runs such as cron jobs with toolsAllow require an exact backend-owned translation. The bundled claude-cli backend disables Claude's native tools and user, project, and local customizations, including hooks, plugins, agents, skills, and CLAUDE.md. It then exposes every allowed OpenClaw tool through the grant-scoped MCP server. … Backends without an exact translation still fail closed.」 ↩

  14. 出典: Configuration reference「The cron block is strict; cron.enabled, cron.triggers, cron.webhookToken, cron.sessionRetention, and cron.failureAlert are the only accepted keys.」ツールの許可範囲を制御するキーは含まれていません。 ↩

  15. 出典: Dreaming「Background consolidation is informed by sleep-time compute (arXiv:2504.13171).」論文は Sleep-time Compute: Beyond Inference Scaling at Test-time です。 ↩

  16. 出典: Active memory。rememberAcrossConversations が有効なとき「private direct and persistent explicit UI conversations can recall one another / groups and channels are neither recall sources nor recall destinations / another agent's transcripts are never eligible」という固定のプライバシー境界が適用されます。 ↩

1
0
3

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?