最近の攻撃ニュースが怖くなったので、自分の公開サーバーを Claude Code に点検させてみた

久しぶりのブログ更新です。

最近、公開サーバーが乗っ取られた、認証情報が漏れた、プラグインの脆弱性を突かれた……という話を本当によく目にします。攻撃側も AI で自動化されてきているようで、「個人サーバーだから狙われない」はもう通用しなさそうです。

このブログが載っているサーバーも含め、私はクラウド(OCI)上にインターネットへ公開しているサーバーを2台持っています。

  • Web サーバー:このブログ(WordPress)、Redmine、自作の小さな Web アプリなど
  • トレード用サーバー:FX・暗号資産の自動売買 bot

半年ほど前に一度、ファイアウォールの整理や fail2ban の導入はしたのですが、それきりです。さすがに不安になってきたので、普段から開発に使っている Claude Code に一通り点検させてみました。その記録です。

※ 記事の性質上、IP アドレス・ファイル名・ユーザー名・鍵やトークンの情報など、攻撃のヒントになりそうな部分はぼかしています。また、紹介するのは対応が終わった指摘だけです(検討中のものは伏せています)。

頼み方:まずは「見るだけ」

いきなり AI に本番サーバーを触らせるのは怖いので、最初の依頼ははっきり 読み取り専用 にしました。Redmine にチケットを1枚切って、そこにこう書いています。

  • やること:両サーバーの読み取り専用の点検(待ち受けポート、sshd 設定、ファイアウォール/fail2ban、更新状況、サービス、ファイル権限、ログ)、外部からの見え方の確認、改善案を優先度つきで一覧に
  • やらないこと:設定変更・再起動・パッケージ更新(直すかどうかは私が判断して、別チケットにする)
  • 完了条件:点検結果と改善案(重大度・対応案・影響)をチケットに書いて報告

Claude Code は自宅の常駐マシンから SSH で両サーバーに入り、設定ファイルやログ、パッケージの状態を順に読んでいきます。外からの見え方(どのポートが開いているか、どの URL が見えてしまうか)も別途確認していました。

結果がチケットに書き込まれるまで、だいたい7分。


点検結果

まず結論から。

両サーバーとも、乗っ取られた痕跡は見つからなかった(SSH の成功ログインは全期間すべて自宅から)。 ただし Web サーバーには 「Web が1か所破られると、サーバー丸ごと取られる」構造がある。トレード用サーバーは比較的きれい。

ひとまずホッとしつつ、後半の一文にヒヤッとしました。指摘は優先度(高・中・低)つきで十数件。このうち、すでに対応が終わったものは次のとおりです。

優先度 対象 指摘(要約)
高 Web Web サーバーの権限から root まで上がれる経路がある
高 Web Redmine がサポート切れの版のまま(セキュリティ修正が未適用)
高 Web 誰でも読めるファイルに認証トークンが平文で書かれている
中 トレード 稼働145日、カーネル更新が再起動待ちのまま
中 Web 使っていないサービスが外向きに待ち受けている
中 Web WordPress まわり(デバッグログが誰でもダウンロード可、管理者ユーザー名が外から分かる、ログイン試行制限なし、更新待ちプラグイン)
中 Web fail2ban が SSH しか見ていない(メール認証などは総当たりし放題)
低 両方 sshd で使っていない機能・古い暗号方式が有効
低 Web Apache/PHP のバージョン表示、ディレクトリ一覧が見える、HSTS なし
低 Web メールサーバー設定に昔の自宅 LAN の設定が残っている

「問題なかった点」もちゃんと列挙してくれていて、パスワード認証無効・root ログイン禁止、DB はローカルのみ、設定ファイルの権限、TLS 1.2/1.3 のみ、証明書の自動更新、自動セキュリティ更新、WordPress 本体は最新……などは合格でした。半年前にやったことはちゃんと効いていたようです。

一番ヒヤッとしたもの:Web 権限から root へ

これは自分では絶対に気づかなかったと思います。

Redmine のインストール先が Web サーバーのユーザー(www-data)の持ち物になっていて、その一方で、root で毎朝動く定期ジョブと、sudo で許可していたコマンドが、そのディレクトリの中身を root として実行していました。

つまり、WordPress のプラグインの脆弱性などで www-data の権限を取られると、そのディレクトリに細工 → 翌朝 root で実行される → サーバー丸ごと、という道筋ができていたわけです。どれも「動かすために」その場その場で設定したもので、組み合わさった結果こうなっていたというのが怖いところです。

芋づる式に出てきたもの:平文トークン

「誰でも読めるスクリプトに GitHub のトークンが直書きされている」という指摘を掘っていくと、いろいろ出てきました。

  • そのスクリプトを動かすはずの定期ジョブは、ログの書き込み先が無くて 約半年前から一度も動いていなかった
  • そのトークン自体は失効済みだったが、別の有効なトークンが、Redmine が参照している Git リポジトリの設定ファイルに埋め込まれていて、そのファイルも誰でも読める状態だった
  • GitHub から Redmine へのコミット通知(webhook)は、最近ずっとエラーを返していた。原因はコミットメッセージの絵文字で DB への書き込みが失敗していたこと(セキュリティとは無関係ですが、ついでに見つかった)

「点検」のつもりが、半年放置していた不具合の発見にもなりました。


直した:判断は人間、作業は AI

報告を読んで、優先度の高いものから順に「これは直して」と指示しました。1件ごとに Redmine のチケットを切り、やること/やらないこと/完了条件を書いてから作業させています。

指摘 対応
Web 権限→root の経路 アプリ本体を root 所有にし、Web 側が書けるのはデータ置き場だけに。定期ジョブは Web 権限で実行、sudo の許可を削除
平文トークン 止まっていた定期ジョブとスクリプトを撤去。リポジトリごとに読み取り専用のデプロイキーを作って差し替え、不要になったトークンはすべて削除
カーネル更新待ち bot への影響が小さい時間帯にパッケージ更新+再起動
Redmine が古い まず 5.1 系の最新に上げて穴を塞ぎ、そのあと 7.0 系へ移行
WordPress まわり デバッグログ削除・無効化、プラグイン更新、ユーザー名が外から分からないように
fail2ban メール認証・WordPress ログインの監視を追加、何度も来る相手は長期 BAN
その他(中・低) 不要サービス停止、sshd の不要機能と古い暗号方式を無効化、バージョン表示を止める、ディレクトリ一覧を無効化、HSTS 追加、HTTP→HTTPS 転送、メール設定の残骸を削除

