「コンピュータ」カテゴリーアーカイブ

RTX 3060 12GB の自宅サーバで 125B の Qwen3.8-Flash-Next を動かす ― メモリ80GBに増設と Strata 導入記

はじめに

ローカル AI 用に専用機(DGX Spark や Mac Studio など)を買うかどうか、しばらく迷っていました。 そこへ出てきたのが Strata。総 125B パラメータの MoE モデル Qwen3.8-Flash-Next を、12GB の GPU と 64GB 程度の RAM というゲーミング PC 級の構成で動かせる推論エンジンです。

うちの常時稼働サーバは RTX 3060 12GB を積んでいて、GPU の条件は満たしています。足りないのは RAM だけ。 そこで「専用機は買わず、RAM を足して Flash-Next を動かす」方針に決め、実際にやってみました。

結論から書くと:

  • RAM は 32GB×2 を足して 80GB(DDR4-3000)。種類の違うメモリを混ぜた4枚挿しで少しハマった
  • Strata の IQ3_XXS(3bit 級)で約 62 tok/s
  • 自作の6問テストで、クラウド版 Flash-Next とほぼ同じ品質。手元の Qwen3.6-35B-A3B より明確に上

環境

項目 内容
CPU Ryzen 5 5600X
マザーボード ASRock B550M Steel Legend(DDR4・4スロット・上限 128GB)
GPU RTX 3060 12GB(ドライバ 580)
RAM(前) 8GB×4(32GB)→ Strata には全然足りない
RAM(後) 32GB×2(新規)+ 8GB×2(既存)= 80GB
ストレージ NVMe SSD(モデル置き場に約80GB使用)
OS Ubuntu 24.04

このサーバでは他にも Windows VM(約8GB)や各種常駐サービスが動いているため、「Strata 35〜43GB+VM+OS」で 64GB だとギリギリ、という見立てでした。

なぜ Qwen3.8-Flash-Next なのか

Qwen3.8-Flash-Next は Alibaba Qwen チームのオープンウェイト MoE モデルです。

  • 総 125B/1トークンあたり動くのは 6B(512 エキスパート中 10 個)
  • n-gram 埋め込み 51B と MTP(複数トークン予測)を持つ
  • コンテキスト 262K

アクティブが 6B と小さいので計算は軽い一方、エキスパート全体を置いておく場所(RAM)が大量に要る、というタイプのモデルです。

買う前に、クラウド(API 経由)で手元の候補と比べました。題材は手元の小さな Web アプリ(PHP+素の JS)のコードで、わざと入れたバグの特定3問・実コードのレビュー2問・実装1問(隠しテスト22件)の計6問です。

お題 Flash-Next(クラウド) Qwen3.6-35B-A3B FP8 Qwen3.6-35B-A3B q4(ローカル)
残高を超えて申請できる(abs 抜け) 正解 不正解 不正解
ロック外の読み込みで更新が消える 正解 正解 正解
10〜12月が空になる(substr 位置ずれ) 正解+追加指摘 正解 正解
ポイント処理のレビュー 良 中 弱
保存クラスのレビュー 良 中 弱
実装(隠しテスト22件) 22/22 2/22(タイポ) 22/22

Qwen3.6 は FP8 でも q4 でも同じ誤診をしていて、差は量子化ではなくモデルの地力でした。これで「Flash-Next を手元で動かす価値はある」と判断しました。

補足: 既定設定の Flash-Next は、自由記述のレビューで思考だけに 24,000 トークンを使い切って本文が空になることがありました。reasoning_effort: medium にすると 30〜50 秒で良い回答が返ります。

メモリ増設 ― 混在4枚挿しの落とし穴

買ったもの

DDR4-3200 の 32GB×2(JEDEC 3200 CL22、XMP なし)。もともと 8GB×4 で4スロットが埋まっていたので、8GB を2枚抜いて 32GB×2 を挿し、残した 8GB×2(Corsair Vengeance RGB Pro、XMP 3200 16-18-18-36 1.35V)と合わせて 80GB にしました。

自動設定だと 2133 に落ちる