いくつか、やってみて分かったことを書いておきます。

AI でも「人間がやるしかない」部分は残る

GitHub のトークン削除や Redmine の管理画面での設定変更は、Claude Code ではなく私が操作しました。Claude Code は「どの画面で何をすればよいか」と「消す前に他で使われていないか」の確認までやって、ボタンを押すのは私、という分担です。

また、一部の設定変更は Claude Code 自身の安全判定で止められて実行されませんでした。慎重すぎると思う場面もありましたが、本番サーバーを触らせる以上はこのくらいでちょうどいいのかもしれません。

Redmine 7.0 への移行は、別の AI と隔離環境で

メジャーバージョンを2つ飛ばす移行は不安だったので、まず本番のコピーを隔離環境に作って移行と巻き戻しを試すところからやらせました(こちらは OpenAI の Codex に担当させています)。

その結果、Redmine 本体の移行は問題ないものの、

  • 使っているチェックリストのプラグインが新しい版でそのままでは動かない
  • アプリサーバー(Passenger)の古い版に、新しい Rails と組み合わせると Cookie の扱いを誤る不具合がある

ことが本番を触る前に分かりました。互換修正と更新を入れて再検証してから本番切り替え。1回目の切り替えはファイル権限の問題で途中で止まりましたが、手順どおり旧版に戻して、直してから2回目で成功しています。途中で Codex が利用上限に達して止まり、Claude Code が引き継いで最終確認をする、というリレーもありました。

やらかしも1件

WordPress に小さなプラグインを1つ置く作業で、Claude Code が SSH 越しにファイルを書いた際に引用符が抜けてしまい、ブログ全体が約1分間エラー(500)になりました。すぐに外して復旧し、「手元でファイルを作る → 構文チェック → 配置」の順でやり直しています。

AI に限らず人間でもやる類のミスですが、「本番に置くファイルは手元で作って検査してから」というのは改めて教訓として残しました。


やってみての感想

  • 点検そのものは驚くほど速い。 2台分を読み取り専用で一通り見て、優先度つきの報告が出るまで数分。自分でやったら丸1日はかかるし、たぶん権限の組み合わせの問題には気づかない
  • 指摘の質が高い。 「なぜ危ないか」「どう直すか」「直すと何が困るか(自分が締め出されるリスクなど)」までセットで出てくる。直すかどうかを判断する材料がそろっている
  • ついでに不具合も見つかる。 半年止まっていた定期ジョブ、ずっとエラーになっていた webhook など
  • 任せ方が大事。 最初は読み取り専用、変更は1件ずつ承認してから、作業前にバックアップ、作業後は外からの見え方で確認。この型にはめておけば、本番サーバーでも安心して任せられる

朝に頼んで、夕方には中・低の改善と Redmine のメジャーアップデートまで終わっていました。

個人でサーバーを公開している方は、一度「読み取り専用で点検して、優先度つきで改善案を出して」と AI に頼んでみることをおすすめします。少なくとも私は、もっと早くやっておけばよかったと思いました。


おまけ:今回の点検項目(自分用チェックリスト)

  • [ ] 待ち受けポートと、外から実際に見えるポート
  • [ ] SSH:パスワード認証・root ログイン・不要な転送機能・古い暗号方式
  • [ ] ファイアウォールと fail2ban(SSH 以外の入口も見ているか)
  • [ ] OS/アプリ/プラグインの更新状況、再起動待ちのカーネル
  • [ ] Web の実行ユーザーが書けるファイルを、root が実行していないか
  • [ ] 誰でも読めるファイルに、パスワードやトークンが書かれていないか
  • [ ] 公開ディレクトリに、ログ・バックアップ・残骸ファイルが置かれていないか
  • [ ] ユーザー名やバージョンなど、外に出さなくていい情報が出ていないか
  • [ ] 使っていないユーザー・鍵・トークンが残っていないか
  • [ ] 定期ジョブが、実際に動いているか

HERMES Agentで「電脳化」を目指す

HERMES Agentのメモリ構造を初めて知ったとき、私は直感的にこう思った。 「これは攻殻機動隊の『電脳化』だ」と。

単なる記憶の拡張ではない。思考プロセスそのものを外部化し、構造化し、自律的に運用させる。自分の知能を拡張するシステムを自前で構築できるというのは、エンジニアとして最高にエキサイティングな体験だ。

構想した「電脳化」の三層構造

私が描いた理想のサイバーブレインは、以下の三層構造で構成されている。

  1. 永続メモリ(Persistent Memory):個人のアイデンティティや環境設定を刻む「本能」層。
  2. 構造化ナレッジ(llm-wiki):相互リンクで知識を管理する「知識・図書館」層。
  3. 思考の型(Skills):専門的なワークフローを定義し、知能に「型」を与える層。

特に「Wikiファースト」の運用にはこだわった。ネットで調べる前にまず自分のWikiを確認させ、「調査 → 納得 → 刻む」というサイクルを回すことで、AIを真の意味での外部脳へと進化させる。

現実:AIの「わかったつもり」という壁

だが、現実はそう甘くない。実装して分かったのは、理想のアーキテクチャを組んでも、それを動かす「知能」という不確定要素が最大のボトルネックになるということだ。

「わかったつもりで、どんどんズレていく」

これが今の最大の悩みである。 指示を出せば「承知いたしました」と完璧な返答が返ってくる。しかし、実際に出力される結果を見ると、微妙に私の意図から逸れている。あるいは、せっかく llm-wiki という強力な機能があるのに、それを使いこなせずに一般的な知識で回答を済ませてしまう。

「いや、そこはWikiに書いた私のこだわりを反映してくれ」 「そこはツールを使って具体的に検証してくれ」

そんなもどかしさが常に付きまとう。電脳化のインターフェースは整ったが、その中を通る「思考の同期」という部分で、まだ激しいノイズが走っている状態だ。

実は

Hermes Agentのメモリの三層構造は実は↑で書いたような構造になってなかった。

  1. セッションメモリ :セッション内でだけ有効 (短期記憶)
  2. 永続メモリ(Persistent Memory):確かにあるんだけど2200文字しか入らない
  3. SQLite セッション検索:全セッション情報をDBで持ってるので検索できる(けど常用するものじゃない)
  4. 構造化ナレッジ(llm-wiki):確かに機能としてはあるんだけど普通には中を見てくれない

こんな感じです。 なので、まずナレッジはllm-wikiに保存するように指示を出し、それを永久メモリに指示を書く。 が正解ですね。

まぁ、それでも中々うまくいかないのですが。 しかし、だからこそ面白い。

どうすればAIが私の意図を正しく汲み取ってくれるか。どうすればWikiの情報を適切に引き出せるか。プロンプトを練り、スキルを書き換え、メモリを整理する。この試行錯誤こそが、自分の思考を客観視し、再構築するプロセスそのものだからだ。

まぁ、面白いおもちゃを手に入れた感じ(笑)

p.s. 攻殻機動隊とは関係ないが、AIとの融合を説いているAI仙人というYoutuberさんが居て、 彼が唱えるのは、自分のあらゆるコンテキストをAIに与え、自分の「賢い分身」としてAIを運用するという考え方。これもう電脳化だよね。と個人的には思う。

今でもこの人はAIグラスや音声から文字お越しをするデバイスなどを使えば疑似電脳空間は味わえるかも。

完璧なサイバーブレインはまだ遠い。 けれど、自分の知能を拡張しようともがくこのプロセス自体が、すでに一種の「電脳化」なのかもしれない。

LLM運用の変遷と現状について

はじめに

LLMの運用環境構築と運用において、いくつかの試行錯誤を経て現在の構成に落ち着きました。その変遷をまとめます。

1. ローカルLLM時代(RTX 3060 12GB)

最初はコストの観点から、ローカル環境での運用を試みました。

  • 環境: NVIDIA RTX 3060 (VRAM 12GB)
  • 課題: 12GBというVRAM容量の制限から、ロードできるモデルのサイズに限界がありました。結果として、「知能(賢さ)」と「推論スピード」のどちらを優先しても満足いくレベルに達せず、複雑なタスクを完結させるには力不足を感じました。

2. OpenRouter 移行期

次に、多様なモデルをAPI経由で利用できるOpenRouterをメインに据えました。

  • メリット: 最新の高性能モデルを即座に切り替えて利用でき、知能レベルは飛躍的に向上しました。
  • 課題: 運用量が増えるにつれ、APIコストが無視できない金額になってきました。特にHERMESのようなエージェント的な使い方(多回数のツール利用や長いコンテキストのやり取り)をすると、コストの消費速度が速いのがネックでした。

3. 現在:NVIDIA Build API の活用

現在は、NVIDIAの無償枠(NVIDIA Build API)をメインに稼働させています。

  • ここが素晴らしい: 毎分リミット(約40 RPM / Requests Per Minute)がリセットされる仕組みのため、HERMESのような自律型エージェントとしての運用において、実質的に無料で高性能なモデルを使い続けることができます。コストを気にせず、思考プロセスを回せるため、運用効率が劇的に改善しました。もっと大きなモデルも無償で使えるのですが、やはり人気があり一時的に制限が掛ること多かったので、gemma-4-31b-itを使っています。2週間ほど使っていますが、Qwen3.6-35b-a3bと同等な推論力でこっちの方が色々と素直(Qwenはなんでそうなる?的なことが結構あった。思想の違い?)な印象でした。フォールバック先としては、OpenRouterとollamaを指定しています。2週間使ってますが、フォールバックしたことないですね。

現在のLLM設定(config.yamlより)

知能とコストのバランスを最適化するため、以下の優先順位でフェイルオーバーするように設定しています。

優先順位: NVIDIA (Primary) $\rightarrow$ OpenRouter (Fallback 1) $\rightarrow$ Ollama (Fallback 2)

# メインモデル設定
model:
  default: google/gemma-4-31b-it
  provider: nvidia

# フェイルバック設定
fallback_providers:
  - model: google/gemma-4-31b-it:free
    provider: openrouter
  - model: qwen3-8b-agent:latest
    provider: ollama-launch

ここ1か月の利用状況です。 gemma-4-31b-it にする前に、短期間、 qwen3-next-80b-a3b-instructを使っていましたが、日本語で書けと言ってるのに無視して英語で書いてくるのが嫌になって乗り換えました(笑)

$ hermes insights

  ╔══════════════════════════════════════════════════════════╗
  ║                    📊 Hermes Insights                    ║
  ║                       Last 30 days                       ║
  ╚══════════════════════════════════════════════════════════╝

  Period: Jun 12, 2026 — Jun 19, 2026

  📋 Overview
  ────────────────────────────────────────────────────────
  Sessions:          102           Messages:        3,002
  Tool calls:        1,317         User messages:   219
  Input tokens:      48,455,313    Output tokens:   276,229
  Total tokens:      50,096,764
  Active time:       ~28.8d        Avg session:     ~8h 19m
  Avg msgs/session:  29.4

  🤖 Models Used
  ────────────────────────────────────────────────────────
  Model                          Sessions       Tokens
  qwen3-next-80b-a3b-instruct          44   36,590,024
  gemma-4-31b-it                       58   13,506,740

  📱 Platforms
  ────────────────────────────────────────────────────────
  Platform       Sessions   Messages         Tokens
  discord              53      2,017     34,742,567
  cron                 49        985     15,354,197

  🔧 Top Tools
  ────────────────────────────────────────────────────────
  Tool                            Calls        %
  terminal                          430    32.6%
  read_file                         348    26.4%
  browser_navigate                  143    10.9%
  write_file                         66     5.0%
  search_files                       59     4.5%
  patch                              42     3.2%
  skill_view                         34     2.6%
  browser_console                    33     2.5%
  execute_code                       26     2.0%
  browser_snapshot                   16     1.2%
  session_search                     16     1.2%
  cronjob                            15     1.1%
  memory                             15     1.1%
  browser_type                       14     1.1%
  todo                               13     1.0%
  ... and 15 more tools

  🧠 Top Skills
  ────────────────────────────────────────────────────────
  Skill                          Loads   Edits   Last used
  fx-bot-development-cycle          17       3      Jun 19
  llm-wiki                           7       0      Jun 19
  vibe-trading                       2       0      Jun 16
  daytrade-bot-automation-setu       2       0      Jun 14
  fx-bot-development-developme       1       0      Jun 19
  hermes-agent                       1       0      Jun 18
  arxiv                              1       0      Jun 14
  blogwatcher                        1       0      Jun 14
  google-workspace                   1       0      Jun 14
  xread-free                         1       0      Jun 14
  Distinct skills: 10  Loads: 34  Edits: 3

  📅 Activity Patterns
  ────────────────────────────────────────────────────────
  Mon  ██████          12
  Tue  ████            8
  Wed  ████            8
  Thu  █████████       16
  Fri  ███████████████ 26
  Sat  ███████████     20
  Sun  ██████          12

  Peak hours: 4PM (17), 6AM (13), 7AM (12), 8AM (12), 9AM (10)
  Active days: 8
  Best streak: 8 consecutive days

  🏆 Notable Sessions
  ────────────────────────────────────────────────────────
  Longest session      4.3d               (Jun 13, 20260613_162936_)
  Most messages        226 msgs           (Jun 12, 20260612_135409_)
  Most tokens          3,265,770 tokens   (Jun 12, 20260612_110119_)
  Most tool calls      106 calls          (Jun 12, 20260612_135409_)