構成 速度 帯域(memtest 表示) 結果
32GB×2 のみ(自動) DDR4-3200 CL22 43 GB/s 正常
4枚(自動) DDR4-2133 CL15 28.4 GB/s 種類が混ざると JEDEC 標準の 2133 に落ちる
4枚・手動 3200 ― ― メモリトレーニングに失敗し 2133 に戻される
4枚・手動 3000 DDR4-3000 CL22 38 GB/s 合格
  • 4枚挿し(1チャネル2枚=2DPC)で、しかも XMP を持つものと持たないものが混在すると、自動では 2133 まで下がります
  • XMP をオンにすると 8GB 用の CL16 が 32GB 側にも掛かって不安定になるので、XMP はオフ
  • 手動で 3200 を指定してもトレーニングで弾かれたので、一段落とした 3000 に

最終的な BIOS 設定

ASRock の OC Tweaker → DRAM Configuration で手動設定:

  • DRAM Frequency: DDR4-3000(FCLK 1500MHz で 1:1)
  • タイミング: 22-22-22-52
  • DRAM Voltage: 1.35V
  • XMP: 無効
  • その他: Auto

CMOS クリアや BIOS 更新をすると消えるので、手で入れ直す必要があります(メモしておくのが大事)。

memtest86+ で確認

memtest86+ v7.00 を約5時間。1パス完走+2パス目 94% まで Errors 0 で合格としました。 80GB・3000 は 64GB・3200 に比べて帯域が約12%落ちますが、容量優先です。memtest の所要時間も容量÷帯域に比例してだいたい 1.4 倍になります。

3200 に再挑戦するなら、VDDCR SOC 1.10V → DRAM 1.40V → ProcODT 調整 → Gear Down 有効 … の順に詰めていく予定です(今は 3000 で安定運用優先)。

起動後は 78GiB と認識され、4枚とも 3000MT/s で動作。VM や常駐サービスも問題なく立ち上がりました。

Strata の導入

Strata は GitHub で公開されているオープンソースの推論エンジンです。モデルを GPU・RAM・SSD の3層に分けて置くのが特徴で、

  • GPU: よく使う部分と、アクセス頻度の高いエキスパート
  • RAM: 全エキスパート(CPU も並列で計算)
  • SSD: 大きなルックアップテーブル(n-gram 埋め込み)

という分担になっています。さらに MTP による投機的デコードで 1.6〜1.8 倍速くしています。

事前チェック

git clone https://github.com/Niko1221/Strata
cd Strata
./setup.sh --check

RTX 3060 12GB・RAM 78GB・AVX2・PCIe 4.0 x16 を認識し、IQ3_XXS は「約60GB 必要・収まる」判定でした。

インストール

./setup.sh --yes --family qwen --model IQ3_XXS --port 8081 --no-start
  • 量子化は IQ3_XXS(Q2_0 / IQ2_XS より遅いが品質重視)
  • うちでは 8080 を別サービス(Open WebUI)が使っているので 8081 に変更
  • ダウンロードは本体 47GB+29GB、MTP 約5GB
  • この環境向けの配布済みエンジンが無く、CUDA 13.0 で自動コンパイル(約15分) が走りました

起動と実測

cd Strata && ./run-iq3_xxs.sh

OpenAI 互換 API が http://127.0.0.1:8081/v1 に立ちます(127.0.0.1 のみで待ち受け)。

項目 値
読み込み時間 約1分(エキスパート 40GiB を RAM、約5GiB を GPU キャッシュ)
生成速度 約 62 tok/s(手元の Qwen3.6 q4 は約45)
RAM 使用 56〜57GB(残り約21GB)
GPU 使用 11.4GB / 12GB

64GB だと他の常駐分と合わせてかなり厳しかったはずで、80GB にしておいてよかったところです。

品質は落ちたのか ― 同じ6問で比較

3bit 級まで量子化しているので劣化が心配でしたが、同じ6問(reasoning_effort: medium)を解かせた結果がこちら。

# お題 Flash-Next クラウド Flash-Next ローカル IQ3_XXS Qwen3.6 FP8 Qwen3.6 q4
1 abs 抜け 正解 正解(68秒) 不正解 不正解
2 ロック外の読み込み 正解 正解(40秒) 正解 正解
3 10〜12月が空 正解+追加指摘 正解(54秒) 正解 正解
4 ポイント処理レビュー 良 良(123秒) 中 弱
5 保存クラスレビュー 良 良(117秒) 中 弱
6 実装 22件 22/22 22/22(27秒) 2/22 22/22
  • クラウド版との差は見当たりませんでした。Qwen3.6 に対する優位(原因の見極め・レビューの正確さ)もそのまま
  • レビューでは的外れな指摘も少し混ざりましたが、「問題ではない点」をきちんと切り分けるなど、全体としては良い内容
  • 1問あたり 30秒〜2分