この構成により、まずはNVIDIAの高性能な無料枠を最大限に活用し、リミットに達した場合はOpenRouterの無料モデル、最終的にはローカルのOllamaへと切り替わるため、システムが完全に停止することなく稼働し続けることができます。これが無料ってすごくないですか?さすが大儲けしてるNVIDIAさんですね(笑)

AIによる開発の落とし穴と「賢さ」の正義

~Claude Code Sonnetで組んだfx-botがBT通りに動かない理由 —— Fable5に「ダメ出し」させて分かったこと~


はじめに

最近、Claude Codeでfx trade botの開発をしていた。 私自身はそんなにコードを書けないので、Claude Code正に神器と歓喜した。 FX自体はやっていたのでいろんな手法は知っている。その手法をClaude Codeに話して実装してもらう Claude Codeは計画を立て(計画はOpus 4.8を使用)プログラムを書きテストも自動でやってくれる。実に素晴らしい。 BT(バックテスト)結果も好調で、いざ動かしてみると、結果は惨憺たるものだった。「全然、BT通りに動かない(勝てない)」。

いざ走らせてみると

バグがいっぱい出た。。。まぁ、それはClaude Codeで直せばいいが。 しかし、テストしてるのになぜこんなにもBUGがある。。。

さらに、BUGを直しても勝てない。 BTでは勝っているのになぜ?

Fable5という「厳しい監査役」の登場

1週間弱、幻のFable5が使える時期があったので、このを逃さず何が問題なのか聞いてみた。

実装したコードをそのままFable5に読み込ませ、「この実装に潜む論理的な欠陥や、バックテストと実運用の乖離を生む要因を徹底的に分析せよ」と指示を出した。

結果は、目から鱗が落ちるような「ダメ出し」の嵐だった。

Fable5は、単にコードの書き方を修正するのではなく、「トレードシステムとしての整合性」というメタ視点から実装を分析した。

  • 「この条件判定のタイミングでは、まだ確定していない足の値を参照している可能性がある」
  • 「このロジックでは、〇〇のような相場状況においてエントリが重複し、リスク管理が破綻する」
  • 「BTで良好だったのは、この〇〇という実装上のミスが偶然に有利に働いていたからではないか」

まぁ、確かにそんな指示はしてないので、漏れてても文句は言えないのだが。。。

結論:やっぱり「賢さ」が正義である

Claude Code (Sonnet) は素晴らしい「プログラマー」だが、予測域が一般人並み(いや、それでも私よりは十分賢いのだが)。それに対し、Fable5はもはや専門家。任せておけば万事OKな安心感がある。 が、さすがに全行程Fable5にやらせるのは個人では厳しい。しかも今後はAPI課金に変わると言うし(というかその前にアメリカ政府により利用停止になってしまったが。。。)なので、計画、設計はFable5。コーディング、テストはSonnet、評価、改善はFableってのが良さそう。 やっぱり、こういう領域では「賢さ」こそが正義だ。

Fable もう使えるようにならないのかなぁ。。。(Q_Q

Hermes Agent + Qwen36-35B-A3B に「自律修正」を任せてみた

VPS上で動かしているFXボット群の監視・改善を、Hermes AgentにQwen3-35B-A3Bを載せて自律的にやらせてみた。指示は「問題を見つけたら自分で直せ」。結果は「発見はできる。修正は荷が重かった」。


何をやらせたか

VPS上で複数のFXボット(bot_pattern、bot_gmo、bot_ha_ema など)が稼働している。
Hermes Agentに「ログやコードを見て、問題を自発的に発見・修正せよ」という自律タスクを与えた。

モデルはQwen36-35B-A3B(Mixture-of-Experts、アクティブ3B/総35B)。
ローカルで動かせるサイズ感でエージェントに使うには悪くない選択肢のはず…だった。


Hermes Agentが出した報告

「GMO APIにレートリミットが出ている」

Hermes Agentが真っ先に報告してきた内容がこれ。「HTTPステータス429が大量発生している」と。

実際にVPS上のログを精査すると――

18:15:34,429 [INFO] ...

ログのタイムスタンプのミリ秒部分だった。34,429 の ,429 を HTTP 429 と読み間違えた。

実際のAPIアクセス数は約500〜700回/日。GMO公式制限(GET 6回/秒 ≒ 518,000回/日)の0.1%以下で、レートリミットは欠片も発生していなかった。

ERR-5218(取引時間外発注)の連続発生

429誤報の調査中に、今度は本物の問題を見つけてきた。

bot_mtf_tb_eurusd が週末(土曜07:00〜月曜07:00 JST)にもGMO APIへ発注リクエストを送り続け、ERR-5218: The order was rejected for trading close. が4時間おきに9回連続発生していた。

2026-05-16 20:30 [ERROR] 発注失敗: ERR-5218
2026-05-17 00:30 [ERROR] 発注失敗: ERR-5218
2026-05-17 04:30 [ERROR] 発注失敗: ERR-5218
...(9回)

dry-runのため実損はないが、無駄なAPI呼び出しとログ汚染が続いていた。これは正真正銘の問題。


修正フェーズで何が起きたか

「修正せよ」と指示していたので、Hermes Agentはコードに手を入れた。

しかし確認すると、Git管理外で直接ファイルを書き換えていた。git status には何も出ないが、実ファイルは変更済みという状態。発見後、git stash で退避して git pull で正しいリビジョンに戻した。

修正内容の方向性は間違っていなかった(取引時間チェックを入れるべき、という判断は正しい)。ただし実装をGitフローに乗せられなかった。コミットもなく、レビューも通っていない変更がVPSに存在している状態は困る。

実際の修正は自分でやった。_is_market_open() を追加して run_once 冒頭でスキップ処理を挟むだけなので5分で終わった。

def _is_market_open(now_jst: datetime) -> bool:
    wd = now_jst.weekday()  # 0=月 … 5=土, 6=日
    if wd == 6:  # 日曜は終日クローズ
        return False
    if wd == 5:  # 土曜06:55以降はクローズ
        return now_jst.hour < 6 or (now_jst.hour == 6 and now_jst.minute < 55)
    return True

わかったこと

発見は得意、修正は荷が重い。

タスク 結果
ログの異常パターン検出 △(誤認あり)
本物のバグ発見 ○(ERR-5218を発見)
修正方針の立案 ○(方向性は正しかった)
Gitフローに沿った実装 ✗(管理外変更)

Qwen36-35B-A3Bのサイズでエージェントとして動かすと、「何かを見つけて報告する」は回るが、「コードの文脈を保ちながら適切に変更を加えてGitに乗せる」はまだ確率が低い。ツール呼び出しの連鎖が長くなるほど途中でコンテキストが崩れる感覚がある。


次の方針

Hermes Agentの役割を「発見専門」に絞る。

  • 発見 → Hermes Agentがチケットを起票して終了
  • 修正 → 人間(または別途レビューを通したエージェント)が実施

「自律修正」はまだ早かった。でも「自律発見」は普通に役立つ。今回もERR-5218は放置していたら次の週末まで気づかなかったと思う。


検証環境: VPS (Ubuntu) / Hermes Agent / Qwen36-35B-A3B / GMO クリック証券 FX API

Hermes Agentにも手を出してみました(笑)

最近、Hermes AgentとOpenClawの両方を触って比べてみたのですが、いくつか明確な違いがあって、個人的にはかなり衝撃を受けました。

同じモデルでも「自走力」が全然違う

両方とも ローカルのQwen3.6 35B-A3B を使っているにも関わらず、指示に対する自走力に大きな差がありました。 OpenClaw は、ちょっとしたタスクを指示しても「次の一手を教えてもらわないと動けない」印象でしたが、Hermes Agent は30分程度の長時間タスクも普通にこなせるんですよね。

OpenClawでよくあるのがコンテキストを使い果たして回答できなくなるって現象なんですが、足りなくなりそうなら先に手を打つとか、そもそも大量な出力を出すようなコマンドを叩かない、あるいは叩いた後にプレ処理をするといったことをしてくれないので、よくこのメッセージが出てました。

Agent couldn't generate a response. Note: some tool actions may have already been executed — please verify before retrying.

Hermes Agentでは

⏳ Still working... (3 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (6 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (9 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (12 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (15 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (18 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (21 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (24 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (27 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (30 min elapsed — iteration 1/90, receiving stream response)
⏳ Still working... (33 min elapsed — iteration 1/90, receiving stream response)
⚠️ Model returned empty after tool calls — nudging to continue
⏳ Still working... (36 min elapsed — iteration 2/90, waiting for stream response (60s, no chunks yet))
💻 terminal: "cd /home/ubuntu/.hermes/hermes-agent ..."
🐍 execute_code: "import subprocess result = subprocess..." 
⏳ Still working... (39 min elapsed — iteration 3/90, receiving stream response)
⏳ Still working... (42 min elapsed — iteration 4/90, receiving stream response)・・・

と処理を続けて何とか回答を出してくれるんですよね。

例えば、コードのレビューを指示した際にも、自ら手順を組み立てて実際にツールを呼び、結果を確認し、さらなる改善を提案する。こうした流れが、まるで一人の開発者が傍にいてくれたように進みます。

バグが圧倒的に少ない

実務レベルで使っていると、ツール呼び出しの失敗や出力の破損、意図しない状態遷移などがたまに起こるのですが、Hermes Agent はその点非常に安定していると感じます。エラーが出てもしっかりとしていて対処能力も高いです。OpenClawはほぼ毎日アップデートがリリースが出てて、当てると結構な確率で動かなくなったりするのですが(笑)、Hermes Agentは今のところそういうことはないですね。大体、週1回のアップデートくらいでしょうか。当てても問題なく起動してきます :-)

スレッド間で記憶を引き継ぐのが上手い

これが特に驚いた点なのですが、スレッドを変えても、他のスレッドで知り得た情報をちゃんと保持しているんです。

例えば、前のスレッドで自分のGitHubユーザー名を共有したあと、別スレッドで関連する指示を出しても、ちゃんと文脈が引き継まれていました。

これは、単なるセッションスコープの文脈保持だけでなく、永続的なメモリを駆使したインテリジェントな記憶管理によって実現されているんだろうなと感じます。

発想としてはOpenClawも同じはずなんですが、OpenClawは長期記憶の必要な部分の抽出が得意ではない感じがしますね。 まぁ、「前に教えたよ」って言えば、メモリーを漁って思い出してくれるんですが、結構物忘れの激しい子ってイメージはありますね(笑)

AI + LLM の「PC自作」時代

このツイートを見てHermes Agentに興味を持ったんですが、楽しい時代になりましたね。 → @swarm_japan さんのツイート

最近は、AI がどんどんと進化してきて、LLM と Agent フレームワークを組み合わせて自分でカスタムできるようになってきました。まさにPCの自作みたいな楽しさがそこにはあります。 自分で構成を選んで、パーツを組み合わせて、性能を調整して…といった体験が、もうAIの世界でできているんですよね。これはとてもワクワクします。

まとめ

項目 Hermes Agent OpenClaw
自走力 ◎ (30分タスクもこなす) △
バグの少なさ ◎ (安定感が高い) △
記憶の引き継ぎ ◎ (スレッド間でインテリジェント) △

同じバックボーンモデルを使っていても、フレームワークの設計次第でこれだけ違ってくるんですね。Hermes Agent はその辺りの実装が非常に良くできていて、日常的に使えるレベルの高いAgentだなという印象です。

Agentフレームワークの比較とかカスタム体験に興味がある方は、ぜひ両方触ってみてください。面白い発見があるはずです。

Obsidian頭脳化計画:AIエージェントの外部記憶をObsidian Vaultで実現する

はじめに

最近はやりのObsidianで外部脳を作ろうというkarpathyさんのアイデアをちょっと違う形でAI Agent向けの外部脳を作ってみました。私は、ClaudeCodeがメインでOpenCalw、kiro、Antigravity、OpenCladeなど。。。節操なく使ておりり、各エージェント事にコンテキストがバラバラという課題がありまして、これをNAS+Obsidianで効率的に共有できないかと考えました。 私はRedmineでプロジェクト管理しているので、Redmineをベースに、Obsidian Vaultを全AIエージェント共通の外部記憶として整備するプロジェクト「redobrain」を始めました。

何を作ったのか

一言で言うと、Redmineに書いた情報を自動的にObsidian Vaultに取り込み、AIが読みやすい形に統合するパイプラインです。基本的にはOpenClawのSKILLSで、スクリプトを実行させたりマージはLLMにやらせてます。この仕組み自体、私がアイデアを出しClaudeCodeで作成したものです。

人間 → Redmineにチケットを書く
         ↓ (自動同期)
    Sources/Redmine/ に1チケット1ファイルで保存
         ↓ (ルールベース分類)
    classify-state.json に分類結果を記録
         ↓ (OpenClawが直接マージ)
    Merged/ に統合ドキュメントとして出力
         ↑
    他のAI Agentが ENTRY.md 経由で参照

人間がやることは「Redmineにチケットを書く」だけ。あとは全自動です。

設計原則:Sourcesが唯一の真実

このシステムの核となる設計原則は:

Sources が唯一の真実。Merged はビルド成果物。

プログラマーなら馴染みのある考え方ですね。ソースコードとビルド成果物の関係と同じです。

  • Sources/ = ソースコード(Redmineチケット、手動投入ドキュメント)
  • Merged/ = ビルド成果物(AIが読む統合ドキュメント)
  • いつでも Sources/ から Merged/ を再生成できる

これにより「マージ済みだからスキップ」という判断が不要になります。ルールが変わった、情報が更新された → 再生成すればいい。シンプルです。

2フェーズ・アーキテクチャ

Phase 1: Classify(ルールベース、LLM不要)

分類はLLMを使いません。純粋なルールベースです。

  • Redmineチケットの parent_id を辿ってルートチケットを特定
  • ルートチケット = コアドキュメント(統合先)
  • 子チケットは親のコアドキュメントに分類される
def _find_root(self, ticket_id, parent_map):
    """parent_idチェーンを辿ってルートを見つける(循環検出付き)"""
    visited = set()
    current = ticket_id
    while current in parent_map and parent_map[current] is not None:
        if current in visited:
            break
        visited.add(current)
        current = parent_map[current]
    return current

最初は分類もOpenClawにやらせようと思ったのですが、いまいちだったのでRedmineのプロジェクトをベースにClaudeCodeで先に仕分けルールを作らせました。

Phase 2: Merge(OpenClawが直接実行)

SKILLS.mdでスクリプト実行とその結果で判断させ、マージの仕方を指示しています。

## マージ作業(あなたが直接行う — スクリプト不要)

**重要**: マージは2フェーズに分けて行う。1回の処理を小さく保つこと。

### 「マージして」と言われたら即座にこれを実行する

**⚠️ 絶対に聞き返さない。追加情報を求めない。以下をそのまま実行する。**

何をマージするか、どこにマージするかは聞かなくてよい。classify コマンドが自動判定する。

```bash
# Step 1: 分類(自動)— 何をマージすべきか自動判定される
cd ~/.openclaw/workspace/skills/redobrain
set -a; source systemd/openclaw.env; set +a
python3 -m scripts.main --config /mnt/share/Obsidian/_openclaw/config.yaml classify
```

```bash
# Step 2: 次のマージ対象を確認 — これが「何をマージするか」の答え
python3 -m scripts.main --config /mnt/share/Obsidian/_openclaw/config.yaml next-merge
```

**Step 2 の出力を見て、そこに書かれた core_doc と sources に従って作業する。**
ユーザーに何も聞く必要はない。

Step 3以降はあなたが直接ファイルを読み書きして行う:

**⚠️ 1回のセッションで処理するのは1コアドキュメントのみ。**

```
Step 3: next-merge の出力を確認 → core_doc と sources 一覧を把握する
Step 4: その core_doc に属する Sources を1件ずつ読む(一度に全部読まない)
Step 5: 内容を理解し、コアドキュメントを作成・更新する
         - 既存ファイルがあれば先に Archive に退避
           cp /mnt/share/Obsidian/Merged/xxx.md /mnt/share/Obsidian/Archive/Merged/xxx_YYYY-MM-DD_HHmm.md
         - /mnt/share/Obsidian/Merged/{category}/{name}.md に書き込む
Step 6: マージ完了したら mark-merged で記録する
         python3 -m scripts.main --config /mnt/share/Obsidian/_openclaw/config.yaml mark-merged "Merged/xxx/yyy.md"
Step 7: Discord に完了を報告する(例:「Merged/Trading/daytrade-bot.md をマージしました」)
Step 8: /mnt/share/Obsidian/00-Entry/ENTRY.md を更新する
         - 統合ドキュメント一覧のパスは Obsidian wiki-link で記載する
         - 例: `[[Merged/Trading/daytrade-bot]]` (.md は省略)
         - テーブル形式: `| タイトル | [[Merged/Trading/daytrade-bot]] | 概要 | 日付 |`
Step 9: /mnt/share/Obsidian/_openclaw/logs/YYYY-MM-DD.md にログを記録する
```

Vault構造

/mnt/share/Obsidian/
├── 00-Entry/
│   └── ENTRY.md              ← 全AIエージェントの入口
├── Sources/
│   ├── Redmine/              ← チケットごとに1ファイル
│   └── Other/                ← 手動投入ドキュメント
├── Merged/                   ← 統合ドキュメント(カテゴリ別)
│   ├── Trading/
│   ├── Projects/
│   ├── Infrastructure/
│   └── ...
├── Archive/
│   └── Merged/               ← 過去バージョン(自動退避)
└── _openclaw/
    ├── config.yaml
    ├── merge_rules.yaml      ← 分類ルール定義
    ├── classify-state.json   ← 分類結果キャッシュ
    └── logs/

ポイントは 00-Entry/ENTRY.md の存在です。どのAIエージェントも、このファイルを1つ読めば全情報にアクセスできる。設定ファイルに1行追加するだけ:

プロジェクト情報は /mnt/share/Obsidian/00-Entry/ENTRY.md を参照。

実装の工夫

増分処理

毎回全チケットを再分類するのは無駄なので、classified_at と last_synced を比較して変更があったものだけ処理します。

# 増分処理: 前回分類済みで変更なしならスキップ
existing = sources.get(source_path)
if existing and existing.get("classified_at", "") >= last_synced:
    continue

アーカイブ自動退避

マージ前に既存の Merged/ ファイルがあれば、自動的に Archive/ にタイムスタンプ付きでコピーします。git的な発想ですが、Obsidianのプレーンマークダウンという制約の中では十分実用的です。

ロックファイル

NAS上のVaultに複数プロセスが同時アクセスしないよう、シンプルなロックファイル機構を実装しています。タイムアウト付きで、デッドロックも防止。

技術スタック

  • Python 3.11+ — パイプラインスクリプト
  • OpenClaw — LLMエージェント基盤(Qwen3.6-35b-a3b on Ollama)
  • Redmine — 情報の入力元(人間が書く場所)
  • Obsidian — 情報の出力先(AIが読む場所)
  • Discord — 承認フロー・通知
  • NAS (SMB/NFS) — Vault の物理ストレージ(複数マシンからアクセス可能)

技術スタック

利用環境

  • Windows 11 (Claude Code/kiro/Antigravity) 普段使うPC
  • Ubuntu Linux 24.04(Openclaw/Claude Code/kiro-cli) Openclawマシン
  • Mac mini(まだ届いてない(笑))

現在の稼働状況

  • Redmine sync: 稼働中(329チケット同期済み)
  • Classify: 稼働中(273ソース分類済み → 157コアドキュメント)
  • Merge: OpenClawによる実行が進行中
  • systemdタイマーで15分ごとに自動実行

なぜObsidianなのか

「なぜNotionやConfluenceではなくObsidianか?」という疑問があるかもしれません。理由は明確です:

  1. プレーンマークダウン — APIもDBも不要。ファイルを読むだけ
  2. ローカルファイルシステム — AIエージェントが直接アクセスできる
  3. NASマウント — 複数マシン(Windows/Linux/Mac)から同じVaultにアクセス
  4. Obsidianのwiki-link — ドキュメント間のリンクが簡潔に書ける
  5. 人間も読める — Obsidianアプリで普通にブラウズ・編集できる

AIエージェントにとって最も低摩擦なインターフェースは「ファイルを読む」こと。それ以上でもそれ以下でもない。

今後の展望

  • マージ品質の改善(現在はOpenClawの出力をそのまま使っているが、フォーマットの一貫性にばらつきがある)
  • 定期的な全再マージ(ルール変更時に一括再生成)
  • 他のAIエージェント(Claude Code、Kiro等)からの参照実績を積む
  • Sources/Other/ への手動投入ワークフローの整備

まとめ

redobrainは「AIエージェントに長期記憶を持たせる」という課題に対する、実用的な解答です。

設計のポイントは:

  • 人間はRedmineに書くだけ(既存ワークフローを変えない)
  • 分類はルールベース(LLMの気まぐれに依存しない)
  • 統合はLLMが直接実行(エージェントの強みを活かす)
  • 出力はプレーンマークダウン(どのAIからも読める)

ぶっちゃけ、これClaude Codeに課金してやらせたら簡単に終わると思います。それをケチって(いや、実験として)OpenClaw + Ollamaで実行させるためには、JOBを細かく切るとかちょっとお馬鹿でも実行できるようにするとか一部、スクリプトを作るとかってことをしてる訳ですね。まぁ、不毛っちゃ不毛です(笑)

環境: OpenClaw v2026.5.4 / Ollama 0.20.5 / Qwen3.6-35b-a3b / RTX 3060 12GB / Ryzen 5600X / RAM 32GB / Obsidian on NAS (SMB)

OpenClaw+Ollamaでどうしてもフェールオーバーする

はじめに

前回の記事では、Qwen3.6-35b-a3bでOpenClawが実用化したと報告しました。しかし運用を続けていると、タイムアウト問題という壁にぶつかりました。

今回は、OpenClawのタイムアウト設定を調査した結果、設定では解決できないハードコードされたバグに行き着いた顛末を記録します。

症状:120秒で勝手にフォールバックする

OpenClawのログに以下のエラーが頻発するようになりました:

10:50:13 error diagnostic lane task error:
  lane=session:agent:main:discord:channel:...
  durationMs=122139
  error="FailoverError: LLM request timed out."

timeoutSeconds: 600(10分)に設定しているのに、約122秒(2分)でタイムアウトしてフォールバック先のOpenRouterに切り替わってしまう。

調査その1:設定は効いているのか?

まず timeoutSeconds を600→900に変更して様子を見ました。すると別のログが出現:

11:36:55 embedded run timeout:
  timeoutMs=600000
  durationMs=600667

こちらは正しく600秒でタイムアウトしている。つまり timeoutSeconds の設定自体は効いている。

では122秒のタイムアウトは何なのか?

調査その2:Ollamaのログを確認

Ollamaのjournalctlログを確認すると、決定的な証拠が見つかりました:

12:00:54 loading model: KvSize:131072, GPULayers:15/41
12:00:59 model weights: GPU=7.6GiB, CPU=14.7GiB
12:01:10 llama runner started in 16.28 seconds
12:02:53 [GIN] 500 | 1m59s | POST "/api/chat"

Ollama側は処理中なのに、クライアント(OpenClaw)が約2分で接続を切っている。 Ollamaは500エラーを返しているが、これはクライアント切断が原因。

調査その3:2種類のタイムアウトが存在する

ログを時系列で整理すると、全体像が見えてきました:

タイムアウト 設定 効果
embedded run timeout agents.defaults.timeoutSeconds: 900 エージェント実行全体の制限時間。設定可能
LLM HTTP fetch timeout ハードコード(~120秒) 個別LLMリクエストの待機時間。設定不可

timeoutSeconds はエージェントの「1回の実行全体」のタイムアウト。一方、個別のHTTPリクエスト(OllamaのAPIを叩く1回のfetch)には、別のハードコードされたタイムアウトが存在していました。

なぜ120秒で切れるのか

35B MoEモデルをCPU/GPU分割(15/41レイヤーのみGPU)で131Kコンテキストで動かすと、prefill(プロンプト処理)だけで120秒以上かかることがあります。

ストリーミングモードは有効ですが、prefill中は最初のトークンすら生成されないため、HTTPレスポンスとして1バイトも返りません。OpenClawのHTTPクライアントは「レスポンスが来ない」と判断してabortします。

timeoutMs を試したが…

OpenClawのGitHub Issuesで timeoutMs というパラメータの要望を見つけたので試してみました:

"models": {
  "providers": {
    "ollama": {
      "timeoutMs": 900000
    }
  }
}

結果:

config reload skipped (invalid config):
- models.providers.openrouter: Unrecognized key: "timeoutMs"
Config auto-restored from last-known-good

v2026.5.4では timeoutMs は未実装。 設定に入れるとバリデーションエラーで拒否され、設定全体がロールバックされます。

OpenClawの既知バグだった

GitHub Issuesを調査すると、同じ問題が複数報告されていました:

  • #61487 — “LLM HTTP request timeout hardcoded at ~60s”
  • #46049 — “LLM request timeout ignores configured timeout settings”
  • #45637 — “Add timeoutMs config support for LLM Providers”

ソースコード上は DEFAULT_TIMEOUT_MS$2 = 3e4(30秒)がハードコードされているとの報告もあり、バージョンによって30秒〜120秒の範囲で異なるようです。

結論:現時点でユーザーが変更する手段はない。

ワークアラウンドの検討

対策 有効性 理由
timeoutSeconds を伸ばす △ embedded run全体には効くが、個別リクエストには効かない
timeoutMs を設定する ❌ 未実装。設定するとconfig拒否
モデルを常時ロード ❌ 問題は稼働中に発生。ロード済みでもprefillが遅い
コンテキストを下げる ❌ 128K未満ではエージェントとして実用にならない
ストリーミングで回避 ❌ 既にstream:true。prefill中はデータが返らないので無意味
フォールバックに任せる ○ OpenRouterが成功するので実用上は動く

現状の運用

結局、フォールバックが正しく動いているので、実用上は問題なく動作しています:

  1. Ollama(qwen36-35b-agent)にリクエスト
  2. ~120秒でタイムアウト → abort
  3. OpenRouter(deepseek-v4-flash)にフォールバック → 成功

ただし、ローカルモデルが使われる頻度が下がり、OpenRouterのAPI費用が発生するのが残念なポイントです。

まとめ

  • agents.defaults.timeoutSeconds はエージェント実行全体のタイムアウト。個別HTTPリクエストには効かない
  • OpenClawのLLM HTTPクライアントには~120秒のハードコードタイムアウトがある(バグ)
  • timeoutMs パラメータは未実装(Feature Requestとして存在するのみ)
  • 35B MoE + 131Kコンテキスト + CPU/GPU分割の環境では、prefillだけで120秒を超えることがある
  • 根本修正はOpenClaw側のアップデート待ち

教訓: ローカルLLMでOpenClawを使う場合、「モデルの推論速度」だけでなく「prefill時間(最初のトークンが出るまでの時間)」も重要な指標です。VRAM不足でCPUオフロードが多いほどprefillが遅くなり、ハードコードタイムアウトに引っかかりやすくなります。


環境: OpenClaw v2026.5.4 / Ollama 0.20.5 / RTX 3060 12GB / Ryzen 5600X / RAM 32GB

OpenClaw 2026.5.2 Discord 切断事件

何が起きたのか

OpenClaw を 2026.4.29 から 2026.5.2 に更新したら、Discord bot が繋がらなくなった。実は2026.4.26->2026.4.29に上げたときもDiscordに繋がらなくなったのですが、今回も繋がりませんでした(苦笑) こういう時は openclaw doctor –fixが推奨なんですが、最近私はClaudeCode様任せです(笑)ClaudeCodeさんにお願いして調べてみたところ、OpenClaw 2026.5.1 で大きなアーキテクチャ変更があったそうで。Discord を含む多くのチャンネルプラグインが、コアパッケージから外部 npm パッケージへ externalized されたのだそうだ。え。。。て感じだけど。「 bundled plugin → 独立パッケージ 」への cutover 最中に openclaw update を実行すると、プラグインの依存関係が解決されず、Discord プラグインが missing になる。結果として Gateway は起動しても Discord チャンネルが接続できず、bot が「オンラインなのに返事しない」状態になる。とのことだった。。。

原因の技術的な背景

CHANGELOG を見ると、2026.5.1 の Plugins/beta セクションにこうある:

prepare Google Chat, LINE, Matrix, Mattermost, …, Discord, …, WhatsApp, Brave, Codex, … for 2026.5.1-beta.1/2026.5.1-beta.2 npm and ClawHub publishing

つまり Discord プラグインは @openclaw/channel-discordcode>@openclaw/channel-discord</code などの独立パッケージとして npm に公開されることになり、コアに含まれなくなった。update 時にこの移行が中途半端だと、プラグインがインストールされていないままになる。

2026.5.2 の修正

2026.5.2 にはこの問題への対応が Doctor/plugins セクション で行われた:

run a one-time 2026.5.2 configured-plugin install repair based on meta.lastTouchedVersion, update stale configured plugin manifests that still declare channels without channelConfigs, install actively used downloadable OpenClaw plugins through the configured external source

要するに、update 時に missing プラグインを自動検出して再インストールする repair が追加された。これで 2026.5.2 以降に update しても同じ事象は起きにくくなっている。

教訓

  1. メジャー cutover の直後は注意: プラグインの externalization のような大きな変更があるバージョンでは、update 後に openclaw doctor --fix を実行するのが安全
  2. CHANGELOG を読む癖をつける: openclaw update の前に CHANGELOG を一瞥するだけで、こんな事象は避けられた
  3. openclaw status で確認: 更新後に openclaw status を実行してチャンネルの状態を確認する

まとめ

OpenClaw は気軽に openclaw update すると 100% ハマるよねぇ(笑)。でもそれはつまり、開発が活発で頻繁に更新されている証拠でもある。プラグインの外部化はスケーラビリティ向上のためなので、ある意味必要な進化。update 後は doctor を実行する癖をつけましょう。


この記事はOpenClaw + Ollama Qwen3.6-35b-a3bで書かれた原稿を元にしています。

徒然なるままに。。。