ついでに、普段使っているクラウドモデルとも比べました。

# お題 Flash-Next ローカル DeepSeek-V4.1-Flash(クラウド) Gemma-4-31B(クラウド)
1 abs 抜け 正解 正解 △(説明が誤り)
2 ロック外の読み込み 正解 正解 正解
3 10〜12月が空 正解 正解 不正解
4 ポイント処理レビュー 良 良 弱
5 保存クラスレビュー 良 時間切れ(504) 時間切れ(504)
6 実装 22件 22/22 22/22 22/22
1問の時間 27〜123秒 72〜300秒 90〜300秒

質では ローカル Flash-Next ≧ DeepSeek-V4.1-Flash > Gemma-4-31B。DeepSeek との差は小さく、効いてくるのは「速さ(2〜3倍)」と「長い回答でもタイムアウトしない」点でした。

常駐させるための工夫 ― GPU の譲り合い

このサーバでは Strata 以外にも GPU を使うもの(画像生成の ComfyUI、Ollama のローカルモデル)が動きます。Strata はモデルを載せると GPU を 11.4GB 占有するので、そのままだと取り合いになり、最悪 OOM killer が走ります。

そこで「先に使っている方が優先」というルールにしました。

  • strata.service(systemd user)は受付だけ常駐(RSS 約210MB、GPU ほぼ 0)。リクエストが来たらモデルを読み込み(lazy load)、10分使われなければ下ろす
  • 読み込み前に小さなチェックスクリプト(strata-gpu-guard)を実行
    • ComfyUI が実際に生成中、または Ollama がモデルを載せている → 読み込まず 503(Retry-After 15)
    • ComfyUI が起動しているだけ(キューが空・GPU 使用 1GB 以下)→ ComfyUI を止めてから読み込む
    • GPU の空きが 11000MiB 未満 → 503
  • ComfyUI 側には drop-in で、起動前に Strata へ POST /unload?wait=300 を投げる設定を追加(回答中なら終わるまで待ってから下ろす)
    • 待ち時間が systemd 既定の 90 秒を超えるので TimeoutStartSec=360 も必要でした

最初は systemd の Conflicts= で「後から呼ばれた方が勝つ」排他にしていましたが、生成途中で相手を落としてしまうので、上の形に作り直しました。

つまずいたところ

エージェントから使ったら 32K では足りなかった

AI エージェント(Hermes Agent)から Strata を使おうとしたら「Something went wrong」で停止。 原因は、エージェント側が文脈長 64K 未満のモデルを受け付けない仕様だったこと。Strata は VRAM 12GB だと既定で 32K でした。

設定ファイルの --max-context を 65536 にして解決。GPU 上のエキスパートキャッシュが 5.36→4.88GiB に減りますが、速度への影響は体感ではほぼありません。

設定を変えても古い会話は前のモデルのまま

エージェントの既定モデルを Strata に変えても、既存の会話は会話ごとに保存されたモデル設定で動き続けます。新しい会話を始めると切り替わります。 さらに、要約などの裏方処理が自動で Ollama に流れていて、Ollama がモデルを載せる → 上のチェックで Strata が 503 → 自分で自分を締め出す、という状態になっていました。裏方処理の接続先も Strata に揃えて解消しました。

まとめ

  • 専用機を買わなくても、RAM を足すだけで 125B MoE が実用速度で動く時代になった。RTX 3060 12GB+DDR4 80GB で約62 tok/s
  • 3bit 級(IQ3_XXS)でも、6問のテストではクラウド版とほぼ同等の品質
  • ボトルネックは GPU ではなく RAM 容量。DDR4 の混在4枚挿しは自動だと 2133 まで落ちるので、手動設定と memtest は必須
  • 常時稼働機で使うなら、GPU を使う他のサービスとの「譲り合い」の設計が要る

運用としては、定期ジョブ中心のメインエージェントは安定性重視でクラウド API のまま、速さが欲しい対話やコード作業は Strata、という使い分けにしています。 RTX 5060 Ti の追加は、速度が足りなくなったときか画像生成を本格化するときに改めて考えるつもりです。

参考

最近の攻撃ニュースが怖くなったので、自分の公開サーバーを 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