<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>AI コンピューター on 向叔の手帳</title>
        <link>https://ttf248.life/ja/categories/ai-%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC/</link>
        <description>Recent content in AI コンピューター on 向叔の手帳</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>ja</language>
        <lastBuildDate>Sun, 26 Jul 2026 22:50:29 +0800</lastBuildDate><atom:link href="https://ttf248.life/ja/categories/ai-%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Vera Rubin の 10 倍 / メガワットあたりの Tokens は、AI の価格を引き下げるのか？</title>
        <link>https://ttf248.life/ja/p/vera-rubin-tokens-per-megawatt-ai-price/</link>
        <pubDate>Wed, 22 Jul 2026 21:13:54 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/vera-rubin-tokens-per-megawatt-ai-price/</guid>
        <description>&lt;p&gt;NVIDIA が DeepSeek-R1 推論について発表したベンダーのベンチマークによれば、Vera Rubin NVL72 は 1 メガワットあたりのトークン数において、比較対象の GB200 NVL72 の 10 倍の性能を示すという。これはラック規模システムでの比較であり、単一 GPU に関する結論ではない。&lt;/p&gt;
&lt;p&gt;この数字が大きすぎて、誰もが次の文を推測したくなる。同じ1メガワットで10倍の作業ができるなら、AIはすぐに値下がりするはずだ、と。&lt;/p&gt;
&lt;p&gt;方向性としては概ね正しいと思うが、結論を急ぎすぎている。&lt;/p&gt;
&lt;p&gt;まずこの「10倍」を本来のテスト枠組みに戻そう。これは NVIDIA が、DeepSeek-R1 の推論ワークロード、ラックスケール NVL72 同士のベンダー間ベンチマークとして提示したものである。つまり電力制約のあるシナリオにおいて、1 メガワットあたりでいくつの Tokens を出せるかを示しているに過ぎず、すべてのモデルが10倍速いとか、100万トークンあたりの総コストが90%減ったとは主張していない。現実の運用コストにその指標を換算するには、公表されている資料だけでは不十分である。学習、長コンテキスト、低コンカレンシー、小さなバッチサイズ、異なる精度、異なるサービス品質目標によって、別の数字が出てくる可能性がある。&lt;/p&gt;
&lt;p&gt;ただし、この指標は依然として重要です。電力アクセス、液冷、またはデータセンター納入に制約があるプロジェクトでは、同じ電力枠でより多くの推論を実行できれば、拡張のたびに変電所やデータセンターを待つ必要はありません。&lt;/p&gt;
&lt;p&gt;問題は、電気料金が原価表の中の一行に過ぎないということです。&lt;/p&gt;
&lt;p&gt;Vera Rubin NVL72 を 1 セット導入するということは、古いラック内のカードを入れ替えるだけでは終わりではありません。新しい GPU、相互接続、スイッチネットワーク、液冷、配備エンジニアリングがすべて設備投資に組み込まれます。サービスプロバイダーはさらに、減価償却期間、資金調達コスト、ソフトウェア移行、フォールトトレランス、そして利用率にも対応しなければなりません。マシンが遊んでいる状態では、たとえ 1 メガワットあたりのスループットがいかに見栄え良く見えても、それが自動的に安価な Token にはなりません。&lt;/p&gt;
&lt;p&gt;サービスプロバイダーの単位サービスコストを以下のように簡略化します：&lt;/p&gt;
$$
\text{トークン単位コスト} \approx \frac{\text{減価償却 + 電力 + データセンター回線 + 運用保守}}{\text{実際に販売された Tokens}}
$$&lt;p&gt;これは変数間の関係を簡略化した枠組みであり、公表資料から算出した TCO ではありません。这里的分母は実際に販売された Tokens であり、設備の理論的スループットではありません。&lt;/p&gt;
&lt;p&gt;每メガワット Tokens の基準が直接的に改善するのは、単位電力で支えられる推論能力であり、Token あたりの電力投入を低下させる可能性があります。需要と稼働率が伴って初めて、実際の販売量の増加によって単位サービスコストが改善されます。&lt;/p&gt;
&lt;p&gt;新システムの設備投資、減価償却、展開コストは上昇する可能性もあります。ネットワーク、ストレージ、キューイング、スケジューリングも制約要因となり得ます。システムは単一の GPU で動作しているわけではないからです。&lt;/p&gt;
&lt;p&gt;最初に起きるのは値下げとは限らない。事業者は新しい余剰容量を、より長いコンテキスト、より速い応答、より高い同時実行性、あるいは元々キュー待ちだった企業の需要を受け止めるために使うかもしれず、開発者にとっては価値があるが、価格表はすぐには変わらない可能性がある。&lt;/p&gt;
&lt;p&gt;実際の価格低下が実現するのは、新しいラックがサンプルプロジェクトから複製可能なデータセンター構成へと移行し、利用率も引き上がったときである。その時になって初めて、クラウド事業者やモデル企業、推論サービス事業者が効率向上分を顧客に還元するかどうかは、競争状況次第となる。さらに難しいのは需要の問題である。推論の低価格化が即座に10倍の呼び出し量を誘発すれば、業界全体が得られるのは一人ひとりのコスト低下ではなく、総支出の増大とデータセンターの増加かもしれない。&lt;/p&gt;
&lt;p&gt;AIインフラはデフレと拡張の両方を同時に生み出します。1回の生成はより省電力になる可能性があり、ユーザーはより良いモデル能力を得られる可能性がありますが、サービスプロバイダーは新しい能力が新たな用途を引き出すため、より多くのデータセンターを建設する可能性があります。&lt;/p&gt;
&lt;p&gt;したがって、Vera Rubin の10倍という数値は、値下げを通知する通達というよりも、値下げへのチケットのようなものです。電力に制約のあるシナリオにおける推論能力を向上させ、サービス提供者にも値下げの余地を残します。その余地を最終的に誰が手に取るのかは、ハードウェアの価格設定、減価償却、データセンターの利用率、そして競争次第です。&lt;/p&gt;
&lt;p&gt;ユーザーは最終的に「API がすぐに10倍安くなるか」といった点にこだわらなくてよい。観察する価値があるのは、もっと素朴な2つのシグナルである。同じ予算で、より速く、より長く、より信頼性の高い推論を安定的に買えるかどうか、そして供給が増えてきたとき、サービス事業者が効率性のどれだけを損益計算書に残し、どれだけを価格表に反映するか。前者はまず製品機能の形で現れるかもしれない。後者が現れるかどうか、そして現れる時期は、依然として供給、利用率、競争次第である。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.nvidia.com/en-us/data-center/vera-rubin/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NVIDIA Vera Rubin データセンター プラットフォーム&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.nvidia.com/en-us/data-center/gb200-nvl72/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NVIDIA GB200 NVL72&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.nvidia.com/en-us/networking/products/spectrum-x/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NVIDIA Spectrum-X ネットワーキング&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details class=&#34;article-notes&#34;&gt;
    &lt;summary&gt;写作附记&lt;/summary&gt;
    &lt;div class=&#34;article-notes__content&#34;&gt;
        &lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;NVIDIA Vera Rubin が全面量産に入り、Spectrum-6 ネットワークと NVL72 のエネルギー効率が 10 倍に向上。DeepSeek R1 の推論テストでは、Vera Rubin NVL72 のトークン処理量がワットあたり GB200 NVL72 比で 10 倍に向上したことが示されています。大規模に出回るようになれば、AI の価格を下げられるようになるのでしょうか。エネルギー効率の明確な向上が見られる一方で、ハードウェアへの投資は大幅に増加しています。&lt;/p&gt;
&lt;/blockquote&gt;
    &lt;/div&gt;
&lt;/details&gt;</description>
        </item>
        <item>
        <title>コードモデルにいくつかのコードアンカーを与える</title>
        <link>https://ttf248.life/ja/p/code-anchors-for-llm-requirements/</link>
        <pubDate>Sun, 05 Jul 2026 23:04:15 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/code-anchors-for-llm-requirements/</guid>
        <description>&lt;p&gt;エンコーディングモデルに要件を書くとき、私はますます、リポジトリで検索できる名前をいくつか添える傾向があります。関数名、コンポーネント名、CSSクラス名、あるいはインターフェースパスなど。これらの言葉がなければ、モデルが対応できないわけではありませんが、たいていはまず「この文章はどのコードに対応するのか」を推測する時間を一回費やすことになります。&lt;/p&gt;
&lt;p&gt;例えば、次のように書きます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ログインボタンの無効化状態を調整し、送信中に繰り返しクリックされないようにし、スタイルもグレーにする。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;人間はページ全体の印象から「ログインボタン」がどこにあるかを理解できるが、コーディングモデルは数十個のボタン、複数のログインエントリーポイント、コンポーネント・状態管理・スタイルファイルに散らばった実装に直面する可能性がある。まず自然言語の「ログインボタン」をリポジトリ内の具体的なシンボルにマッピングし、その上でイベント処理・状態変数・CSS のどれを修正すべきかを判断しなければならない。&lt;/p&gt;
&lt;p&gt;要件を以下のように変更すると、検索範囲はかなり小さくなります。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;LoginForm&lt;/code&gt; の &lt;code&gt;handleSubmit&lt;/code&gt; における送信状態を調整します。送信中は &lt;code&gt;.login-submit&lt;/code&gt; を無効化し、重複リクエストを防ぎます。既存のエラー表示の動作は変更しません。受け入れ基準: リクエストが完了していない状態で再度クリックしても 2 件目のリクエストは送信されず、ボタンは無効化されたスタイルになります。また、リクエスト完了後は元の状態に戻ります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ここで本当に役立つのはプロンプトが長くなることではなく、コード上に落とせるアンカーが数枚増えることである。&lt;/p&gt;
&lt;h2 id=&#34;モデルが予測中エージェントはまずコードを探す&#34;&gt;モデルが予測中、エージェントはまずコードを探す
&lt;/h2&gt;&lt;p&gt;現在の主流大規模言語モデルは、通常、入力をトークンに分割し、既存の文脈に基づいて後続のトークンを段階的に予測します。Transformer の自己注意機構により、シーケンス内のトークン同士が関連付けられるようになります。大規模な事前学習とそれに続くアラインメントを経ることで、モデルは指示に従い、コードを解釈し、修正案を生成することができるようになります。しかし、「文脈に基づいて生成できる」ということと、「現在のあなたのリポジトリ内のログインボタンの配置を自然に把握している」ということは同義ではありません。&lt;/p&gt;
&lt;p&gt;コーディングエージェントにはもう一つの層があります。ファイル検索、テキスト検索、読み取り、テストツールを呼び出して、リポジトリから関連コードをモデルのコンテキストに取り込みます。関数名 &lt;code&gt;handleSubmit&lt;/code&gt; やクラス名 &lt;code&gt;.login-submit&lt;/code&gt; はこの段階で二重の役割を果たします。&lt;/p&gt;
&lt;p&gt;第一の層は&lt;strong&gt;検索アンカー&lt;/strong&gt;です。自然言語における「ログインボタン」は、文言、コメント、テスト、複数のコンポーネントと一致する可能性があります。正確なシンボルはテキスト検索ツールに直接渡すことができ、定義や参照、関連するテストを素早く見つけることができます。関連のないファイルを少し読む手間を省くことで、時間とトークンを節約できるだけでなく、無関係なコードが判断を妨げるのも軽減されます。&lt;/p&gt;
&lt;p&gt;第二の層は&lt;strong&gt;意味的な制約&lt;/strong&gt;です。&lt;code&gt;handleSubmit&lt;/code&gt; は変更が送信ロジックに関連することを示唆し、&lt;code&gt;.login-submit&lt;/code&gt; は視覚的状態を特定のセレクタに限定し、&lt;code&gt;LoginForm&lt;/code&gt; はコンポーネントの境界を提供します。これらが一体となって、「そもそもどのボタンなのか、状態はどの層に置くべきなのか」という曖昧さを減らします。モデルは依然として確率的に生成していますが、選択可能な解釈が減り、次のステップが正しいコードパスに沿って展開しやすくなります。&lt;/p&gt;
&lt;p&gt;だからこそ、私はこの書き方を「プロンプトのテクニック」ではなく「座標を提供する」と呼びたいのです。座標はモデルだけでなく、モデル外部のツールチェーンにも役立ってくれます。別のコーディングモデルに置き換えたとしても、リポジトリの検索が必要である限り、これらの座標は価値を持ち続けます。&lt;/p&gt;
&lt;h2 id=&#34;優れた要件は単なるキーワードの羅列ではない&#34;&gt;優れた要件は単なるキーワードの羅列ではない
&lt;/h2&gt;&lt;p&gt;シンボル名だけでは不十分です。以下のような記述は検索しやすいものの、何に変更すべきか分かりません。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;LoginForm&lt;/code&gt;、&lt;code&gt;handleSubmit&lt;/code&gt;、&lt;code&gt;.login-submit&lt;/code&gt; を最適化してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;私が現在よく使っている書き方には、4種類の情報が含まれています。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;情報&lt;/th&gt;
					&lt;th&gt;役割&lt;/th&gt;
					&lt;th&gt;例&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;コードアンカー&lt;/td&gt;
					&lt;td&gt;検索範囲を絞り込む&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;LoginForm&lt;/code&gt;、&lt;code&gt;handleSubmit&lt;/code&gt;、&lt;code&gt;.login-submit&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;目標とする挙動&lt;/td&gt;
					&lt;td&gt;変更後に何が起こるかを説明する&lt;/td&gt;
					&lt;td&gt;送信中は重複リクエストを禁止する&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;保持する項目&lt;/td&gt;
					&lt;td&gt;隣接する挙動の偶発的な変更を防ぐ&lt;/td&gt;
					&lt;td&gt;既存のエラー表示を変更しない&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;受入条件&lt;/td&gt;
					&lt;td&gt;実装とテストの終了点を提供する&lt;/td&gt;
					&lt;td&gt;2 回目のクリックではリクエストを送信せず、リクエスト終了後に復旧する&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ファイルパスやテスト名、インターフェース名、エラーメッセージもアンカーとして機能します。自分が確認した、識別性の高い名前を優先し、具体的に見せるためにすべての関連シンボルを詰め込む必要はありません。通常、一二つのエントリ関数や一つのコンポーネント、スタイル名で、エージェントが検索を始めるには十分です。その他の呼び出し関係は、エージェントにコードから検証させるべきであり、要件作成者が記憶から補完するべきではありません。&lt;/p&gt;
&lt;p&gt;誤った座標にも警戒が必要です。関数の名称が変更されていたり、クラス名が複数の場所で再利用されていたり、あるいは要件が実際には別のページを指しているような場合、精密だが間違ったキーワードは、モデルをより速く誤った方向へと導いてしまいます。安全な表現としては、「名称が変更されている可能性があるため、まず検索して確認してください」という一文を追加するか、ページの動作と表示されるテキストの両方を提供して、エージェントに相互検証させるといった方法が挙げられます。&lt;/p&gt;
&lt;p&gt;したがって、より実用的な結論は「要件にキーワードを多く詰め込む」ことではなく、&lt;strong&gt;人のページに対する印象をリポジトリで检索可能な座標に翻訳し、さらに行動と受け入れ条件によって修正結果を制約すること&lt;/strong&gt;である。前者はコードを探すコストを減らし、後者は誤ったコードを書く余地を減らす。この両方が同時に存在して初めて、コーディングモデルの効率向上はより安定したものとなる。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/1706.03762&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Attention Is All You Need&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://arxiv.org/abs/2005.14165&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Language Models are Few-Shot Learners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/academy/what-is-ai/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Academy：AI fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/why-language-models-hallucinate/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI：Why language models hallucinate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details class=&#34;article-notes&#34;&gt;
    &lt;summary&gt;写作附记&lt;/summary&gt;
    &lt;div class=&#34;article-notes__content&#34;&gt;
        &lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;大規模モデルでコーディングの要件を書く際に、関連する関数名やフロントエンドに関連するスタイル名などのキーワードを含めると、モデルの効率が向上します。LLMの原理を少し説明し、現在の 대규모モデルの原則を解説し、なぜこのようにする方がより優れているのかについて説明します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ここでは「関数名やスタイル名を覚えればコーディング効率が上がる」という現場の判断をそのまま残しつつ、言語モデルによる生成とコーディングエージェントによる検索の違いを補足しました。Transformer の完全なチュートリアル、モデルの世代間比較、汎化的なプロンプト一覧は省いており、仕組みの説明が本来扱いたいエンジニアリング上の論点から目を逸らさないようにしました。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;</description>
        </item>
        <item>
        <title>Hermes の検索が不安定：SearXNG のアウトバウンドを Mihomo に任せる</title>
        <link>https://ttf248.life/ja/p/hermes-searxng-mihomo-proxy/</link>
        <pubDate>Sun, 21 Jun 2026 20:33:01 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/hermes-searxng-mihomo-proxy/</guid>
        <description>&lt;p&gt;Hermes を SearXNG に接続すると、表面上は検索の問題を本機内に回収したように見えます：&lt;code&gt;SEARXNG_URL=http://localhost:8888&lt;/code&gt;。しかし、国内サーバー（中華圏のサーバー）で実際に詰まりやすいのは Hermes から SearXNG への通信ではなく、SearXNG が独自に Google、DuckDuckGo、Brave、Startpage といった検索ソースへアクセスする部分です。&lt;/p&gt;
&lt;p&gt;最終的に、私はリンクを3層に分割しました。Hermes はローカルの SearXNG にのみアクセスし、SearXNG は設定内で HTTP/HTTPS のアウトバウンドリクエストを明示的に Mihomo に委ね、Mihomo が単独でサブスクリプション、ヘルスチェック、ノードの自動選択を担当します。この方法のメリットは「設定がかっこいい」ことではなく、問題発生時に階層ごとに確認できる点です。Hermes がローカル検索にリクエストを送ったか、SearXNG が JSON を返したか、Mihomo に利用可能なノードがあるか、そしてサブスクリプション自体の解析に失敗していないか。&lt;/p&gt;
&lt;p&gt;全体のフローは次のとおりです。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hermes Agent
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; http://localhost:8888
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; SearXNG
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; http://mihomo:7890
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; Mihomo が利用可能なノードを自動選択
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; 海外の検索エンジン
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ホストマシンでローカルポートのみを公開する：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1:8888  -&amp;gt; SearXNG
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1:7897  -&amp;gt; Mihomo 混合プロキシ、デバッグ用
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;127.0.0.1:9097  -&amp;gt; Mihomo コントローラー、ローカル管理用
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SearXNG と Mihomo は同じ Docker ネットワーク内にいるため、SearXNG はホストマシンの &lt;code&gt;127.0.0.1:7897&lt;/code&gt; にアクセスせず、コンテナ名でアクセスします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://mihomo:7890
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;searxng-で最も見落とされやすい-2-箇所&#34;&gt;SearXNG で最も見落とされやすい 2 箇所
&lt;/h2&gt;&lt;p&gt;Hermes が SearXNG を呼び出す際に JSON をリクエストします。SearXNG 公式 Search API ドキュメントにも明記されている通り、&lt;code&gt;format&lt;/code&gt; パラメータを使用できるかどうかは &lt;code&gt;settings.yml&lt;/code&gt; の &lt;code&gt;search.formats&lt;/code&gt; で有効化されているかどうかに依存します。有効化されていないフォーマットをリクエストすると 403 が返されます。したがって、デフォルトの HTML だけを残しておくわけにはいきません。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;safe_search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;autocomplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;formats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;2つ目はプロキシです。Docker の環境変数やシステムレベルの &lt;code&gt;http_proxy&lt;/code&gt; がアプリケーション層で安定的に継承されると過信しないでください。SearXNG のリクエストは独自に行われるため、最も直接的な方法は &lt;code&gt;outgoing.proxies&lt;/code&gt; に明示的に記述することです。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;outgoing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;request_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_request_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;40.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;extra_proxy_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;proxies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;http://&amp;#34;: &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://mihomo:7890&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;https://&amp;#34;: &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://mihomo:7890&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SearXNG のデフォルト設定例では &lt;code&gt;all://:&lt;/code&gt; という書き方が見られるため、自然に間違った設定項目ではないことが分かります。ただし、私が今回使用した環境では、&lt;code&gt;all://:&lt;/code&gt; は期待通りにマッチせず、最終的に落ち着いたのは &lt;code&gt;http://&lt;/code&gt; と &lt;code&gt;https://&lt;/code&gt; を分けて記述する方法でした。記事内でこの境界を保持しているのは、ある一度の実測結果をすべてのバージョンにおける確定的な結論のように書いてしまわないためです。&lt;/p&gt;
&lt;p&gt;完全な SearXNG の主要な設定は以下のように圧縮できます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;use_default_settings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;general&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;instance_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Hermes SearXNG&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;safe_search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;autocomplete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;formats&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;secret_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请替换成随机密钥&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;limiter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image_proxy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bind_address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;0.0.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;valkey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;valkey://valkey:6379/0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;outgoing&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;request_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;max_request_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;40.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;extra_proxy_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;proxies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;http://&amp;#34;: &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://mihomo:7890&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;https://&amp;#34;: &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http://mihomo:7890&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;engines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bing&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bing news&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bin&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;google&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;go&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;brave&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;br&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;duckduckgo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ddg&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;startpage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;wikipedia&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;wp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;arxiv&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;shortcut&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;arx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;sogou&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;360search&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;disabled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;ui&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_use_hash&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここでちょっとした落とし穴があります：SearXNG のデフォルトエンジン設定では、Bing ニュースの &lt;code&gt;name&lt;/code&gt; は &lt;code&gt;bing news&lt;/code&gt; であり、&lt;code&gt;engine&lt;/code&gt; が &lt;code&gt;bing_news&lt;/code&gt; です。&lt;code&gt;use_default_settings: true&lt;/code&gt; の場合、&lt;code&gt;engines&lt;/code&gt; は &lt;code&gt;name&lt;/code&gt; でマージおよび上書きされるため、ここでは &lt;code&gt;name: bing news&lt;/code&gt; と記述し、&lt;code&gt;name: bing_news&lt;/code&gt; とは記述しないでください。&lt;/p&gt;
&lt;h2 id=&#34;mihoma-がやることはただ1つsearxng-に安定した出口を与えること&#34;&gt;Mihoma がやることはただ1つ：SearXNG に安定した出口を与えること
&lt;/h2&gt;&lt;p&gt;Mihomo はサーバー全体を引き継ぐ必要はなく、Docker をグローバルにプロキシ経由にする必要もありません。mixed port を 1 つだけ開いて、同じ Docker ネットワーク内の SearXNG がアクセスできるようにします:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;mixed-port&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7890&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;allow-lan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;bind-address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;rule&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;log-level&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;ipv6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;external-controller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9090&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;secret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请替换成随机密钥&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;profile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;store-selected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;store-fake-ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;proxy-providers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sub&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;你的订阅地址&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;./proxy_providers/sub.yaml&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;health-check&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://www.gstatic.com/generate_204&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lazy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expected-status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;204&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;proxy-groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;AUTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;url-test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;sub&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://www.gstatic.com/generate_204&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tolerance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;lazy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expected-status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;204&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;PROXY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;proxies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;AUTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;DIRECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;sub&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;MATCH,PROXY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この設定の意味はとても限定的です：購読は 3600 秒ごとに更新され、ノードは 300 秒ごとにヘルスチェックを行い、&lt;code&gt;AUTO&lt;/code&gt; は &lt;code&gt;url-test&lt;/code&gt; でレイテンシに基づいてノードを選択し、すべてのトラフィックは最終的に &lt;code&gt;PROXY&lt;/code&gt; にマッチします。新しい設定が最初に起動されたとき、&lt;code&gt;PROXY&lt;/code&gt; リストの最初にあるのは &lt;code&gt;AUTO&lt;/code&gt; です。今後、コントロールパネルでノードを手動で切り替えた場合、&lt;code&gt;store-selected: true&lt;/code&gt; が選択を保持するため、「デフォルトで AUTO を通る」とは限りなくなります。&lt;/p&gt;
&lt;p&gt;また、サブスクリプション形式にも注意が必要です。&lt;code&gt;proxy-providers&lt;/code&gt; は provider 形式、あるいは Mihomo が provider として解析できるサブスクリプションに適しています。サービス事業者によっては、完全な Clash 設定を返すものもあれば、ノードリストを返すものもあります。ログに解析失敗のエラーが出た場合、SearXNG を疑うのではなく、まずサービス事業者の管理画面で &lt;code&gt;Clash Meta&lt;/code&gt;、&lt;code&gt;Mihomo&lt;/code&gt;、&lt;code&gt;Proxy Provider&lt;/code&gt; 形式に切り替えてください。&lt;/p&gt;
&lt;h2 id=&#34;mod-スクリプト&#34;&gt;MOD スクリプト
&lt;/h2&gt;&lt;p&gt;このスクリプトは、SearXNG を &lt;code&gt;/opt/searxng&lt;/code&gt; に配置済みのマシンを対象としています。既存の &lt;code&gt;docker-compose.yml&lt;/code&gt; と &lt;code&gt;searxng/settings.yml&lt;/code&gt; をバックアップし、本機にあらかじめ用意されている &lt;code&gt;metacubex/mihomo&lt;/code&gt; イメージをそのまま利用し、SearXNG、Valkey、Mihomo を同じ compose プロジェクトにまとめます。&lt;/p&gt;
&lt;p&gt;このスクリプトはMihomoのイメージを自動的にプルしません。SearXNGとValkeyについても、ローカルに対応するイメージがない場合、&lt;code&gt;docker compose up&lt;/code&gt;が起動できるかどうかは、ローカルのイメージとネットワーク環境によって異なります。完全にオフラインの環境では、3つのイメージを事前にすべて用意しておいてください。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo bash -s &lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;set -euo pipefail
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;APP_DIR=&amp;#34;/opt/searxng&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;COMPOSE_FILE=&amp;#34;$APP_DIR/docker-compose.yml&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;SETTINGS_FILE=&amp;#34;$APP_DIR/searxng/settings.yml&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;MIHOMO_DIR=&amp;#34;$APP_DIR/mihomo&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if [ ! -f &amp;#34;$COMPOSE_FILE&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;$COMPOSE_FILE が見つかりません。SearXNG が /opt/searxng にデプロイされているか確認してください&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if [ ! -f &amp;#34;$SETTINGS_FILE&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;$SETTINGS_FILE が見つかりません。SearXNG settings.yml のパスを確認してください&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if docker image inspect metacubex/mihomo:latest &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  MIHOMO_IMAGE=&amp;#34;metacubex/mihomo:latest&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  MIHOMO_IMAGE=&amp;#34;$(docker images --format &amp;#39;{{.Repository}}:{{.Tag}}&amp;#39; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    | awk -F: &amp;#39;$1==&amp;#34;metacubex/mihomo&amp;#34; &amp;amp;&amp;amp; $2!=&amp;#34;&amp;lt;none&amp;gt;&amp;#34; {print; exit}&amp;#39;)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if [ -z &amp;#34;${MIHOMO_IMAGE:-}&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;利用可能なローカル metacubex/mihomo イメージが検出されませんでした。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;先に確認してください：docker images | grep -i mihomo&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;ローカル Mihomo イメージを検出しました：$MIHOMO_IMAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;LOCAL_MIHOMO_IMAGE=&amp;#34;searxng-mihomo-local:latest&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;docker tag &amp;#34;$MIHOMO_IMAGE&amp;#34; &amp;#34;$LOCAL_MIHOMO_IMAGE&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;printf &amp;#34;Clash/Mihomo の購読 URL を入力してください: &amp;#34; &amp;gt; /dev/tty
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;IFS= read -r -s SUB_URL &amp;lt; /dev/tty
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;printf &amp;#34;\n&amp;#34; &amp;gt; /dev/tty
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if [ -z &amp;#34;$SUB_URL&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;購読 URL が空のため、終了します。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;mkdir -p &amp;#34;$MIHOMO_DIR/proxy_providers&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;chmod 700 &amp;#34;$MIHOMO_DIR&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;TS=&amp;#34;$(date +%Y%m%d-%H%M%S)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;cp -a &amp;#34;$COMPOSE_FILE&amp;#34; &amp;#34;$COMPOSE_FILE.bak.$TS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;cp -a &amp;#34;$SETTINGS_FILE&amp;#34; &amp;#34;$SETTINGS_FILE.bak.$TS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;バックアップを作成しました：&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;  $COMPOSE_FILE.bak.$TS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;  $SETTINGS_FILE.bak.$TS&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;MIHOMO_SECRET=&amp;#34;$(openssl rand -hex 16)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;cat &amp;gt; &amp;#34;$MIHOMO_DIR/config.yaml&amp;#34; &amp;lt;&amp;lt;YAML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;mixed-port: 7890
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;allow-lan: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;bind-address: &amp;#39;*&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;mode: rule
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;log-level: info
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;ipv6: false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;external-controller: 0.0.0.0:9090
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;secret: &amp;#34;$MIHOMO_SECRET&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;profile:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  store-selected: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  store-fake-ip: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;proxy-providers:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  sub:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    type: http
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    url: &amp;#34;$SUB_URL&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    interval: 3600
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    path: ./proxy_providers/sub.yaml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    health-check:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      enable: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      url: https://www.gstatic.com/generate_204
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      interval: 300
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      timeout: 5000
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      lazy: false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      expected-status: 204
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;proxy-groups:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  - name: AUTO
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    type: url-test
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    use:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - sub
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    url: https://www.gstatic.com/generate_204
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    interval: 300
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    timeout: 5000
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    tolerance: 50
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    lazy: false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    expected-status: 204
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  - name: PROXY
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    type: select
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    proxies:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - AUTO
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - DIRECT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    use:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - sub
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;rules:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  - MATCH,PROXY
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;YAML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;chmod 600 &amp;#34;$MIHOMO_DIR/config.yaml&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;OLD_SECRET=&amp;#34;$(grep -E &amp;#39;^[[:space:]]*secret_key:&amp;#39; &amp;#34;$SETTINGS_FILE&amp;#34; | head -n1 | sed -E &amp;#34;s/.*secret_key:[[:space:]]*[&amp;#39;\&amp;#34;]?([^&amp;#39;\&amp;#34;]+)[&amp;#39;\&amp;#34;]?.*/\1/&amp;#34; || true)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if [ -z &amp;#34;$OLD_SECRET&amp;#34; ] || [ &amp;#34;$OLD_SECRET&amp;#34; = &amp;#34;secret_key:&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  OLD_SECRET=&amp;#34;$(openssl rand -hex 32)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;cat &amp;gt; &amp;#34;$SETTINGS_FILE&amp;#34; &amp;lt;&amp;lt;YAML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;use_default_settings: true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;general:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  instance_name: &amp;#34;Hermes SearXNG&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;search:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  safe_search: 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  autocomplete: &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  formats:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    - html
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    - json
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;server:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  secret_key: &amp;#34;$OLD_SECRET&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  limiter: yml:ro
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - searxng-cache:/var/cache/searxng:rw
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    depends_on:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - valkey
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - mihomo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    networks:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - searxng-net
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    logging:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      driver: json-file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      options:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-size: &amp;#34;2m&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-file: &amp;#34;3&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  valkey:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    image: docker.io/valkey/valkey:8-alpine
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    container_name: searxng-valkey
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    restart: unless-stopped
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    command: valkey-server --save 30 1 --loglevel warning
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    volumes:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - valkey-data:/data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    networks:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - searxng-net
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    logging:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      driver: json-file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      options:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-size: &amp;#34;2m&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-file: &amp;#34;3&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  mihomo:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    image: $LOCAL_MIHOMO_IMAGE
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    container_name: searxng-mihomo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    restart: unless-stopped
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    command: [&amp;#34;-d&amp;#34;, &amp;#34;/root/.config/mihomo&amp;#34;]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    ports:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - &amp;#34;127.0.0.1:7897:7890&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - &amp;#34;127.0.0.1:9097:9090&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    volumes:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - ./mihomo:/root/.config/mihomo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    networks:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      - searxng-net
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;    logging:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      driver: json-file
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;      options:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-size: &amp;#34;2m&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;        max-file: &amp;#34;3&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;networks:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  searxng-net:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;volumes:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  searxng-cache:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  valkey-data:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;YAML
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;cd &amp;#34;$APP_DIR&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;if docker compose version &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  DC=&amp;#34;docker compose&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;elif command -v docker-compose &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  DC=&amp;#34;docker-compose&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  echo &amp;#34;docker compose / docker-compose が見つかりません&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  exit 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;サービスを開始しています...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;$DC up -d --no-build
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;サービスの起動を待機しています...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;sleep 12
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;コンテナーの状態:&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;$DC ps
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Mihomo の最新ログ:&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;$DC logs --tail=80 mihomo || true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Mihomo ローカルプロキシーポート 127.0.0.1:7897 をテストしています:&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;curl -I -sS --max-time 25 --proxy http://127.0.0.1:7897 https://www.gstatic.com/generate_204 || true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;SearXNG JSON 検索をテストしています:&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;curl -sS --max-time 50 &amp;#34;http://127.0.0.1:8888/search?q=openai%20gpt&amp;amp;format=json&amp;#34; \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;  | python3 -c &amp;#39;import sys,json; d=json.load(sys.stdin); print(&amp;#34;OK:&amp;#34;, len(d.get(&amp;#34;results&amp;#34;, [])), &amp;#34;results&amp;#34;)&amp;#39; || true
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;完了しました。&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Hermes は引き続き次の設定を使用します: SEARXNG_URL=http://localhost:8888&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;SearXNG 送信プロキシー: searxng -&amp;gt; http://mihomo:7890&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Mihomo ローカルデバッグプロキシー: http://127.0.0.1:7897&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Mihomo 制御ポート: http://127.0.0.1:9097&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;echo &amp;#34;Mihomo 設定ファイル: $MIHOMO_DIR/config.yaml&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;hermes-は検索エントリのみを保持する&#34;&gt;Hermes は検索エントリのみを保持する
&lt;/h2&gt;&lt;p&gt;Hermes 側は Mihomo について知る必要はありません。必要なのは、ローカルマシンに SearXNG があるということだけです。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nano ~/.hermes/.env
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;書き込み：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;SEARXNG_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;http://localhost:8888
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に、&lt;code&gt;~/.hermes/config.yaml&lt;/code&gt; で検索バックエンドを指定します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;web&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;search_backend&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;searxng&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hermes 公式の SearXNG skill をインストールしている場合は、引き続き使用できます。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hermes skills install official/research/searxng-search
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;もし Hermes がユーザーサービスであれば：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl --user restart hermes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl --user status hermes --no-pager
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここにも境界があります：SearXNG は検索を担当し、ウェブページ本文の抽出は担当しません。Hermes のドキュメントでも search backend と extract backend は分けられています。後で Hermes に検索結果ページの本文を読み込ませたい場合は、&lt;code&gt;web.extract_backend&lt;/code&gt; に Firecrawl、Tavily、Exa、Parallel などの抽出ソリューションを別途設定する必要があります。&lt;/p&gt;
&lt;h2 id=&#34;検証階層をスキップしないこと&#34;&gt;検証：階層をスキップしないこと
&lt;/h2&gt;&lt;p&gt;まず Mihomo をテストしてください。すぐに Hermes に問い合わせないでください。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -I --proxy http://127.0.0.1:7897 https://www.gstatic.com/generate_204
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;HTTP ステータスを返せる場合、ホストのデバッグプロキシポートが利用可能であることを示します。次に SearXNG の JSON をテストします。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -s --max-time &lt;span class=&#34;m&#34;&gt;50&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://127.0.0.1:8888/search?q=openai%20gpt&amp;amp;format=json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; python3 -c &lt;span class=&#34;s1&#34;&gt;&amp;#39;import sys,json; d=json.load(sys.stdin); print(len(d.get(&amp;#34;results&amp;#34;, [])), &amp;#34;results&amp;#34;)&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここで 403 が発生した場合は、まず &lt;code&gt;search.formats&lt;/code&gt; に &lt;code&gt;json&lt;/code&gt; が含まれているか確認してください。ここでタイムアウトが発生したり結果が空の場合は、SearXNG のログを確認してください。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /opt/searxng
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose logs -f searxng
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に、Hermes で検索をトリガーするリクエストを送信します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;OpenAI GPT の最新情報をインターネットで検索し、ソースリンクを列挙してください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ログに &lt;code&gt;/search?...format=json&lt;/code&gt; が表示されている場合、Hermes がローカルの SearXNG を呼び出していることを示しています。次に Mihomo を確認します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /opt/searxng
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose logs -f mihomo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;サブスクリプションの更新、provider、health check、AUTO といった情報に注目してください。 Mihomo がサブスクリプションを解析できていなければ、SearXNG をどれだけ正しく設定しても意味がありません。&lt;/p&gt;
&lt;h2 id=&#34;省いてはいけない境界線いくつか&#34;&gt;省いてはいけない境界線いくつか
&lt;/h2&gt;&lt;p&gt;まず、ポートをパブリックネットワークに公開しないでください。本記事の compose はローカルホストのみにバインドしています：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1:8888:8080&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1:7897:7890&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1:9097:9090&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;「変更しないでください：」のように変更しないでください。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8888&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8080&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7897&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7890&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9097&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9090&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;そうでない場合、検索サービス、プロキシポート、および Mihomo のコントロールポートは、いずれもパブリックネットワークから悪用されるリスクがあります。&lt;code&gt;external-controller: 0.0.0.0:9090&lt;/code&gt; はコンテナ内でのリッスンであり、外部からアクセスできるかどうかを実際に決定するのは compose のポートバインディングです。&lt;/p&gt;
&lt;p&gt;第二に、Google や Startpage が頻繁にタイムアウトする場合、すぐにリンク構成全体を否定的に見直さないでください。まず Bing、Brave、DuckDuckGo、Wikipedia、arXiv などをそのまま残しておき、Mihomo のサブスクリプションとヘルスチェックが安定してから、验证码やタイムアウトを引き起こしやすいエンジンを有効にしてください。&lt;/p&gt;
&lt;p&gt;第三に、スクリプトのロールバックポイントが明確である点です。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /opt/searxng
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp docker-compose.yml.bak.あなたのタイムスタンプ docker-compose.yml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp searxng/settings.yml.bak.あなたのタイムスタンプ searxng/settings.yml
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;私はサーバー全体にグローバルプロキシを適用するよりも、このように役割を分割するアプローチを好みます。グローバルプロキシの問題は影響範囲が広すぎることであり、障害が発生した際に、それがシステム環境、Docker、アプリケーション設定、それともプロキシノード自体が原因なのかを判断するのが難しくなります。Hermes、SearXNG、Mihomo はそれぞれ一つの役割だけを担うため、トラブルシューティング時にはむしろ楽になります。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/web-search&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent：Web Search &amp;amp; Extract&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/skills/optional/research/research-searxng-search&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent：Free meta-search via SearXNG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.searxng.org/dev/search_api.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SearXNG Search API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.searxng.org/admin/settings/settings.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SearXNG settings.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.searxng.org/admin/settings/settings_outgoing.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SearXNG outgoing settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.searxng.org/admin/settings/settings_engines.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SearXNG engines settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/searxng/searxng/blob/master/searx/settings.yml&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SearXNG デフォルト settings.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://wiki.metacubex.one/en/config/proxy-providers/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mihomo proxy-providers configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://wiki.metacubex.one/en/config/proxy-groups/url-test/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mihomo url-test proxy group&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details class=&#34;article-notes&#34;&gt;
    &lt;summary&gt;写作附记&lt;/summary&gt;
    &lt;div class=&#34;article-notes__content&#34;&gt;
        &lt;p&gt;この文章では、元の素材の中で最も実用的な部分を保持しています。具体的には、階層化アーキテクチャ、SearXNG JSON、明示的な outgoing proxy、Mihomo の provider とヘルスチェック、Docker Compose、Hermes 設定、検証コマンド、よくある質問、そしてロールバックです。削減したのは繰り返しの説明や、誤解を招きやすい絶対的な表現です。たとえば &lt;code&gt;all://:&lt;/code&gt; は汎用的に無効な設定ではなく、この環境では期待どおりにマッチしなかっただけです。&lt;/p&gt;
&lt;p&gt;また、設定名を1か所修正しました：SearXNG の Bing ニュースエンジンは &lt;code&gt;name: bing news&lt;/code&gt; と記述する必要があります。&lt;code&gt;name: bing_news&lt;/code&gt; と書くと、デフォルトのエンジン名と一致しないため、通常のスペルミスよりもリスクが高くなります。&lt;/p&gt;
&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;ユーザーは、「中国国内サーバーへの Hermes + SearXNG + Mihomo デプロイ：Hermes 検索をプロキシ経由にし、利用可能なノードを自動選択させる」と題した完全なデプロイ資料を提供し、整理・分析して記事に誤りがないことを確認した上で、ブログ執筆スキルを呼び出して記事にまとめるよう求めています。&lt;/p&gt;
&lt;p&gt;資料には、背景、目標アーキテクチャ、なぜシステムプロキシを使用しないのか、SearXNG settings.yml、Mihomo config.yaml、Docker Compose、改造スクリプト、Hermes 設定、検証フロー、よくある質問、ロールバック方法、最終的な効果が含まれています。&lt;/p&gt;
&lt;/blockquote&gt;

    &lt;/div&gt;
&lt;/details&gt;</description>
        </item>
        <item>
        <title>Loop engineering 的人物を checkpoint に移動する</title>
        <link>https://ttf248.life/ja/p/loop-engineering-human-checkpoints/</link>
        <pubDate>Sun, 14 Jun 2026 07:35:00 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/loop-engineering-human-checkpoints/</guid>
        <description>&lt;p&gt;昨日 MiniMax のオフライン開発者会議に参加して、戻ってきてからずっと頭から離れない言葉がある：loop engineering。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;简单说，就是把&amp;quot;提示词—模型输出—反馈&amp;quot;做成一个闭环，让模型自己改 prompt、自己改自己。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;筆者の理解では、これは要するに「プロンプト → モデルの出力 → フィードバック」という闭环を作り、モデル自身がプロンプトを改め、自らを改善していく仕組みのことである。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;但它真正让人不安的地方在于：当 loop 足够长、反馈足够稠密，模型就开始越过&amp;quot;工具&amp;quot;那条线，开始自己决定要解决的问题、自己判断完成的标准。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;しかし本当に不安を感じさせる点は、loop が十分に長く、フィードバックが十分に密になると、モデルが「ツール」という一線を越えてしまい、自らが解決すべき問題を決め、自らが完成の基準を判断し始めることだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;记得大会上有个工程师打了个比方说：&amp;ldquo;以前我们养的是宠物，loop engineering 养的是同事。&amp;rdquo;&lt;/p&gt;
&lt;p&gt;最初はエージェントを何ラウンドか回すだけだと思っていた。この理解はあまりにも浅はかだった。本当に行き詰まったのは、AI がコードを書く速度がもはや人間がコードをレビューする速度を大幅に超えてしまっているということで、もし人間の関与が「すべてのステップを確認し、すべてのステップで判断する」レベルにとどまっているなら、最終的に生産性は人間の確認速度によって制限されてしまう。&lt;/p&gt;
&lt;p&gt;これは、私が最近 Codex を使って感じたこととつながる。以前&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/codex-goal-command-explained/&#34; &gt;その目標に関する記事&lt;/a&gt;を書いた時、私がより注目していたのは「完了条件」という事柄だった。何が目標で、どこに境界線があり、何で検証し、いつ完了とみなすのか。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;以下は補足です。最初の文「この文章は CC BY-NC-SA 4.0 のライセンスで公開されています。」のような前置きや、結論段落の「この方向が正しいと確信している理由は、まだこれからです。」も訳した方がよろしいですか？必要であれば、追加で翻訳いたします。&lt;/p&gt;
&lt;p&gt;大会が終わって改めて振り返ると、goal は loop engineering の中の小さくはあるが非常に重要な一部分に過ぎない。gole は、単一のタスクが人間から繰り返し指示されなくても前に進めるようにするためのものだ。さらに大きな問題は、どのタスクをループに任せるべきか、どのチェックポイントを人間に残すべきか、どの判断を事前にシステムに書き込んでおくべきか、どの責任を AI に押し付けるべきではないのか、ということだ。&lt;/p&gt;
&lt;p&gt;今の私が最も契合するシナリオは二つあると感じています。&lt;/p&gt;
&lt;p&gt;ひとつはパフォーマンス最適化です。これはもともと指標があり、できれば自動再テストも備えています。エージェントに「インターフェースの P95 をいくつまで下げる」「ファーストビューを何ミリ秒に抑える」「バンドルサイズを何 KB まで削減する」「回帰テストは失敗させてはいけない」と伝えます。エージェントは変更するたびにベンチマーク・プロファイリング・負荷テストを毎回実行し、目標に達しなければボトルネックの探索を続けます。ここで人の価値は毎回どの行を修正したかを確認することではなく、まず受入可能な指標を提示し、そのうえで重要な節目で「この最適化が業務セマンティクスを変えていないか」を判断することにあります。&lt;/p&gt;
&lt;p&gt;もう一つは UI のリファクタリングです。その前提として、明確なデザイン案が必要となります。理想的には 1:1 で忠実に再現できることが望ましいです。デザイン案がない場合、人は「このマージンがおかしい」「この色が違和感ある」「このインタラクションは違う」といった瑣末な判断に常に引き戻されてしまいます。デザイン案があれば、AI のループはスクリーンショット、DOM、スタイル、視覚的な差分を中心に収束させることができます。人はすべての CSS 調整につき従う必要はありませんが、最終的な UI には責任を持つべきです。&lt;/p&gt;
&lt;p&gt;これら 2 つのシナリオに共通しているのは、検収物が「もっとうまくやってほしい」のような一言ではないということです。パフォーマンス最適化には数値があり、UI リファクタリングにはデザインがあります。ループが機能するのは、AI がより従順だからではなく、タスク自体に比較可能な目標があるからです。&lt;/p&gt;
&lt;h2 id=&#34;multica-は共同作業ボードのようなものです&#34;&gt;Multica は共同作業ボードのようなものです
&lt;/h2&gt;&lt;p&gt;会場では、オープンソース界隈の人々からプロジェクトの紹介を受けることもあり、その中で Multica はなかなか興味深いものでした。帰って調べてみたところ、これは新しい单体（单体）的コーディングエージェントではなく、Claude Code、Codex、GitHub Copilot CLI、OpenCode、Gemini、Kimi、Cursor Agent などのツールを同じタスク協調レイヤーに接続するものだと分かりました。&lt;/p&gt;
&lt;p&gt;その README では、agent を teammate として記述しています。issue を割り当てられたり、blocker を報告したり、ステータスを更新したり、カンバンやコメント、タスクのライフサイクルに登場したりします。ドキュメントではさらに具体的に、agent は workspace の一級メンバーであり、issue を assign でき、コメントで発言でき、&lt;code&gt;@&lt;/code&gt; でメンションされ、agent を作成するときには背後にある AI coding tool を選択でき、instructions、model、環境変数、CLI 引数、可視性、並行制限を設定できると説明されています。&lt;/p&gt;
&lt;p&gt;これにより、「どのモデルを使うか」がプロンプトの中での一時的な選択から、チームコラボレーションにおける役割の設定へと変わります。&lt;/p&gt;
&lt;p&gt;この仕組みの最も興味深い点は、「マルチエージェント」という言葉そのものではなく、異なるエージェントに異なる役割を割り当てられることだ。例えば、あるエージェントには安価なモデルを使って反復的な修正を担当させ、別のもっと強力なモデルを使うエージェントにはアーキテクチャの判断を担当させ、さらに別のエージェントにはレビューだけを行わせてコードは変更させない。こうしてSquadのような仕組みを組み合わせ、リーダーエージェントがissueの内容に応じてタスクを適切なメンバーにルーティングするのである。&lt;/p&gt;
&lt;p&gt;私は Multica を最初から最後まで完全に動かしたわけではないので、ここでは公開されている資料で照合できるサンプルとして扱うしかない。ただ、この設計の方向性は loop engineering と同じ種類の問題であり、1 つの AI にすべてを任せるのではなく、タスク・役割・モデル・レビュー・状態遷移を同じループの中に組み込むというものである。&lt;/p&gt;
&lt;p&gt;企業が実際にAIによるコーディング導入を検討する場合、この違いは非常に重要である。&lt;/p&gt;
&lt;p&gt;現在はモデルごとに価格も能力の境界も異なっています。すべてのタスクに最も高額なクローズドソースモデルを使うと、コストを必ずしもちません。すべてのタスクに安いモデルを使うと、手戻り作業やレビュー漏れによってコストが後段に移転する可能性があります。より現実的な方法は階層化することです。リスクが低く、反復的で、境界がはっきりしている作業はまず安いモデルに任せます。重要な変更、アーキテクチャの取捨選択、最終レビューは、より高性能なモデルや人に残します。&lt;/p&gt;
&lt;p&gt;クローズドソースの高性能モデルがレビュー担当として使われるのは、私は良い位置取りだと思います。レビューは単に「文法ミスを見つける」だけではなく、要件が歪められていないか、境界を越えていないか、テストが表面しかカバーしていないか、コミットメッセージがリスクを隠していないかを確認する必要があります。このようなタスクにはより高い判断力が求められますが、実装段階ほど呼び出し頻度は高くないかもしれず、コストの計算もより受け入れやすくなります。&lt;/p&gt;
&lt;h2 id=&#34;人手の関与が少ないことは人が責任を負わないということではない&#34;&gt;人手の関与が少ないことは、人が責任を負わないということではない
&lt;/h2&gt;&lt;p&gt;円卓会議であった意見に私も共感する点がある：コードはAIが書くが、コードを提出するのは人間である。&lt;/p&gt;
&lt;p&gt;この言葉は責任を問うリマインダーのように聞こえるが、実はプロセス設計の原則でもある。AI はコードを書いたり、修正したり、テストを実行したり、PR の説明を生成したり、さらには別のモデルに先にレビューさせることもできる。しかし、最終的にコードをメインブランチにマージする人は、「これは AI が書いたもので、自分には関係ない」とは言えない。&lt;/p&gt;
&lt;p&gt;会社で求められるのは、誰がキーボードで文字を打ったかではなく、誰が結果に責任を持つかだ。あなたが提出したということは、今回の変更のビジネスセマンティクス、リスク境界、テストのエビデンス、ロールバック計画に対して責任を持つ意思があるということだ。AI の関与が深いほど、この点を曖昧にしてはならない。&lt;/p&gt;
&lt;p&gt;つまり、loop engineering は人をプロセスから完全に排除するものではありません。むしろ、人の配置を再構築するようなものです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;タスク開始前に、人間が目標、境界、受け入れ基準を明確にする。&lt;/li&gt;
&lt;li&gt;ループ実行中、システムとエージェントが反復的な試行、テスト、修正、状態同期を自ら処理する。&lt;/li&gt;
&lt;li&gt;重要な節目では、人間が証拠、差異、リスクを確認し、AI の出力を逐行で追わない。&lt;/li&gt;
&lt;li&gt;コードを提出する際、結果に対する責任は人間が負い、AI を免責の理由にしない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;だからこそ私は、goal、性能指標、デザイン稿、Multica という、一見ばらばらのものを結びつけているのです。これらはすべて、人の判断を前倒しにし、外在化し、構造化しています。人の関与は少なくなりますが、関わるポイントはより重要になります。&lt;/p&gt;
&lt;p&gt;この件をうまくやらないと、別の形の非効率になってしまう。AI が多くを生み出すが、人間がレビューしきれず、最終的にチームは「何となく大丈夫そう」という感覚でコードをマージする。問題が起きた後、その責任を AI に押し付ける。それはエンジニアリング化されたとは言えず、単に混乱の生産者を変えただけにすぎない。&lt;/p&gt;
&lt;p&gt;本当に追いかける価値のあるループとは、AI にずっと書き続けさせることではなく、書く・直す・テストする・レビューするという各ラウンドを、同じ受入チェックリストに立ち返らせることなのだ。人の仕事は「書いているのを見張る」ことから、「何が良しとされるかを定義し、エビデンスが十分かを確認し、提出物に責任を持つ」ことへと変わる。loop engineering という言葉がずっと私の心に留まっているのは、たぶんこの点なのだ。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/multica-ai/multica&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Multica GitHub README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://multica.ai/docs/agents&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Multica Docs: Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://multica.ai/docs/agents-create&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Multica Docs: Create and configure an agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://multica.ai/docs/providers&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Multica Docs: AI coding tools matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://multica.ai/docs/squads&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Multica Docs: Squads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details class=&#34;article-notes&#34;&gt;
    &lt;summary&gt;写作附记&lt;/summary&gt;
    &lt;div class=&#34;article-notes__content&#34;&gt;
        &lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;$blog-writer 昨日、Minimaxのオフライン開発者会議に参加したのですが、ずっと頭から離れなかったものがあり、それは「loop engineering」です。最近は codex を使ってコード開発をしていますが、goal も使うのが好きで、goal に関する記事を書いたこともあります。2 つのユースケースを発見しましたが、最も契合するのは次の 2 つです。1 つはパフォーマンス最適化で、要求したパフォーマンス指標を直接出力してくれること。もう 1 つは UI リファクタリングで、デザイン案を提供すれば 1:1 で復元してくれることです。冒頭に述べた loop engineering に戻ると、AI 時代のプログラミングでは、AI の生産性は人間を遥かに超えているため、人間のレビュー速度では AI の出力速度にまったく追いつけません。しかし、現在の vibe coding では、多くの意思決定に依然として人間の関与が必要です。人間の関与が増えると、全体的なフローを完全に自動化することが難しくなります。loop engineering の理念は、まさに人間の関与の度合いを下げることにあります。また、オープンソースコミュニティの人々が自らのプロジェクトを宣伝するのにも遭遇しましたが、その中で特に興味深いプロジェクトが一つありました。それは Multica です。関連情報を調べて、簡単に紹介してみてください。彼の設計理念を除いて、最も興味深い点は、与えられたモデルごとに異なるアイデンティティを付与することで、各社の大規模モデルを効果的に活用できることです。結局のところ、現在モデルの価格はさまざまで、ソース非公開のモデルにレビューを行わせるというのは良いアプローチです。会社における AI コードの導入について、ラウンドテーブルのディスカッションで一致していた見解もあります。コードは AI が書きますが、コードを提出するのは人間であり、提出するコードに対して責任を負う必要があります。これはあなたの責任感や、物事に取り組む姿勢を示すものです。AI が書いたものだから、自分とは関係がないとは言えません。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;執筆思路の要約&#34;&gt;執筆思路の要約
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;2026-06-13 に MiniMax のオフライン開発者会議に参加するという現場のきっかけを保持し、それをカンファレンスのレポートに膨らませることはしない。&lt;/li&gt;
&lt;li&gt;主軸を「人の参与位置がどう変わるか」に収斂させ、loop engineering、goal、Multica、そして会社の責任を逐一説明することはしない。&lt;/li&gt;
&lt;li&gt;Multica のパートは公開資料で裏付けられる能力のみを記述し、「クローズドソースのモデルを審査に用いる」という点は著者の判断として明示する。&lt;/li&gt;
&lt;li&gt;具体的なモデルの価格、会社の管理制度、コードレビューのフローに関する展開は抑え、記事がワークフローの観察から管理制度の提言に脱線するのを避ける。&lt;/li&gt;
&lt;/ul&gt;
    &lt;/div&gt;
&lt;/details&gt;</description>
        </item>
        <item>
        <title>Codex がインターフェースを書くのに失敗したあと、ChatGPT に UI を描かせる</title>
        <link>https://ttf248.life/ja/p/codex-chatgpt-ui-mockup-workflow/</link>
        <pubDate>Sun, 14 Jun 2026 05:14:22 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/codex-chatgpt-ui-mockup-workflow/</guid>
        <description>&lt;p&gt;最初は単にフロントエンドの整備が後回しになっているだけだと思っていました。&lt;code&gt;strategy_studio&lt;/code&gt; のビジネスロジックは着実に前へ進んでおり、行情同期、PostgreSQL、非同期バックテスト、レポートの DB 格納、リサーチワークベンチへと次々と接続されていきましたが、ページは「機能を先に乗せ、 UI は後で清算する」ような状態に見えてきました。Codex に UI を破壊的に再構築させようとしたとき、初めて問題がはっきりと表面化しました。プロンプトをどれだけ強く書いても、界面は古い枠の中でコンポーネントを挪動させているだけのように見えました。&lt;/p&gt;
&lt;p&gt;Codex を使ってコードを改善するのは、今回が初めてではありません。バックエンドのロジック、API 連携、テスト修正、レポート生成といったタスクは、ふだんからそのままゴールだけ放り込んで、ファイルを読ませ、コードを修正させ、検証を走らせ、コミットさせています。問題になったのはフロントエンドのリファクタリングです。今回は UI のデザイン案を先に作らず、しかも事前に業務の土台を先に組み上げてしまいました。一度でも旧 UI が存在すると、モデルに見えるのは要件だけではありません。既存のコンポーネント、既存のルーティング、既存のスタイル、そしていくつかの歴史的な慣性までもが見える状態になります。&lt;/p&gt;
&lt;p&gt;私の最初の反応もとても普通でした：プロンプトを追加し続ける。破壊的な再構成を許可し、UIとインタラクションのロジックを再設計し、要素を詰め込みすぎず、24インチと32インチのモニターに対応し、コア機能に焦点を絞り、保守的にならない。一つ一つの文は単体で見ればどれも正しいのですが、全部合わせてもまだ何かが足りません：最終的に一体どうあるべきか、ということです。&lt;/p&gt;
&lt;h2 id=&#34;つまずくのはボタンの色ではない&#34;&gt;つまずくのはボタンの色ではない
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;strategy_studio&lt;/code&gt; はボタンが 2、3 個しかない小さなツールではありません。README では、すでに中国語を優先した戦略研究プラットフォームとして位置付けられています。Next.js のフロントエンド、FastAPI の API、PostgreSQL、Worker、Scheduler、Yahoo 同期パイプラインが一緒に動作します。さらにフロントエンドの README は、ページを 1 つのリサーチワークベンチへと集約しています。サンプル準備、実験構成、タスク追跡、結果レビュー、テンプレート管理、そしてレポート詳細と運用・保守のエントリポイントです。&lt;/p&gt;
&lt;p&gt;このプロジェクトにおけるフロントエンドの問題は、表面上は「十分に美しくない」というものですが、実際には情報の秩序が定まっていないことにあります。ユーザーはまず相場を見るのか、それともまずバックテストのタスクを見るのか。レポートの詳細画面では、曲線、指標、入力パラメータ、再実行ボタンのうちどれがより重要なのか。トップページはナビゲーションのページなのか、それともワークスペースなのか。大画面では要素を隙間なく敷き詰めるのか、それとも余白を持たせるのか。&lt;/p&gt;
&lt;p&gt;これらの判断は文章だけで説明されているため、Codex は「既存ページの中で少し最適化する」という解釈を容易にしてしまいます。コンポーネントの変更、余白の調整、色の変更などを行いますが、それでも古い構造に沿って作業を進めます。破壊的なリファクタリングを許可するだけでは不十分です。なぜなら、破壊的なリファクタリングが解決するのは「コードを大幅に変更できるかどうか」という問題であり、「検証可能なビジュアル目標が存在するかどうか」という問題ではないからです。&lt;/p&gt;
&lt;p&gt;日中に一度出かけたのですが、夜になって急に思いつきました。Codex に UI を推測させるのはやめよう。まずは ChatGPT の Web 上で UI デザイン案を描き出して、その画像を Codex に渡して再現させよう。&lt;/p&gt;
&lt;p&gt;当時使っていたプロンプトはとても直接的でした：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://github.com/ttf248/strategy_studio 現在のプロジェクトのフロントエンドコードを分析し、業務ロジックを理解した上で、プロのUIデザイナー・インタラクションデザイナーとして、フロントエンドページを設計し直してください。各ページごとに個別に画像を作成し、24インチ・32インチのディスプレイに対応させ、要素を必要以上に詰め込みすぎず、ユーザーが中核機能に集中して使いやすいようにしてください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;このステップで出た効果は、Codex で形容詞を積み重ね続けるよりもずっと安定している。Codex にはまず可視的な目標が与えられる。ページをどう並べるか、モジュール比率をどう分けるか、ビジュアルセンターの配置、余白のおおよその目安といったものだ。その後の Codex が取り組むタスクは、「審美眼を頼りに再設計する」ことから「図に基づいて業務を理解しコードを復元する」へと変わる。&lt;/p&gt;
&lt;h2 id=&#34;配色も先に素材にしよう&#34;&gt;配色も先に素材にしよう
&lt;/h2&gt;&lt;p&gt;初稿の図でレイアウトの問題は解決しましたが、デフォルトの配色が依然として通常のバックエンドシステムらしい青と白であり、私の美的感覚にはあまり合っていません。ここで「青と白が好きじゃない、もっと落ち着いた配色にして」とそのまま Codex に投げてしまうと、本質的にはまた推測させることになります。&lt;/p&gt;
&lt;p&gt;これが最初の青と白のカラーリングバージョンです。ページ構造を示すことはできていますが、まだ普通の管理画面の雰囲気です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://ttf248.life/p/codex-chatgpt-ui-mockup-workflow/strategy-studio-white-blue-blog.webp&#34;
	width=&#34;1200&#34;
	height=&#34;675&#34;
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Strategy Studio 初版藍白 UI 稿&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;その後、私はやり方を変えました。まず ChatGPT のウェブ版で配色の方向性について話し合い、ベースカラー、アクセントカラー、カードの階層、そして研究ツールらしい雰囲気について明確に伝えました。その上で、画像モデルにその方向性に従って意図を示してもらいました。これは正式な Figma ではなく、完全なデザインシステムでもありませんが、フロントエンドの再構築で最もずれやすい要素を固定するには十分です。&lt;/p&gt;
&lt;p&gt;最終的に手にしたのは「大きく網羅した1枚のホームページ」ではなく、ページごとに分かれたデザイン原稿です。ホームページ、行情研究、バックテスト実験、レポートセンター、レポート詳細、ストラテジーテンプレート、運行保守。 &lt;strong&gt;この分割方法が非常に重要&lt;/strong&gt; です。&lt;code&gt;strategy_studio&lt;/code&gt; のフロントエンドはマーケティングページではなく研究ツールです。ホームページ、行情ページ、レポート詳細ページが担う閲覧タスクはそれぞれ異なるため、すべてを同じカードグリッドに詰め込むことはできません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://ttf248.life/p/codex-chatgpt-ui-mockup-workflow/strategy-studio-home-blog.webp&#34;
	width=&#34;1200&#34;
	height=&#34;675&#34;
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Strategy Studio ホームページデザイン&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://ttf248.life/p/codex-chatgpt-ui-mockup-workflow/strategy-studio-report-detail-blog.webp&#34;
	width=&#34;1200&#34;
	height=&#34;675&#34;
	
	loading=&#34;lazy&#34;
	
		alt=&#34;Strategy Studio レポート詳細デザイン&#34;
	
	
		class=&#34;gallery-image&#34; 
		data-flex-grow=&#34;177&#34;
		data-flex-basis=&#34;426px&#34;
	
&gt;&lt;/p&gt;
&lt;p&gt;図が描けたことで、Codexの役割が明確になります。CodexはゼロからUIデザイナーを務めるのではなく、既存のビジネスロジックを読み、コンポーネントを分解し、レイアウトを調整し、インタラクション状態を揃え、lint/buildを実行し、そして旧フロントエンドを設計稿に近い目標状態にリファクタリングします。&lt;/p&gt;
&lt;h2 id=&#34;単なるウェブ版の方が賢いではない&#34;&gt;単なる「ウェブ版の方が賢い」ではない
&lt;/h2&gt;&lt;p&gt;その後、公式資料をもう少し調べてみたが、この件を「異なるチャネルの ChatGPT の知能レベルが異なる」や「Codex を直接使用すると機能が制限される」と解釈できるかどうかを確認したかった。この説明はあまりにも粗い。&lt;/p&gt;
&lt;p&gt;OpenAI による Codex CLI の説明は、ローカルのターミナルで動作する coding agent に関するものです。現在のディレクトリにあるコードを読んだり、変更したり、コマンドを実行したりできます。Codex web は、クラウド環境でコードタスクを処理します。OpenAI が Codex agent loop について語るとき、重視しているのは「モデルがすべてを凭空に生み出す」ことではなく、モデルの推論、文脈管理、ツール呼び出し、ファイルの読み書き、コマンド実行が一体となってソフトウェアタスクを構成するという点です。&lt;/p&gt;
&lt;p&gt;ChatGPT Images は別のエントリーポイントです。OpenAI Help における Images in ChatGPT の説明によると、ユーザーは会話内で画像を作成および編集したり、モックアップやクリエイティブなビジュアルを作成したりできます。この製品の形態は、納品物がコードではなく画像であるため、ビジュアル目標をまず探索するのに本質的により適しています。&lt;/p&gt;
&lt;p&gt;したがって、今回の違いは「どちらがより賢いか」ではなく、タスクの形態が異なるという点にあります。「UIの再設計」を直接 Codex に任せると、コードリポジトリの視点で考えます。どのファイルを修正すべきか、どのコンポーネントを壊してはいけないか、どうすればビルドを通すことができるかを考えます。同じビジネスコンテキストをまず ChatGPT Images に渡すと、抽象的な美的感覚と情報の階層をまず見える目標画像に圧縮します。&lt;/p&gt;
&lt;p&gt;これはまた、後になって Codex がむしろ使いやすくなる理由を説明している。設計ドキュメントが Codex を回避したのではなく、設計ドキュメントが Codex にコンテキストと受け入れ基準を補完したのである。公式の Codex prompting ドキュメントも、Codex に関連ファイル、画像、明確な完了基準を提供することを強調している。図がない場合、「要素を密集させすぎないでください」は単なる形容詞に過ぎないが、図があって初めて、それは再現可能なレイアウト制約となる。&lt;/p&gt;
&lt;h2 id=&#34;よりスムーズなリンク&#34;&gt;よりスムーズなリンク
&lt;/h2&gt;&lt;p&gt;これ以降は、この種フロントエンドのリファクタリングを3つのパートに分割することにします。&lt;/p&gt;
&lt;p&gt;第一段階は、まずビジュアル探索から始めます。ChatGPT の Web 版にリポジトリを読ませ、業務を理解させ、ページごとに画像を生成させ、色使い、密度、大画面対応、ビジュアル階層といった点を中心に繰り返し調整します。この段階で生み出される成果物はコードではなく、目標となる画像です。&lt;/p&gt;
&lt;p&gt;第二段階では、目標画像とエンジニアリング上の制約を Codex に渡します。プロンプトは「UI を再設計してください」で止めてはいけません。代わりに、どの画像を目標とするか、どのビジネスロジックを壊してはならないか、どのページが破壊的な再構築を許可されているか、どのテストとビルドが通らなければならないかを明確に記述する必要があります。&lt;/p&gt;
&lt;p&gt;第三段落ではエンジニアリングによる復元に入ります。ここで初めて Codex にゴールモードや連続タスクモードを使わせるのに適しています。まずフロントエンドの構造を読み取り、次にページごとに分割して実装します。各ページが完了したら検証を実行し、最後にインタラクションとレスポンシブ対応を一括して確認します。&lt;/p&gt;
&lt;p&gt;以前は「プロンプトをもっと強く書くこと」を解決策だと考えがちでした。今振り返ると、フロントエンドのリファクタリングにおいて本当に有効なのは強引さではなく、不足している中間成果物を補うことだと分かります。UI デザインがない場合、破壊的なリファクタリングは単に分解を広げるだけに過ぎません。UI デザインがあって初めて、破壊的なリファクタリングには正しい方向性が生まれます。&lt;/p&gt;
&lt;p&gt;このフローは &lt;code&gt;strategy_studio&lt;/code&gt; にしか使えないわけではない。すでにビジネスロジックはあるものの、フロントエンドをずっと後付けで継ぎ足してきたような個人プロジェクトなら、どれでも同じ要領で進められる。まず画像モデルに UI のゴールを描かせ、次に Codex にそのゴールをコードに変換させる。各モデルが互いに代替し合うのではなく、それぞれ得意な工程を担当するという形だ。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ttf248/strategy_studio GitHub リポジトリ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio/blob/main/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Strategy Studio README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio/blob/main/frontend/README.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Strategy Studio Frontend README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio/tree/main/ui&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Strategy Studio UI デザイン原稿ディレクトリ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/11084440-images-in-chatgpt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help：Images in ChatGPT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/9260256-chatgpt-capabilities-overview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Help：ChatGPT Capabilities Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/cli&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Developers：Codex CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/cloud&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Developers：Codex web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/prompting&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI Developers：Codex prompting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://openai.com/index/unrolling-the-codex-agent-loop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenAI：Unrolling the Codex agent loop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;details class=&#34;article-notes&#34;&gt;
    &lt;summary&gt;写作附记&lt;/summary&gt;
    &lt;div class=&#34;article-notes__content&#34;&gt;
        &lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;$blog-writer 日常的に codex を使って ChatGPT モデルを调用しコードを書いているが、オープンソースプロジェクト &lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ttf248/strategy_studio&lt;/a&gt; を開発する際、当初は UI モックアップを作成せず、直接ビジネスロジックの開発を行っていた。そのためフロントエンドの UI が計画されておらず、codex 内で直接プロンプトを書いてみた。「破壊的なリファクタリングを許可し、UI とインタラクションロジックを再設計してください」と指示したが、調整してもなかなか良い結果が得られなかった。この時点ではまだ codex の問題を疑っていなかった。昼間外出した夜、ふと閃いた。「Web 版で image2 を呼び出して UI デザイン案をいくつか生成し、それを codex に渡して goal モデルで復元開発してもらえばいいのでは？」と。早速試してみたところ、全く問題なく進められた。使用したプロンプトはこちら: &lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ttf248/strategy_studio&lt;/a&gt; プロジェクトのフロントエンドコードを解析し、ビジネスロジックを理解したうえで、プロの UI デザイナー、インタラクションデザイナーとして、フロントエンドページを一式再設計してください。各ページごとに個別に画像を出力し、24 インチと 32 インチのディスプレイに対応させ、要素が密集しすぎないようにして、ユーザーがコア機能に集中しやすくしてください。これでかなり良い結果が得られたが、デフォルトの配色（よくある青と白の組み合わせ）が自分の好みには合わなかった。そこでさらに調整した。まず Web 上で適切な配色をいくつか相談し、image にその配色でデモ画像を生成させる。次にその配色方案と先ほどのプロンプトを組み合わせることで、以下を得ることができた: &lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio/tree/main/ui&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ttf248/strategy_studio/tree/main/ui&lt;/a&gt;。書いた内容が多いので、整理して一篇の記事にまとめてほしい。分からない点があれば、自分でネット検索して調べてください。提供した &lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/strategy_studio/tree/main/ui&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/ttf248/strategy_studio/tree/main/ui&lt;/a&gt; には画像がたくさんあるので、適当に 2 枚ほど選んでブログに貼り付けてください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;執筆思路の概要&#34;&gt;執筆思路の概要
&lt;/h3&gt;&lt;p&gt;この書き直しでは、原文の判断と材料をそのまま保ちながら、冒頭部分を「まずは完全な答えを示す」から「フロントエンドのリファクタリングで行き詰まった現場に入る」に変更している。記事は汎用的なモデル評価を省き、今回のワークフローで実際に効果があった転換、つまり視覚的な目標をあまずグラフ化し、それから Codex にエンジニアリングの復元を行わせる、という点だけを記述している。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;</description>
        </item>
        <item>
        <title>Codex goalは、完了基準をタスク自体に委ねること</title>
        <link>https://ttf248.life/ja/p/codex-goal-command-explained/</link>
        <pubDate>Wed, 27 May 2026 20:11:41 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/codex-goal-command-explained/</guid>
        <description>&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; は、「agent にしばらく動作を続けさせる」という命令だと誤解されやすいです。&lt;/p&gt;
&lt;p&gt;これは当然、その表象にすぎません。Codexに目標を与えるだけで、その目標を中心に継続的に推し進めることができ、一度の回答で止まるわけではありません。しかし、真に注目すべき点は「長く稼働できること」ではなく、「何が完了と見なされるか（終了条件）」という概念を一時的なリマインダーからタスク自体の一部へと昇華させた点です。&lt;/p&gt;
&lt;p&gt;通常のプロンプト（prompt）は、次に何をすべきかを述べています。それに対し、&lt;code&gt;goal&lt;/code&gt; は、エージェントに対して『受入チェックリスト』を渡しているようなものです：目標が何か、境界線（スコープ）はどこか、どの検証項目を通過する必要があるか、そして作業完了のために満たすべき条件とは何か、といった要素を定義しています。&lt;/p&gt;
&lt;h2 id=&#34;目標は次へまたは続行ボタンではありません&#34;&gt;目標は「次へ（または続行）ボタン」ではありません
&lt;/h2&gt;&lt;p&gt;コマンドの形式（命令形）だけを見ると、&lt;code&gt;/goal&lt;/code&gt; は「完了するまで続ける」という概念を強化したようなものに非常に似ています。しかし、このように捉えすぎると、議論が脱線してしまいます。&lt;/p&gt;
&lt;p&gt;長期間のタスクで最も厄介な点は、モデル自身が継続を望むかどうかという点ではなく、各ラウンド終了後に、誰が（またはどの仕組みが）継続すべきかを判断する点です。&lt;/p&gt;
&lt;p&gt;これらの停点は必ずしも間違っているわけではありませんが、人の受け入れ基準とは異なる場合がよくあります。&lt;/p&gt;
&lt;p&gt;目標が解決すべきことは、このことです。すなわち、受入基準（または「判定基準」）を事前に明確に記述し、それによって以降のすべてのラウンドで判断ができるようにすることです。&lt;/p&gt;
&lt;p&gt;一般的な目標の例は以下の通りです。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal フロントエンドを Next.js に移行する手伝いをしてください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;その問題は短いことではなく、停止条件がないことです。Codexは数ページの移動ができたり、ついでにコンポーネントをリファクタリングしたりでき、さらに追加すべきだと考えるものを継続的に追記し続けることもできます。&lt;/p&gt;
&lt;p&gt;より使える書き方は次のようになります。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal 注文の管理画面を React Router から Next.js App Router へ移行する。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ログインページ、注文リスト、注文詳細、および購入（または決済）ページの見栄えは旧バージョンと一致させる必要がある。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;API契約とデータベーススキーマは変更しないこと。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ページ群が完成するたびに、npm run build、npm test、およびPlaywrightの重要パスを実行すること。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;これらの検証すべてが通った場合のみ完了とする。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この追加部分は、単なる余談ではなく、4つのコントロールプレーン（制御面）に関するものです：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;要素&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;目標&lt;/td&gt;
					&lt;td&gt;最終的にどのような結果であるか&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;境界&lt;/td&gt;
					&lt;td&gt;手動では対応できないインターフェース、データ、ファイル、または動作は何か&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;検証&lt;/td&gt;
					&lt;td&gt;それが本当に完了したことを証明するための証拠は何か&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;停止条件&lt;/td&gt;
					&lt;td&gt;どのような条件を満たした後に停止できるか&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;「目標」を高くするのは、これら4つのことです。&lt;/p&gt;
&lt;h2 id=&#34;なぜ長時間実行できるのか&#34;&gt;なぜ長時間実行できるのか
&lt;/h2&gt;&lt;p&gt;Codex は、一度の回答が引き伸ばされたからではなく、goal の下で継続的に推進することができます。&lt;/p&gt;
&lt;p&gt;実際の作業方法は、むしろサイクルに近いです。すなわち、計画し、実行し、ツールの結果を観察し、修正を行い、続けるかどうかを決定する、というプロセスです。ビルド失敗、テスト失敗、スクリーンショットの不一致、リンティングエラー、評価サンプルが通らないといった事象はすべて、タスクを次のサイクルに戻します。&lt;/p&gt;
&lt;p&gt;「検証方法」が目標に記載されている場合、エージェントは直感や推測だけで「完了したはずだ」とは述べられません。必ず証拠を得る必要があります。証拠が得られない場合は調査を継続し、証拠に問題がある場合は修正を続けなければなりません。すべての証拠が通過して初めて、「完了」と認める資格があります。&lt;/p&gt;
&lt;p&gt;これが、&lt;code&gt;goal&lt;/code&gt; が移行（マイグレーション）、リファクタリング、バッチ校正、プロンプト評価、長尺のデバッグといったタスクに適している理由です。これらの共通の特徴は、一度で完結しない点、そして完成に主観的な判断だけでは頼れない点にあります。&lt;/p&gt;
&lt;p&gt;逆に、このような目標は非常に危険です：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/goal より高度なプロダクトプランを考案する
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;境界がなく、検証もされず、かつ停止条件もない。エージェントは長時間動作するかもしれませんが、「長い時間動くこと」が「有用であること」を意味するわけではありません。最低限、何組のソリューションを出力するのか、どのような制約を網羅しているのか、どの基準で絞り込むのか、そしていつ停止するのかを明確に記述する必要があります。&lt;/p&gt;
&lt;h2 id=&#34;claude-codeも同じことを処理しています&#34;&gt;Claude Codeも同じことを処理しています
&lt;/h2&gt;&lt;p&gt;Claude Code にも &lt;code&gt;/goal&lt;/code&gt; があり、公式ドキュメントの説明の方がより直接的です。ユーザーが「完了条件」（completion condition）を設定すると、Claude はその条件が満たされるまでターンをまたいで継続的に作業します。&lt;/p&gt;
&lt;p&gt;『Claude Code』のドキュメントには、各ラウンド終了時に完了条件が満たされているかを確認し、もし条件を満たしていない場合は次のラウンドへ進むと記されています。この点が非常に重要であるのは、「継続」という判断をモデル自身の主観的な結論付けのプロセスから切り離し、外部の追加的な条件判定（ロジック）としているためです。&lt;/p&gt;
&lt;p&gt;両社の具体的な実装詳細が無理に同一である必要はありませんが、方向性は一致しています。すなわち、エージェントは「次の指令を実行する」という段階から、「検証可能な目標を中心に継続的に推進していく」という段階へと移行し始めているということです。&lt;/p&gt;
&lt;p&gt;簡単に分類すると：&lt;/p&gt;
&lt;p&gt;この表において、&lt;code&gt;goal&lt;/code&gt; の役割は非常に明確です。それはフックの代替ではなく、記憶（メモリ）の代替でもありません。それが管理しているのは、「今回のタスクをどの程度まで達成すれば完了とみなせるか」という点です。&lt;/p&gt;
&lt;h2 id=&#34;good-goals-should-be-written-like-acceptance-criteria&#34;&gt;Good goals should be written like acceptance criteria
&lt;/h2&gt;&lt;p&gt;今から、一つのゴールを四行に分けて記述します。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;目標：最終的にどのようなユーザーに見える結果が出なければならないか。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;範囲：どのファイル、インターフェース、データ、視覚的要素、または動作を変更してはならないか。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;検証：どのようなコマンド、テスト、スクリーンショット、評価、または手動チェックを証拠として使用するか。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;停止条件：すべてが満たされたときに停止するもの。どの権限、事実、製品判断に遭遇したときに一時停止するか。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これは普通のプロンプトとは大きく違います。&lt;/p&gt;
&lt;p&gt;通常のプロンプトは次のアクション（行動）のようなものであり、ゴール（目標）は完成の基準（クオリティ）のようなものです。それは人間をプロセスから排除するのではなく、人間の判断を事前に組み込むものになります。あなたは、「これはまだ完了ではない」と都度指摘する必要がなくなり、「何をもって完了とするか」という条件を最初から守らなければならない制約として記述できるようになるのです。&lt;/p&gt;
&lt;p&gt;ですから、エージェントに自主的に動かしてもらいたいほど、目標はより狭く（限定的に）設定する必要があります。&lt;/p&gt;
&lt;p&gt;プロセスへの注視を減らそうとすればするほど、検証（バリデーション）はより具体的・現実的に記述する必要があります。&lt;/p&gt;
&lt;p&gt;逸脱（暴走）を最も避けたいからこそ、境界線を明確に定義することが重要だ。&lt;/p&gt;
&lt;p&gt;「goal」が真に注目すべき点は、ここです。単にコマンドが増えることでも、どれだけ長く動作するかという点でもありません。むしろ、ターミナルエージェントが、「完了の判断を下す主体は誰か」という問題を表舞台に引き上げてきた点にあります。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/use-cases/follow-goals&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;目標に従う | Codex ユースケース&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/cli/slash-commands&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex CLI のスラッシュコマンド | OpenAI Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/blog/run-long-horizon-tasks-with-codex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Codex で長期のタスクを実行する | OpenAI Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/goal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;目標に向かってClaudeを機能させ続ける | Claude Code Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;執筆に関する補足&#34;&gt;執筆に関する補足
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer codexが新しくリリースしたgoalコマンドの詳細について、動作原理は何か、なぜ長時間の処理が継続するのか、そして公式が提供する具体的な事例を解説してください。Claude Codeに同様の命名規則はあるか？また、ついでに、最近リリースの2つのターミナルで、便利でおすすめな機能をいくつかピックアップして表としてまとめてください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;執筆のアイデア概要&#34;&gt;執筆のアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;原文の主要な判断点を維持する：&lt;code&gt;goal&lt;/code&gt; の核となるのは、コマンド名ではなく、完了条件である。&lt;/li&gt;
&lt;li&gt;元のプロンプトで要求されていた Claude Code の比較とターミナル機能の表を補完する。&lt;/li&gt;
&lt;li&gt;「公式ドキュメントの再述」は排除し、実用的な goal の記述方法に重点を置く。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>ChatGPTが公開された後、NVIDIAのデータセンター向けGPUはどのように進化するでしょうか？</title>
        <link>https://ttf248.life/ja/p/nvidia-data-center-gpu-since-chatgpt/</link>
        <pubDate>Fri, 15 May 2026 19:58:51 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/nvidia-data-center-gpu-since-chatgpt/</guid>
        <description>&lt;p&gt;まず、時期を明確にしましょう。ChatGPTの公開研究プレビュー版は、2023年ではなく、2022年11月30日にリリースされました。[1]&lt;/p&gt;
&lt;p&gt;この時期以降、NVIDIAのデータセンターGPUのメインラインは非常に明確です。Ampereが終息し、Hopperに引き継がれ、Hopperは大容量メモリを刷新し、そしてBlackwellが重心を「単一カードでの高密度計算能力」から、「推論スループット、消費電力、システム全体レベルの相互接続性」へと移していくという流れです。対照的に、中国向け特別仕様ラインは別の物語があります。A800、H800、H20といったものは、本質的には米国の輸出規制の制約の下で作られた&lt;/p&gt;
&lt;p&gt;本稿では、2本の線のみを統計しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;グローバルデータセンター向けのトレーニング／推論メインライン：比較基準としてA100、H100、H200、B200、B300。&lt;/li&gt;
&lt;li&gt;中国向け特別供給ライン：A800、H800、H20。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L4、L40、L40S、L2といったものは本文に組み込んでいません。それらが重要でないわけではなく、むしろこれらはビデオ推論、一般推論、グラフィックス、仮想化という用途ラインがメインであり、A100/H100/H200/B200のような大規模モデルトレーニングの主軸と混ざってしまうと、価格や性能の指標が混乱してしまうからです。&lt;/p&gt;
&lt;h2 id=&#34;まずメインラインを見る&#34;&gt;まずメインラインを見る
&lt;/h2&gt;&lt;p&gt;結論から述べます。2022年11月30日以降の発表ペースで見ると、H100が生成AI爆発初期の真の起点となり、H200は「メモリ不足」を補うための刷新的なカードであり、B200こそが真の意味でのプラットフォームレベルの世代交代であり、B300はBlackwellを推論（Inference）および思考（Reasoning）の時代へとさらに押し進めたと言えます。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;モデル名&lt;/th&gt;
					&lt;th&gt;リリース日&lt;/th&gt;
					&lt;th&gt;アーキテクチャ&lt;/th&gt;
					&lt;th&gt;メモリ容量&lt;/th&gt;
					&lt;th&gt;メモリ帯域幅&lt;/th&gt;
					&lt;th&gt;インターコネクト&lt;/th&gt;
					&lt;th&gt;公式性能指標&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;A100 80GB&lt;/td&gt;
					&lt;td&gt;2020-11、対照ベースラインとして&lt;/td&gt;
					&lt;td&gt;Ampere&lt;/td&gt;
					&lt;td&gt;80GB HBM2e&lt;/td&gt;
					&lt;td&gt;2.039 TB/s&lt;/td&gt;
					&lt;td&gt;NVLink 600 GB/s&lt;/td&gt;
					&lt;td&gt;BF16/FP16 Tensor Core 312 TFLOPS，INT8 624 TOPS [2]&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;H100 SXM&lt;/td&gt;
					&lt;td&gt;2022-03-22&lt;/td&gt;
					&lt;td&gt;Hopper&lt;/td&gt;
					&lt;td&gt;80GB HBM3&lt;/td&gt;
					&lt;td&gt;3.35 TB/s&lt;/td&gt;
					&lt;td&gt;NVLink 900 GB/s&lt;/td&gt;
					&lt;td&gt;BF16/FP16 1,979 TFLOPS，FP8 3,958 TFLOPS；DGX H100 シングルシステムで 32 PFLOPS FP8、DGX A100 から 6 倍向上 [3][4]&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;H200 SXM&lt;/td&gt;
					&lt;td&gt;2023-11-13&lt;/td&gt;
					&lt;td&gt;Hopper 改良版&lt;/td&gt;
					&lt;td&gt;141GB HBM3e&lt;/td&gt;
					&lt;td&gt;4.8 TB/s&lt;/td&gt;
					&lt;td&gt;NVLink 900 GB/s&lt;/td&gt;
					&lt;td&gt;公式が強調しているのはコア演算能力の倍増ではなく、Llama2 70B 推論で 1.9 倍、GPT-3 175B 推論で 1.6 倍の向上；H100 に対する相対的なメリットはより大&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ここで最も誤解しやすい点は、H200が「演算能力を暴力的に倍にしたカード」ではないということです。むしろHopper世代のための補習（キャッチアップ）のようなものです。大規模モデルの訓練と推論が超長コンテキスト、巨大なKVキャッシュ、MoE、そしてより大きなバッチサイズという段階に入ると、ボトルネックはもはや単純なBF16のピーク性能ではなく、VRAM容量とVRAM帯域幅になるからです。H200はこの弱点を補完しました。&lt;/p&gt;
&lt;p&gt;真の世代的な飛躍はBlackwellにあります。Blackwellが売っているのは単なる単体のカードではなく、一連のプラットフォーム能力：新しい精度、インターコネクト、システム全体レベルの帯域幅、推論コスト、消費電力効率、ラックスケールでの組織方式といったもの全般です。これが、多くの資料がB200について語る際に、単体カードの指標がH100ほど一目で理解しにくい理由であり、なぜならNVIDIAのナラティブ（物語上の焦点）が、「この&lt;/p&gt;
&lt;h2 id=&#34;中国限定ラインを再確認&#34;&gt;中国限定ラインを再確認
&lt;/h2&gt;&lt;p&gt;中国専用ラインは個別に検討する必要があります。なぜなら、その目的が世界のフラッグシップ製品を打ち破ることではなく、輸出規制のレッドラインを下回りながら、商用利用可能性を可能な限り保持することにあるからです。&lt;/p&gt;
&lt;p&gt;このラインで最も覚えておくべき一文は、「A800とH800は『相互接続を減らす』ものであり、H20は『計算能力すらも抑え込まなければならない』ものである」ということです。&lt;/p&gt;
&lt;p&gt;そのため、誰かが単にVRAMの数字だけを見て、「H20はH800より新しいから、もっと高性能だ」と判断するのは誤りです。H20の96GB HBM3と4.0 TB/sの帯域幅は悪くありませんが、それが登場する前提条件は、より厳しい輸出規制を満たすことです。その商業的な目的は、まず「売れること」、次に「可能な限り使いこなせること」なのです。&lt;/p&gt;
&lt;h2 id=&#34;前世代と比較して具体的にどれだけアップグレードされたのか&#34;&gt;前世代と比較して、具体的にどれだけアップグレードされたのか
&lt;/h2&gt;&lt;p&gt;計算方法から説明します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-latex&#34; data-lang=&#34;latex&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;\[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;\text&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{アップグレード率}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;\frac&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;\text&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{次世代指標}&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;\text&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{前世代指標}}{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;\text&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;{前世代指標}}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;\]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ただし、この数式は定義（スコープ）が統一された指標にのみ適しています。メモリ（VRAM）、メモリ帯域幅、NVLinkの帯域幅は直接計算が可能です。一方で、プラットフォームレベルの推論コストやシステム全体の処理能力（スループット）といった要素は、シングルカードのTFLOPSのような単一基準には無理に当てはめることはできません。&lt;/p&gt;
&lt;h3 id=&#34;世界の主要動向&#34;&gt;世界の主要動向
&lt;/h3&gt;&lt;p&gt;読み進めていくと、ある法則があることに気がつきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;H100は、単一カードのテンソル演算能力を飛躍的に引き上げた世代です。&lt;/li&gt;
&lt;li&gt;H200は、VRAM（ビデオメモリ）を補強した世代です。&lt;/li&gt;
&lt;li&gt;B200は、「トレーニング用カード」を「AIファクトリーのインフラストラクチャ」へと変貌させた世代です。&lt;/li&gt;
&lt;li&gt;B300は、Blackwellをより明確に推論および大規模な推論の領域へ押し進めた世代です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;中国特別供給ライン&#34;&gt;中国特別供給ライン
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;世代&lt;/th&gt;
					&lt;th&gt;直感的印象はアップグレードに見えるが、実際には分けて考える必要がある&lt;/th&gt;
					&lt;th&gt;私の考察&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;A800 -&amp;gt; H800&lt;/td&gt;
					&lt;td&gt;ローカルHBM帯域幅だけを見ると、A100からH100レベルまでは、約+64%の世代的な進歩と理解できる&lt;/td&gt;
					&lt;td&gt;しかし、根幹となる制約は依然としてインターコネクト&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;それゆえに、「各世代でどれだけ総合的に向上するか」という形で記述するのは、中国の特注ラインには適さないのです。このラインは元来コンプライアンス上の制約を伴っており、設計目標が技術的な最適さではなく、ルールによる制約の下での商業的な実現可能性にあるからです。&lt;/p&gt;
&lt;h2 id=&#34;販売価格は一体どれくらい上がったのか&#34;&gt;販売価格は一体どれくらい上がったのか
&lt;/h2&gt;&lt;p&gt;この部分は誤った情報が書き込まれやすい箇所です。NVIDIAはデータセンターGPUの単体MSRPをほとんど公開していないため、一般的に利用できる情報は以下の通りです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DGXシステムの価格、またはサードパーティによるシステムの実売価格（提示価格）。&lt;/li&gt;
&lt;li&gt;中国向け特別仕様カードのチャネルからの見積もり価格。&lt;/li&gt;
&lt;li&gt;メディア、証券会社、またはサプライチェーンからの情報。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのため、ここでは「公開で追跡可能な価格サンプル」のみを提供し、一見すると完璧だが実際には算出基準が混乱した公式の価格表を偽造することはしません。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;デバイス&lt;/th&gt;
					&lt;th&gt;公開価格サンプル&lt;/th&gt;
					&lt;th&gt;前世代との比較の解釈&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;DGX H100&lt;/td&gt;
					&lt;td&gt;2022-03-22 发布時官方起售价 1&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;したがって、「全体の販売価格はどの程度上がったのか」という点で、2つの結論をご報告します。&lt;/p&gt;
&lt;p&gt;第一に、世界のフラッグシップ主力製品は確かに上昇しており、その上昇幅もさほど小さいものではありません。公開で比較可能なサンプルを見る限り、DGX B200は、同時期にリストされているDGX H100と比較して、およそ40％から50％高価になっています。[19]&lt;/p&gt;
&lt;p&gt;第二に、中国の特別供給ラインは一律に価格が上昇しているわけではなく、「後から出るカードの方が安価」という状況が発生する可能性があります。H20の8枚カードサーバーの公開見積もりは、H800の8枚カードサーバーよりも約30%低い水準ですが、これは良心の問題ではなく、性能能力がさらに圧縮されたためです。[17]&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ
&lt;/h2&gt;&lt;p&gt;ChatGPTが公開された以降のNVIDIAデータセンター用GPUの変化を一言にまとめると、私の判断は〜です。&lt;/p&gt;
&lt;p&gt;H100 は生成AIが爆発した時点でのスタートの引き金であり、H200 はメモリ志向の延命措置です。B200 こそが AI ファクトリー時代における真のプラットフォーム世代交代であり、B300 は推論（reasoning）時代に向けて明確に道筋をつけ始めています。中国向け特別供給ラインは全く別のロジックに基づいています。それはフラッグシップを追いかけるのではなく、ルールの隙間で可能な限り利用可能性を維持することを目指しているのです。&lt;/p&gt;
&lt;p&gt;この2つの要素は混同しないでください。混ぜて見ると、「新しいカードのVRAMが大きいから、世代がより優れている」「価格が低いから、コストパフォーマンスが高い」といった、大きな差はないものの、方向性自体を間違えた結論を導き出しやすいです。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;h2 id=&#34;執筆注記&#34;&gt;執筆注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;ChatGPTのリリース以降、Nvidiaが発表したGPUモデルとそれに対応する性能パラメーターをまとめてください。前世代と比較してどれくらいアップグレードされたか、また全体的な価格はどの程度上昇しているかを知りたいです。データセンターで使用されるGPUが必要で、中国向けの特別版も含めてください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティング執筆の構成案要約&#34;&gt;ライティング（執筆）の構成案要約
&lt;/h3&gt;&lt;h3 id=&#34;拡張ブレーンストーミング&#34;&gt;拡張ブレーンストーミング
&lt;/h3&gt;&lt;p&gt;| 方向 | 正文への採用可否 | 対応理由 |
| &amp;mdash; |&lt;/p&gt;</description>
        </item>
        <item>
        <title>AIがコードを書き始めたけど、新人は何でスキルアップすればいいの？</title>
        <link>https://ttf248.life/ja/p/when-ai-writes-code-how-juniors-level-up/</link>
        <pubDate>Mon, 27 Apr 2026 23:18:36 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/when-ai-writes-code-how-juniors-level-up/</guid>
        <description>&lt;p&gt;ここ数ヶ月、ClaudeやCodexといったツールを使ってコードを書いている中で、最も強く感じているのは、「プログラマーが不要になる」ということではなくて、以前は新人に練習課題として出していたような作業まで、AIがすでに叩き台（ドラフト）を生成してくれることだ。&lt;/p&gt;
&lt;p&gt;スキャフォールドの作成、いくつかのテストの追加、ついでに小さな機能を修正する…という操作を続けていくと、その速度があまりにも速くて、なんとも言えない「意難平」な気分になる。&lt;/p&gt;
&lt;p&gt;私のような卒業から10年が経過した人間にとって、正直なところ、これは主に効率化の問題です。なぜなら、どこを信じてよいか、どこを信用してはいけないか、そして表面上は動作しているように見えても、実は後に罠（落とし穴）がある場所などを概ね把握しているからです。しかし、新卒者にとっては、この問題はそれほど簡単ではありません。AIは単に数時間の肉体労働を奪ってくるだけでなく、「初心者がどうやって無知から熟練へとなるか」という確立された道筋そのものを圧縮してしまっているようなものです。これが私が改めて書きたいと考えている点でもあります。&lt;/p&gt;
&lt;h2 id=&#34;本当に淘汰されたのはプログラマーではなくスマホの技能大会モバイルスキルだった&#34;&gt;本当に淘汰されたのは、プログラマーではなく、「スマホの技能大会（モバイルスキル）」だった
&lt;/h2&gt;&lt;p&gt;以前のチームには、技術的な難易度は高くないものの、新人にとって非常に適した種類のタスクが常にあります。例えば、ページ修正、インターフェース（API）連携、CRUD機能の実装、エッジケースのバグ修正、ログを追跡しながら一つずつデバッグを行うといった作業です。タスク自体は大規模ではありませんが、「文法を書ける」だけの段階の人を、「実際のシステム全体がどう動いているか」を理解できるレベルまで育て上げることができます。&lt;/p&gt;
&lt;p&gt;現在、このような仕事はAIに最も早く飲み込まれる傾向があります。&lt;/p&gt;
&lt;p&gt;米国労働統計局（BLS）が2025年版の職業展望において、非常に興味深い対照的な指摘をしています。&lt;/p&gt;
&lt;p&gt;一方では、ソフトウェア開発やテストといった職種は今後10年間も成長し続けると述べる一方で、「コンピュータープログラマー」という、より「コードの記述・実行」に重点を置いた職種については減少傾向にあるとし、多くの定型的な（反復的な）プログラミング作業が継続的に自動化されるだろうと明確に記しています。&lt;/p&gt;
&lt;p&gt;この変化は極めて重要です。&lt;/p&gt;
&lt;p&gt;ソフトウェア業界から人がいなくなるという意味ではありません。というのも、「ただタスクを受けてコードを書くだけ」という価値が、ますます薄くなっているからです。企業は当然、コスト計算をします。AIにまずドラフトを作成させ、その後経験豊富な人材に仕上げ（磨き上げ）てもらえるのであれば、なぜこれまでのように多くのジュニアポジションを配置して時間をかけて育成する必要があるのでしょうか。&lt;/p&gt;
&lt;p&gt;だからこそ怖いのは、必ずしも人員削減ではないのかもしれない。むしろ、人が補充されなくなることだ。道（チャンス）自体はまだそこにあるものの、幅が狭くなってしまったということだ。&lt;/p&gt;
&lt;h2 id=&#34;なぜベテランほどaiの恩恵を受けやすいのか&#34;&gt;なぜベテランほどAIの恩恵を受けやすいのか
&lt;/h2&gt;&lt;p&gt;この件、ちょっと矛盾している気がしますね。一見すると、AIが生成したコードでも、新卒のエンジニアより優れているとは限りません。しかし、真にAIを使いこなせるプロは、多くの場合、何らかの失敗（落とし穴）を経験してきたベテランなのです。&lt;/p&gt;
&lt;p&gt;理由は複雑ではありません。&lt;/p&gt;
&lt;p&gt;まず、ベテランは、「動くように見える」ことと「実際に本番環境で機能する」ことは別物だと知っています。Anthropicは、2026年1月のEconomic Indexにおいて、ソフトウェア開発を個別に分析した結果、このようなリクエストは高度に体系化されているものの、タスク成功率は約61%に留まることが判明しました。また、ほとんどのシナリオでは、一度AIに任せて終わりではなく、往復での反復的なやり取りが必要&lt;/p&gt;
&lt;p&gt;第二に、ベテランには「コードのセンス」というものがある。この言葉は少し玄妙だが、非常に実効性がある。インターフェースをこう分割すべきか、例外処理をこのように飲み込むべきか、テストが単にCIをごまかすだけではないか、リファクタリングによって来週分の落とし穴まで先に埋めてしまうのではないか。AIも今では間違いを犯すのだが、その多くは構文ミスではなく、方向性の誤りや抽象化の誤り、境界の誤りだ。古法でのプログラミングを経験したことがない人は、正直なところ、こうした誤りを識別するのがより難しい。&lt;/p&gt;
&lt;p&gt;つまり、AI時代において最も価値があるのは、タイピングの速さではなく、判断力なのです。&lt;/p&gt;
&lt;h2 id=&#34;新人が道がないのではなく古い道が存在しなくなっただけのことだ&#34;&gt;新人が道がないのではなく、古い道が存在しなくなっただけのことだ
&lt;/h2&gt;&lt;p&gt;新しい分野に参入した人が、完全に機会を失うとは思えません。世界経済フォーラム（WEF）は、2025年1月のレポートにおいても、ソフトウェアおよびアプリケーション開発者を成長が著しい職種として位置づけています。また、米国労働統計局のソフトウェア開発職に関する長期的な展望も依然として増加傾向にあります。これは、需要が突然消滅したわけではないことを示しています。&lt;/p&gt;
&lt;p&gt;しかし、参入方法が確実に変わった。&lt;/p&gt;
&lt;p&gt;以前の標準的なキャリアパスは、まず実務を通じて苦労を重ね、書きながら学習し、経験を積んで感覚（フィーリング）を磨き出すというものでした。しかし現代では、企業はあなたが入社したらすぐに2つのことを期待する傾向がより強くなっています。&lt;/p&gt;
&lt;p&gt;まず、AIを「答え」としてではなく、「ツール（道具）」として扱うことが大切です。問題点を明確に言語化したり、要件を細かく分解したりして、まずは利用できる草稿を出してもらうといった対応ができる必要があります。&lt;/p&gt;
&lt;p&gt;もう一つの点は、それ（コードなど）をレビューできる能力です。単に「これは間違っている」と言うだけでなく、どこが間違いなのか、なぜ間違いなのか、そしてプロジェクトのコンテキストに合わせてどのように修正すべきかを理解していることです。&lt;/p&gt;
&lt;p&gt;これは困りましたね。「コードレビューができる能力」というのは、本来数年間の仕事経験を積んで身につくものなのに、今は練習する機会が減っているのに、かえって新人にこの能力を早く持っていることを求められている。どう言えばいいか、まるでゲームの初心者村が取り壊されたのに、ボスは目の前で待っているような状況です。&lt;/p&gt;
&lt;h2 id=&#34;今後の展望&#34;&gt;今後の展望
&lt;/h2&gt;&lt;p&gt;私の現在の判断は比較的単純です。&lt;/p&gt;
&lt;p&gt;AI は熟練者の生産性を向上させ続けると同時に、初級職における最も標準化しやすく、細分化しやすい業務部分を圧縮し続けるでしょう。この二つの事象は矛盾することなく、同時に発生する可能性が高いです。ILO は 2025 年 5 月の報告書で非常に抑制的な見解を示しており、生成AIは単に仕事全体を一気に消滅させるというよりは、タスク構造そのものを変えるものだとしています。問題なのは、タスク構造が変わると、最も先に廃止されがちなのが、本来新人育成のために設計されていた低リスクの業務であるということです。&lt;/p&gt;
&lt;p&gt;したがって、次に希少価値が高まるのは、「最もコードが書ける人」ではなく、基本的な能力を持ち、AIを使いこなすことができ、さらにビジネスと品質に対して責任を持てる人物です。&lt;/p&gt;
&lt;p&gt;経験者にとって、これはより鋭いシャベルを一つ加えたようなものであり、疲れはするものの、効率が格段に上がりました。しかし、新人にとっての問題は、AIを使えるかどうかではなく、最初からAIに頼って書いた場合、いつが質の高い文章で、いつが本気でデタラメ（嘘）を書いているのかを誰が教えてくれるのかという点なのです。&lt;/p&gt;
&lt;p&gt;この答えは、今のところ学校でもAIでも提供できません。結局は自分で補完していく必要性が高いでしょう。「門が閉まったわけではないけれど、より入るのが難しくなってきましたね。」&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.weforum.org/reports/the-future-of-jobs-report-2025/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;2025年仕事の未来に関するレポート&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bls.gov/ooh/computer-and-information-technology/software-developers.htm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ソフトウェア開発者、品質保証アナリスト、テスター&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bls.gov/ooh/computer-and-information-technology/computer-programmers.htm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;コンピュータプログラマー&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.bls.gov/opub/mlr/2025/article/ai-impacts-in-bls-employment-projections.htm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;BLS雇用予測におけるAIの影響&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.anthropic.com/research/anthropic-economic-index-january-2026-report&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Anthropic経済指数：最新データからの洞察&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Anthropic経済指数&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;AIプログラミングに関するいくつかの考察です。新卒の学生は、コーディング能力がClaudeやCodexには及ばないのは間違いないでしょう。ベテランにとってはAIが効率性を高めてくれますが、同時にAIによって企業側がジュニアプログラマーのポジションを大幅に削減するという事態も生じました。私は卒業から十年が経ち、初心者から熟練者へと成長する道のりを経験してきました。これから新しく業界に入ってくる人たちはどうなっていくのでしょうか？私たち年配の世代は「古き良き」コーディング手法を経験してきたため、簡単に言えば、現在の段階にあるAIが書いたコードが良いものなのか悪いものなのかを見分けることができます。畢竟（ひんこう）今のAIはまだ間違いをするからです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;執筆の考え方または論旨の要約&#34;&gt;執筆の考え方（または論旨）の要約
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;主張の軸を「AIが圧縮しているのは、新参者の練習機会であり、ソフトウェア業界全体ではない」とする点に置く。&lt;/li&gt;
&lt;li&gt;前半部では、ベテラン層がなぜAIの恩恵をより大きく受けるのかを述べた後、それが&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>聯通に引っ越してから、アメリカのノードが急にそれほど良くなくなった。</title>
        <link>https://ttf248.life/ja/p/us-nodes-not-as-good-after-switching-to-china-unicom/</link>
        <pubDate>Thu, 16 Apr 2026 01:56:14 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/us-nodes-not-as-good-after-switching-to-china-unicom/</guid>
        <description>&lt;p&gt;最近引っ越したため、自宅のブロードバンドを電信から聯通に変更しました。普段ドラマを見たりゲームをしたりする分には、特に何も感じませんが、先日資料をダウンロードしようとして、癖でアメリカノードに切り替えたところ、どうやっても速度が上がらず、私は少し呆然としました。&lt;/p&gt;
&lt;p&gt;この件は後になって理解できました。以前は、アメリカのデータセンターの帯域幅が十分与えられているから、アメリカのノードは元々より強力だとずっと思っていました。今見ると、その認識は半分しか正しくありません。アメリカのサーバーのリソースが豊富であることは一つの側面ですが、国内でどの回線を使うか、国際出口をどう通すか、戻りの経路でより良いバックボーンを利用できているか、というのがもう一つの側面です。以前は中国電信を使っていたので露呈しなかった問題が、ユニコムに替わってからは全て明らかになりました。&lt;/p&gt;
&lt;h2 id=&#34;平常では本当に見つけにくい&#34;&gt;平常では本当に見つけにくい
&lt;/h2&gt;&lt;p&gt;このような差異は、普段は気づかれやすいものです。&lt;/p&gt;
&lt;p&gt;ドラマを見る場合は動画プラットフォーム独自のスケジューリングが使われることが多く、クロスボーダー帯域を常に最大に引き出す必要はありません。ゲームの場合は遅延の揺らぎやノードの安定性がより重要で、実際に大容量ファイルのダウンロードや高帯域幅での継続的な実行になると、回線が適切かどうかが一目瞭然になります。&lt;/p&gt;
&lt;p&gt;そのため、今となってはダウンロード速度こそが最も正直な測定だと感じています。普段はすべて正常だと感じるかもしれませんが、それはこの道が本当に広いということではなく、単に限界まで走らせていないだけなのかもしれません。&lt;/p&gt;
&lt;h2 id=&#34;かつてアメリカのノードはフル稼働できたのでアメリカのデータセンターだけが優れているわけではない&#34;&gt;かつてアメリカのノードはフル稼働できたので、アメリカのデータセンターだけが優れているわけではない
&lt;/h2&gt;&lt;p&gt;中国电信が独自に公開している資料によると、ChinaNet は同社のメインの広域網であり、&lt;code&gt;CN2 (AS4809)&lt;/code&gt; は低遅延と高品質を強調した次世代のグローバルバックボーンネットワークで、国際的な品質をより重視するビジネス向けです。この件は多くの人が聞いたことがあり、普段空港の業者はこれをセールスポイントとしてよく使います。&lt;/p&gt;
&lt;p&gt;そのため、以前は電気通信のブロードバンドを利用していて、アメリカノードに切り替えるだけでダウンロード速度を上げることができましたが、今振り返ると、「アメリカが生まれつき速い」というよりは、「アメリカのデータセンターリソース ＋ ノードの上流回線 ＋ 電気通信側の国際ルーティング」がたまたま重なっただけだと思います。回線が電気通信にとって好都合な方向に当たると、体感は本当に良くなりますね。&lt;/p&gt;
&lt;p&gt;率直に言って、以前のスピードは、ノード全体が強いというよりは、私がちょうど有利な側に立っていただけだと思います。&lt;/p&gt;
&lt;h2 id=&#34;中国聯通は国際回線がないわけではないが以前と同じルートとは限らない&#34;&gt;中国聯通は国際回線がないわけではないが、以前と同じルートとは限らない
&lt;/h2&gt;&lt;p&gt;しかし、この件を単に「中国電信網への依存」と理解することはできません。&lt;/p&gt;
&lt;p&gt;中国聯通独自の国際ネットワークもそれなりに大きい。联通の国際公式サイトには明確に記載されており、そのバックボーン網である &lt;code&gt;AS4837&lt;/code&gt; は世界中に 400以上の PoP を持ち、さらに品質の高いキャパシティを担う &lt;code&gt;AS9929&lt;/code&gt; も持っている。カバレッジで見ると、シンガポール、台湾、アメリカといった地点には自前で展開している。&lt;/p&gt;
&lt;p&gt;しかし、問題はここにあります。「国際回線がある」ことと、「今購入したプロキシノードがたまたまこのキャリアにフレンドリーである」ことは、別物なのです。&lt;/p&gt;
&lt;p&gt;家庭のブロードバンドユーザーが真に感じるのは、キャリアが海外リソースを持っているかどうかだけではなく、以下の点も含まれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;お客様のローカルキャリアはどちらですか&lt;/li&gt;
&lt;li&gt;プロキシサービスプロバイダーが購入するアップストリームはどちらの帰り回線に傾いていますか&lt;/li&gt;
&lt;li&gt;ノードの往路と復路は同じ種類の最適化ですか&lt;/li&gt;
&lt;li&gt;ピーク時に混雑はありますか&lt;/li&gt;
&lt;li&gt;このリンクは中国电信寄りですか、それともユニコムや移動体通信寄りですか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;多くの米国のノードについて、以前は中国電信（China Telecom）を使っていた時は回線が満杯になるほど使えたのですが、聯通（China Unicom）に替えてからは駄目になりました。私はこれを「これらのノードの回線構成自体が、元々中国電信寄りのものなのだ」と理解する方がしっくりきます。以前はそう思わなかったのは、自分自身が中国電信を使っていたからかもしれません。&lt;/p&gt;
&lt;h2 id=&#34;なぜシンガポールと台湾が逆に順調なのか&#34;&gt;なぜシンガポールと台湾が逆に順調なのか
&lt;/h2&gt;&lt;p&gt;これもかなり面白いですね。&lt;/p&gt;
&lt;p&gt;聯通に乗り換えた後、アメリカのノードはダメになりましたが、シンガポールと台湾はかなり快適になりました。この変化の方が、「アメリカのノードの速度低下」よりも問題をよく示しています。&lt;/p&gt;
&lt;p&gt;私の理解では、アジア方面は元々より近く、経路が短く、地域間の相互接続も密です。联通（China Unicom）自身がシンガポールと台湾の両方にネットワークリソースとPoPを持っているため、このような状況で代理サービスプロバイダーがアジアのノード上でよりスムーズな地域パスを提供すれば、ダウンロード速度は自然と出しやすくなります。&lt;/p&gt;
&lt;p&gt;これはシンガポールや台湾のデータセンターがアメリカより優れていることを意味するわけでもなく、すべてのブロードバンド接続でアジアノードを選ぶべきだという意味でもありません。むしろ、現在お使いのブロードバンド回線とこれらのリージョンノードとの相性が高いということのようです。&lt;/p&gt;
&lt;p&gt;どう言えばいいか、ノードの強さは、単にデータセンターの場所だけでは決まらない。結局は、自宅からの道のりがあなたを認めてくれるかどうかを見なす必要があるんだよ。&lt;/p&gt;
&lt;h2 id=&#34;この件で私のこれまでの認識が修正されました&#34;&gt;この件で、私のこれまでの認識が修正されました
&lt;/h2&gt;&lt;p&gt;私の以前の考えはかなり単純でした。アメリカのデータセンターは大きく、ブロードバンドのリソースが豊富なので、資料をダウンロードする際はアメリカのノードを選ぶのが基本で、間違えることはないと考えていました。&lt;/p&gt;
&lt;p&gt;今のところ、この判断はあまりに大雑把です。&lt;/p&gt;
&lt;p&gt;より正確な言い方としては、&lt;/p&gt;
&lt;p&gt;アメリカのノードが満杯かどうかは、単にアメリカのデータセンターだけを見ているわけではなく、あなたの家のブロードバンドがどのバックボーンネットワークに接続されているかにも左右されます。&lt;/p&gt;
&lt;p&gt;電信ユーザーが快適に使える回線でも、ユニコムに変わると必ずしもそうとはいかない。逆にユニコムの下の方がスムーズなシンガポールや台湾も、「アジアのノードが急に強くなった」わけではなく、単に回線がようやくしっくりきただけだ。&lt;/p&gt;
&lt;p&gt;そのため、今後プロキシやノードを選ぶ際は、アメリカに固執することは少なくなるでしょう。まず自分の回線がどのようなものか、次にサービス提供者がどの回線に重点を置いているかを見る方が、「データセンターがアメリカにあるかアジアにあるか」よりも重要になります。&lt;/p&gt;
&lt;p&gt;あー、こういう差は、普段ドラマを見たりゲームをしたりしているだけではなかなか気づきにくいですね。実際に大きなファイルを扱うとなると、回線（帯域）の実力が一気に表れちゃいますね。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.ctamericas.com/wp-content/uploads/2018/10/IP-Access.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;China Telecom Americas: IP Access / Global Internet Service（CN2、ChinaNet 介绍）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://sg.chinaunicomglobal.com/products-dia&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;China Unicom Global Singapore: DIA（AS4837、AS9929 介绍）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://eu.chinaunicomglobal.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;China Unicom Global Europe: Global Presence（新加坡、台湾、美国等海外节点）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：中国本土で代理ソフトウェアを使い、科学的にインターネットに接続する方法を試したところ、中国電信と聯通のブロードバンドの違いに気づきました。普段ドラマを見たりゲームをしたりするだけでは、その違いはほとんど分かりません。資料をダウンロードすることがたまにあるのですが、アメリカのノードを選ぶことが多く、そちらのノードだとダウンロード速度がほぼ最大まで出ます。これは以前の認識とも一致しており、アメリカのデータセンターのサーバーは十分なブロードバンドリソースを提供していると感じていました。最近引っ越しをして聯通の回線に切り替えたところ問題に気づきました。アメリカのノードではダウンロード速度が出なくなりました。シンガポールや台湾に切り替えるとかなり良くなりました。これは中国のブロードバンドのバックボーンネットワーク、つまりCN2高速バックボーンネットワークがすべて電信のものなので、聯通は電信の回線を借りているという関係に関係しているのだと思います。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングのアイデア概要&#34;&gt;ライティングのアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「引っ越しで回線を変えて初めて違いに気づいた」というリアルなトリガーポイントは維持し、記事を単なるネットワークの科学解説にしない。&lt;/li&gt;
&lt;li&gt;コアとなる判断基準は「ノードの速さだけでなく、国内回線と国際ルーティングも見る必要がある」という点を維持する。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CN2&lt;/code&gt;、中国光通信（Unicom）の国際バックボーン、および海外PoPについて補足的な検証を行い、「中国光通信は電信網に完全に依存している」という記述をより正確な表現に修正する。&lt;/li&gt;
&lt;li&gt;シンガポールや台湾が速い点については、「地域パスが短い」「回線マッチング度が高い」といった形で説明し、絶対的な法則として断定しない。&lt;/li&gt;
&lt;li&gt;構成としては、まず体感（実体験）から書き始め、次にその理由を解説し、最後に「今後どのようにノードを選ぶべきか」という結論に落とし込む。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>アーキテクチャが変わったので、HermesとOpenClawのトークンの消費方法は違います。</title>
        <link>https://ttf248.life/ja/p/hermes-openclaw-token-usage-diff/</link>
        <pubDate>Thu, 16 Apr 2026 01:13:53 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/hermes-openclaw-token-usage-diff/</guid>
        <description>&lt;p&gt;昨日書いた&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/hermes-openclaw-not-the-same-game/&#34; &gt;《HermesをOpenClawの代替品と見なすのは危険かもしれない》&lt;/a&gt;を書き終えた後、私は周りのドキュメントを巡回しました。巡るほど、この二つのものの違いを見るには、機能だけを見ているだけでは不十分で、トークンがどのように消費されるかを見る方が、より直接的だと感じました。&lt;/p&gt;
&lt;p&gt;私の判断は、まずここに置きます。&lt;/p&gt;
&lt;p&gt;OpenClaw はデフォルトで長期的にオンラインのワークベンチのようなものであり、多くのアイデンティティ、ルール、ワークスペースファイル、メッセージ面制約などが自然に各対話フローに引き継がれるため、ベースラインは通常重くなります。一方、Hermes は明らかに抑制的で、多くのコンテキストはオンデマンドで発見され、オンデマンドで注入されます。システムプロンプトも意図的に安定したプレフィックスを維持しており、デフォルトではトークンを抑えやすいです。&lt;/p&gt;
&lt;p&gt;もちろん、これはHermesが必ずしもより節約できるという意味ではありません。memory provider、skills、sub-agent、長いツール出力をすべて有効にすると、同じように大量のトークンを消費します。しかし、率直に言って、これら2つのアーキテクチャは、初日から異なる方法でトークンを消費しています。&lt;/p&gt;
&lt;h2 id=&#34;openclaw-はなぜデフォルトでより重いのか&#34;&gt;OpenClaw はなぜデフォルトでより重いのか
&lt;/h2&gt;&lt;p&gt;OpenClaw の設計ロジックは、元々「軽いエージェントを一つ出して、ちょっとおしゃべりする」というものではなく、「まず長期的に存在するエージェントのワークステーションを構築する」というものです。この点は公式の workspace ドキュメントに非常に明確に書かれています。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;SOUL.md&lt;/code&gt;、&lt;code&gt;USER.md&lt;/code&gt; はセッションごとにロードされます。&lt;code&gt;IDENTITY.md&lt;/code&gt;、&lt;code&gt;TOOLS.md&lt;/code&gt;、&lt;code&gt;HEARTBEAT.md&lt;/code&gt;、&lt;code&gt;BOOT.md&lt;/code&gt;、&lt;code&gt;MEMORY.md&lt;/code&gt; といったファイルも、同じワークスペース内で巡回します。ドキュメントはさらには、&lt;code&gt;HEARTBEAT.md&lt;/code&gt; は非常に短く保つよう注意喚起し、トークン消費を避けるように促しています。このような注意喚起自体が、OpenClaw が自身のデフォルトのコンテキストが比較的厚いことを明確に示しています。&lt;/p&gt;
&lt;p&gt;しかし、一つ明確にしておくべき点があります。OpenClaw はすべてを無条件で全文常駐させるわけではありません。公式のトークンドキュメントには、skills をシステムプロンプトに組み込む場合、デフォルトでは単なるメタデータであり、具体的な説明は必要に応じて &lt;code&gt;read&lt;/code&gt; する必要があると明記されています。したがって、問題は「節約ができない」ことではなく、「デフォルトで持っていく土台自体が元々大きい」ということです。&lt;/p&gt;
&lt;p&gt;この件は実は理解しにくいものではありません。OpenClaw が解決しようとしているのは、「長期的なオンライン状態」と「複数のメッセージ面での存在感」です。&lt;/p&gt;
&lt;p&gt;Telegram、Discord、Slack、WhatsAppといった複数の場所に同時に存在し、アイデンティティ、ルーティング、境界線、委任（delegate）を伴いながら活動させる場合、多くのルールは後から付け足すものであってはなりません。それはまず自分自身が何者であるか、どのように話すべきか、誰に向き合っているのか、現在のワークスペースの制約は何か、スキルをどこから取得するのか、どの記憶を持ち運ぶべきで、どの記憶を持ち運んではいけないのかを知る必要があります。&lt;/p&gt;
&lt;p&gt;そのため、OpenClaw のトークン消費は、より固定のオーバーヘッドが大きい傾向があります。&lt;/p&gt;
&lt;p&gt;メッセージを送信するたびに、単にモデルに一文を話しかけているのではなく、すでに完成された「アシスタント環境」全体を呼び出しています。この環境は使いやすいのですが、その代償としてベースとなるプロンプトがより厚くなり、たとえ今回のターンで直接使われなくても、多くのコンテキストがそこに保持されることになります。&lt;/p&gt;
&lt;h2 id=&#34;hermes-はなぜより抑制的に見えるのか&#34;&gt;Hermes はなぜより抑制的に見えるのか
&lt;/h2&gt;&lt;p&gt;Hermes の件ですが、ドキュメントの中で最も興味深い点は、常に2つのことを強調している点です。それは「オンデマンドローディング」と「プロンプトキャッシュの保持」です。&lt;/p&gt;
&lt;p&gt;まずコンテキストファイルをチェックしてください。Hermesはセッション開始時に、現在の作業ディレクトリでヒットした種類のプロジェクトコンテキストのみをロードします。&lt;code&gt;AGENTS.md&lt;/code&gt;や&lt;code&gt;CLAUDE.md&lt;/code&gt;、&lt;code&gt;.cursorrules&lt;/code&gt;などは「最初に見つかったものが採用される（first match wins）」ため、すべてが一度に読み込まれるわけではありません。さらに重要なのは、サブディレクトリ内の&lt;code&gt;AGENTS.md&lt;/code&gt;は起動時にすべて読み込まれるのではなく、実際にそのディレクトリに移動し、そのファイルを読み込み、そのパスに到達したときに、段階的に発見され、段階的に注入されるということです。&lt;/p&gt;
&lt;p&gt;公式ドキュメントでは、この設計の利点が明確に書かれています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;システムプロンプトの肥大化なし&lt;/li&gt;
&lt;li&gt;プロンプトキャッシュの保持&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この味はOpenClawとは全然違いますね。Hermesが言っているように、システムプロンプトは長すぎない方がいいし、後回しにできるコンテキストは後回しにして、関連するタイミングでのみ出現するものなら、最初のラウンドで詰め込みすぎない方がいいですよ。&lt;/p&gt;
&lt;p&gt;skills も同じ考え方です。Hermes の skills ドキュメントには、プログレッシブ・ディスクロージャー（段階的開示）が明確に書かれており、目的はトークン使用量の最小化です。言い換えれば、skill はデフォルトで全文常駐するのではなく、モデルにまず軽量なインデックスを見せ、本当に必要なときだけ具体的な内容を展開させるということです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;データマイニング&lt;/li&gt;
&lt;li&gt;ディープラーニング&lt;/li&gt;
&lt;li&gt;ニューラルネットワーク&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そして、その記憶システムも組み合わせ型に偏っています。公式ドキュメントでは組み込みメモリが厳しく制限されており、&lt;code&gt;MEMORY.md&lt;/code&gt; は約 800 トークン、&lt;code&gt;USER.md&lt;/code&gt; は約 500 トークンで、合計すると固定のコンテキストウィンドウは約 1300 トークンになります。&lt;code&gt;SOUL.md&lt;/code&gt; は固定のアイデンティティであり、&lt;code&gt;USER.md&lt;/code&gt; とメモリはシステムプロンプトに含まれますが、セッション検索やメモリプロバイダー、Honchoなどはより外部レイヤーのようなものです。この構造自体がプロンプトを自然に短くするわけではありませんが、コスト管理がしやすいデフォルトの姿勢を提供しています。&lt;/p&gt;
&lt;p&gt;そのため、アーキテクチャの観点から見ると、私はHermesを「デフォルトでは控えめだが、徐々に重みを増していく」と分類する方が気が進みます。&lt;/p&gt;
&lt;h2 id=&#34;これは誰がより進んでいるかではなくどこにコストをかけるかである&#34;&gt;これは誰がより進んでいるかではなく、どこにコストをかけるかである
&lt;/h2&gt;&lt;p&gt;多くの比較記事は、トークン消費を単一の結論として記述する傾向がありますが、これは適切ではないと思います。&lt;/p&gt;
&lt;p&gt;OpenClaw が重いのは、設計が悪いからではありません。むしろ、意図的に多くのものを前置しているのです。長期オンラインで、クロスプラットフォームで、パーソナリティを持ち、ワークスペースとルーティングを備えたアシスタントを求めるなら、これらのコンテキストにはいずれコストがかかります。単にデフォルトのパスでこれらを一式揃えているだけです。&lt;/p&gt;
&lt;p&gt;Hermes はより抑制的ですが、それがないわけではありません。長い &lt;code&gt;SOUL.md&lt;/code&gt; やプロジェクトの &lt;code&gt;AGENTS.md&lt;/code&gt;、複数のスキル、MCP、メモリプロバイダー、サブエージェント、長いツール出力などを重ねると、トークンはやはり速く消費されます。特にツールの結果自体が非常に長い場合や、複雑なコードベース内を何度も検索させる場合は、アーキテクチャ名だけで節約できるわけではありません。&lt;/p&gt;
&lt;p&gt;したがって、より正確な言い方は以下の通りです。&lt;/p&gt;
&lt;p&gt;OpenClaw は、コストを「アシスタント環境の常駐」に前倒しします。&lt;/p&gt;
&lt;p&gt;Hermes はコストを「必要な時に能力を展開する」ことに後置します。&lt;/p&gt;
&lt;p&gt;これら二つのアプローチに絶対的な優劣はありませんが、請求書の構造が全く異なります。&lt;/p&gt;
&lt;h2 id=&#34;本当に差がつくのはシステムプロンプトだけではない&#34;&gt;本当に差がつくのは、システムプロンプトだけではない
&lt;/h2&gt;&lt;p&gt;他にも、見落とされがちな細かい点があります。&lt;/p&gt;
&lt;p&gt;第一に、Hermes は context files の部分を安定したプレフィックスにするように設計されています。サブディレクトリの hint は、関連するツールの結果に追加されるものであり、すべてのプロジェクトコンテキストを system prompt に絶えず流し込むわけではありません。このアプローチはトークンを節約するだけでなく、本質的にはプロバイダーのプロンプトキャッシュのためのスペースを確保しているとも言えます。&lt;/p&gt;
&lt;p&gt;第二に、Hermes の &lt;code&gt;execute_code&lt;/code&gt; のようなツールは、設計上、スクリプトが最終的に &lt;code&gt;print()&lt;/code&gt; で出力した結果のみをモデルに返すように設計されており、途中の RPC ツール呼び出しの結果がすべてコンテキストに入るわけではありません。複雑なフローの場合、この構造により、無意味なツールのノイズを大幅に削減できます。&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;OpenClaw のワークスペースの哲学は、「家財道具を全部持っていく」というものに近いです。たとえ個々のファイルが短くても、種類が多い、人格レイヤーが多い、ルールレイヤーが多い、スキルや記憶の階層が多いだけで、基本的なコンテキストは少しずつ厚みを増していきます。この厚みはバグではなく、製品としての取捨選択によるものです。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第四に、両側がサブエージェントの処理を行うことも、総勘定書に影響を与えます。Hermes の多くの設計はローカルなコンテキストとローカルな実行を強調していますが、OpenClaw は複数のエージェントのアイデンティティ、ルーティング、委任といった組織能力をより重視しています。一方はコンテキストを切り替えるようなものであり、もう一方は存在関係を組織するようなものです。最終的にトークン料金に落とし込むと、形状は当然異なります。&lt;/p&gt;
&lt;h2 id=&#34;本当に計算するなら口先だけではダメだ&#34;&gt;本当に計算するなら、口先だけではダメだ
&lt;/h2&gt;&lt;p&gt;長期的に使うつもりなら、誰かが「こっちの方が節約になる」と言っても鵜呑みにせず、ツールが出したデータを見てください。&lt;/p&gt;
&lt;p&gt;OpenClaw の公式ドキュメントには、&lt;code&gt;/context detail&lt;/code&gt; や &lt;code&gt;/usage tokens&lt;/code&gt; のようなコマンドがあり、ドキュメントでもセッション開始時にどのファイルが注入されるか通知してくれます。これはベースディスクがどれだけ分厚いかを見るのに非常に適しています。&lt;/p&gt;
&lt;p&gt;Hermes の件ですが、公式ドキュメントの Honcho や関連する機能において、トークンバジェット、スキルプログレッシブディスクロージャー、コンテキストファイル注入の方法といった手がかりが提供されています。これらは &lt;code&gt;hermes insights&lt;/code&gt;、セッションストレージ、および実際のプロバイダーの請求書と合わせて確認できます。&lt;/p&gt;
&lt;p&gt;要するに、アーキテクチャは「どう使うか」しか決められず、「どれだけ使うか」までは決めてくれない。実際に請求額を決めるのは、君が書いた &lt;code&gt;SOUL.md&lt;/code&gt; の長さ、詰め込んだ記憶の量、開いたスキル数、ツールの出力をどれだけ取り込めたか、そしてモデル自体の価格だ。&lt;/p&gt;
&lt;h2 id=&#34;結局私はこの側に立つ&#34;&gt;結局、私はこの側に立つ
&lt;/h2&gt;&lt;p&gt;デフォルトのアーキテクチャだけを見て、極端な設定は考慮に入れなければ、私はやはり Hermes の方がトークンの消費を比較的抑制された範囲に抑えやすいと考えています。&lt;/p&gt;
&lt;p&gt;より強力だからではなく、プロンプト設計の段階から「無意味な永続コンテキストの膨張」を回避し続けているからです。OpenClawはそれとは対照的で、多少多く持っていくことを厭わずとも、その長期オンラインアシスタントとしてのアイデンティティ、ワークスペース、メッセージングインターフェースの境界が崩れないことを保証します。&lt;/p&gt;
&lt;p&gt;そのため、トークンコストを特に気にする場合や、ワークフローが主にローカル、CLI、コードリポジトリ、スキル蓄積といったシナリオで発生する場合は、Hermesのアプローチの方が一般的に扱いやすいでしょう。&lt;/p&gt;
&lt;p&gt;もしあなたが、様々なメッセージの場に本当に常駐する長期アシスタントを求めているのであれば、OpenClawはトークンを多めに使う方が、むしろ正常な対価だと思います。まるで人間のように常にオンラインでありながら、毎回使い捨ての小さなツールであるかのような軽さを要求することはできませんから。&lt;/p&gt;
&lt;p&gt;ああ、結局この件はまた元の問題に戻ってきましたね。&lt;/p&gt;
&lt;p&gt;あなたはオンラインアシスタントを育てているのか、それともローカルエージェントコアを育てているのか。これを明確にすれば、トークン計算はそれほど難しく感じなくなるはずだ。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/hermes-openclaw-not-the-same-game/&#34; &gt;前の記事：Hermes を OpenClaw の代替品と見なすのは、最初から偏っているかもしれない&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/overview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Features Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/context-files/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Context Files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/personality/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Personality &amp;amp; SOUL.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/reference/tools-reference/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Built-in Tools Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/honcho/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Honcho Memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/agent-workspace&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Agent Workspace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/reference/token-use&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Token Use and Costs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/memory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/multi-agent&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Multi-Agent Routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/reference/context&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Context Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：Hermes と OpenClaw について、両者のトークン消費状況に関する記事をもう一つ書いてください。アーキテクチャが異なるため、消費量も当然異なります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングのアイデア概要&#34;&gt;ライティングのアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;前回の記事の判断を引き継ぎつつ、論点をトークン消費に絞り込み、全体的なアーキテクチャ比較は繰り返さない。&lt;/li&gt;
&lt;li&gt;「どちらが省」といった空論ではなく、両者のデフォルトのコンテキストアセンブリ方法を重点的に比較する。&lt;/li&gt;
&lt;li&gt;Hermes はプログレッシブディスカバリー（段階的開示）、オンデマンドでの発見、およびプロンプトキャッシュの保持に焦点を当てる。&lt;/li&gt;
&lt;li&gt;OpenClaw はワークスペース常駐ファイル、長期オンラインアシスタント環境、固定オーバーヘッドに焦点を当てる。&lt;/li&gt;
&lt;li&gt;結びではユーザーが提示した核心的な判断は維持しつつも、「実際の請求書を見るなら、公式の usage/context ツールと実際のプロバイダーの課金体系を考慮する必要がある」という現実的な注意喚起を補足する。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>Hermes を OpenClaw の代替品として見ると、最初は偏りがあるかもしれません。</title>
        <link>https://ttf248.life/ja/p/hermes-openclaw-not-the-same-game/</link>
        <pubDate>Wed, 15 Apr 2026 23:52:20 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/hermes-openclaw-not-the-same-game/</guid>
        <description>&lt;p&gt;この二日間、HermesとOpenClawのドキュメントを何度も読み返しましたが、読むほどに、多くの人がこれら2つのプロジェクトを一緒にして比較していますが、実は最初から比較の軸がずれていると感じました。&lt;/p&gt;
&lt;p&gt;もちろん、これらはすべて「パーソナルAIアシスタント」を構築しています。メッセージの受信、モデルの呼び出し、ツールの実行、そしてある程度のコンテキスト保持が可能です。Hermesはさらには&lt;code&gt;hermes claw migrate&lt;/code&gt;という専用コマンドまで用意しており、OpenClawユーザーの一団を受け入れることを明白に知っているようです。&lt;/p&gt;
&lt;p&gt;しかし、端的に言えば、Hermes は OpenClaw のスキン変更版ではなく、OpenClaw もメッセージ入力口がいくつか増えたエージェントフレームワークではありません。一方は &lt;code&gt;Gateway&lt;/code&gt; から外側へ伸びていき、もう一方は &lt;code&gt;AIAgent&lt;/code&gt; から外側へ伸びています。この違いを先に理解しないと、後でアーキテクチャや設計思想、エコシステムについて話しても、どんどん話が混乱していきます。&lt;/p&gt;
&lt;h2 id=&#34;それらは最初から一つのものになるつもりではなかった&#34;&gt;それらは最初から一つのものになるつもりではなかった
&lt;/h2&gt;&lt;p&gt;OpenClaw の公式ドキュメントでは &lt;code&gt;Gateway&lt;/code&gt; を非常に早い位置に置いています。その定義は非常に直接的です。長期実行される Gateway がすべてのメッセージ面を保持し、コントロール面クライアント、Web UI、Node デバイスがすべてこの Gateway に WebSocket 経由で接続します。さらに、ホスト上にはコアなメッセージ接続を管理する Gateway は一つしかなく、WhatsApp のようなセッションも明確にそれが独占します。&lt;/p&gt;
&lt;p&gt;これはどういう意味ですか？それは、OpenClaw の世界観が「まずエージェントがあり、それにいくつかのインターフェースを接続する」というものではなく、「まず常駐の通信および制御プレーンがあり、その中にエージェントランタイム、セッション、スキル、デリゲート、サブエージェントなどをすべて編成する」ということです。&lt;/p&gt;
&lt;p&gt;Hermes はこの味ではない。そのアーキテクチャ図は最初から非常に明確で、CLI、Gateway、ACP、Batch Runner、API Server、Python Library といったエントリポイントがすべて同じ &lt;code&gt;AIAgent&lt;/code&gt; コアに集約されている。セッションストレージは SQLite + FTS5 であり、ツールバックエンド、プロバイダー解決、プロンプトビルダーはすべてこのコアを中心に構成されている。&lt;/p&gt;
&lt;p&gt;そのため、骨格から見ると、OpenClaw は「常駐型のパーソナルアシスタントシステム」に近く、Hermes は「エージェントランタイムプラットフォーム」に近く、メッセージ入力は単なるその延長面の一つに過ぎません。&lt;/p&gt;
&lt;h2 id=&#34;gatewayを主役にしたものとagentを主役にしたもの&#34;&gt;Gatewayを主役にしたものと、Agentを主役にしたもの
&lt;/h2&gt;&lt;p&gt;このアーキテクチャの違いは、最終的に利用体験の違いに直結します。&lt;/p&gt;
&lt;p&gt;OpenClaw の強みは、「多くのチャネルで長期的にオンラインで存在し、アイデンティティと境界を持ち、ルーティング可能なアシスタントをどう持つか」という点に非常に力を入れていることです。デフォルトの DM ペアリング、セキュリティポリシー、チャネル/アカウント/ピアごとのルーティング、マルチエージェントバインディング、デリゲートモードがあり、さらには「誰になりすまして発言するか、どの口座で受信するか、どのグループに出現するか」といった組織レベルの問題までドキュメント化されています。&lt;/p&gt;
&lt;p&gt;言い換えれば、OpenClaw がまず解決したいのは存在性の問題です。このエージェントは、まず本物の人間か、あるいは真の組織アシスタントのように振る舞い、Telegram、Discord、Slack、WhatsApp、Signal、WebChatといったプラットフォーム上で生きている必要があります。その後に、コードを書けるかどうか、タスクをディスパッチできるかどうかを議論するのです。&lt;/p&gt;
&lt;p&gt;Hermes の重点は「能力の蓄積」にあります。もちろん Gateway もあり、Telegram、Discord、Slack、WhatsApp などのプラットフォームにも接続できますが、公式な説明の中で最も前面に出ている単語は、ルーティングやアカウントではなく、persistent memory、skills、MCP、sub-agents、toolsets、さらには batch processing、trajectory export、RL training です。&lt;/p&gt;
&lt;p&gt;ここが重要です。Hermes が解決すべき中心的な問題は、「いかに多くのメッセージングプラットフォームに AI を接続するか」ということではなく、「このエージェント自身が段階的にスキルや記憶、再利用可能な能力を育み、さらには訓練データや実験として使えるようにすること」なのです。&lt;/p&gt;
&lt;p&gt;そのため、私はこのように要約するのがより良いと思います：&lt;/p&gt;
&lt;p&gt;OpenClaw はコミュニケーションファーストのパーソナルアシスタントシステムです。&lt;/p&gt;
&lt;p&gt;Hermes は agent-core-first のセルフホスト型エージェントプラットフォームです。&lt;/p&gt;
&lt;h2 id=&#34;記憶スキルそして拡張の方法も一つの味ではない&#34;&gt;記憶、スキル、そして拡張の方法も、一つの味ではない
&lt;/h2&gt;&lt;p&gt;多くの人が「これら2つともskill、memory、pluginをサポートしているのでは？」と言うでしょう。その通り、どちらもサポートしています。しかし、焦点が違います。&lt;/p&gt;
&lt;p&gt;OpenClaw のエージェントランタイムにおいて、ワークスペースは非常に重い概念です。&lt;code&gt;AGENTS.md&lt;/code&gt;、&lt;code&gt;SOUL.md&lt;/code&gt;、&lt;code&gt;TOOLS.md&lt;/code&gt;、&lt;code&gt;BOOTSTRAP.md&lt;/code&gt;、&lt;code&gt;IDENTITY.md&lt;/code&gt;、&lt;code&gt;USER.md&lt;/code&gt; といったファイル群は、新しいセッションの最初のラウンドで直接コンテキストに注入されます。スキル（技能）のロードにも一連の優先順位があり、ワークスペース内のもの、プロジェクト内のもの、個人ディレクトリ内のもの、&lt;code&gt;~/.openclaw/skills&lt;/code&gt; 内のもの、バンドルされたもののすべてが積み重なります。本質的には、「ペルソナ + ルール + ワークスペース + チャネル」を統合した長期的なアシスタント環境を構築しているのです。&lt;/p&gt;
&lt;p&gt;Hermes のスキルシステムは明らかに「手続き的記憶」に偏っています。公式ドキュメントには、skills はオンデマンドの知識ドキュメントであり、プログレッシブディスクロージャーを採用し、&lt;code&gt;agentskills.io&lt;/code&gt; のオープン標準に対応しており、すべて &lt;code&gt;~/.hermes/skills/&lt;/code&gt; 以下に統一して配置され、さらにエージェント自身がスキルを修正・削除できると明記されています。これは単に「アシスタントに説明書を数冊渡す」という感じではなく、「実行したことを再利用可能な能力ブロックとして蓄積する」という感覚です。&lt;/p&gt;
&lt;p&gt;記憶も同じです。Hermes には控えめな &lt;code&gt;MEMORY.md&lt;/code&gt; と &lt;code&gt;USER.md&lt;/code&gt; が組み込まれており、これに SQLite + FTS5 のセッション検索と、さらに 8 種類のメモリプロバイダーを外付けしています。この設計は非常に興味深く、最初から「長期的な人格環境」を厚く記述するのではなく、短期記憶、検索式回想、外付けの長期記憶を分離している点です。&lt;/p&gt;
&lt;p&gt;OpenClaw は記憶がないわけでもなく、サブエージェント、マルチエージェント、デリゲートといった高度な能力を持たないわけでもありません。むしろ、それらは十分に備わっています。しかし、ドキュメントの構造とデフォルトの思考モデルから見ると、それは継続的にオンラインのアシスタントワークスペースを運営しているように見えます。一方、Hermes は絶えず進化するエージェント能力グラフを運営しているように見えます。&lt;/p&gt;
&lt;h2 id=&#34;エコシステムはなぜ離れていくのか&#34;&gt;エコシステムはなぜ離れていくのか
&lt;/h2&gt;&lt;p&gt;エコシステムに関しては、表面的にはすべて「オープンソース＋拡張可能」に見えますが、実際には分岐が非常に明確です。&lt;/p&gt;
&lt;p&gt;OpenClaw のエコシステムはより広く、外部接続レイヤーに重点を置いています。公式プラグインでは、channels、model providers、tools、skills、speech、web fetch、web search、memory を拡張でき、コミュニティプラグインや ClawHub も「より多くのプラットフォーム」「より多くのアカウント」「より多くのワークフロー」への接続を目指しています。さらには、&lt;code&gt;.codex-plugin&lt;/code&gt;、&lt;code&gt;.claude-plugin&lt;/code&gt;、&lt;code&gt;.cursor-plugin&lt;/code&gt; のようなバンドル形式との互換性も明言しています。この動きは非常に賢く、要するに他社のエコシステムの「殻」を先に取り込み、入口（エントランス）を大きくしようとしているのです。&lt;/p&gt;
&lt;p&gt;OpenClaw のドキュメントを再確認すると、sub-agent、delegate、組織エージェント、thread binding、DM pairing、group mention などについて非常に詳細に記述されていることがわかります。これは単なるシングルマシンプレイヤーの遊び場ではなく、真に長期的に動作するエージェントオペレーティングシステムになることを目指していることを示しています。&lt;/p&gt;
&lt;p&gt;Hermes のエコシステムは、「コア機能の外部接続」という側面が強いです。Python プラグインシステムがあり、メモリプロバイダープラグインがあり、コンテキストエンジンプラグインがあり、MCP サーバーへの接続もあり、さらに Skills Hub や &lt;code&gt;agentskills.io&lt;/code&gt; のようなオープンなスキル標準があります。これに加えて、バッチランナー、トラジェクトリエクスポート、Atropos といったトレーニング関連のインターフェースがあるため、Hermes のエコシステムは自然と二種類のユーザー層を引きつけます。&lt;/p&gt;
&lt;p&gt;一方は、それを個人のエージェントとして使う人です。&lt;/p&gt;
&lt;p&gt;もう一つの分類は、それを研究、トレーニング、実験、ワークフローの基盤として利用する人々です。&lt;/p&gt;
&lt;p&gt;この2種類のユーザーのニーズは大きく異なりますが、Hermesのアーキテクチャはどちらもカバーできます。そのため、HermesのエコシステムはOpenClawのように「チャネル数」や「メッセージの存在感」で先行して広がるわけではないと感じるかもしれませんが、私はむしろ、エージェント基盤（agent substrate）におけるその潜在力の方が大きいと感じています。&lt;/p&gt;
&lt;p&gt;さらに興味深い詳細があります。Hermesの公式READMEには&lt;code&gt;hermes claw migrate&lt;/code&gt;だけでなく、コミュニティプロジェクトである&lt;code&gt;HermesClaw&lt;/code&gt;も掲載されており、これを使うことで同じWeChatアカウント上でHermes AgentとOpenClawを同時に実行できます。このシグナルは非常に明白です。Hermesは自分とOpenClawが関係ないふりをしているのではなく、ユーザーの移行パスが存在することを認め、さらにそのパスを製品化して提供しているのです。&lt;/p&gt;
&lt;h2 id=&#34;私の最終的な判断&#34;&gt;私の最終的な判断
&lt;/h2&gt;&lt;p&gt;もしあなたが「本当にメッセージングレイヤー上で動作する個人アシスタントシステム」を求めているのであれば、アカウント、チャネル、ルーティング、デリゲート、組織境界、常時オンライン、強力なコントロールプレーンが必要なのであれば、OpenClawの道筋の方がより完全であり、成熟した通信基盤に近いです。&lt;/p&gt;
&lt;p&gt;もしあなたが「使うほど自分専用のワークステーションのように馴染むエージェントコア」を求めていて、スキル蓄積、メモリの組み合わせ、MCP、プラグイン、サブエージェント、学習データ、そしてその後の可塑性を重視するなら、Hermesの方が使いやすいでしょう。&lt;/p&gt;
&lt;p&gt;ですから、「Hermes は OpenClaw に取って代われるか？」といった単純な質問はもうしないでください。その質問の仕方が少々粗雑です。&lt;/p&gt;
&lt;p&gt;より正確な聞き方は以下の通りです。&lt;/p&gt;
&lt;p&gt;メッセージングネットワーク内に存在するAIアシスタントを求めているのか、それともローカルのワークフローやエージェントランタイムに組み込まれるAIプラットフォームを求めているのでしょうか？&lt;/p&gt;
&lt;p&gt;これをしっかり理解すれば、選択はそれほど迷いませんよ。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/NousResearch/hermes-agent&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent GitHub README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent 公式サイト Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/developer-guide/architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Skills System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/memory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Persistent Memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Hermes Agent Plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openclaw/openclaw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw GitHub README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Gateway Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/agent&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Agent Runtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/multi-agent&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Multi-Agent Routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/concepts/delegate-architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Delegate Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/tools/subagents&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Sub-Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/tools/plugin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.openclaw.ai/tools/skills-config&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;OpenClaw Skills Config&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：HermesとOpenClawの違い、アーキテクチャ上の違い、設計思想上の違い、エコシステムの違い&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングのアイデア概要&#34;&gt;ライティングのアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「代替品比較」というよくある質問形式は外し、「二つのプロジェクトの中心がどこにあるのか」というメインラインに直接絞る。&lt;/li&gt;
&lt;li&gt;アーキテクチャ部分は、コミュニティによる二次的なまとめではなく、公式ドキュメントのメインエントリとコアコンポーネントを優先して参照する。&lt;/li&gt;
&lt;li&gt;設計理念の部分では、抽象的な価値判断は行わず、Gateway、Agent Core、memory、skill、delegateといった具体的な設計に落とし込む。&lt;/li&gt;
&lt;li&gt;エコシステム部分は、星マークや人気度、コミュニティでの憶測合戦はせず、拡張の方向性に重点を置く。&lt;/li&gt;
&lt;li&gt;事実確認は、2026年4月15日時点で公開されている公式リポジトリと公式ドキュメントを基準とする。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>AI はデモの作成が速く、修正作業も本当に速いです。</title>
        <link>https://ttf248.life/ja/p/ai-demo-fast-rework-faster/</link>
        <pubDate>Fri, 10 Apr 2026 15:39:51 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/ai-demo-fast-rework-faster/</guid>
        <description>&lt;p&gt;最近AIを使ってC++の小規模なプロジェクトを立ち上げたんだけど、一番「やられる」瞬間は、それがコードを書いてくれないことじゃなくて、たった3分でそれっぽくディレクトリツリーを組み立ててくれて、ついでにサードパーティライブラリをいくつか突っ込んで、デモが本当に動く時なんだよね。問題もそこにある。新しく導入したライブラリが具体的に何に対応しているのか、コンパイルのパスはどうなるのか、どこに境界線があるのか、まだ把握できていないのに、後で手戻りが発生するのはほぼ避けられない。&lt;/p&gt;
&lt;p&gt;最近、AIプログラミングで最も怖いのはモデルの賢さではなく、最初からやりすぎなところだと感じています。特にC++のような、しっかりしたフレームワーク（脚手架）に頼れない言語の場合、手順を一つ間違えるだけで、コンパイル、リンク、ライブラリのバージョン、ディレクトリ構造など、後でいくつもの手間が増えてしまいます。&lt;/p&gt;
&lt;p&gt;この件について、私自身の結論は非常に明確です。AI は、初期設計や依存関係の決定をすべて肩代わりするのではなく、急速に推進力のあるペアプログラマーとして適しています。GitHub のドキュメントでは、最初はより簡単なタスクから始めるよう推奨しており、エージェントにバグ修正、ドキュメント作成、テスト、技術的負債といった境界がより明確な作業を先にこなしてもらうべきだと述べています。一方、Anthropic の Plan Mode のドキュメントは、むしろ複雑な変更に対する保険のようなものであり、「まずコードを読み、計画を立ててから、修正するかどうかを決める」という流れです。両者の主張は完全に一致しているわけではありませんが、指し示す方向性は似ています。最初から最も難しく、最も混沌としていて、依存関係が最も多い塊をすべてAIに丸投げするのは避けるべきです。&lt;/p&gt;
&lt;p&gt;そのため、この記事では大量の仕様を語るのではなく、すぐに手を動かせる小さなケーススタディを提供します。任意の空のC++リポジトリがあれば、これに従って作業できます。&lt;/p&gt;
&lt;h2 id=&#34;aiじゃないからダメなのではなく最初の一手が貪欲すぎるからだ&#34;&gt;AIじゃないからダメなのではなく、最初の一手が貪欲すぎるからだ
&lt;/h2&gt;&lt;p&gt;人工知能のプロジェクト、特にC++の場合、多くの時は非常に原始的な方法になりがちです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;まずは &lt;code&gt;main.cpp&lt;/code&gt; から最小実行可能なバージョンを始める&lt;/li&gt;
&lt;li&gt;まずコンパイルのリンクを通す&lt;/li&gt;
&lt;li&gt;その後、どのライブラリを導入するか決める&lt;/li&gt;
&lt;li&gt;一歩進むごとにビルドできることを保証する&lt;/li&gt;
&lt;li&gt;ビジネスの輪郭が見えてから、リファクタリングを開始する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この方法は遅く見えるかもしれませんが、実際は非常に安定しています。なぜなら、どのステップで何を得たのか、そして問題がどのステップから生じているのかをすべて知っているからです。&lt;/p&gt;
&lt;p&gt;AI はこのリズムを崩しやすいです。一気に「完璧に手伝ってくれる」のが好きなんです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;設定ファイルもついでに用意したよ&lt;/li&gt;
&lt;li&gt;ログモジュールもついでに取り出したよ&lt;/li&gt;
&lt;li&gt;エラーコード、ユーティリティクラス、ディレクトリ構造もまとめて整理したよ&lt;/li&gt;
&lt;li&gt;サードパーティライブラリの組み込み方法も、代わりに選んでおいたよ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;結果として、デモは完成しているように見えても、あなたのメンタルモデルは空っぽである。その後、ライブラリの能力境界とあなたが考えていることに少しでも食い違いがあると、手直しが必要なのは一点ではなく、連続したものになってしまう。&lt;/p&gt;
&lt;h2 id=&#34;まずは小さなプロジェクトで練習する&#34;&gt;まずは小さなプロジェクトで練習する
&lt;/h2&gt;&lt;p&gt;個人的には、練習に最適だと思うのは、非常に小さなログスキャンツールを作ることです。名前は適当でいいですが、例えば &lt;code&gt;logscan&lt;/code&gt; のようなものです。&lt;/p&gt;
&lt;p&gt;それはただ一つのことをします。あるディレクトリ内のログファイルをスキャンし、&lt;code&gt;error&lt;/code&gt; と &lt;code&gt;warn&lt;/code&gt; の数を数え、その結果を出力するだけです。この問題はそれほど大きくありませんが、C++の小規模プロジェクトで最も一般的ないくつかの部分をすべて通るのにちょうど良いものです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;main&lt;/code&gt; と引数エントリポイント&lt;/li&gt;
&lt;li&gt;出力フォーマット化&lt;/li&gt;
&lt;li&gt;ログ&lt;/li&gt;
&lt;li&gt;設定ファイル&lt;/li&gt;
&lt;li&gt;ビジネスモジュールの分割&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重要なのは問題がどれだけ高度かではなく、分解の方法です。&lt;/p&gt;
&lt;p&gt;これを4つのステップに分割し、各ステップではAIが現在の小さな一歩のみを行うようにします。&lt;/p&gt;
&lt;h2 id=&#34;ステップ1まず出力を準備する&#34;&gt;ステップ1：まず出力を準備する
&lt;/h2&gt;&lt;p&gt;最初のステップは、ログや設定には触れず、抽象化を考えないことです。&lt;/p&gt;
&lt;p&gt;2つのことをする：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最低限の &lt;code&gt;main.cpp&lt;/code&gt; を作成する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fmt&lt;/code&gt; をインポートし、スキャンしたディレクトリと統計結果を出力する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;fmt&lt;/code&gt; の公式ドキュメントには、非常に明確な CMake の使い方が記載されています。そこには &lt;code&gt;fmt::fmt&lt;/code&gt; と &lt;code&gt;fmt::fmt-header-only&lt;/code&gt; という2つのターゲットがあり、ドキュメントではコンパイル版をより推奨していると明記されており、その理由は単純で、ビルド時間がより親切だからです。CMake の &lt;code&gt;FetchContent&lt;/code&gt; のドキュメントも新しいプロジェクトの開始に非常に適しています。なぜなら、これはビルド段階になってから一時的にダウンロードするのではなく、configure 段階で依存関係を読み込むからです。&lt;/p&gt;
&lt;p&gt;このステップでは、依存戦略を固定し、AIに自由に発揮させません。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;FetchContent&lt;/code&gt; を統一する&lt;/li&gt;
&lt;li&gt;または &lt;code&gt;find_package&lt;/code&gt; を統一する&lt;/li&gt;
&lt;li&gt;いざという時に vcpkg、いざという時に &lt;code&gt;add_subdirectory&lt;/code&gt;、そしてまた手動でヘッダーファイルをコピーするのはやめてほしい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;もし練習用のプロジェクトであれば、私はAIにこのように制約をかけます：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;アーキテクチャを一度に最適化しないでください。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;現在の目標はこのステップのみであり、プロジェクトは常にコンパイル可能でなければなりません。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;このステップでは以下の3点のみを行います：
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. ルートの CMakeLists.txt に fmt を導入する
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. main.cpp で渡されたディレクトリとスキャン結果を fmt で出力する
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 既存のターゲット名とディレクトリ構造を維持し、ログ、設定、テストフレームワークは追加しない
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;まず修正リストを提示し、その後コードを提示してください。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;完了したら、ビルドコマンドと期待される出力を提示してください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここに重要な詳細があります。AIは、制約がない場合、「ついでにこれもやった」ということを加点要素として扱いがちです。今回のラウンドでは範囲を超えてはいけないと明確に伝える必要があります。&lt;/p&gt;
&lt;h2 id=&#34;ステップ2ログのアップロード&#34;&gt;ステップ2、ログのアップロード
&lt;/h2&gt;&lt;p&gt;まずステップとして、コードが書けて、動いて、出力も綺麗になったら、&lt;code&gt;spdlog&lt;/code&gt;を追加する。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;spdlog&lt;/code&gt; の公式 README は、実際何ができるかを非常に分かりやすく記述しています。コンソールログだけでなく、通常のファイル、ローテーションファイル、日付ごとの分割、さらにはバックトレースリングバッファまで対応できます。問題はここです。機能が多すぎると、AI は興奮しすぎてしまい、まるで初版でカラーコンソール、ローテーションログ、日付アーカイブ、グローバルロガーファクトリを全部盛り込みたがるのです。&lt;/p&gt;
&lt;p&gt;不要です。&lt;/p&gt;
&lt;p&gt;このステップでは、コンソールログを出すか、せいぜい最もシンプルなファイルログを追加するだけです。なぜなら、ここで本当に学ぶべきことは、「どうやってロギングシステムを完全に設計するか」ではなく、以下の3点だからです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ロガーの初期化はどこで行うべきか&lt;/li&gt;
&lt;li&gt;ビジネスロジック内でどのようにロガーを取得するか&lt;/li&gt;
&lt;li&gt;エラー発生時と通常出力時のログの役割分担はどうすべきか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;もし最初から &lt;code&gt;rotating_file_sink&lt;/code&gt; や &lt;code&gt;daily_file_sink&lt;/code&gt; を使うと、「機能がとても充実した」ロギングモジュールを手に入れたように感じますが、実際にはローテーションや日付ごとの分割が必要なのか、それともデバッグ段階でターミナルに出力するだけで十分なのか、自分自身がまだ分かっていないかもしれません。&lt;/p&gt;
&lt;p&gt;要するに、ログファクトリをいかに美しく描くかよりも、まず&lt;code&gt;spdlog::info()&lt;/code&gt;の使い方を理解することがより重要です。&lt;/p&gt;
&lt;h2 id=&#34;ステップ3設定ファイルに触れる&#34;&gt;ステップ3、設定ファイルに触れる
&lt;/h2&gt;&lt;p&gt;設定ファイルの部分は、AIによって大規模なプロジェクトになりやすいです。&lt;/p&gt;
&lt;p&gt;私は、それが「最強」だからというよりは、新しいプロジェクトの初期段階に適しているから、&lt;code&gt;toml++&lt;/code&gt; のようなシンプルなライブラリで練習したいと思っています。それ自体が C++17 のヘッダーオンリーな TOML パーサーであり、README に記載されている例も非常に短く、&lt;code&gt;toml::parse_file(&amp;quot;configuration.toml&amp;quot;)&lt;/code&gt; で直接読み込めます。さらに重要なのは、単一ヘッダーファイル形式が本当に手間いらずなことです。公式の説明文もとても面白いのですが、シングルヘッダーのソリューションは「&lt;code&gt;toml.hpp&lt;/code&gt; をソースツリーに放り込むだけ」で、「第二の手順はありません」。&lt;/p&gt;
&lt;p&gt;このステップでは「設定センター」は行わず、以下の3つのフィールドを読み込んでください：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スキャンディレクトリ&lt;/li&gt;
&lt;li&gt;キーワードリスト&lt;/li&gt;
&lt;li&gt;出力はファイルに書き込むか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そしてそれらを非常に薄い &lt;code&gt;AppConfig&lt;/code&gt; 構造体に詰め込みます。&lt;/p&gt;
&lt;p&gt;それで十分です。&lt;/p&gt;
&lt;p&gt;多くの手戻りは、実はここから生じているんです。設定を起動時に一度読み込むのか、実行時にホットアップデートするのか。ローカルのCLI専用なのか、それとも将来的にサービスプロセスで再利用するのか、ご自身でまだ明確に考えていない。AIはすでにあなたのために5、6層も処理してくれました。後から方向性を変更すると、これまで積み上げてきた「完璧な設計」がすべて重荷になってしまいますよ。&lt;/p&gt;
&lt;h2 id=&#34;ステップ4ビジネスモジュールの分解&#34;&gt;ステップ4：ビジネスモジュールの分解
&lt;/h2&gt;&lt;p&gt;例えば、&lt;code&gt;fmt&lt;/code&gt;、&lt;code&gt;spdlog&lt;/code&gt;、&lt;code&gt;toml++&lt;/code&gt; などはすべて自分で公式ドキュメントを一度確認し、実際に動作テストを行った上で、AIにモジュール分割を手伝ってもらう、といった具合です。&lt;/p&gt;
&lt;p&gt;この時分解すると、心に余裕ができます。&lt;/p&gt;
&lt;p&gt;通常、私は以下のようなファイルを収集します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;main.cpp&lt;/code&gt; はアセンブリのみを担当する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app_config.{h,cpp}&lt;/code&gt; は設定の読み取りのみを担当する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logger.{h,cpp}&lt;/code&gt; はログの初期化のみを担当する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;log_scanner.{h,cpp}&lt;/code&gt; に業務ロジックを配置する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意点として、この段階になってから分割するものであり、最初から分割するわけではありません。最初のステップで目次をきれいに並べることは、多くの場合、視覚的に心地よいだけであり、認知的な明確さが増すわけではありません。&lt;/p&gt;
&lt;h2 id=&#34;本当に役立つのは複雑な規範ではない&#34;&gt;本当に役立つのは、複雑な規範ではない
&lt;/h2&gt;&lt;p&gt;インターネット上には、AIのコーディング規約が非常に複雑なものが多くて、十数項目、数十項目とあって、見るだけで疲れますね。私が今残したものは、実はたった3つだけなので、これで十分だと思います。&lt;/p&gt;
&lt;p&gt;第1条、まず「ライブラリカード」を作成します。&lt;/p&gt;
&lt;p&gt;サードパーティライブラリを準備するたびに、私はまずAIに以下の4つの質問だけを回答するようにしてもらいます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;このライブラリは何の問題を解決しますか&lt;/li&gt;
&lt;li&gt;公式版はどこまでサポートしていますか&lt;/li&gt;
&lt;li&gt;今回はどの機能の 1 つか 2 つに絞って使いたいと思っています&lt;/li&gt;
&lt;li&gt;ビルド、デプロイ、実行にどのような制約をもたらしますか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このカードが分からない場合は、とりあえず受けないでください。&lt;/p&gt;
&lt;p&gt;第2条、一度にAIを一つのチェックポイントだけに通す。&lt;/p&gt;
&lt;p&gt;例えば、このラウンドではこれだけを完了させることを許可する：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コーディングできる&lt;/li&gt;
&lt;li&gt;実行できる&lt;/li&gt;
&lt;li&gt;期待される出力を確認できる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同じラウンドで「ついでにディレクトリをリファクタリングする」「ついでに設定クラスを追加する」「ついでに例外処理の仕組みも統一する」といったことをするのはやめてください。C++プロジェクトでは、「ついで」というものが、問題の原因箇所を汚染しやすくなります。&lt;/p&gt;
&lt;p&gt;第3条、各ラウンドでロールバックポイントを残すこと。&lt;/p&gt;
&lt;p&gt;コミットしなくても、以下の質問に答えられる必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;このステップで具体的に何が変わったのか&lt;/li&gt;
&lt;li&gt;間違っていた場合、どこを削除する必要があるか&lt;/li&gt;
&lt;li&gt;一つ前のステップに戻した場合、プロジェクトはまだ編集可能か&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;気づくと、この考え方は実は手動での開発と非常によく似ています。違いは、以前は自分でコードを書いていたのに対し、今はAIが暴走しないように見張っているという点だけです。&lt;/p&gt;
&lt;h2 id=&#34;より実戦的なaiの活用方法&#34;&gt;より実戦的なAIの活用方法
&lt;/h2&gt;&lt;p&gt;この一連のものを本当に習得したいなら、3周連続でやることをお勧めします。&lt;/p&gt;
&lt;p&gt;第1ラウンドは、AIに&lt;code&gt;fmt&lt;/code&gt;の補完だけを任せて、残りは自分でCMakeの設定と出力コードを読み直してください。&lt;/p&gt;
&lt;p&gt;第2ラウンドは、AIに&lt;code&gt;spdlog&lt;/code&gt;のみを扱わせてください。コンソールログにするかファイルログにするかは自分で決めてください。両方同時に使うのは禁止です。&lt;/p&gt;
&lt;p&gt;第3ラウンドは、AIに&lt;code&gt;toml++&lt;/code&gt;の受け渡しのみをさせ、設定項目は自分で決め、AIに将来のニーズを推測させることは禁止とする。&lt;/p&gt;
&lt;p&gt;この3周を終えると、AIプログラミングに対する感覚が大きく変わるでしょう。前は「どうしてこんなにたくさん生成してくれるんだ」という感じだったのが、徐々に「次のステップをどれくらい小さくすれば最も効率的か」という視点になるようになります。&lt;/p&gt;
&lt;p&gt;これが今のAIプログラミングで最も価値のある能力だと思います。&lt;/p&gt;
&lt;p&gt;デモを出すわけではない。&lt;/p&gt;
&lt;p&gt;むしろ、一つのプロジェクトを確実に前進させる。&lt;/p&gt;
&lt;p&gt;正直なところ、このやり方は目新しくなく、むしろ古臭いかもしれません。しかし、古い方法は再作業に強い傾向があります。特にC++のような言語では、AIに少し任せる部分を減らして、自分で確認する部分を増やすと、後が本当に楽になります。そうしないと、3分で飛び立っても、3時間かけてやり直すのは自分自身ですからね。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.anthropic.com/en/docs/claude-code/common-workflows&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Anthropic, Claude Code Common Workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.anthropic.com/en/docs/claude-code/overview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Anthropic, Claude Code Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/en/copilot/tutorials/cloud-agent/get-the-best-results&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Docs, Best practices for using GitHub Copilot to work on tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://cmake.org/cmake/help/latest/module/FetchContent.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CMake Docs, FetchContent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://fmt.dev/latest/get-started/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;{fmt} Get Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/gabime/spdlog&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gabime/spdlog README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/gabime/spdlog/wiki/Sinks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gabime/spdlog Wiki: Sinks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/marzer/tomlplusplus&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;marzer/tomlplusplus README&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：人間がプロジェクトを構築する際、C++のようにフレームワークを使わない言語の場合、まず&lt;code&gt;main&lt;/code&gt;からロジックを展開していく「骨格」を作り、徐々に設定ファイル、ログモジュール、反復的なビジネスモジュールなどを追加していくのが良いと思います。私の習慣としては、毎回コンパイルが通ることを確認し、段階的にリファクタリングを進めることです。最初から最適解である必要はありません。AIによるプログラミングは、今や多くのケースで工程を飛ばしたり、初期の思考が不足したりしがちです。特に新しいサードパーティライブラリを導入する場合、AIはすぐにデモを出せますが、私が新しく導入したサードパーティライブラリの詳細な仕様やサポートする機能が不明確なため、関連ロジックの作り直し（手戻り）率は人間による開発よりも明らかに高くなります。学べるような良い実例はありませんか？インターネット上には複雑なAIプログラミング規約はたくさんあると知っていますが、私はもっとシンプルで、すぐに適用できるものが欲しいです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングのアイデア概要&#34;&gt;ライティングのアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;トピックを &lt;code&gt;tooling&lt;/code&gt; レーンに絞り、AI がワークフローを変えた後、どこが楽になり、逆にどこが不自然になったかを重点的に書く。&lt;/li&gt;
&lt;li&gt;一般的な規範リストではなく、C++ の小規模プロジェクトの段階的な練習事例に変更する。&lt;/li&gt;
&lt;li&gt;ユーザーが「&lt;code&gt;main&lt;/code&gt; から始め、各ステップでコンパイルでき、徐々にリファクタリングできる」という核となる判断を維持し、これを記事全体のメインラインとする。&lt;/li&gt;
&lt;li&gt;Anthropic、GitHub、CMake、fmt、spdlog、toml++ の一次資料を補完し、ツールの機能や依存方法について憶測するのを避ける。&lt;/li&gt;
&lt;li&gt;記事の構成は &lt;code&gt;fmt -&amp;gt; spdlog -&amp;gt; toml++ -&amp;gt; モジュール分割&lt;/code&gt; の順に進め、意図的に AI に一度で全てを解決させないようにする。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>VS CodeでC&#43;&#43;を扱う際は、CMakeとGDB Printerを忘れないように。</title>
        <link>https://ttf248.life/ja/p/vscode-cpp-debug-prelaunch-cmake-gdb-printer/</link>
        <pubDate>Thu, 09 Apr 2026 19:21:36 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/vscode-cpp-debug-prelaunch-cmake-gdb-printer/</guid>
        <description>&lt;p&gt;以前VS CodeでC++をデバッグするとき、設定は基本的に&lt;code&gt;launch.json&lt;/code&gt;に留まっていて、せいぜいGDBの行を追加する程度でした。
&lt;code&gt;program&lt;/code&gt;を埋めて、&lt;code&gt;gdb&lt;/code&gt;を埋めて、ブレークポイントを設定する。それで終わり？毎回デバッグ前にターミナルで手動で&lt;code&gt;cmake --build&lt;/code&gt;しないといけませんでした。
さらに面倒なのは、カスタム価格、契約、注文タイプなどでブレークポイントを打った後、VS Codeのデバッグウィンドウには内部フィールドが大量に表示されるだけで、データ自体は正しいのですが、人間が理解できる言葉になっていない点です。
この件がおかしいと思う点は、以前見たチュートリアルも&lt;code&gt;launch.json&lt;/code&gt;までしか触れていなかったことです。最近AIに新しいプロジェクトの設定を依頼したところ、なんと自動で&lt;code&gt;preLaunchTask&lt;/code&gt;と&lt;code&gt;gdb_printers.py&lt;/code&gt;を追加してくれたので、「VS CodeでC++をデバッグするって、ただGDBを起動させるだけじゃないんだな」と気づきました。デバッグ前にCMakeのコンパイルを自動実行できるし、ブレークポイントで停止した後に、GDBにPythonスクリプトをロードさせて、ビジネスロジックの型を自分が見やすい形に整形させられるんです。
正直なところ、これは何かの「裏ワザ」というわけではありません。
しかし、C++の日常的なデバッグにおける非常に面倒な2つの空白部分――&lt;strong&gt;起動前のビルド&lt;/strong&gt;と&lt;strong&gt;ブレークポイント後の変数表示&lt;/strong&gt;――を完璧に埋めてくれたのです。&lt;/p&gt;
&lt;h2 id=&#34;以前只配了一半&#34;&gt;以前只配了一半
&lt;/h2&gt;&lt;p&gt;多くのチュートリアルにある &lt;code&gt;.vscode/launch.json&lt;/code&gt; は、大体このような内容です：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Debug with GDB&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cppdbg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;program&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}/build/debug/bin/vscode_cpp_debug_demo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;stopAtEntry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;MIMode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;miDebuggerPath&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;setupCommands&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Enable pretty-printing for gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-enable-pretty-printing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この部分は間違っているとは言えません。
VS Code の公式の C++ サンプルでも、同様の構造が使われています：&lt;code&gt;type&lt;/code&gt; に &lt;code&gt;cppdbg&lt;/code&gt; を使い、&lt;code&gt;MIMode&lt;/code&gt; に &lt;code&gt;gdb&lt;/code&gt; を使い、&lt;code&gt;setupCommands&lt;/code&gt; で pretty-printing を有効にしています。
しかし、決定的に欠けている動作があります。
F5 を押すと、それは &lt;code&gt;program&lt;/code&gt; が指す実行ファイルを起動します。問題は、そのファイルが今まさにコンパイルされたものかどうかです？
もしそうでなければ、前回ビルドした古いプログラムをデバッグしてしまいます。
私も以前、よくこんな馬鹿なことをしていました。コードを変更し、ブレークポイントも設定したのに、しばらく動かしてみたら動作がおかしいことに気づき、最後に「ああ、さっき再コンパイルするのを忘れていた」と思い出す、ということがありました。&lt;/p&gt;
&lt;h2 id=&#34;prelaunchtask-こそがそのフックである&#34;&gt;preLaunchTask こそがそのフックである
&lt;/h2&gt;&lt;p&gt;VS Code の Tasks は、本質的に外部コマンドをエディタに組み込む仕組みです。
コンパイル、テスト、パッケージングといった作業は、以前はターミナルで手動で行う必要がありましたが、今では &lt;code&gt;.vscode/tasks.json&lt;/code&gt; に記述できます。そして &lt;code&gt;launch.json&lt;/code&gt; の中の &lt;code&gt;preLaunchTask&lt;/code&gt; が、そのラベルを使って該当するタスクを探し出します。
最小限の CMake プロジェクトを例に挙げると、このように配置できます：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── .vscode/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   ├── launch.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── tasks.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── CMakeLists.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── src/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│   └── main.cpp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── tools/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    └── gdb_printers.py
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;CMakeLists.txt&lt;/code&gt; はまず、これだけ記述します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cmake&#34; data-lang=&#34;cmake&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VERSION&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;3.16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;project&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;vscode_cpp_debug_demo&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;LANGUAGES&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;CXX&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;CMAKE_CXX_STANDARD&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;CMAKE_CXX_STANDARD_REQUIRED&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;CMAKE_RUNTIME_OUTPUT_DIRECTORY&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;CMAKE_BINARY_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/bin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;add_executable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;vscode_cpp_debug_demo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s&#34;&gt;src/main.cpp&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に、&lt;code&gt;.vscode/tasks.json&lt;/code&gt; です：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;tasks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake: configure debug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;process&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;-S&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;-B&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}/build/debug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;-DCMAKE_BUILD_TYPE=Debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;problemMatcher&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake: build debug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;process&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}/build/debug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;--parallel&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;dependsOn&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake: configure debug&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;isDefault&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;problemMatcher&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;$gcc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここの &lt;code&gt;cmake --build&lt;/code&gt; に注目してください。
CMake の公式なビルドのエントリーポイントは、この形式です：&lt;code&gt;cmake --build &amp;lt;dir&amp;gt;&lt;/code&gt;。これは、Make や Ninja、MSBuild といった背後のネイティブビルドツールを呼び出します。
つまり、VS Code はあなたのプロジェクトが &lt;code&gt;make&lt;/code&gt; を実行すべきなのか &lt;code&gt;ninja&lt;/code&gt; を実行すべきなのかを知る必要がないのです。
そのことは CMake に任せているわけです。&lt;/p&gt;
&lt;h2 id=&#34;f5-の前にまずコンパイルする&#34;&gt;F5 の前に、まずコンパイルする
&lt;/h2&gt;&lt;p&gt;その後、&lt;code&gt;.vscode/launch.json&lt;/code&gt; に戻り、&lt;code&gt;preLaunchTask&lt;/code&gt; を追記してください：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;CMake Debug with GDB&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cppdbg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;program&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}/build/debug/bin/vscode_cpp_debug_demo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;stopAtEntry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;environment&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;externalConsole&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;MIMode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;miDebuggerPath&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;setupCommands&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Enable pretty-printing for gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-enable-pretty-printing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;preLaunchTask&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake: build debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここが重要です：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;preLaunchTask&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cmake: build debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;F5 を押す流れは以下のようになります：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;launch.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; preLaunchTask
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    -&amp;gt; tasks.json: cmake: build debug
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      -&amp;gt; dependsOn: cmake: configure debug
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        -&amp;gt; cmake -S ... -B ...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      -&amp;gt; cmake --build ...
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -&amp;gt; gdb が最新の program を起動する
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Windows + MinGW の場合、&lt;code&gt;program&lt;/code&gt; は &lt;code&gt;.exe&lt;/code&gt; 付きのパスに変更する必要がある可能性が高く、&lt;code&gt;miDebuggerPath&lt;/code&gt; も自身の &lt;code&gt;gdb.exe&lt;/code&gt; を指すようにする必要があります。
Visual Studio Generator のような複数の設定を生成するジェネレータの場合は、ビルド引数に通常 &lt;code&gt;--config Debug&lt;/code&gt; を追加する必要があります。
しかし、基本的な流れは変わりません。
デバッグする前に VS Code に一度ビルドタスクを実行させてください。自分で記憶に頼るのはやめましょう。&lt;/p&gt;
&lt;h2 id=&#34;もう一つの課題点カスタム型の可読性&#34;&gt;もう一つの課題点：カスタム型の可読性
&lt;/h2&gt;&lt;p&gt;コンパイルリンクを繋げるだけでは不十分です。
C++コードで少し業務的な型をラップするだけで、VS Codeの左側の変数ウィンドウがすぐに見づらくなります。
例えば、以下の例を見てください。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;src/main.cpp&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;cstdint&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;string_view&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;market&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Price&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int64_t&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;from_double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int64_t&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;static_cast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;struct&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Instrument&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;char&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;last&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Instrument&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string_view&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;double&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Instrument&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;snprintf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;sizeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;%s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;());&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;last&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// namespace market
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vector&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;market&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Instrument&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;watchlist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;market&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;IF2406&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;3578.6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;market&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;make_instrument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;IH2406&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;2468.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;market&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;limit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;market&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Price&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_double&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;3600.5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// ここでブレークポイントを置き、watchlistとlimitを観察する。
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;watchlist&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;limit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;market::Price&lt;/code&gt; は業務上「価格」です。
しかし、デバッガがデフォルトで見せるのは以下のようになるかもしれません：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;limit = {raw = 36005000}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;その通り、データは正しいです。
しかし、私の頭の中では、この &lt;code&gt;36005000&lt;/code&gt; を手動で &lt;code&gt;3600.5000&lt;/code&gt; に変換しなければなりません。もしプロジェクト内に &lt;code&gt;Price&lt;/code&gt;、&lt;code&gt;Quantity&lt;/code&gt;、&lt;code&gt;OrderId&lt;/code&gt;、&lt;code&gt;Instrument&lt;/code&gt;、&lt;code&gt;AlgoState&lt;/code&gt; などが山ほどある場合、デバッグウィンドウはすぐに構造体の墓場になってしまいます。
このときこそ GDB の pretty-printer が必要になります。
GDB の公式マニュアルには非常に明確に書かれています。それは、Pythonコードを使って値をpretty-printするための仕組みを提供しており、この仕組みはMI（Machine Interface）とコマンドラインの両方に適用できるということです。
VS CodeのC++デバッグがまさに GDB/MI という経路を通っています。&lt;/p&gt;
&lt;h2 id=&#34;ビジネスタイプ用のpython表示層の作成&#34;&gt;ビジネスタイプ用のPython表示層の作成
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;tools/gdb_printers.py&lt;/code&gt; を新規作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;gdb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;gdb.printing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;PricePrinter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.0&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.4f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;InstrumentPrinter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;symbol&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;price_raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;last&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;][&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;price&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;price_raw&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;10000.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; last=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.4f&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;build_pretty_printer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;printer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;gdb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RegexpCollectionPrettyPrinter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;market&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;printer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_printer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Price&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^market::Price$&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PricePrinter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;printer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_printer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Instrument&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;^market::Instrument$&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;InstrumentPrinter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;printer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;gdb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;printing&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;register_pretty_printer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;gdb&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_objfile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;build_pretty_printer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;次に、&lt;code&gt;launch.json&lt;/code&gt; の &lt;code&gt;setupCommands&lt;/code&gt; にこれをソースとして読み込ませます：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;setupCommands&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gdbのプリティプリンティングを有効化&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-enable-pretty-printing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;プロジェクトのプリティプリンターをロード&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-interpreter-exec console \&amp;#34;source ${workspaceFolder}/tools/gdb_printers.py\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;F5 を再実行します。
この後、デバッグウィンドウを見ると、&lt;code&gt;Price&lt;/code&gt; の表示は以下に近くなるはずです：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;limit = 3600.5000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;Instrument&lt;/code&gt; もまた、単なる配列や構造体から、よりビジネスに近いものになります：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;IF2406 last=3578.6000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ここで「近い」と言っているのは意図的です。なぜなら、プリティプリンターはコンパイラ、型名、実際のフィールドレイアウトと一致させる必要があるからです。
もしあなたのビジネスタイプの中に &lt;code&gt;std::vector&lt;/code&gt; や &lt;code&gt;std::array&lt;/code&gt;、スマートポインタなどがネストされている場合、Pythonスクリプトからアクセスするフィールドはさらに深い呼び出しが必要になるかもしれません。一つのスクリプトですべてをカバーできると期待しないでください。
しかし、考え方はしっかりしています。
「デバッグ時に人間が見たい姿」を、独立したPythonの表示ロジックとして記述するのです。&lt;/p&gt;
&lt;h2 id=&#34;launchjson-を全てだと思ってはいけない&#34;&gt;launch.json を全てだと思ってはいけない
&lt;/h2&gt;&lt;p&gt;この設定群を見ると、少なくとも3層あると感じます。
&lt;code&gt;.vscode/launch.json&lt;/code&gt; は「デバッガをどう起動するか」を担当します。
&lt;code&gt;.vscode/tasks.json&lt;/code&gt; は「デバッガを起動する前に、まずプロジェクトをビルドする」を担当します。
&lt;code&gt;tools/gdb_printers.py&lt;/code&gt; は「ブレークポイントで止まった後、変数を人間が理解できる形で表示する」を担当します。
以前は最初の層だけを設定していました。
動くものの、非常に素っ気ないものでした。
本当に快適な C++ デバッグというのは、「まずターミナルでコンパイルしてから、戻ってきて F5 を押して、変数ウィンドウでフィールドの意味を頭の中で計算する」というものであってはいけないはずです。
より快適なフローは、F5 を押すと VS Code が自動的に CMake を実行し、GDB がプロジェクトの Python printer を自動ロードし、ブレークポイントで停止した際に、デバッグウィンドウが直接ビジネス言語で表示してくれることです。
今回 AI にプロジェクトの設定をしてもらったことで、最も価値があったのは、どれだけ C++ コードを生成したかということではありませんでした。
むしろ、これらの古いツール間の「接着剤」の部分を補ってくれた点です。
以前から CMake や GDB が分からないわけではありませんでした。
ただ、その中間にあるいくつかのフック（接続部分）を設定していなかっただけなのです。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://code.visualstudio.com/docs/cpp/config-linux&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VS Code で Linux 上の C++ を使用する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://code.visualstudio.com/docs/debugtest/tasks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VS Code: タスク経由で外部ツールと統合する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://cmake.org/cmake/help/latest/manual/cmake.1.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CMake cmake(1) マニュアル&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://sourceware.org/gdb/current/onlinedocs/gdb.html/Pretty-Printing.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GDB マニュアル: プリティプリンティング&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://sourceware.org/gdb/current/onlinedocs/gdb.html/Writing-a-Pretty_002dPrinter.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GDB マニュアル: プリティプリンタの記述&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：$blog-writer vscode で C++ を開発する際、以前見たチュートリアルは、&lt;code&gt;launch.json&lt;/code&gt; 内の gdb デバッグ情報の設定のみで、&lt;code&gt;preLaunchTask&lt;/code&gt; の設定に触れていませんでした。CMake のコンパイルを自動的にトリガーできる機能があれば、これは AI が新しいプロジェクトを設定する上で非常に役立つものです。もしコードにカスタムデータ型が多く含まれていて、VS Code のデバッグウィンドウで直接表示できない場合でも、Python スクリプトを導入して前処理を行うことで、それらも表示できるようになります。上記の内容について、すべて実際のコード例を提供してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングの骨子まとめ&#34;&gt;ライティングの骨子まとめ
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;メインテーマを「これまで &lt;code&gt;launch.json&lt;/code&gt; の設定だけだったが、実際にはデバッグ前のビルドとデバッグ時の表示という2層の接着剤（仕組み）が欠けていた」ことに置く。&lt;/li&gt;
&lt;li&gt;ユーザーから提供されたトリガーポイントは維持する：AI が新しいプロジェクトを設定する際に、&lt;code&gt;preLaunchTask&lt;/code&gt; で CMake のコンパイルが自動的にトリガーされることを発見した点。&lt;/li&gt;
&lt;li&gt;コード例は最小限の CMake プロジェクトで構成し、&lt;code&gt;CMakeLists.txt&lt;/code&gt;、&lt;code&gt;tasks.json&lt;/code&gt;、&lt;code&gt;launch.json&lt;/code&gt;、C++ のカスタム型、および GDB Python pretty-printer を含める。&lt;/li&gt;
&lt;li&gt;事実確認は VS Code、CMake、GDB の公式ドキュメントを最優先とし、本文ではドキュメント全体を翻訳せず、このデバッグフローに関連する事実のみを残す。&lt;/li&gt;
&lt;li&gt;pretty-printer に関しては、型名、標準ライブラリの実装、フィールドレイアウトなどが Python スクリプトに影響を与える点について注意喚起を行う。プロジェクト内では自身の型に合わせて修正が必要である旨を明記する。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>フォルダの階層構造に名前空間を重ねる、これは一体何と呼ばれますか？</title>
        <link>https://ttf248.life/ja/p/cpp-folder-namespace-what-is-it-called/</link>
        <pubDate>Thu, 09 Apr 2026 02:31:07 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/cpp-folder-namespace-what-is-it-called/</guid>
        <description>&lt;p&gt;最近アルゴリズムサービスを書いていて、&lt;code&gt;twap&lt;/code&gt; や &lt;code&gt;vwap&lt;/code&gt; のようなモジュールをいくつか展開したところ、またこの古い問題に直面しました。&lt;/p&gt;
&lt;p&gt;C++ でクラス名に頼ってセマンティクスを無理やり押し付けると、名前はすぐに制御不能になります。&lt;code&gt;TwapOrderManager&lt;/code&gt;、&lt;code&gt;VwapOrderManager&lt;/code&gt;、&lt;code&gt;AlgoOrderManager&lt;/code&gt; のようなものは、書き進めているうちに「自分の構造が手に負えないことはわかっているけど、とりあえずプレフィックスを付け足しておこう」という感じになってしまいます。端的に言えば、フォルダで階層分けをして、さらに &lt;code&gt;namespace&lt;/code&gt; を一つ追加するのは、コードの潔癖症なのではなく、C++ に Java のようなネイティブな &lt;code&gt;package&lt;/code&gt; システムがないことによる空隙を埋めているのです。&lt;/p&gt;
&lt;h2 id=&#34;結論から言うと&#34;&gt;結論から言うと
&lt;/h2&gt;&lt;p&gt;もし最も近いソフトウェア工学の用語を探さなければならないとしたら、私は以下の2つの言葉が最も適切だと思います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モジュール化&lt;/strong&gt;（modularization）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;名前空間管理&lt;/strong&gt;（namespace management）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;もう少し具体的に言うと、このようなディレクトリ構成は、しばしば以下のようなことを行っています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;機能ごとのパッケージング / ドメインごとのパッケージング&lt;/strong&gt;、つまり一般にいう &lt;code&gt;package by feature&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ビジネス境界が非常に明確な場合は、&lt;strong&gt;バウンデッドコンテキスト&lt;/strong&gt;の要素も含まれます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、これは単一の標準的な訳語を持つ小さな概念というよりも、いくつかの設計原則が積み重なったもののようなものです。&lt;/p&gt;
&lt;h2 id=&#34;これは事前に解決しているというよりは見栄えの問題ではない&#34;&gt;これは事前に解決している、というよりは「見栄え」の問題ではない
&lt;/h2&gt;&lt;p&gt;多くの人は &lt;code&gt;namespace&lt;/code&gt; を見ると、まず名前の衝突を避けることを思い浮かべます。これはもちろん正しいです。C++ の標準ライブラリにおける &lt;code&gt;namespace&lt;/code&gt; は、本来大規模なプロジェクトでの名前の衝突を防ぐために存在します &lt;a class=&#34;link&#34; href=&#34;https://en.cppreference.com/w/cpp/language/namespace&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cppreference&lt;/a&gt;。しかし、実際のビジネスコードにおいては、その価値はそれだけにとどまりません。&lt;/p&gt;
&lt;p&gt;ディレクトリ構造と &lt;code&gt;namespace&lt;/code&gt; が整列されることで、クラス名が上位のセマンティクス（意味）を繰り返す必要がなくなります。&lt;/p&gt;
&lt;p&gt;例えば、以前は以下のように書くことが多かったかもしれません：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;TwapOrderManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;TwapScheduleEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VwapOrderManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;VwapScheduleEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ディレクトリと名前空間を使うように変更すると、より自然な書き方は通常以下のようになります：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;algo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;twap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;OrderManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ScheduleEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;algo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vwap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;OrderManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;ScheduleEngine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これにより、冗長な接頭辞がなくなり、かえってセマンティクスが明確になります。「それがどのコンテキストに属するか」という情報がクラス名の中に詰め込まれるのではなく、ディレクトリ構造と &lt;code&gt;namespace&lt;/code&gt; に委ねられるようになるからです。&lt;/p&gt;
&lt;p&gt;したがって、このアプローチの本質は、**「名前からコンテキスト情報を抽出し、構造（ディレクトリや名前空間）に担わせる」**ことなのです。&lt;/p&gt;
&lt;h2 id=&#34;これはむしろ機能特性ごとにパッケージ化するに近い&#34;&gt;これはむしろ「機能（特性）ごとにパッケージ化する」に近い
&lt;/h2&gt;&lt;p&gt;もしあなたのディレクトリが以下のように長い場合：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;strategy/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  twap/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    order_manager.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    schedule_engine.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    slicer.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  vwap/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    order_manager.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    schedule_engine.h
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    slicer.h
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;あなたはもはや従来の「技術層ごとにパッケージ化する」ことをしているわけではありません。&lt;/p&gt;
&lt;p&gt;伝統的な分け方は、むしろ以下のようになります：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;models/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;services/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;utils/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;controllers/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この分け方は初期段階では整然として見えますが、ビジネスロジックが増えてくると、&lt;code&gt;service&lt;/code&gt; ディレクトリはゴミ集積所のようになってしまいます。ある機能に関連するクラスが異なるディレクトリに散らばり、コードを読むたびに頭の中が飛び回ります。&lt;/p&gt;
&lt;p&gt;一方、&lt;code&gt;twap&lt;/code&gt; や &lt;code&gt;vwap&lt;/code&gt; のような分け方は、「&lt;strong&gt;機能（フィーチャー）ごとにパッケージ化する (package by feature)&lt;/strong&gt;」という考え方に近いです。つまり、あるディレクトリはまず「このビジネス領域は何をするのか？」に答え、その中にそのビジネスに必要なオブジェクトやフローを配置していくイメージです。Javaの世界ではこの言い方がより一般的ですが、C++においても同様に成立します。ただし、それを支えているのはネイティブな &lt;code&gt;package&lt;/code&gt; ではなく、「&lt;strong&gt;ディレクトリ + 名前空間 (namespace) + ヘッダーファイルの境界&lt;/strong&gt;」になります。&lt;/p&gt;
&lt;p&gt;端的に言えば、あなたはコードを「&lt;strong&gt;見た目（構造）で組織するのではなく、変更の理由（振る舞い）によってコードを組織している&lt;/strong&gt;」のです。&lt;/p&gt;
&lt;h2 id=&#34;一歩遡るとそれは高凝集低結合ということになる&#34;&gt;一歩遡ると、それは高凝集・低結合ということになる
&lt;/h2&gt;&lt;p&gt;ソフトウェア工学でよく耳にする「高凝集、低結合」という言葉は、まさにこのような場所に当てはまります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;twap&lt;/code&gt; の下のオブジェクト同士が頻繁に協調して動作する場合、それらは物理的にも近く配置し、名前空間も近接させるべきです。&lt;code&gt;vwap&lt;/code&gt; もこれと似ていますが、全く同じわけではないので、独立した境界を持たせるべきです。このようにすることで、いくつかの直接的な利点があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同じモジュール内のクラス名を短くできる&lt;/li&gt;
&lt;li&gt;モジュール間の依存関係が視覚的に把握しやすくなる&lt;/li&gt;
&lt;li&gt;リファクタリングの際、変更が他の場所に波及するかどうかを判断しやすくなる&lt;/li&gt;
&lt;li&gt;将来的に特定の機能を独立したライブラリとして切り出す際のコストも低くなる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが、多くの成熟したプロジェクトが最終的に「ディレクトリ境界 + 名前空間境界 + コンパイル境界」が可能な限り一致する形になる理由です。QuickFIX のようなプロジェクトを見ても、同様の考え方が見られます。型や拡張ポイントは、長いクラスプレフィックスに頼って強制的に区別するのではなく、できるだけ明確な名前空間の下に配置されています &lt;a class=&#34;link&#34; href=&#34;https://quickfixengine.org/c/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QuickFIX&lt;/a&gt; &lt;a class=&#34;link&#34; href=&#34;https://github.com/quickfix/quickfix&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;いつまた足りなくなるのか&#34;&gt;いつまた足りなくなるのか
&lt;/h2&gt;&lt;p&gt;しかし、この件を神格化する必要はありません。&lt;/p&gt;
&lt;p&gt;フォルダの階層化にさらに&lt;code&gt;namespace&lt;/code&gt;を適用したとしても、それはあなたがモジュール化の方向に進んでいることを示すだけであり、アーキテクチャが自動的に良くなるわけではありません。よくある落とし穴も明白です：&lt;/p&gt;
&lt;h3 id=&#34;ディレクトリと名前空間が一致していない&#34;&gt;ディレクトリと名前空間が一致していない
&lt;/h3&gt;&lt;p&gt;ディレクトリは &lt;code&gt;twap/&lt;/code&gt; なのに、コードの中にはバラバラに配置されたグローバルクラスや、&lt;code&gt;namespace common&lt;/code&gt; があちこちに散らばっていて、これは基本的に無駄です。&lt;/p&gt;
&lt;h3 id=&#34;モジュール境界は偽の境界である&#34;&gt;モジュール境界は偽の境界である
&lt;/h3&gt;&lt;p&gt;表面上には &lt;code&gt;twap&lt;/code&gt; や &lt;code&gt;vwap&lt;/code&gt; があるが、実際にはお互いに &lt;code&gt;#include&lt;/code&gt; しており、共通ロジックは自由に透過し、結局ただファイルを移動させただけで、結合度は全く下がっていない。&lt;/p&gt;
&lt;h3 id=&#34;common-ディレクトリが肥大化する&#34;&gt;&lt;code&gt;common&lt;/code&gt; ディレクトリが肥大化する
&lt;/h3&gt;&lt;p&gt;これが最もよくあるケースです。多くのプロジェクトは最初はきれいに分割されているのに、後になると面倒になり始め、「&lt;code&gt;common&lt;/code&gt;」「&lt;code&gt;base&lt;/code&gt;」「&lt;code&gt;util&lt;/code&gt;」などに物を放り込みがちになります。その結果、最終的には真に安定した抽象概念が蓄積されるどころか、誰でも触れてしまい、誰もが依存してしまう巨大な穴（負債）ができてしまいます。&lt;/p&gt;
&lt;h3 id=&#34;構造はレイヤーごとに分けビジネスロジックごとには分けない&#34;&gt;構造はレイヤーごとに分け、ビジネスロジックごとには分けない
&lt;/h3&gt;&lt;p&gt;もしあなたのディレクトリが常に &lt;code&gt;api&lt;/code&gt;、&lt;code&gt;service&lt;/code&gt;、&lt;code&gt;dao&lt;/code&gt;、&lt;code&gt;model&lt;/code&gt; のようになっている場合、多くのビジネス概念に適切な「家」が存在しません。クラス名は必然的にどんどん長くなり、本来構造で表現すべきものをすべて名前に詰め込むことになります。&lt;/p&gt;
&lt;h2 id=&#34;それって結局何と呼ぶべきか&#34;&gt;それって結局何と呼ぶべきか
&lt;/h2&gt;&lt;p&gt;チーム内でコミュニケーションする場合、私は3つのレベルに分けて話せると思います：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;人間言葉で伝えたいだけなら：&lt;strong&gt;ディレクトリと名前空間に基づいてモジュール化する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;よりエンジニアリングっぽく言いたいなら：&lt;strong&gt;機能（フィーチャー）ごとにパッケージを分ける方法で、階層的な名前空間を組み合わせる&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;もしこの境界がすでにビジネスのセマンティクスに強く結びついている場合：&lt;strong&gt;バウンデッドコンテキスト（Bounded Context）の匂いがするモジュール分割&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私自身は2番目に傾いています。なぜなら、それがあなたが説明しているシナリオに最も近いからです。&lt;/p&gt;
&lt;p&gt;あなたが言っているのはC++の文法的なテクニックでも、単なる命名規則でもなく、もっと本質的なことをやろうとしているのです：&lt;strong&gt;構造を使ってセマンティクスを担わせ、名前を本来の意味に戻すこと&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;クラス名が短くなり、ファイル名も短くなることで、コードを読む際に最初に目に入るのは、ディレクトリの責務、命名の責務、実装の責務をすべてごちゃ混ぜにした&lt;code&gt;TwapOrderManagerImpl&lt;/code&gt;のようなものではなく、コンテキストが明確な&lt;code&gt;twap::OrderManager&lt;/code&gt;のようなオブジェクトになります。&lt;/p&gt;
&lt;p&gt;そうなることで、ようやくJavaでパッケージ構造が成熟した後のような感覚になるのです。&lt;/p&gt;
&lt;h2 id=&#34;最後のまとめ&#34;&gt;最後のまとめ
&lt;/h2&gt;&lt;p&gt;したがって、ソフトウェア工学には当然対応する概念はありますが、唯一の正解というわけではありません。&lt;/p&gt;
&lt;p&gt;より大きな視点で見れば、「モジュール化」と呼ばれます。コードの構成という観点からは「機能ごとのパッケージング」、さらにネームスペース管理が加わります。ドメイン境界という観点から見ると、それはある種のバウンデッドコンテキストの意味合いも持ちます。&lt;/p&gt;
&lt;p&gt;どう言えばいいでしょうか、このようなプラクティスの最も価値のある点は、「名前がきれいに整った」ことではなく、ついに超長いプレフィックスに頼って構造的な欠如を補わなくてよくなった、という点なのです。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://en.cppreference.com/w/cpp/language/namespace&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cppreference: Namespaces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://quickfixengine.org/c/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QuickFIX/C++ 公式サイト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/quickfix/quickfix&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QuickFIX GitHub リポジトリ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.javapractices.com/home/HomeAction.do&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Java Practices: Package by feature, not layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://martinfowler.com/bliki/BoundedContext.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Martin Fowler: Bounded Context&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：コーディング開発において、C++の良いプラクティスの一つは、フォルダで階層化し、各クラスに名前空間（namespace）を適用することです。これはJavaのパッケージのようなもので、ファイル名やクラス名に含まれる冗長な内容を効果的に減らすことができます。quickfixという古典的なプロジェクトがありますが、最近開発したアルゴリズムサービスでも同様のデザインを使用しました。TWAPやVWAPなど、多くの機能モジュールが似ています。ソフトウェア工学において、これに特化した概念はありますか？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングの思考プロセス要約&#34;&gt;ライティングの思考プロセス要約
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;アルゴリズムサービスにおける &lt;code&gt;twap&lt;/code&gt; や &lt;code&gt;vwap&lt;/code&gt; の実際のモジュールトリガーポイントから切り込み、まず判断を明確にする。&lt;/li&gt;
&lt;li&gt;問題を単一の名詞として無理に説明するのではなく、モジュール化、名前空間管理、特性ごとのパッケージ分けといった、より正確な階層に分解した。&lt;/li&gt;
&lt;li&gt;QuickFIX と Java パッケージの対応関係を残し、C++ がディレクトリと名前空間に頼って構造的な意味（セマンティクス）を補うことが多いことを説明するために用いた。&lt;/li&gt;
&lt;li&gt;「重複名の回避」といった表層的な説明に留まるのではなく、「構造を用いて意味を担わせる」点に重点を置いた。&lt;/li&gt;
&lt;li&gt;後続の展開が容易になるよう、&lt;code&gt;namespace&lt;/code&gt;、&lt;code&gt;package by feature&lt;/code&gt;、&lt;code&gt;bounded context&lt;/code&gt; に関する参考リンクを追加した。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>Googleが今回Gemma 4を公開した（3）</title>
        <link>https://ttf248.life/ja/p/gemma-4-series-vram-cliff-and-mac-unified-memory/</link>
        <pubDate>Wed, 08 Apr 2026 23:56:20 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/gemma-4-series-vram-cliff-and-mac-unified-memory/</guid>
        <description>&lt;p&gt;今回フォーラムを巡回していて、一番印象に残ったのは、「またランキングを出した」というところではなく、「VRAMが足りないから、パラメータがどれだけ大きくても無駄だ」という、かなり生易しい（陳腐な）一言でした。&lt;/p&gt;
&lt;p&gt;以前は「モデルが遅い」ことを計算能力の問題だと捉えがちでした。しかし、後になってよく気づいたのは、多くのケースでGPUの計算能力が足りないのではなく、データが適切な場所に留まらないことが原因だということです。メモリのパスが少し変わるだけで、トークン速度は少し落ちるというレベルではなく、直接落ちてしまいます。&lt;/p&gt;
&lt;p&gt;前2の記事で、前提となる問題は全て網羅しました。&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-models-and-license/&#34; &gt;第1回&lt;/a&gt; ではリリースとライセンスについて、&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-local-test-on-rtx-3060/&#34; &gt;第2回&lt;/a&gt; では3060 12GBでなぜまず&lt;code&gt;26B A4B&lt;/code&gt;を見るのかについて解説しました。そして、今回の記事では、速度が具体的にどのように落ちていくのかだけを扱います。&lt;/p&gt;
&lt;h2 id=&#34;vram不足慢のはちょっとの問題ではない&#34;&gt;VRAM不足、慢のはちょっとの問題ではない
&lt;/h2&gt;&lt;p&gt;推論というプロセスを分解して見ると、特に重要なのが以下の2点です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;モデルの重み（モデルウェイト）&lt;/li&gt;
&lt;li&gt;KVキャッシュ
重みはモデルそのものを決定し、KVキャッシュはこれまでの文脈の状態を記録します。コンテキストが長くなるほど、KVキャッシュは大きくなります。この2つが安定してGPUのVRAM内に収まっていれば、トークンを生成する際も基本的に高帯域幅なVRAM内でのデータ読み出し、計算、結果書き戻しが行われるため、速度は通常期待できます。
本当に厄介なのは、VRAMに乗り切らない場合です。
一度容量オーバーになると、推論フレームワークは譲歩せざるを得ません：&lt;/li&gt;
&lt;li&gt;一部の重みをシステムメモリに配置する&lt;/li&gt;
&lt;li&gt;あるいは一部のKVキャッシュをシステムメモリに配置する&lt;/li&gt;
&lt;li&gt;あるいはCPUとGPU間でデータを頻繁に行き来させる
この状況では問題は「少し計算量が増えた」というレベルではなく、「トークンを一つ出すたびにデータ待ちが発生する」というレベルになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;なぜ急落断崖が発生するのか線形に遅くなるわけではない&#34;&gt;なぜ急落（断崖）が発生するのか、線形に遅くなるわけではない
&lt;/h2&gt;&lt;p&gt;この罠に初めて遭遇した多くの人は、「モデルが $14\text{B}$ から $31\text{B}$ になったら、2倍以上遅くなるから、我慢できる範囲だ」と直感的に考えます。&lt;/p&gt;
&lt;p&gt;しかし、現実はそうではありません。&lt;/p&gt;
&lt;p&gt;真の境界線はパラメータが2倍になることではなく、ワークセットがVRAM（ビデオメモリ）の境界を越えたかどうかです。&lt;/p&gt;
&lt;p&gt;まだ越えていない場合、モデルが大きくなることで遅くなるのは、通常予測可能な範囲内です。&lt;/p&gt;
&lt;p&gt;一度それを超えると、システムの状態が根本的に変わります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;それまでは「VRAM内でのクローズドループ」だった&lt;/li&gt;
&lt;li&gt;今や「VRAM + メインメモリ + バスによるデータ転送」になる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;経路が変わるだけで、コストは全く異なります。特にデコード（生成）の段階では、元々トークンを一つずつ順に進んでいき、バッチサイズもそれほど大きくないため、この時最も怖いのは、すべてのトークンに対してデバイスをまたいでデータを待つ必要があることです。&lt;/p&gt;
&lt;p&gt;そのため、非常に典型的な現象を目にすることがあります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;モデルが動かないわけではない&lt;/li&gt;
&lt;li&gt;GPUも完全に遊んでいるわけではない&lt;/li&gt;
&lt;li&gt;しかし、トークン/秒（token/s）の数値が非常に悪い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが皆が言う「断崖」です。モデルが突然賢さを失ったのではなく、メモリのデータ経路が突然非効率的になったのです。&lt;/p&gt;
&lt;h2 id=&#34;26b-a4bがローカルプレイヤーにとってより親切な理由&#34;&gt;「26B A4B」がローカルプレイヤーにとってより親切な理由
&lt;/h2&gt;&lt;p&gt;この点も、なぜ私が前回の記事で一貫して「26B A4B」を重視してきたのかを説明しています。
当然ながら総パラメータ数は小さいわけではありませんが、実際にトークンごとにアクティブになるのは約「3.8B」程度です。これは、類似のデプロイメント条件下において、計算リソースやVRAMへの負荷が、密な（dense）大規模モデルよりも管理しやすい場合が多いことを意味します。
これも魔法ではありません。
もしコンテキストを長くしすぎたり、量子化やフレームワークのサポートが不十分だと、これでも苦労します。ただ、最初からVRAMを使い切ってしまうような密なモデルと比較すると、「26B A4B」は、一般消費者向けのグラフィックカードにとってより現実的な選択肢という側面があります。
ですから、多くのケースで「31B」が弱いのではなく、ローカルマシンが誰と長期的に付き合うのに適しているか、という問題なのです。&lt;/p&gt;
&lt;h2 id=&#34;mac-が爆発しにくい理由&#34;&gt;Mac が「爆発しにくい」理由
&lt;/h2&gt;&lt;p&gt;Mac の最も異なる点は、モデルではなくメモリ構造にあります。
&lt;code&gt;Apple silicon&lt;/code&gt; はユニファイドメモリを採用しています。CPU と GPU が同じメモリプールを共有するため、専用GPU搭載機のように、片方がVRAM、もう片方がメインメモリで、間にバスを介してデータを移動させるという構造ではありません。
この構造の最大の利点は、専用GPU搭載機では「VRAMにそもそも収まらない」モデルでも、Mac 上では別の状態になることです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;必ずしも速くはないが&lt;/li&gt;
&lt;li&gt;まずは格納できる可能性が高いということです。
つまり、Mac は最初から非常に硬い「VRAMの壁」にぶつかりにくいのです。
これが、多くの人が Mac がローカルでの大規模言語モデル（LLM）において特に適していると感じる理由です。それは、「まずワークセット全体を同じメモリプールに詰め込めるか否か」という問題を解決してくれるからです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;しかしユニファイドメモリが高速を保証するわけではない&#34;&gt;しかし、ユニファイドメモリが高速を保証するわけではない
&lt;/h2&gt;&lt;p&gt;この部分は分けて考える必要があります。
ユニファイドメモリは何を解決したのか？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;専用GPUメモリとメインメモリの物理的な分離の問題を解決した&lt;/li&gt;
&lt;li&gt;小容量のVRAMでは直接搭載できなかった多くのモデルに対応できるようになった&lt;/li&gt;
&lt;li&gt;非常に煩雑な、デバイス間でのデータの往復移動の問題を解決した
しかし、何が解決されていないのか？&lt;/li&gt;
&lt;li&gt;大規模モデルの推論を「大量のメモリ読み出し」から別のものに変えていない&lt;/li&gt;
&lt;li&gt;大規模モデルが突然帯域幅を消費しなくなるわけではない&lt;/li&gt;
&lt;li&gt;すべての推論フレームワークが自動的にCUDAのような成熟したエコシステムを持つわけではない
したがって、Macの快適さとNVIDIAの大容量VRAMカードの速さは、同じものではありません。
Macはむしろ以下のようなものです：&lt;/li&gt;
&lt;li&gt;機械が静かであること&lt;/li&gt;
&lt;li&gt;総メモリが大きいこと&lt;/li&gt;
&lt;li&gt;統一されていること&lt;/li&gt;
&lt;li&gt;これまで搭載できなかった多くのモデルを、とりあえず動かすことができるようになったこと
NVIDIAの大容量VRAMカードはむしろ以下のようなものです：&lt;/li&gt;
&lt;li&gt;エコシステムが成熟していること&lt;/li&gt;
&lt;li&gt;CUDAツールチェーンが完全であること&lt;/li&gt;
&lt;li&gt;モデルとキャッシュをGPU内に留め込むことができれば、速度を上げやすいこと&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;なぜスピードを求めるのか結局はnvidiaのvram容量が重要になる&#34;&gt;なぜスピードを求めるのか、結局はNVIDIAのVRAM容量が重要になる
&lt;/h2&gt;&lt;p&gt;これは感情的な判断ではなく、ローカルにデプロイする過程で容易にたどり着く現実的な結論です。
もしあなたが以下のようなものを追求しているなら：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ローカルアシスタントの常駐化&lt;/li&gt;
&lt;li&gt;多回の長文対話&lt;/li&gt;
&lt;li&gt;長いコンテキストウィンドウ&lt;/li&gt;
&lt;li&gt;より高いトークン/秒 (token/s)&lt;/li&gt;
&lt;li&gt;待ち時間を極力減らすこと
それらの場合、結局はVRAM容量の大きなNVIDIA製GPUが重要になります。なぜなら、あなたが真に購入しているのは、モデルとキャッシュをできるだけ安定してGPU上に保持する能力だからです。
Macももちろん当てはまりますが、こちらは別の種類の要求に適しています：&lt;/li&gt;
&lt;li&gt;大きなモデルを一度に搭載したい&lt;/li&gt;
&lt;li&gt;速度は平均的でも良いが、ドライバや周辺機器の設定で手間をかけたくない&lt;/li&gt;
&lt;li&gt;全体的な体験、消費電力、騒音を重視する
これら二つのアプローチはいずれも合理的ですが、解決しようとしている問題点が異なります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;gemma-4-に戻る私の最終判断&#34;&gt;Gemma 4 に戻る、私の最終判断
&lt;/h2&gt;&lt;p&gt;今回、&lt;code&gt;Gemma 4&lt;/code&gt; は、ローカルでオープンソースのモデルが、より真剣にハードウェアについて議論すべき段階に入ったと感じさせられました。
しかし、モデルが強くなっても、物理法則まで緩むわけではありません。
どれだけ強力な &lt;code&gt;31B&lt;/code&gt; でも、VRAM が不足すれば速度は落ちます。
どんなに現実的な &lt;code&gt;26B A4B&lt;/code&gt; でも、コンテキストが長すぎれば負荷がかかります。
Mac のユニファイドメモリは快適ですが、それは単に「とりあえず動かす」のが容易になるだけであり、大容量の VRAM を持つ CUDA カードの速度を無償で提供してくれるわけではありません。
そのため、結局やはりこの地味な結論になります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;速度を求めるなら、最優先は NVIDIA の大容量 VRAM です。&lt;/li&gt;
&lt;li&gt;万全を期すなら、Mac のユニファイドメモリは確かに快適です。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;3060 12GB&lt;/code&gt; のようなマシンで長期的に遊ぶのであれば、常に巨大なモデル（dense model）ばかりを気にするのではなく、&lt;code&gt;26B A4B&lt;/code&gt; のようなアプローチの方が現実的です。
この一連の記事は、ここまでで締めくくりとします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4: Byte for byte, the most capable open models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/docs/core/model_card_4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4 model card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.apple.com/newsroom/2023/10/apple-unveils-m3-m3-pro-and-m3-max-the-most-advanced-chips-for-a-personal-computer/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apple unveils M3, M3 Pro, and M3 Max&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.apple.com/newsroom/2023/01/apple-unveils-m2-pro-and-m2-max-next-generation-chips-for-next-level-workflows/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apple unveils M2 Pro and M2 Max&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.apple.com/macbook-pro/specs/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MacBook Pro Tech Specs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer Googleが1年ぶりにGemma4モデルをリリースしました。いつものように、ローカルデプロイメントを試します。使用するのはアップグレードされていないデスクトップPCに搭載されている3060 12GB NVIDIAグラフィックボードです。今回は初出陣でしたが、以前よく使っていたGemma3のアップグレード版が見つかりませんでした。しかし、類似のバージョンであるGemmaE4bというものがあるので、まずこれを検索して紹介してください。今回リリースされた全モデルについて、含まれる略語アルファベットがそれぞれ何を意味するのかを説明し、さらにオンライン上のGemma4に関する評価を検索してください。重要な点として、今回のGoogleによる更新でモデルのプロトコルが変更され、利用時の制限が緩和されました。最大の驚きは、私がよく使うテスト問題です。「C++コードを書いて、コンソールに五芒星を出力しなさい」というものでした。昨年の小規模パラメータのオープンソースモデルではこの問題をクリアできませんでしたが、Googleはこの回で成功させました。最初の回答は私の予想を完全に超えており、私の意図（トラップ）を理解していました。コンソールへの五芒星の出力は非常に厄介なため、直接アスキーアートとして文字列をハードコーディングし、コンソールに出力しました。これが原文です：「純粋なテキストのコンソール（Console）で数学的なロジックだけで正確な幾何学的構造を持つ五芒星を描画するのは非常に複雑である（座標変換やピクセル充填が関わるため）。最も古典的で視覚効果が高い方法は、アスキーアート（文字芸術）を使用することである。私が計算を強制的に要求した後も、それは成功しました。数学的な計算を通じて、五芒星を描画したのです。」以前はローカルでの翻訳タスクにGemma4をよく使用していました。現在のブログの多くの過去の記事の多言語版がこのようにして作られています。ローカルテストに使用したのは：gemma-4-26b-a4bモデルで、31bバージョンは本当に遅すぎます。しかし、レビューを見ると31bの効果は非常に良く、ランキングの成績も優れています。同時にフォーラムを閲覧し、私は「VRAMが不足している場合、モデルパラメータを上げると、生成トークンの速度が急激に低下する」ということに気づきました。なぜそうなるのか説明してください。Macではこの問題は発生しません。ユニファイドメモリを使用しているため、技術的な理由を説明してください。また、速度が必要な場合は、やはりNVIDIAのVRAM大容量グラフィックボードが必要です。Macのソリューションはバックアップにはなりますが、速度が出ません。今回の内容は多岐にわたるので、シリーズ記事に分割すべきか評価してください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングの骨子まとめ&#34;&gt;ライティングの骨子まとめ
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;第3編では、「なぜスピードが落ちるのか」と「Macが速さ＝ではない理由」の2つの論点のみを残し、前2編の内容への回帰的な説明は行わない。&lt;/li&gt;
&lt;li&gt;まずVRAM（ビデオメモリ）の限界について述べ、次に非線形な速度低下について述べることで、前回版よりも論理の流れがスムーズになる。&lt;/li&gt;
&lt;li&gt;MacとNVIDIAをそれぞれ異なる側面から語り分け、一方は「安定性重視」、もう一方は「速度重視」という形で対比させる。&lt;/li&gt;
&lt;li&gt;結論ではハードウェアの判断のみに留め、シリーズ分割の理由付けは繰り返さない。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>Googleが今回Gemma 4を公開した（2）</title>
        <link>https://ttf248.life/ja/p/gemma-4-series-local-test-on-rtx-3060/</link>
        <pubDate>Wed, 08 Apr 2026 23:52:20 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/gemma-4-series-local-test-on-rtx-3060/</guid>
        <description>&lt;p&gt;ランキングだけを見ると、一番心が動くのは間違いなく &lt;code&gt;31B&lt;/code&gt; です。
しかし、実際にマシンを前にすると、やはりアップグレードされていない &lt;code&gt;RTX 3060 12GB&lt;/code&gt; の方が、判断はすぐに変わります。どう言えばいいか、ローカルにデプロイするということは、最後に一番派手なものが勝つのではなく、長く一緒にいられそうなものを選ぶことなんです。私にとっては、今回まず試す価値があるのは &lt;code&gt;31B&lt;/code&gt; ではなく、&lt;code&gt;26B A4B&lt;/code&gt; です。&lt;/p&gt;
&lt;p&gt;前回の記事 &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-models-and-license/&#34; &gt;GoogleがGemma 4を公開した件（一）：急いでローカルに動かす前に、モデル名とプロトコルを理解すべき&lt;/a&gt; では、リリースとプロトコルについて説明しました。今回の記事ではローカルでの体験そのものに焦点を当てています。最後の記事では &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-vram-cliff-and-mac-unified-memory/&#34; &gt;GoogleがGemma 4を公開した件（三）：VRAM不足でなぜ急落するのか、Macはなぜバックアップになり得るのに速くないのか&lt;/a&gt; を続けます。&lt;/p&gt;
&lt;h2 id=&#34;なぜ先に26b-a4bを試すのか&#34;&gt;なぜ先に「26B A4B」を試すのか
&lt;/h2&gt;&lt;p&gt;理由は実はかなり現実的、つまりハードウェアの制約によるものです。
「31B」はもちろん強力で、公式ランキングやコミュニティからの初期フィードバックも非常に高いです。しかし、それを「RTX 3060 12GB」のようなマシンに載せると、問題はすぐに「どれだけ強いか」から「待つ価値があるか」へと変わってきます。モデルやキャッシュがシステムメモリに退避してしまうと、速度が急激に落ちてしまうことがあり、この件については第3弾で詳しく解説します。
「26B A4B」は違います。
総パラメータ数は「25.2B」ですが、実際にトークンごとにアクティブになるのは約「3.8B」程度です。平たく言えば、これは今回のGemma 4の中で、「ローカルユーザー向けに特別に用意された」モデルと言えます。
ですから、もしあなたのマシンが私と同じような、コンシューマーグレードの古いグラボであるなら、判断はシンプルになります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ランキングを見たいだけなら、「31B」を試す&lt;/li&gt;
&lt;li&gt;本格的に長期でローカルに使いたいなら、まず「26B A4B」から始める&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;五芒星の問題今回はついに誰かが私が罠を仕掛けていることに気づいた&#34;&gt;五芒星の問題、今回はついに誰かが私が罠を仕掛けていることに気づいた
&lt;/h2&gt;&lt;p&gt;私自身がずっと持っている、かなり原始的なテスト問題があります。モデルに &lt;code&gt;C++&lt;/code&gt; コードを書いて、コンソールに五芒星を出力させるというものです。&lt;/p&gt;
&lt;p&gt;この問題は冗談のように見えますが、実際には結構厄介です。なぜなら、多くのモデルはこれを純粋な数学的な描画問題だと誤解し、座標系や三角関数、ループ処理などを持ち出してきてしまい、最終的にテキストコンソール上に、全く見づらい文字の塊を出力してしまうからです。&lt;/p&gt;
&lt;p&gt;去年の小規模パラメータのオープンソースモデルの多くが、この点でつまずきました。&lt;/p&gt;
&lt;p&gt;しかし、今回 &lt;code&gt;Gemma 4&lt;/code&gt; の最初の反応は、逆に私を驚かせました。すぐに理解したふりをするのではなく、制約条件を先に認識し、以下の判断を出してくれたのです：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;純粋なテキストコンソール（Console）上で、正確な幾何学的構造を持つ五芒星を数学的なロジックだけで描画するのは非常に複雑です（座標変換やピクセル充填が関わってきます）。最も古典的で視覚的に効果的な方法は、ASCII Art（文字アート）を使用することです。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;五芒星の問題今回はついに誰かが私が仕掛けた罠を理解してくれた&#34;&gt;五芒星の問題、今回はついに誰かが私が仕掛けた罠を理解してくれた
&lt;/h2&gt;&lt;p&gt;端的に言うと、まず問題の背後にある環境的な制約を理解した点だ。コンソールはキャンバスではなく、文字グリッドもピクセルグリッドではない。先に「どうすれば安定して五芒星を出力できるか」を考え抜いてから、数学的な描画について語るべきだった。&lt;/p&gt;
&lt;p&gt;そして、最初のバージョンではいきなりハードコーディングされた五芒星の文字列を提示した。
この行動は非常に的確だ。推論を見せるためではなく、まず問題を正しく解くことを優先した。&lt;/p&gt;
&lt;h2 id=&#34;さらに驚いたのはそれがさらに進んでいくことだった&#34;&gt;さらに驚いたのは、それがさらに進んでいくことだった
&lt;/h2&gt;&lt;p&gt;単にASCIIアートで止まっていただけなら、この問題はトラップを認識したとしか言えない。
私が高く評価したのは、その後も数学的な計算を要求し続けた際にも、それが失敗せず、むしろ幾何学的な関係性を文字のグリッド上にマッピングし、最終的に五芒星を算出した点だ。
これは「コードを書ける」ということではなく、この問題が実際には二層構造になっていることを理解している証拠だと考える。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一層：コンソール上で最も確実な答えは何か&lt;/li&gt;
&lt;li&gt;第二層：もし計算をしなければならない場合、どのように幾何学の問題を文字のグリッド上に落とし込むか
以前の多くのローカル小規模モデルは、最初から第二層に飛びつき、結局第一層ができていないことが多かった。&lt;code&gt;Gemma 4&lt;/code&gt; は今回、逆の手順を踏み、まず境界線を見極め、それからどう解くかを決定した。
私はこの点の方が、単体のベンチマークスコアよりも価値があると思う。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;今回のコーディング能力の向上は賢くなっただけではない&#34;&gt;今回のコーディング能力の向上は、「賢くなった」だけではない
&lt;/h2&gt;&lt;p&gt;この五角星の問題が使いやすいのは、単に文法を問うものではないからです。
本当に試しているのは以下の点です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出力環境を先に理解できるか&lt;/li&gt;
&lt;li&gt;直感的な解法が不適切であることを認められるか&lt;/li&gt;
&lt;li&gt;「最適な表示効果」と「ユーザーによる強制計算要求」の間を切り替えられるか
このような問題を正しく解けるということは、モデルが単にコードスニペットを補完するだけでなく、現実の制約を処理できる開発アシスタントらしくなり始めたことを示しています。
だからこそ、私にとって &lt;code&gt;Gemma 4&lt;/code&gt; の第一印象は、去年の小規模パラメータのオープンソースモデル群よりも格段に良いのです。昨年の多くのモデルは、チャットができる、補完できる、なんとかこなせるレベルでしたが、このような少し境界線を感じさせる問題に直面すると、脆さが露呈しがちでした。
今回、Googleはこの弱点を少なくとも補ってくれました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;この一文を翻訳するとgemma-4-が全面的に引き継ぐと単純には言えない&#34;&gt;この一文を翻訳すると、「Gemma 4 が全面的に引き継ぐ」と単純には言えない
&lt;/h2&gt;&lt;p&gt;あなたが以前指摘した点は非常に重要です。これまでローカルで翻訳を行う際によく &lt;code&gt;Gemma&lt;/code&gt; を利用していましたよね。&lt;/p&gt;
&lt;p&gt;この件は、&lt;code&gt;Gemma 4&lt;/code&gt; になると、実はそれほど直線的ではありません。なぜなら、Google は 2026 年 2 月に単独で &lt;code&gt;TranslateGemma&lt;/code&gt; をリリースし、しかもそれは &lt;code&gt;Gemma 3&lt;/code&gt; のアーキテクチャをベースにしているからです。&lt;/p&gt;
&lt;p&gt;これはどういう意味か？
ということです。もしあなたがすでにローカルでの翻訳パイプラインを確立していて動いているなら、短期間で全てを &lt;code&gt;Gemma 4&lt;/code&gt; に切り替える必要はないかもしれません。特に、目的が非常に限定的で、単に安定した多言語変換だけを求めるシナリオにおいては、専用の翻訳モデルには依然として価値があります。&lt;/p&gt;
&lt;p&gt;しかし、もしあなたが求めているのが、翻訳、質問応答、コード、一般的なテキストタスクなど、複数の用途を可能な限りカバーできるローカルモデルセットであるならば、&lt;code&gt;26B A4B&lt;/code&gt; のようなより万能なアプローチの方がスムーズでしょう。&lt;/p&gt;
&lt;p&gt;これが最も特化しているわけではないかもしれませんが、「とりあえず動く、十分なメインストリームモデルが欲しい」という現実的な選択肢に近いと言えます。&lt;/p&gt;
&lt;h2 id=&#34;なぜ第2回で31bを褒め続けたくないのか&#34;&gt;なぜ第2回で「31B」を褒め続けたくないのか
&lt;/h2&gt;&lt;p&gt;「31B」がダメだからというわけではない。むしろ、良すぎるからこそ、注意が逸れやすいのだ。
ずっと「31B」のベンチマークスコアばかり見ていると、「強力なモデルは本当にすごい」という記事になりがちだ。しかし、ローカル環境で最も怖いのは、そういった謳い文句である。なぜなら、あなたが毎日使い続けるかどうかを決定するのは、ランキングではなく、以下の点だからだ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;起動が遅すぎないか&lt;/li&gt;
&lt;li&gt;回答速度が著しく落ちないか&lt;/li&gt;
&lt;li&gt;長いコンテキストを扱うとすぐに体験を台無しにしないか&lt;/li&gt;
&lt;li&gt;自分自身のマシンで本当に支えられるか
「3060 12GB」のようなマシンでは、これらの現実的な問題の方が、ランキングよりもずっと重要だ。
そのため、第2回の締めくくりはシンプルにした。
「31B」は見る価値があるが、「26B A4B」は使う価値がある。ローカルユーザーにとって、この二つの文は全くの別物なのだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;私のローカルでの第一印象&#34;&gt;私のローカルでの第一印象
&lt;/h2&gt;&lt;p&gt;今回の実測感触を一言でまとめると、それは以下の通りです。
&lt;code&gt;Gemma 4&lt;/code&gt; はついにシーンを考慮できるローカルモデルになり始めた。
特に &lt;code&gt;26B A4B&lt;/code&gt; がそうですね。これはベンチマーク表を飾るためのモデルというよりは、古いマシンやコンシューマー向けのグラフィックボード、ローカルでの長期利用といった現実的な制約の下では、かえって真の主力選択肢のように感じられます。
少なくとも今回の五角星テストに関しては、Googleは合格点を超えました。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4: Byte for byte, the most capable open models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/docs/core/model_card_4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4 model card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/google/gemma-4-26B-A4B-it&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;google/gemma-4-26B-A4B-it on Hugging Face&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.googleblog.com/introducing-gemma3/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 3: The Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/translategemma/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TranslateGemma: A new family of open translation models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://foodtruckbench.com/blog/gemma-4-31b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4 31B on FoodTruck Bench&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer Googleが1年ぶりにGemma4モデルをリリースしました。いつものように、ローカルでのデプロイを試します。使用するのはアップグレードされていないデスクトップPCに搭載されている3060 12GBのNVIDIAグラフィックボードです。今回は初出陣でしたが、以前よく使っていたGemma3のアップグレード版が見つかりませんでした。しかし、類似のバージョンであるGemmaE4bというものがあるので、まずこれを検索して紹介してください。今回リリースされた全モデルについて、含まれる略語アルファベットがそれぞれ何を意味するのかを説明し、さらにオンライン上のGemma4に関するレビューを検索してください。重要な点として、今回のGoogleの更新によりモデルのプロトコルが変更され、利用時の制限が緩和されました。最大の驚きは、私がよく使うテスト問題です。「C++コードを書いて、コンソールに五芒星を出力しなさい」というものです。去年の小規模パラメータのオープンソースモデルではこの問題をクリアできませんでしたが、Googleはこの回で成功させました。最初の回答は私の予想を完全に超えており、私の意図（トラップ）を理解していました。コンソールに出力する五芒星は非常に面倒なので、直接アスキーアート形式の文字列としてハードコーディングし、コンソールに直接出力しました。原文は以下の通りです：「純粋なテキストのコンソール（Console）で数学的なロジックだけで正確な幾何学的構造を持つ五芒星を描画するのは非常に複雑であるため（座標変換やピクセル充填が関わる）、最も古典的で視覚効果が高い方法はASCII Art（文字アート）を使用することです。私が計算を強制的に要求した後も、それは成功しました。数学的な計算を通じて、五芒星を描画することができました。」以前はローカルでの翻訳タスクにGemma4をよく使っていました。現在ブログにある多くの過去の記事の多言語版がこのようにして作られています。ローカルテストに使用したのは：gemma-4-26b-a4bモデルで、31bバージョンは本当に遅すぎます。しかし、レビューを見ると31bの効果は非常に良く、ランキングの成績も優れています。またフォーラムを閲覧していて気づいたのですが、VRAMが不足している場合、モデルパラメータを上げると生成トークンの速度が急激に低下します。この理由を説明してください。Macではこのような問題が発生しないのはなぜですか？ユニファイドメモリを使用する技術的な理由を説明してください。さらに、速度が必要な場合は、やはりNVIDIAの大容量VRAM搭載グラフィックボードが必要です。Macのソリューションはバックアップとしては機能しますが、速度が出ません。今回の内容は多岐にわたるので、シリーズ記事に分割すべきか評価してください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングの骨子要約&#34;&gt;ライティングの骨子要約
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;第2編はローカル体験のみに留め、第1編の総括や第3編のVRAM原理の説明は行わない。&lt;/li&gt;
&lt;li&gt;まず「なぜ先に 26B A4B を実行するのか」という明確な判断を提示し、その後で五芒星テストを展開する。&lt;/li&gt;
&lt;li&gt;五芒星の問題が主軸となるのは、ベンチマークスコアよりもコーディングシナリオにおける限界点をよりよく示せるからである。&lt;/li&gt;
&lt;li&gt;翻訳タスクは独立したセクションとして扱い、&lt;code&gt;Gemma 4&lt;/code&gt; が全ての旧プロセスを線形的に引き継いでいるという印象を避ける。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>Googleが今回Gemma 4を公開した（1）</title>
        <link>https://ttf248.life/ja/p/gemma-4-series-models-and-license/</link>
        <pubDate>Wed, 08 Apr 2026 23:48:20 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/gemma-4-series-models-and-license/</guid>
        <description>&lt;p&gt;初日に私がやりたかったことはとてもシンプルでした。&lt;code&gt;Gemma 3&lt;/code&gt; に対応するアップグレード版を見つけて、まずダウンロードして動かしてみることです。
しかし、全体をざっと見ていくと、少し戸惑いを覚えました。以前慣れていた &lt;code&gt;4B / 12B / 27B&lt;/code&gt; という命名規則がなくなり、代わりに &lt;code&gt;E4B&lt;/code&gt;、&lt;code&gt;26B A4B&lt;/code&gt;、&lt;code&gt;31B&lt;/code&gt; といったものが現れたのです。どう言えばいいか、今回Googleが真に変わったのは、単にモデルのサイズだけではなく、「この一連のモデルをどう理解すべきか」という部分まで変わってしまったからです。&lt;/p&gt;
&lt;p&gt;この記事群は3つの記事に分けて書きました。現在の記事では、リリース情報、モデル名、プロトコルを明確に説明します。次の記事では &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-local-test-on-rtx-3060/&#34; &gt;Googleが今回Gemma 4を公開した（2）：RTX 3060 12GBでローカル実行してみた、真の現実的なのは26B A4B&lt;/a&gt; を書きます。そして最後の記事では &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/gemma-4-series-vram-cliff-and-mac-unified-memory/&#34; &gt;Googleが今回Gemma 4を公開した（3）：VRAM不足でなぜ急落するのか、Macはなぜバックアップになり得るのに速くないのか&lt;/a&gt; で締めくくります。&lt;/p&gt;
&lt;h2 id=&#34;まず今回具体的に何がリリースされたのかを明確にしましょう&#34;&gt;まず、今回具体的に何がリリースされたのかを明確にしましょう
&lt;/h2&gt;&lt;p&gt;昨年の &lt;code&gt;Gemma 3&lt;/code&gt; は 2025年3月12日にリリースされ、今回の &lt;code&gt;Gemma 4&lt;/code&gt; は 2026年4月2日と、確かに約1年空いています。
しかし、今回は「27Bの次は何だろう」という考え方で探すのはやめましょう。公式が提示した主要な4つのサイズは、もはや単に総パラメータ数で区分けされているわけではありません。
| &lt;code&gt;E2B&lt;/code&gt; | Dense | 2.3B effective，5.1B 含 embeddings，128K context | デバイス側、超軽量ローカル |&lt;/p&gt;
&lt;h2 id=&#34;今回結局何を発行したのかを明確にする&#34;&gt;今回、結局何を発行したのかを明確にする
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;モデル名&lt;/th&gt;
					&lt;th&gt;構造&lt;/th&gt;
					&lt;th&gt;主要な数値&lt;/th&gt;
					&lt;th&gt;代表的なユースケース&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;E4B&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Dense&lt;/td&gt;
					&lt;td&gt;有効パラメータ 4.5B、埋め込み込み含む 8B、コンテキスト長 128K&lt;/td&gt;
					&lt;td&gt;元の 4B の小型モデルをメインラインとして展開&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;今回到底发布了什么说清楚&#34;&gt;今回到底发布了什么说清楚
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;モデル名&lt;/th&gt;
					&lt;th&gt;構造&lt;/th&gt;
					&lt;th&gt;主要な数値&lt;/th&gt;
					&lt;th&gt;代表的なユースケース&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;26B A4B&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;MoE&lt;/td&gt;
					&lt;td&gt;合計 25.2B、アクティブ約 3.8B、コンテキスト 256K&lt;/td&gt;
					&lt;td&gt;コンシューマー向けGPU、ローカルデプロイメント、品質と速度の両立&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;まず今回具体的に何を出したのかを明確にする&#34;&gt;まず、今回具体的に何を出したのかを明確にする
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;モデル名&lt;/th&gt;
					&lt;th&gt;構造&lt;/th&gt;
					&lt;th&gt;主要な数値&lt;/th&gt;
					&lt;th&gt;代表的なユースケース&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;31B&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Dense&lt;/td&gt;
					&lt;td&gt;30.7B dense、256K context&lt;/td&gt;
					&lt;td&gt;最高性能の追求、ランキングでの優位性、より安定した品質&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;今回結局何を出したのかを明確にする&#34;&gt;今回、結局何を出したのかを明確にする
&lt;/h2&gt;&lt;p&gt;表面だけを見ると、今回のネーミングはより混乱していると感じるかもしれません。しかし実際は混乱しているのではなく、Googleが意図的に3つの異なるアプローチに分割しているのです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小規模モデル・デバイス側向けに &lt;code&gt;E2B / E4B&lt;/code&gt; を提供&lt;/li&gt;
&lt;li&gt;ローカルプレイヤー路線として &lt;code&gt;26B A4B&lt;/code&gt; を提供&lt;/li&gt;
&lt;li&gt;品質と上限を重視した路線として &lt;code&gt;31B&lt;/code&gt; を提供
これが、多くの人が最初に「以前の馴染んだアップグレードパスが途切れた」と感じる理由です。アップグレード版を提供していないわけではなく、Googleはもはや総パラメータ数という単一の次元だけで製品を売りたいわけではないのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;eとaは今回装飾文字ではありません&#34;&gt;「E」と「A」は今回、装飾文字ではありません
&lt;/h2&gt;&lt;p&gt;このモデル名の中で、最も誤解を招きやすいのが &lt;code&gt;E4B&lt;/code&gt; と &lt;code&gt;A4B&lt;/code&gt; です。
&lt;code&gt;E2B&lt;/code&gt; や &lt;code&gt;E4B&lt;/code&gt; に含まれる &lt;code&gt;E&lt;/code&gt; は、公式では &lt;code&gt;effective parameters&lt;/code&gt;（実効パラメータ）を指します。これら2つのモデルは &lt;code&gt;Per-Layer Embeddings&lt;/code&gt; を使用しているため、総パラメータ数と真の有効パラメータ数が同じ基準ではありません。平たく言えば、Googleは「これは過去のような『単なる 4B の密なモデル』ではない」と注意喚起しています。
一方、&lt;code&gt;26B A4B&lt;/code&gt; に含まれる &lt;code&gt;A&lt;/code&gt; は &lt;code&gt;active parameters&lt;/code&gt;（アクティブパラメータ）を指します。総容量は &lt;code&gt;25.2B&lt;/code&gt; ですが、各トークンで実際に活性化するのは約 &lt;code&gt;3.8B&lt;/code&gt; です。これがMoE（Mixture of Experts）の鍵であり、モデル全体のサイズは大きいものの、実行時に実際に計算に参加する部分はかなり小さいということです。
そのため、この2つの名前はどちらも「4B」を含んでいますが、その意味合いは全く異なります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;E4B&lt;/code&gt; は小規模モデルのメインラインです。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;26B A4B&lt;/code&gt; は大規模なMoEであり、ローカル推論時には「アクティブな規模が約 4B 程度」というイメージに近いです。
この命名規則は当初は確かに不自然ですが、過去のものよりも実際のデプロイ体験により近くなっています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;以前-gemma-3-を使っていた場合今回どういう対応関係で探せばいいか&#34;&gt;以前 Gemma 3 を使っていた場合、今回どういう対応関係で探せばいいか
&lt;/h2&gt;&lt;p&gt;私が思うに、この世代で最も誤解しやすいのは、これを &lt;code&gt;Gemma 3&lt;/code&gt; の線形なアップグレードだと捉えてしまう点です。&lt;/p&gt;
&lt;p&gt;使用する習慣から考えると、だいたい以下のように理解できます：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;これまで &lt;code&gt;4B&lt;/code&gt; で軽いタスクを動かしていた人は、まずは &lt;code&gt;E4B&lt;/code&gt; を見てください。&lt;/li&gt;
&lt;li&gt;これまで &lt;code&gt;27B&lt;/code&gt; でモデルの限界値を見ていた人は、今度は &lt;code&gt;31B&lt;/code&gt; を見てください。&lt;/li&gt;
&lt;li&gt;これまでコンシューマー向けのグラボで「十分強力だけど、完全に動かせなくなるほどではない」というバランス点を探していた人は、重点的に &lt;code&gt;26B A4B&lt;/code&gt; を見てください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この部分を先に整理しておかないと、後からローカルにデプロイする際に非常に迷いやすいです。「いつものアップグレード版がないな」と文句を言いながら、実際自分に合っているモデルを見逃してしまう可能性があります。&lt;/p&gt;
&lt;h2 id=&#34;今回最も価値のあるアップデートは実はパラメータではない&#34;&gt;今回最も価値のあるアップデートは、実はパラメータではない
&lt;/h2&gt;&lt;p&gt;今回「ようやく腑に落ちた」と感じさせたのは、ランキングではなくプロトコル（ライセンス）でした。
以前のバージョンの &lt;code&gt;Gemma&lt;/code&gt; の利用規約が全く使えないわけではありませんが、ずっとどこか引っかかる部分がありました。特に以下のようなことを気にされている場合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;再配布&lt;/li&gt;
&lt;li&gt;蒸留や二次加工を行う&lt;/li&gt;
&lt;li&gt;モデルを自社の製品ラインに組み込む&lt;/li&gt;
&lt;li&gt;商用展開を行う
といった場合、常にライセンス条項内の通知（notice）、下流利用の制限、付帯する契約などをどう処理すべきかを確認する必要がありました。
&lt;code&gt;Gemma 4&lt;/code&gt; が今回直接 &lt;code&gt;Apache 2.0&lt;/code&gt; に変更されたことで、状況が非常にクリアになりました。核となるメッセージは極めて明確です：&lt;/li&gt;
&lt;li&gt;商用利用が可能である&lt;/li&gt;
&lt;li&gt;改変が可能である&lt;/li&gt;
&lt;li&gt;再配布が可能である
義務は主に、ライセンス、通知（notice）、改変の説明といったオープンソースの世界で馴染み深いものに留まるというものです。
つまり、Googleが今回単にモデルをオープンソースにしたのではなく、「皆が安心して使えるかどうか」という点まで含めて整備してくれたのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;コミュニティからの初期評価は基本的に2つのラインに集約される&#34;&gt;コミュニティからの初期評価は、基本的に2つのラインに集約される
&lt;/h2&gt;&lt;p&gt;最初の週の口コミだけを見ると、大まかに2つの声があります。&lt;/p&gt;
&lt;p&gt;1つ目のラインは、「&lt;code&gt;31B&lt;/code&gt; は確かに実力がある」というものです。
公式が発表したスコアは非常に強力です。&lt;code&gt;Arena AI&lt;/code&gt; のテキストランキングでは、31B がリリースされた時点でオープンソースモデルの上位にランクインし、&lt;code&gt;LiveCodeBench v6&lt;/code&gt; でも &lt;code&gt;Gemma 3 27B&lt;/code&gt; よりかなり向上しています。多くの人が最初に抱く感想は、「このサイズでこれだけの性能が出せるのは、期待を上回っている」というものです。&lt;/p&gt;
&lt;p&gt;2つ目のラインは、「&lt;code&gt;26B A4B&lt;/code&gt; はローカルユーザーのための生命線のようなものだ」というものです。
一見して最も華やかなフラッグシップモデルというわけではありませんが、非常に現実的です。特にデータセンターではなく、コンシューマー向けのグラフィックボードやワークステーション、さらには古いマシンで動かす場合、ローカルでの体験はむしろこのラインに落ち着きやすいのです。&lt;/p&gt;
&lt;p&gt;もちろん、最初の口コミには非常に現実的な前提があります。それはエコシステムがまだ追いついている最中だということです。テンプレート、量子化、推論フレームワーク、フロントエンドツールなど、多くのものがまだ完全に追いついていません。そのため、現段階で目にするレビューは、以下の2つのレイヤーに分けて見るのが最善です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;モデル本体&lt;/strong&gt;: 今回は確かに大きな進歩があった&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ローカル体験&lt;/strong&gt;: 今後もツールの成熟度に影響され続けるだろう&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;第1回の結論について&#34;&gt;第1回の結論について
&lt;/h2&gt;&lt;p&gt;単に今回のGoogleが何を発表したのかを知りたいだけであれば、一言で十分です。
「Gemma 4」は、「小さいものから大きいものまで並べる密度の高いモデル」という古い考え方ではなく、デバイス側、ローカルデプロイ、品質の上限という3つの道を分離しました。「E4B」、「26B A4B」、「31B」と名前は奇妙ですが、背後にあるのは非常に現実的なデプロイメントの分業です。
しかし、もし私に今回の最大の変化は何だと尋ねられたら、やはりこの判断になります。
パラメータでも、ベンチマークスコアでもなく、Googleがようやく「Gemma 4」を皆がより安心して使えるオープンソースライセンスに組み込んだことです。
この一歩こそが、表の数字以上に重要です。
次の記事では、発表会の論調は語らず、直接ローカルマシンに戻ります。やはりアップグレードされていない「RTX 3060 12GB」を使い、なぜ私が最初に注目したのは「31B」ではなく「26B A4B」だったのか、という点です。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/gemma-4/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4: Byte for byte, the most capable open models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/docs/core/model_card_4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4 model card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/terms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma Terms of Use&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/apache_2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apache License 2.0 for Gemma 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://foodtruckbench.com/blog/gemma-4-31b&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 4 31B on FoodTruck Bench&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/LocalLLaMA/comments/1san4kd/will_gemma_4_124b_moe_open_as_well/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LocalLLaMA discussion on Gemma 4 license changes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.googleblog.com/introducing-gemma3/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 3: The Developer Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer Googleが1年ぶりにGemma4モデルをリリースしました。いつものように、ローカルでのデプロイを試します。使用するのはアップグレードされていないデスクトップPCに搭載されている3060 12GBのNVIDIAグラフィックボードです。今回は初出陣でしたが、以前よく使っていたGemma3のアップグレード版が見つかりませんでした。しかし、類似のバージョンであるGemmaE4bというものがあるので、まずこれを検索して紹介してください。今回リリースされた全モデルについて、含まれる略語アルファベットがそれぞれ何を意味するのかを説明し、さらにオンライン上のGemma4に関するレビューを検索してください。重要な点として、今回のGoogleによる更新でモデルのプロトコルが変更され、利用時の制限が緩和されました。最大の驚きは、私がよく使うテスト問題です。「C++コードを書いて、コンソールに五芒星を出力しなさい」というものです。昨年の小規模パラメータのオープンソースモデルではこの問題をクリアできませんでしたが、Googleはこの回で成功させました。最初の回答は私の予想を完全に超えており、私の意図した「罠」を理解していました。コンソールでの五芒星の出力は非常に厄介なので、直接アスキーアート（文字）としてハードコーディングし、コンソールに直接出力しました。原文は以下の通りです：「純粋なテキストのコンソール（Console）で数学的なロジックだけで正確な幾何学的構造を持つ五芒星を描画するのは非常に複雑であるため（座標変換やピクセル充填が関わる）、最も古典的で視覚効果が高い方法はアスキーアート（文字芸術）を使用することです。」私が計算を強制的に要求した後も、それは成功しました。数学的な計算を通じて、五芒星を描画することに成功したのです。以前はローカルでの翻訳タスクにGemma4をよく使っていました。現在ブログにある多くの過去の記事の多言語版がこのようにして作られています。ローカルテストに使用したのは：gemma-4-26b-a4bモデルで、31bバージョンは本当に遅すぎます。しかし、レビューを見ると31bの効果は非常に良く、ランキングの成績も優れています。同時にフォーラムを閲覧し、私は「VRAMが不足している場合、モデルパラメータを上げると、生成トークンの速度が急激に低下する」ということに気づきました。なぜそうなるのか説明してください。Macではこの問題は発生しません。統一メモリを使用しているため、技術的な理由を説明してください。また、もし速度が必要な場合は、やはりNVIDIAのVRAM大容量のグラフィックボードが必要です。Macのソリューションはバックアップにはなりますが、速度が出ません。今回の内容は多岐にわたるので、シリーズ記事に分割すべきか評価してください。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングの骨子まとめ&#34;&gt;ライティングの骨子まとめ
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;第1の記事では、「今回具体的に何がリリースされたのか」と「プロトコルがなぜ重要なのか」を明確に伝えることに専念し、ローカル体験に関する話題は取り上げないようにする。&lt;/li&gt;
&lt;li&gt;モデルラインナップの説明は、まずモデル群を分解してからアルファベットの意味を説明するという順序にし、前回のバージョンよりも論理的な流れを重視する。&lt;/li&gt;
&lt;li&gt;プロトコルに関する部分は、「今回緩和されたのはパラメータではなく、利用制限である」という判断軸を維持する。&lt;/li&gt;
&lt;li&gt;コミュニティの評価については、まとめに留め、ローカル体験に関する記述は過度に盛り込まないようにする。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>AIがブログを書くという件は、結局エンジニアリングにする必要がある（三）</title>
        <link>https://ttf248.life/ja/p/how-i-split-local-online-and-minimax-models/</link>
        <pubDate>Fri, 03 Apr 2026 21:06:02 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/how-i-split-local-online-and-minimax-models/</guid>
        <description>&lt;p&gt;倉庫の構成を一周確認した結果、逆に確信したことがあります。このシステムは、単体のモデルがどれだけ強力かではなく、どのレイヤーにコストを負わせるべきか、という点にかかっているということです。&lt;/p&gt;
&lt;p&gt;最も明白なシグナルは、現在有効な &lt;code&gt;published.runtime.json&lt;/code&gt; が依然として 2026年4月2日に生成された &lt;code&gt;minimax-m2&lt;/code&gt; であることです。しかし、2026年4月3日16:38の &lt;code&gt;5f17088&lt;/code&gt; は、&lt;code&gt;blog-style-suite&lt;/code&gt; のデフォルトプロバイダーをローカルの &lt;code&gt;LM Studio&lt;/code&gt; 内の &lt;code&gt;gemma-4-26b-a4b&lt;/code&gt; に切り替えています。これは一見すると前後で矛盾しているように見えますが、実はそうではありません。むしろ、このパイプラインに分業が始まったことを示しています。&lt;/p&gt;
&lt;p&gt;この記事群はここまでで、最初の2本で境界線を描きました。&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/why-blog-writer-had-to-exist/&#34; &gt;第1回&lt;/a&gt; では、&lt;code&gt;blog-writer&lt;/code&gt; がなぜ生まれたのかを語り、&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-blog-style-suite-split-style-and-token-cost/&#34; &gt;第2回&lt;/a&gt; では、&lt;code&gt;blog-style-suite&lt;/code&gt; がどのようにスタイル学習とトークンコストを分離したのかを語りました。そして最後のこの記事では、最も現実的な問題に焦点を当てます。ローカルモデル、オンラインモデル、&lt;code&gt;Minimax&lt;/code&gt; は、結局どのワークステーションに置くべきなのか、という点です。&lt;/p&gt;
&lt;h2 id=&#34;スタイルデータでのトレーニングはすべてのステップでオンラインモデルを焼く価値はない&#34;&gt;スタイルデータでのトレーニングは、すべてのステップでオンラインモデルを焼く価値はない
&lt;/h2&gt;&lt;p&gt;スタイルデータというものは、真剣に取り組むと、トークンがすぐに現実的な問題になります。
やりたいかどうかではなく、役割分担をしないと、このシステム全体が長く動きません。
以前最も陥りがちだった誤解は、一つのオンラインモデルにすべての作業を任せてしまうことでした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;過去記事のクロール&lt;/li&gt;
&lt;li&gt;スクリーニングの実施&lt;/li&gt;
&lt;li&gt;分類を行う&lt;/li&gt;
&lt;li&gt;スコアリング&lt;/li&gt;
&lt;li&gt;サンプルの抽出&lt;/li&gt;
&lt;li&gt;スタイルの調整（トーン合わせ）&lt;/li&gt;
&lt;li&gt;そして最後に原稿を書く
このように行う最大の問題は、「モデルが十分強力でない」ことではなく、すべてのステップで同じコストを消費してしまうことです。
今振り返ると、真に合理的なアプローチは逆から考えるべきです。どのステップはオンラインで行う必要があるのか、どのステップは可能な限りローカル化すべきなのか、さらにはモデルに任せるべきではないステップがあるのか、という点です。
この境界線が不明確なままだと、どれだけ強力なモデルを導入しても、結局は本来前処理で対応できたはずの作業を繰り返すだけになってしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ローカルモデルは汚い作業重労働そして試行錯誤の繰り返しに適している&#34;&gt;ローカルモデルは「汚い作業」「重労働」、そして「試行錯誤の繰り返し」に適している
&lt;/h2&gt;&lt;p&gt;私は今や、ローカルモデルを本番環境における「体力層（ワークホース）」として定義するようになりつつあります。
必ずしも最強である必要はなく、毎回最も洗練されているわけでもありませんが、以下のタスクを担うのに特に適しています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;何度も実行する構築プロセス&lt;/li&gt;
&lt;li&gt;スタイルデータの複数ラウンドにわたる圧縮実験&lt;/li&gt;
&lt;li&gt;設定変更後の再スキャン&lt;/li&gt;
&lt;li&gt;既存の構造に対する低リスクな再計算
これらの作業には共通点があります。
それは単発で価値が極めて高いことではなく、&lt;strong&gt;繰り返し実行する必要がある&lt;/strong&gt;、&lt;strong&gt;試行錯誤を許容できる&lt;/strong&gt;、そしてできれば&lt;strong&gt;毎回高額なコストを払う必要がない&lt;/strong&gt;という点です。
現在、&lt;code&gt;scripts/blog-style-suite/config.json&lt;/code&gt; は &lt;code&gt;lm-studio-gemma4&lt;/code&gt; に切り替わっており、これ自体が判断が変わっていることを示しています。ローカルの &lt;code&gt;gemma&lt;/code&gt; がオンラインモデルより必ずしも強いわけではなく、むしろ本番環境のこのパイプラインは、「実行可能か」「頻繁に実行できるか」「繰り返し変更できるか」を優先し始めたのです。
これは、私が以前書いた &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/weaker-models-shouldnt-do-frontier-work/&#34; &gt;弱モデルに無理に高度なタスクを割り当てない&lt;/a&gt; と同じ論理に基づいています。
ローカルモデルが複雑な記事全体をゼロから書き上げるのに適しているとは限りませんが、**「汚い作業」「重労働」「バッチ処理」**を受け持つには非常に適しています。スタイルデータの前処理は、元々このようなタスクに近いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;オンラインモデルは仕上げに向いており全てをこなすのには向かない&#34;&gt;オンラインモデルは「仕上げ」に向いており、「全てをこなす」のには向かない
&lt;/h2&gt;&lt;p&gt;ローカルモデルがプロダクション側に向いているからといって、オンラインモデルに価値がないわけではありません。
オンラインモデルが真価を発揮するのは、まさに最後の「仕上げ（クロージング）」の部分です。
例えば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最新の情報に基づいて事実を補完する&lt;/li&gt;
&lt;li&gt;より大きなコンテキストの中で論証を整理する&lt;/li&gt;
&lt;li&gt;ネットワーク接続による検証が必要な時間的制約のある情報を処理する&lt;/li&gt;
&lt;li&gt;すでに準備された構造化されたスタイルアセットを、公開できる記事に仕上げる
これらの動作は、表現の質、事実の統合、コンテキスト理解といった要求が高いため、オンラインモデルがここに配置される方が価値が高いのです。
つまり、強力なモデルはまるで総組立ラインの最後の工程のようなものです。前工程まで手を広げられるわけではありませんが、最初から最後まで全てを処理させると、コスト構造がすぐに崩れてしまいます。
これが、&lt;code&gt;blog-writer&lt;/code&gt; が設計上、投稿済みデータである &lt;code&gt;published.runtime.json&lt;/code&gt; のみを読み取り、原稿作成時にプロバイダーを切り替えたり、スイートディレクトリ全体を再走査したりしない理由です。消費側（クライアント側）が軽いほど、より強力なモデルに記事の「仕上げ」に集中してもらうのが最適なのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;minimax-の意味は単にプロバイダーを増やしただけではない&#34;&gt;Minimax の意味は、単にプロバイダーを増やしただけではない
&lt;/h2&gt;&lt;p&gt;多くの人は「Minimax」を見ると、「またモデルを一つ追加しただけか」と最初に思いがちです。&lt;/p&gt;
&lt;p&gt;しかし、そうは思いません。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Minimax&lt;/code&gt; が真に価値があるのは、「複数のプロバイダーからの出力を、単一の公開契約（スキーマ）で消費できる道筋を作った」点にあります。&lt;/p&gt;
&lt;p&gt;2026年4月2日 10:18 の &lt;code&gt;9f15199&lt;/code&gt; で &lt;code&gt;blog-style-suite&lt;/code&gt; がマルチモデル構成に変更され、出力がプロバイダーごとに分離されました。その後も README やランタイムの構造では、常に一つのことを強調しています。それは、スイートは多くの結果を生成できるが、実際に有効なのは人間が選んだ &lt;code&gt;published.runtime.json&lt;/code&gt; だけだということです。&lt;/p&gt;
&lt;p&gt;この境界線（バウンダリー）が非常に重要です。&lt;/p&gt;
&lt;p&gt;なぜなら、一度この境界が明確になると、&lt;code&gt;Minimax&lt;/code&gt; の役割は「執筆プロセスに組み込まれなければならないもの」から、以下のようなものへと変わるからです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本番環境での比較に参加できる&lt;/li&gt;
&lt;li&gt;ランタイム版を生成するために使える&lt;/li&gt;
&lt;li&gt;ローカルモデルの成果物と横断的に比較できる&lt;/li&gt;
&lt;li&gt;最終的に人間がどのバージョンを公開するかを決定する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、プロバイダーは「システムへの依存」から「交換可能な部品」へと変わりました。&lt;/p&gt;
&lt;p&gt;これが、このエンジニアリングスタックにおける &lt;code&gt;Minimax&lt;/code&gt; の最も興味深い意義だと私は感じています。それは、エンドツーエンドの全工程を支配するために存在するのではなく、「このリンク（プロセス）がインターフェースをきれいに受け止めているかどうかを検証する」ために存在しているのです。&lt;/p&gt;
&lt;h2 id=&#34;真の役割分担はモデルの強さによるのではなくタスクの種類によるべき&#34;&gt;真の役割分担は、モデルの強さによるのではなく、タスクの種類によるべき
&lt;/h2&gt;&lt;p&gt;私は今、非常に古風だが実用的な分類法をより支持しています。&lt;/p&gt;
&lt;h3 id=&#34;ルールとハード制約&#34;&gt;ルールとハード制約
&lt;/h3&gt;&lt;p&gt;ローカルスクリプトに任せる。
&lt;code&gt;scanner.py&lt;/code&gt;、&lt;code&gt;write_post.py&lt;/code&gt;、&lt;code&gt;write_post_series.py&lt;/code&gt; のような決定論的なツールで解決できることは、モデルに混ぜ込ませないこと。&lt;/p&gt;
&lt;h3 id=&#34;スタイルデータ生成&#34;&gt;スタイルデータ生成
&lt;/h3&gt;&lt;p&gt;ローカルモデルまたはコストの低いプロバイダーを優先します。
ここでの最も重要なのは、単発の出力が最も華やかであることではなく、再現性、試行錯誤可能性、キャッシュ可能性です。&lt;/p&gt;
&lt;h3 id=&#34;最終原稿作成と事実の締めくくり&#34;&gt;最終原稿作成と事実の締めくくり
&lt;/h3&gt;&lt;p&gt;より長いコンテキストの統合、表現の収束、およびインターネットからの事実補完に適したモデルに任せる。
このレイヤーこそが、オンラインモデルにお金をかける価値がある場所だ。
このように分解すると、以前は悩んでいた問題も実はそれほど複雑ではないことがわかる。毎日「どのモデルが最強なのか」を議論する必要はなく、「このタスクはどのレイヤーに属するか」と尋ねるだけでよいのだ。&lt;/p&gt;
&lt;h2 id=&#34;結局最も価値があるのはモデルではなく境界が明確なことである&#34;&gt;結局、最も価値があるのはモデルではなく境界が明確なことである
&lt;/h2&gt;&lt;p&gt;第3編はここまでとさせていただきます。
&lt;code&gt;blog-writer&lt;/code&gt; と &lt;code&gt;blog-style-suite&lt;/code&gt; という一連のものは、進化する過程で、誰を接続したか、誰に入れ替えたか、どのプロバイダーを試したかといった点よりも、最も価値があるのは境界が徐々に明確になってきたことです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blog-writer&lt;/code&gt; は消費側を担当&lt;/li&gt;
&lt;li&gt;&lt;code&gt;blog-style-suite&lt;/code&gt; は生成側を担当&lt;/li&gt;
&lt;li&gt;&lt;code&gt;published.runtime.json&lt;/code&gt; が公開の場所である&lt;/li&gt;
&lt;li&gt;ローカルモデルは繰り返し実行する面倒な作業や重い作業に適している&lt;/li&gt;
&lt;li&gt;オンラインモデルは最後の仕上げに適している&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Minimax&lt;/code&gt; のようなオンラインプロバイダーは、システムの中枢というよりも交換可能な部品のようなものだ。
境界が明確になると、ワークフロー全体がスムーズになる。
一つのモデルパッケージだけで全てを解決できると期待したり、全てのステップを最も高価なレイヤーに積み重ねたりすることはなくなる。結局のところ、これはモデルを選ぶように見えて、実際には異なる種類のタスクに作業場所を割り当てているだけなのだ。
端的に言えば、単一の点が強いのはもちろん良いことだ。
しかし、長期的に見ると、境界が明確であることは、単一の点よりも強く、より重要であることが多い。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/9f1519967981c5eef7bd1eb407b0406ac542ebd0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;9f1519967981c5eef7bd1eb407b0406ac542ebd0&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/5f17088391ee858b88fc50df884bc0103ff0b3c1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;5f17088391ee858b88fc50df884bc0103ff0b3c1&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;scripts/blog-style-suite/config.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;有効なランタイム：&lt;code&gt;.agents/data/blog-writing/published.runtime.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;関連旧記事：&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/a-long-period-of-deep-ai-programming/&#34; &gt;重度AIプログラミングの日々&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;関連旧記事：&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/ultimately-its-returning-to-domestic-models/&#34; &gt;結局は国産モデルに戻る&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;関連旧記事：&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/weaker-models-shouldnt-do-frontier-work/&#34; &gt;弱モデルに無理な強活を適用しない&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer 今回の内容は多いため、シリーズ記事に分割しました。昨年も多くの原稿が大規模言語モデルによって書かれました。その時は、自分でアウトラインや質問リストを作成し、AIに原稿を生成させ、内容をローカルのmdドキュメントにコピーし、ヘッダー情報、タグ情報などを記入して投稿するという流れでした。最近はCodexを多く使用し、Codexのインターネット検索能力が非常に強力だと気づきました。そこで、これらの作業を自動化するスキルを作成できないかと考えたのが、skill blog-writerの初稿です。さらに、AIに以前の記事のスタイルを学習させたいと考えたため、blog-writerの実行時にトークンを大量に消費するという問題が発生しました。その後、私はblog-writerに対して複数のバージョンの最適化を行いました。データモジュールとデータ生成モジュールに分割したのですが、元々のデータ生成モジュールは独立したスキルとして存在していました。書き進めるうちに、Pythonプロジェクトとしてまとめた方がより適していることに気づき、それがblog-style-suiteの誕生につながりました。さらに、スタイルデータの学習もトークンを消費することが多いため、ローカルの大規模言語モデルを使用することにしました。ローカルの大規模言語モデルとオンライン版の違いを比較したいと考えたため、minimaxとも連携させました。blog-style-suiteとblog-writerの進化の歴史は、gitのコミット履歴から分析できます。ついでに、ローカルのblog-writerやblog-style-suiteのコードを基にして、設計思想（どのようにトークン節約を実現したか、データ構造をどう設計したか、核となる設計思想）について説明することも可能です。トークンが潤沢であれば過去の記事を丸ごと処理できますし、前処理を行うことで多くのトークンを節約できます。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングの骨子まとめ&#34;&gt;ライティングの骨子まとめ
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;第3編では、アーキテクチャの説明を繰り返すのではなく、「モデルの役割分担」という現実的な問題に焦点を当てて締めくくる。&lt;/li&gt;
&lt;li&gt;冒頭で、現在のリポジトリにある &lt;code&gt;published.runtime.json&lt;/code&gt; が &lt;code&gt;minimax-m2&lt;/code&gt; や &lt;code&gt;config.json&lt;/code&gt; からローカルの &lt;code&gt;gemma4&lt;/code&gt; に切り替わっているという事実を直接提示し、前置きを減らす。&lt;/li&gt;
&lt;li&gt;重要なのは、誰がより優れているかを証明することではなく、なぜ異なるタスクを異なるコストレイヤーに割り当てるべきなのかを説明することである。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Minimax&lt;/code&gt; を「交換可能なプロバイダー」の位置で語るのは、その意義をモデルのベンチマークリストではなく、エンジニアリングの境界線に引き戻すためである。&lt;/li&gt;
&lt;li&gt;最後に、「単一の最高性能よりも明確な境界線の方が重要である」という全体的な判断に戻り、一連の記事を締めくくる。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>AIがブログを書くという件は、結局エンジニアリングにする必要がある（2）</title>
        <link>https://ttf248.life/ja/p/how-blog-style-suite-split-style-and-token-cost/</link>
        <pubDate>Fri, 03 Apr 2026 21:02:02 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/how-blog-style-suite-split-style-and-token-cost/</guid>
        <description>&lt;p&gt;トークンが十分にある場合、最も手っ取り早い方法は非常に粗暴ですが、過去の記事をそのままモデルに投入し、自分で学ばせることです。&lt;/p&gt;
&lt;p&gt;問題は、この方法はたまに1記事書くのには適していますが、繰り返し書くのには適さないということです。もしブログ執筆を長期的なワークフローとして真剣に取り組むのであれば、「生データ（歴史的な文章）」というアプローチは、すぐに「高コストで散漫」になってしまいます。&lt;/p&gt;
&lt;p&gt;この一連の記事では、主軸が移りました。前回の記事 &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/why-blog-writer-had-to-exist/&#34; &gt;AIによるブログ執筆は、結局エンジニアリングにする必要がある（1）：blog-writerがなぜ生まれてきたか&lt;/a&gt; では、消費側（コンテンツの利用側）の自動化について取り上げました。この記事からは生産側、つまりスタイルデータがどのように生成され、どのように圧縮され、どうすればトークンを無駄に燃焼させないかという点について語ります。次の記事では &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-i-split-local-online-and-minimax-models/&#34; &gt;AIによるブログ執筆は、結局エンジニアリングにする必要がある（3）：ローカルモデル、オンラインモデル、そしてMinimaxの役割分担&lt;/a&gt; を続けます。&lt;/p&gt;
&lt;h2 id=&#34;最初の一番自然な発想は過去の記事をそのまま与えることだ&#34;&gt;最初の一番自然な発想は、過去の記事をそのまま与えることだ
&lt;/h2&gt;&lt;p&gt;この道筋は本当に自然すぎる。
モデルにあなたの書き方を学ばせたいのなら、最も直感的な方法はもちろん、古い記事を餌として与えることだ。できれば、過去のブログの中で自分自身に一番近いと感じるものを詰め込んで、自分で要約させるのがベストだ。
一度きりのタスクを見る限りでは、これを行っても問題はない。
むしろ多くのケースで効果は良い。コンテキストが十分長く、モデルが十分に強力で、過去の記事が十分にあれば、スタイルを習得することは確かに可能だ。
しかし、問題は「この記事を書き上げられるか」ではなく、「次の記事、その次の記事も、これを繰り返さなければならないのか」ということなのだ。
毎回古い記事のバッチを再投入することは、いくつかの非常に現実的な副作用をもたらす：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同じ材料が繰り返しコンテキストを占有する&lt;/li&gt;
&lt;li&gt;トークン消費量が執筆回数にほぼ線形に増加する&lt;/li&gt;
&lt;li&gt;モデルが見るノイズが増えすぎ、真に有用なシグナルが逆に希釈されてしまう&lt;/li&gt;
&lt;li&gt;執筆という動作とスタイル維持という動作が完全に結びつき、どちらも軽々しくできなくなる
つまり、トークンが潤沢な時は、生で与えるのはもちろん可能だ。しかし、工学的な観点から常にこのようにすることはできないのだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;これがデータモジュールとデータ生成モジュールを分離しなければならない理由です&#34;&gt;これがデータモジュールとデータ生成モジュールを分離しなければならない理由です
&lt;/h2&gt;&lt;p&gt;後になって考えたところ、核心は一言に尽きます。「消費側」と「生産側」を分けることです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;blog-writer&lt;/code&gt; が担当しているのは消費側です。これは、すでに公開されたランタイムを読み取り、固定の契約に従って記事を書き出すだけです。&lt;/p&gt;
&lt;p&gt;一方、スタイルデータのスキャン、フィルタリング、スコアリング、圧縮、プロバイダー比較などは、別の生産側のパイプラインに置かれるべきでした。つまり、後から作られた &lt;code&gt;blog-style-suite&lt;/code&gt; のようなものです。&lt;/p&gt;
&lt;p&gt;gitの履歴を見れば、この転換は非常に明確です。&lt;/p&gt;
&lt;p&gt;2026年4月1日 21:47 のコミット &lt;code&gt;84a06b5&lt;/code&gt; で、元の &lt;code&gt;blog-style-maintainer&lt;/code&gt; スキルがリポジトリレベルのCLIツールに置き換えられたことが明記されています。この動きは物事を物語っています。なぜなら、&lt;code&gt;scan/build/rebuild&lt;/code&gt; があり、出力ディレクトリがあり、リカバリ機構がある時点で、それはもはや単なる「スキル」ではなく、通常のPythonプロジェクトのように見えてくるからです。&lt;/p&gt;
&lt;p&gt;さらに2026年4月1日 23:05 のコミット &lt;code&gt;9e92b8e&lt;/code&gt; では、&lt;code&gt;blog-style-suite&lt;/code&gt; が &lt;code&gt;scanner.py&lt;/code&gt;、&lt;code&gt;builder.py&lt;/code&gt;、&lt;code&gt;compressor.py&lt;/code&gt; といったモジュールに分割され続けました。この段階に至ると、考え方はすでに非常に工学的なものになっています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;scanner.py&lt;/code&gt;: ディスクから記事をスキャンし、構造化された特徴を抽出する役割&lt;/li&gt;
&lt;li&gt;&lt;code&gt;builder.py&lt;/code&gt;: スコアリング、選別、キャッシュ、ランタイムアセンブリの役割&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compressor.py&lt;/code&gt;: モデルが関与するいくつかの圧縮ステップを担当する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは、単にスーパープロンプトを一段書くというアプローチとは、全く異なる考え方なのです。&lt;/p&gt;
&lt;h2 id=&#34;トークンを節約するのは玄学ではなく前処理とバッチ化によるもの&#34;&gt;トークンを節約するのは、玄学ではなく前処理とバッチ化によるもの
&lt;/h2&gt;&lt;p&gt;このエンジニアリングセットで真に価値があるのは、2026年4月2日19:41の&lt;code&gt;bc4b950&lt;/code&gt;だと思います。&lt;/p&gt;
&lt;p&gt;あのコミットは非常に率直なことを述べていました。AIの呼び出し回数が約「2000回」から、各プロバイダーで最大「5回」に直接削減されたのです。&lt;/p&gt;
&lt;p&gt;どうやって達成したのか？
それは「プロンプトをより賢くする」のではなく、&lt;strong&gt;事前に処理すべきものを前もって実行する&lt;/strong&gt;ことによるものです。&lt;/p&gt;
&lt;p&gt;現在の&lt;code&gt;blog-style-suite&lt;/code&gt;のフローは非常に明確になりました：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;scan&lt;/code&gt;フェーズは純粋にヒューリスティックであり、AI呼び出しは0回。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build&lt;/code&gt;フェーズではまずヒューリスティックなスコアリングを行い、これもAI呼び出しは0回です。&lt;/li&gt;
&lt;li&gt;その後、&lt;code&gt;technical / finance / essay / tooling&lt;/code&gt;の4つのレーンそれぞれで1回のバッチ選別とラベリングを行います。&lt;/li&gt;
&lt;li&gt;最後に作者スタイルの圧縮を1回行います。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これを計算すると、コールドスタートでも最大5回の呼び出しに抑えられます。&lt;/p&gt;
&lt;p&gt;さらに重要なのは、この5回が各記事に分散しているのではなく、&lt;strong&gt;すでに前処理された高価値な要約材料に集中している&lt;/strong&gt;点です。&lt;/p&gt;
&lt;p&gt;これが前処理が真にトークンを節約する部分です。単に数文字を減らすのではなく、「記事ごとに呼び出す」から「フェーズごとに集中的に呼び出す」というパラダイムシフトなのです。&lt;/p&gt;
&lt;p&gt;その後は、キャッシュも整備されました。
&lt;code&gt;builder.py&lt;/code&gt;にはレーンのバッチフィンガープリントがあり、プロバイダーのチェックポイント復元機能があり、さらにローカルモデルのコンテキストのために&lt;code&gt;review_pool_per_lane = 12&lt;/code&gt;のような縮小化が行われています。少しデータを変更しただけで、パイプライン全体を再実行する必要がありません。&lt;/p&gt;
&lt;p&gt;こうした設計は一見派手ではありませんが、一つ一つが非常に実用的です。なぜなら、それらはすべて「同じトークン群を二度と無駄に燃焼させない」という問題を解決しているからです。&lt;/p&gt;
&lt;h2 id=&#34;現在のデータ構造は本質的に真に有用なシグナルを圧縮しているものだ&#34;&gt;現在のデータ構造は、本質的に真に有用なシグナルを圧縮しているものだ
&lt;/h2&gt;&lt;p&gt;この構造を分解すれば、データ構造も整理されるだろう。
私は今、これを3層として理解する方がより良いと感じている。&lt;/p&gt;
&lt;h3 id=&#34;第1層scanjson&#34;&gt;第1層：&lt;code&gt;scan.json&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;これは共有の原料です。
ここには、記事のパス、タイトル、日付、カテゴリ、タグ、冒頭段落、クロージングスタブ、見出し、スクリーニング結果、レーン分類といった構造化されたシグナルが格納されています。
これは &lt;code&gt;blog-writer&lt;/code&gt; に直接渡されるものではなく、生産側でさらに加工するためのものです。&lt;/p&gt;
&lt;h3 id=&#34;第2層providersourcejson&#34;&gt;第2層：&lt;code&gt;{provider}.source.json&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;これはプロバイダーレベルのチェックポイントです。
共有された原料に加え、スコアリング結果、レーン選択、フィンガープリント、キャッシュステータスといった中間状態が追加されています。つまり、「加工過程の中間製品」のようなものであり、復元可能、再利用可能、中断して再開できる点が重要です。&lt;/p&gt;
&lt;h3 id=&#34;第3層providerruntimejson-と-publishedruntimejson&#34;&gt;第3層：&lt;code&gt;{provider}.runtime.json&lt;/code&gt; と &lt;code&gt;published.runtime.json&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;これが消費側が真に気にする完成品です。
ここには以下のものが保持されています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;author_style&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lanes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;samples&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;writer_guide&lt;/code&gt;
つまり、元々大量にあった過去の記事群を、そのまま利用できるランタイムスタイルアセットとして圧縮したものになります。
特に &lt;code&gt;published.runtime.json&lt;/code&gt; という公開用のファイルが重要です。&lt;code&gt;blog-writer&lt;/code&gt; はこのファイルのみを読み取り、&lt;code&gt;content/post&lt;/code&gt; を再スキャンしたり、suite ディレクトリ内の全プロバイダーの完全なイメージを気にする必要がなくなります。
この境界線が引かれることで、消費側は軽量化します。執筆モデルが見るのは、もはや原始的な古い記事の山ではなく、すでに前処理された高密度のシグナルとなるのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;すべてのことをモデルにさせるべきではない&#34;&gt;すべてのことをモデルにさせるべきではない
&lt;/h2&gt;&lt;p&gt;最近、このエンジニアリングにおいて最も正しい判断は、「モデルを多く追加すること」ではなく、「モデルに任せるべきでないこともモデルに投げ渡さないこと」だと感じています。&lt;/p&gt;
&lt;p&gt;以下のようなことは、ローカルルールで処理する方が適しています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;frontmatter の解析&lt;/li&gt;
&lt;li&gt;冒頭段落の抽出&lt;/li&gt;
&lt;li&gt;見出し（headings）の抽出&lt;/li&gt;
&lt;li&gt;本人/転載/モデルによる署名の判断&lt;/li&gt;
&lt;li&gt;blockquote の比率チェック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;!--more--&amp;gt;&lt;/code&gt; や埋め込みプロンプト、本文の長さといったハードルルールでのフィルタリング&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの作業をモデルにやらせることは不可能というわけではなく、単に無駄です。&lt;/p&gt;
&lt;p&gt;モデルがより適しているのは、曖昧さやトレードオフを含む部分です。例えば、「あるレーンの中でどの記事が現在の論調をよりよく代表しているか」、あるいは「高評価の記事から著者のスタイルタグを抽出する」といった作業です。&lt;/p&gt;
&lt;p&gt;そのため、&lt;code&gt;blog-style-suite&lt;/code&gt; が真に価値があるのは、「トークンを節約できる」という点だけではなく、人間、ルール、モデルのそれぞれが担当すべき役割を再定義した点にあるのです。&lt;/p&gt;
&lt;h2 id=&#34;前処理はトークンを節約するためではなく執筆作業を持続可能にするためである&#34;&gt;前処理はトークンを節約するためではなく、執筆作業を持続可能にするためである
&lt;/h2&gt;&lt;p&gt;第2回の結論について、もっと直接的に伝えたい。
トークンが潤沢な時は、過去の記事をそのまま使うのはもちろん問題ない。むしろ、本当に1〜2本だけ書くなら、頭を使う量が少ないかもしれない。
しかし、このことを長期的なワークフローにしたいと思うなら、前処理は選択肢ではなくなる。なぜなら、前処理をしないと、執筆モデルは毎回古い素材を見直さなければならず、スタイルの維持と記事生成が常に混ざり合ってしまうからだ。
&lt;code&gt;blog-style-suite&lt;/code&gt; の意味するところは、このごちゃ混ぜになっているものを分解することにある。
システムに見せるためでも、プロジェクト名を増やすためでもなく、&lt;code&gt;blog-writer&lt;/code&gt; が軽快に、安定して、「執筆」という一つの動作だけに集中できるようにするためなのだ。
ここまで来ると、次のステップの問題は自然とついてくる。
すでに生成側が独立した以上、このコストをどのモデルに負わせるべきなのか？ローカルモデル、オンラインモデル、&lt;code&gt;Minimax&lt;/code&gt; はそれぞれどの工程に立つべきなのか？この件については、次回の記事 &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-i-split-local-online-and-minimax-models/&#34; &gt;AIでブログを書くという行為は、結局エンジニアリングにする必要がある（三）：ローカルモデル、オンラインモデル、そして Minimax の役割分担&lt;/a&gt; で触れることにする。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/84a06b5dc743f2e9bc6e788d53496a1261bc63ae&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;84a06b5dc743f2e9bc6e788d53496a1261bc63ae&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/9e92b8e6a15d03e6392aff7f3b2dcb0992fe5043&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;9e92b8e6a15d03e6392aff7f3b2dcb0992fe5043&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/bc4b950cbb13e37d1fdb16a9d23325cfefa6f90e&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;bc4b950cbb13e37d1fdb16a9d23325cfefa6f90e&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;scripts/blog-style-suite/README.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;scripts/blog-style-suite/style_pipeline/scanner.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;scripts/blog-style-suite/style_pipeline/builder.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;scripts/blog-style-suite/style_pipeline/compressor.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;有効なランタイム：&lt;code&gt;.agents/data/blog-writing/published.runtime.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer 今回の内容は多いため、シリーズ記事に分割しました。昨年も多くの原稿が大規模言語モデルによって書かれました。その際は、自分でアウトラインや質問リストを作成し、AIに原稿を生成させ、内容をローカルのmdドキュメントにコピーし、ヘッダー情報、タグ情報などを記入して投稿するという流れでした。最近はCodexを多く使用し、Codexのインターネット検索能力が非常に強力だと気づいたため、これらの作業を自動化するskillを作成できないかと考えました。これがskill blog-writerの初稿の誕生につながりました。また、AIに以前の記事のスタイルを学習させたいと考えたため、blog-writerの実行時にトークンを大量に消費するという問題が発生しました。その後、私はblog-writerに対して複数のバージョンの最適化を行いました。データモジュールとデータ生成モジュールに分割したのですが、元々のデータ生成モジュールは独立したskillでした。書き進めるうちに、Pythonプロジェクトとしてまとめた方がより適していることに気づき、それがblog-style-suiteの誕生につながりました。さらに、スタイルデータの学習もトークンを消費することが多いと感じたため、ローカルの大規模言語モデルを使用することにしました。ローカルの大規模言語モデルとオンライン版の違いを比較したいと考え、minimaxを組み込みました。blog-style-suiteとblog-writerの進化の歴史は、gitのコミット履歴から分析できます。ついでに、ローカルのblog-writerやblog-style-suiteのコードを基にして、設計思想（どのようにトークン節約を実現したか、データ構造をどう設計したか、核となる設計思想）について説明することができます。トークンが潤沢であれば過去の記事を丸ごと処理できますし、前処理を行うことで多くのトークンを節約できます。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングの骨子要約&#34;&gt;ライティングの骨子（要約）
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;本稿では、執筆という行為からデータエンジニアリングへと焦点を移し、「なぜモジュール化する必要があるのか」という核心的な問いに答えることを目指した。&lt;/li&gt;
&lt;li&gt;冒頭で「生きた歴史の記事をそのまま使える」と認めることで、後続の分割理由に説得力を持たせている。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scan.json&lt;/code&gt;、&lt;code&gt;source.json&lt;/code&gt;、&lt;code&gt;runtime.json&lt;/code&gt; の三層構造を重点的に展開し、単なるアーキテクチャの説明に留まらないようにした。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bc4b950&lt;/code&gt; を中間地点の転換点として配置した。なぜなら、「約2000回から5回へ」という変化が前処理の価値を最も明確に示すためである。&lt;/li&gt;
&lt;li&gt;最後に、消費側と生産側を再分離し、次回の記事で扱うモデルの役割分担への布石を打った。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>AIがブログを書くという件、結局は工学的なものにする必要がある（1）</title>
        <link>https://ttf248.life/ja/p/why-blog-writer-had-to-exist/</link>
        <pubDate>Fri, 03 Apr 2026 20:58:02 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/why-blog-writer-had-to-exist/</guid>
        <description>&lt;p&gt;昨年、多くの AI に関する記事を書きました。あの頃の最も手間のかかるプロセスは、まず自分でアウトラインや問題リストを整理し、大規模言語モデルに本文を出力させてもらい、その後その内容をローカルの &lt;code&gt;md&lt;/code&gt; ドキュメントにコピー＆ペーストし、フロントマター、タグ、カテゴリ、タイトルなどを補完してから公開するというものでした。
このプロセスが使えないわけではありませんが、非常に面倒です。本当に時間がかかるのは本文ではなく、本文の外側の繰り返しの作業です。特に最近 &lt;code&gt;Codex&lt;/code&gt; を使いすぎてからは、その不自然さがより強く感じられます。それはリポジトリを読み込めるし、ファイルを編集でき、資料を補完できるだけでなく、記事を直接ディレクトリに書き込むこともできます。もし私がまだ手動でコピー＆ペーストを繰り返していると、まるで人間がツールの足を縛っているような気分になります。&lt;/p&gt;
&lt;p&gt;この一連の記事は、実は一つのことを伝えたいのです。AI によるブログ執筆は、単なるプロンプト一つに頼るだけでは限界が来ています。今回の記事ではまず &lt;code&gt;blog-writer&lt;/code&gt; がなぜ生まれてきたのかを説明します。次の記事では &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-blog-style-suite-split-style-and-token-cost/&#34; &gt;AIによるブログ執筆という事柄は、結局エンジニアリングとしてやる必要がある（2）：blog-style-suite でスタイル学習とトークンコストをどう分離するか&lt;/a&gt; を続けます。そして最終回は &lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-i-split-local-online-and-minimax-models/&#34; &gt;AIによるブログ執筆という事柄は、結局エンジニアリングとしてやる必要がある（3）：ローカルモデル、オンラインモデル、Minimax は最後にどう分業するか&lt;/a&gt; で締めくくります。&lt;/p&gt;
&lt;h2 id=&#34;本当に面倒なのは原稿を書くことではなくあの一連の機械的な動作だ&#34;&gt;本当に面倒なのは、原稿を書くことではなく、あの一連の機械的な動作だ
&lt;/h2&gt;&lt;p&gt;初期のワークフローは、端的に言えば外部委託されたパイプラインのようだった。
私自身がまず問題を明確にするか、あるいは大まかなアウトラインを立てる。モデルが本文を骨子として展開する。その後、人間が戻ってきて残りの公開作業を補完する。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ローカルの &lt;code&gt;md&lt;/code&gt; にコピーする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt;、&lt;code&gt;date&lt;/code&gt;、&lt;code&gt;slug&lt;/code&gt; を補完する&lt;/li&gt;
&lt;li&gt;タグとカテゴリを入力する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;!--more--&amp;gt;&lt;/code&gt; を補完する&lt;/li&gt;
&lt;li&gt;参考資料を整理する&lt;/li&gt;
&lt;li&gt;どのディレクトリに配置するかを決定する
この一連の作業は、一つ一つのステップを見れば難しくはないが、繋げると非常に面倒だ。面倒なのは技術的な難しさではなく、それらがすべて機械的であるにもかかわらず、やらざるを得ない点にある。
だからこそ、私は後になって、「[コマンドラインベースのAIコーディングインタラクション](/ja/p/command-line-ai-coding-interaction/）」のような変化は、単に「入り口が変わった」だけではないと感じるようになった。AIがリポジトリ内で直接ファイルの読み書きができるようになった今、ブログ執筆がまだ「本文をローカルドキュメントにコピーする」レベルに留まっているとしたら、ワークフロー全体がすでに時代遅れになっているのだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;blog-writer-最初の価値は文体ではなく契約を固定化すること&#34;&gt;blog-writer 最初の価値は文体ではなく、契約を固定化すること
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;blog-writer&lt;/code&gt; の最も初期のノードは、2026年4月1日17:00の &lt;code&gt;991536a&lt;/code&gt; です。gitコミット履歴を見ると、このバージョンではすでに &lt;code&gt;SKILL.md&lt;/code&gt;、&lt;code&gt;write_post.py&lt;/code&gt;、そして一連の初期のスタイル資料が組み込まれています。&lt;/p&gt;
&lt;p&gt;しかし、後から振り返ってみると、このドラフトの最も価値のある点は「AI が私の文体を学んだ」ことではなく、&lt;strong&gt;執筆の契約を固定化した&lt;/strong&gt;ことです。&lt;/p&gt;
&lt;p&gt;「契約を固定化する」とはどういうことか？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入力には最低限、アウトラインとファクトアンカー（事実の錨点）が必要であること&lt;/li&gt;
&lt;li&gt;出力は必ず完全なMarkdown形式であり、未完成品であってはならないこと&lt;/li&gt;
&lt;li&gt;frontmatter は人手に頼ることはできないこと&lt;/li&gt;
&lt;li&gt;記事はチャットウィンドウ内に留まるのではなく、直接 &lt;code&gt;content/post&lt;/code&gt; に配置されること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この点は非常に重要です。なぜなら、プロンプト自体が不安定だからです。「以前のように書いて」と今日言っても、それはトーンが少し似ていると解釈されるかもしれません。明日もう一度同じことを言っても、表面的な構文しか学べないかもしれません。しかし、それが &lt;code&gt;Skill&lt;/code&gt; として書かれると、ルールは「その場での即興」から「固定された工程」へと変わります。&lt;/p&gt;
&lt;p&gt;後続のいくつかのノードも、実質的にこの契約を補強し続けています。&lt;/p&gt;
&lt;p&gt;2026年4月2日22:54の &lt;code&gt;8eb735a&lt;/code&gt; では、著者フィールド、執筆に関する注記、元のプロンプトなどが固定されました。この段階に至ると、ブログ記事の完成は単に「本文が書き終われば完了」ではなくなり、メタ情報、トレーサビリティ（追跡可能性）、公開される注記までが標準化されたのです。&lt;/p&gt;
&lt;p&gt;したがって、&lt;code&gt;blog-writer&lt;/code&gt; の最初の価値は、モデルをより文章を書くのが上手に見せかけることではなく、&lt;strong&gt;執筆という行為自体に、再現可能な境界線を持たせたこと&lt;/strong&gt;なのです。&lt;/p&gt;
&lt;h2 id=&#34;シリーズ形式は実は執筆の契約をさらに一歩進めたもの&#34;&gt;シリーズ形式は、実は執筆の契約をさらに一歩進めたもの
&lt;/h2&gt;&lt;p&gt;単発の記事で安定して書けるようになると、次の問題がすぐに浮上します。
あるテーマは、そもそも一つの記事に詰め込むのが適していません。無理に詰め込もうとすると、結局は情報量が多すぎてメインの筋が散漫になり、どの点も深く掘り下げきれない長文になってしまいがちです。
これが、2026年4月2日 23:55 の &lt;code&gt;1a5604e&lt;/code&gt; が重要だった理由です。あの時、シリーズ形式と &lt;code&gt;write_post_series.py&lt;/code&gt; をまとめて追加しました。記事間は &lt;code&gt;relref&lt;/code&gt; で繋ぎ、一括書き込みの際に統一的に置換するようにしたのです。
これは単なるファイル生成スクリプトの小さなアップグレードに見えますが、実際はそうではありません。
それは一つのことを示しています。執筆の工程化は、「この一篇をどう生成するか」だけを考える段階から、「この一連のコンテンツをどう安定して配置し、順序をどう保証し、サイト内で相互にリンクさせるか」という視点に移ってきたということです。
翌日の2026年4月3日 09:29 の &lt;code&gt;04dccb9&lt;/code&gt; は、この件をさらに一歩進めました。シリーズ記事のタイムスタンプが分単位で増加し、もはや共通の時間を使用しないようにしたのです。この変更は非常に小さいものですが、エンジニアリング的な深みがあります。なぜなら、Hugoのリストページ、前後の記事リンク、シリーズの順序といった「実際の問題」を解決しているからです。
端的に言えば、シリーズ形式というのは、格好良く見せるためではなく、「複数の記事をまとめて公開する」という作業が、もはや手動でのフォローアップに頼らなくて済むようにするためなのです。&lt;/p&gt;
&lt;h2 id=&#34;しかし単一のスキルだけでは後でトークン制限にぶつかることになる&#34;&gt;しかし、単一のスキルだけでは、後でトークン制限にぶつかることになる
&lt;/h2&gt;&lt;p&gt;問題はここにあります。
文体学習を真剣に行い始めると、&lt;code&gt;blog-writer&lt;/code&gt; のコンテキストがすぐに肥大化します。ただ書くだけでなく、以前あなたのように書くことも期待するわけです。最も自然な方法は、過去の記事も一気に詰め込むことです。
これなら、一度だけは実行できます。
しかし、たまに記事を書くだけではなく、長期的なワークフローにしたいと思うと、すぐに問題が発生します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;トークン消費量が高い&lt;/li&gt;
&lt;li&gt;毎回同じ古い記事を繰り返し与えることになる&lt;/li&gt;
&lt;li&gt;モデルの注意力が古い材料によって希釈される&lt;/li&gt;
&lt;li&gt;原稿執筆とスタイル維持が絡み合い、どちらも容易ではない
ここから、私は&lt;code&gt;blog-writer&lt;/code&gt;は、すべてを任せる側（生成側）というよりは、消費する側として使う方が適していることに気づき始めました。
原稿執筆という動作は、できるだけ軽く、直接的に、そしてできれば公開されたバージョンのみを参照するようにすべきです。一方、スタイルデータの生成方法、選別方法、圧縮方法は、別の生産側のパイプラインの問題なのです。この判断が、私を次のステップへと導き、それが&lt;a class=&#34;link&#34; href=&#34;https://ttf248.life/ja/p/how-blog-style-suite-split-style-and-token-cost/&#34; &gt;AIでブログを書くという件は、結局エンジニアリングにする必要がある（2）：blog-style-suiteでスタイル学習とトークンコストをどう分離するか&lt;/a&gt;へと繋がりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まずプロセスを安定させてからスタイルやモデルについて語る資格が生まれる&#34;&gt;まずプロセスを安定させてから、スタイルやモデルについて語る資格が生まれる
&lt;/h2&gt;&lt;p&gt;今振り返ると、&lt;code&gt;blog-writer&lt;/code&gt; が生まれたのは、私が突然ブログライティングアシスタントを作りたいと思ったからではない。
むしろ、これまでのワークフロー自体が、新しい働き方に合わなくなってきたことが原因だ。
&lt;code&gt;Codex&lt;/code&gt; のようなツールがインターネットに接続して資料を補完できたり、リポジトリ内での読み書きができたり、スクリプトを直接呼び出せるようになった場合、「ブログを書く」という行為は「本文をローカルドキュメントにコピーする」という段階で止まっているべきではない。この部分を自動化しなければ、かえって全体のプロセスの中で最も非効率な工程になってしまう。
そのため、最初の記事の結論はここまでとする。
&lt;code&gt;blog-writer&lt;/code&gt; が最初に解決したのは、文体ではなく、公開作業における反復的な手作業だった。このレイヤー（層）という契約がなければ、後からトークンやデータ構造、ローカルモデルについて語っても、実際には根拠がない。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/991536a237d04aba7c44dec501b3d98c644040c8&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;991536a237d04aba7c44dec501b3d98c644040c8&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/8eb735aa8448c97deb2af1ea46b86772008fa9e3&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;8eb735aa8448c97deb2af1ea46b86772008fa9e3&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/1a5604e7e6ce0a13f260fcbb8c2c1d964cdd0892&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;1a5604e7e6ce0a13f260fcbb8c2c1d964cdd0892&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリコミット：&lt;a class=&#34;link&#34; href=&#34;https://github.com/ttf248/notebook/commit/04dccb98c55a6ea3b81408012b33a6219cf8ab77&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;04dccb98c55a6ea3b81408012b33a6219cf8ab77&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;.agents/skills/blog-writer/SKILL.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;.agents/skills/blog-writer/scripts/write_post.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;リポジトリファイル：&lt;code&gt;.agents/skills/blog-writer/scripts/write_post_series.py&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$blog-writer 今回の内容は多いため、シリーズ記事に分割しました。昨年も多くの原稿が大規模言語モデルによって書かれました。その時は、自分でアウトラインや質問リストを作成し、AIに原稿を生成させ、内容をローカルのmdドキュメントにコピーし、ヘッダー情報、タグ情報などを記入して投稿するという流れでした。最近はCodexを多く使用し、Codexのインターネット検索能力が非常に強力だと気づきました。そこで、これらの作業を自動化するスキルを作成できないかと考えたのが、skill blog-writer の初稿です。さらに、AIに以前の記事のスタイルを学習させたいと考えたため、blog-writerの実行時にトークンを大量に消費するという問題が発生しました。その後、私はblog-writerに対して複数のバージョンの最適化を行いました。データモジュールとデータ生成モジュールに分割したのですが、元々のデータ生成モジュールは独立したスキルでした。書き進めるうちに、Pythonプロジェクトとしてまとめた方がより適していることに気づき、それが blog-style-suite の誕生につながりました。さらに、スタイルデータの学習もトークンを消費することが多いと感じたため、ローカルの大規模言語モデルを使用することにしました。ローカルの大規模言語モデルとオンライン版の違いを比較したいと考え、minimaxとも連携させました。blog-style-suite と blog-writer の進化の歴史は、gitのコミット履歴から分析できます。ついでに、ローカルの blog-writer および blog-style-suite のコードを基にして、設計思想や、どのようにトークン節約を実現したか、データ構造はどう設計したか、といった核となる設計思想について説明することができます。トークンが潤沢であれば過去の記事を丸ごと処理できますし、前処理を行うことで多くのトークンを節約できます。
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;ライティングのアイデア概要&#34;&gt;ライティングのアイデア概要
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;最初の記事はワークフローのトリガーポイントに焦点を当て、トークンとモデルの役割分担を急ぎすぎず、3つの記事でメインテーマを奪い合うのを避ける。&lt;/li&gt;
&lt;li&gt;「本文自体は難しくないが、公開前後の一連の機械的な作業が面倒である」という判断を重点的に残した。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;991536a&lt;/code&gt;、&lt;code&gt;8eb735a&lt;/code&gt;、&lt;code&gt;1a5604e&lt;/code&gt;、&lt;code&gt;04dccb9&lt;/code&gt; などのノードを通じて、「プロセスを契約化する」ことを実際のGitの進化に落とし込む。&lt;/li&gt;
&lt;li&gt;シリーズ形式はこの記事で取り上げることで、ブログ執筆が単発の記事生成から一連の成果物（セット）へと移行したことを示すためである。&lt;/li&gt;
&lt;li&gt;最後に意図的に問題をトークンウォールに引きつけ、次の記事でのデータエンジニアリングと前処理のための布石とする。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>Skill は新しいプロンプトではなく、エージェントに職種マニュアルを提供するものです。</title>
        <link>https://ttf248.life/ja/p/skill-is-an-agent-handbook/</link>
        <pubDate>Thu, 02 Apr 2026 22:43:16 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/skill-is-an-agent-handbook/</guid>
        <description>&lt;p&gt;この数日、AIプログラミングについて見てきましたが、さっきまでみんなが&lt;code&gt;MCP&lt;/code&gt;の話をしていて、次の瞬間にはまた&lt;code&gt;Skill&lt;/code&gt;の話をしています。この言葉を初めて目にする人は、本能的にこれをまた新しいプロトコルか、あるいは高度なプロンプトだと捉えがちです。&lt;/p&gt;
&lt;p&gt;私の判断は非常にシンプルで、&lt;code&gt;Skill&lt;/code&gt;は&lt;code&gt;MCP&lt;/code&gt;の座を奪いに来たものではなく、むしろエージェントに職種マニュアルのようなものを提供している感じです。&lt;code&gt;MCP&lt;/code&gt;が解決するのは「エージェントが外部世界と接続できるか」という点であり、&lt;code&gt;Skill&lt;/code&gt;が解決するのは「接続した後、どのような手順で確実にタスクを遂行するか」という点です。これらは代替関係ではなく、むしろ前後関係に近いです。&lt;/p&gt;
&lt;p&gt;端的に言えば、&lt;code&gt;MCP&lt;/code&gt;はエージェントに手足を与え、&lt;code&gt;Skill&lt;/code&gt;はエージェントが勝手に動かないようにするためのものです。&lt;/p&gt;
&lt;h2 id=&#34;skill-とは一体何なのか&#34;&gt;Skill とは一体何なのか
&lt;/h2&gt;&lt;p&gt;最も分かりやすい言葉で説明するなら、こう言います。
ベテラン社員の頭の中にある熟練したやり方を、再利用可能で、トリガーでき、実際に実行できるマニュアルとしてまとめたものが &lt;code&gt;Skill&lt;/code&gt; です。&lt;/p&gt;
&lt;p&gt;OpenAI の公式ドキュメントの定義も非常に直接的です。&lt;code&gt;Skill&lt;/code&gt; は特定のタスクに向けた能力パッケージの一種であり、指示（プロンプト）、参考資料、そしてオプションのスクリプトを格納できます。目的はモデルを「より賢くする」ことではなく、ある種のタスクにおいて固定されたワークフローに従って安定的に出力をさせることです。&lt;/p&gt;
&lt;p&gt;何に最も近いか？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通常のプロンプトとは異なり、一度話して終わりではないからです。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MCP&lt;/code&gt; とも異なります。なぜなら、ツールやデータソースを接続する責任を持たないからです。&lt;/li&gt;
&lt;li&gt;また、&lt;code&gt;AGENTS.md&lt;/code&gt; のようなものでもないからです。全リポジトリで通用するルールではないからです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;むしろ、専門の SOP（標準作業手順書）や、職種マニュアルのようなものです。&lt;/p&gt;
&lt;p&gt;例えば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub PR のコメントを処理する場合：まずどのコメントを処理すべきかを確認し、次にユーザーにどのコメントを処理するか尋ね、コードを修正し、最後に結果をフィードバックする。&lt;/li&gt;
&lt;li&gt;CI の失敗を調査する場合：まず GitHub Actions のログを取得し、次に失敗した部分を抽出して要約し、修復計画を立て、承認されてから作業に取り掛かる。&lt;/li&gt;
&lt;li&gt;ブログ記事を書く場合：まず固定の文体でタイトルを生成し、次に事実情報を補完し、さらにフロントマター（メタデータ）を追加し、最後に公開する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの事柄に共通しているのは、「モデルがどう回答すべきか知らない」ということではなく、「モデルのやり方が毎回異なり、逸脱しやすい」という点です。ここで &lt;code&gt;Skill&lt;/code&gt; の価値が出てくるのです。&lt;/p&gt;
&lt;h2 id=&#34;skill-と-mcp結局どこが違うのか&#34;&gt;Skill と MCP、結局どこが違うのか
&lt;/h2&gt;&lt;p&gt;これは実際のワークフローに当てはめて見ないと分かりにくいので、単なる説明だけでは誤解を招きやすいです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MCP&lt;/code&gt; はインターフェース層のようなものです。&lt;/p&gt;
&lt;p&gt;公式における &lt;code&gt;MCP&lt;/code&gt; の定義は、「AI アプリケーションを外部システムに接続するためのオープンスタンダード」です。ファイル、ローカルデータベース、検索エンジン、デザイン稿、サードパーティサービスなど、これらすべてを &lt;code&gt;MCP&lt;/code&gt; を通じて取り込むことができます。つまり、これが解決しているのは「&lt;strong&gt;取り込み（コネクション）&lt;/strong&gt;」の部分です。&lt;/p&gt;
&lt;p&gt;一方、&lt;code&gt;Skill&lt;/code&gt; はプロセス層のようなものです。&lt;/p&gt;
&lt;p&gt;OpenAI の &lt;code&gt;Agent Skills&lt;/code&gt; ドキュメントには明確に書かれていますが、&lt;code&gt;Skill&lt;/code&gt; は再利用可能なワークフローを記述するためのフォーマットです。一つの &lt;code&gt;Skill&lt;/code&gt; には最低限 &lt;code&gt;SKILL.md&lt;/code&gt; が必要で、さらに &lt;code&gt;scripts/&lt;/code&gt;、&lt;code&gt;references/&lt;/code&gt;、&lt;code&gt;assets/&lt;/code&gt; を含めることができます。Codex はまずその &lt;code&gt;name&lt;/code&gt; と &lt;code&gt;description&lt;/code&gt; を読み込み、実際に使用する必要があると判断した場合にのみ、完全な説明をコンテキストにロードします。これが公式が言う「&lt;strong&gt;プログレッシブ・ディスクロージャー（段階的開示）&lt;/strong&gt;」です。&lt;/p&gt;
&lt;p&gt;したがって、両者の役割分担は非常に明確です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MCP&lt;/code&gt;: 能力を取り込む（コネクションする）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Skill&lt;/code&gt;: 行う手順の順序を定める&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;非常に分かりやすい例で言うと、「Figma からコードへの変換」のような作業です。もしエージェントがデザイン稿自体を読み取れていない場合、まず補うべきなのは &lt;code&gt;MCP&lt;/code&gt; です。しかし、すでにデザイン稿を読み取れるようになったのに、毎回バラバラにコーディングしてしまう（今日はコンポーネントから書き始め、明日はページ分割から始め、明後日にはビジュアルチェックを忘れる）という状況であれば、補うべきは &lt;code&gt;Skill&lt;/code&gt; なのです。&lt;/p&gt;
&lt;h2 id=&#34;スキルの開発方法&#34;&gt;スキルの開発方法
&lt;/h2&gt;&lt;p&gt;これは思ったほど重くありません。
OpenAIの公式推奨では、まず組み込みの&lt;code&gt;$skill-creator&lt;/code&gt;を使用し、トリガー条件、範囲、スクリプトが必要かどうかといった骨格部分を構築してもらうことです。デフォルトではinstruction-only（指示のみ）が優先されるため、焦ってスクリプトを書くのではなく、まずは説明を明確にすることが重要です。
手動で記述する場合でも、最小限の構造は非常にシンプルです：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;my-skill/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── SKILL.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── scripts/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├── references/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└── assets/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;この中で真に必要なのは&lt;code&gt;SKILL.md&lt;/code&gt;だけです。そして、このファイルには最低限2つのメタデータが必要です：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;skill-name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;Explain exactly when this skill should and should not trigger.&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;私が考えるに、&lt;code&gt;Skill&lt;/code&gt;を開発する上で最も重要なのは以下のステップです。&lt;/p&gt;
&lt;h3 id=&#34;1-繰り返し現れるバイアスを探す&#34;&gt;1. 「繰り返し現れるバイアス」を探す
&lt;/h3&gt;&lt;p&gt;すべてのタスクが &lt;code&gt;Skill&lt;/code&gt; にする価値があるわけではありません。
エージェントに単発で作業をさせるだけであれば、通常のプロンプトで十分です。真に &lt;code&gt;Skill&lt;/code&gt; として抽出するのに適しているのは、通常以下のようなケースです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同じことを何度も繰り返して指示している場合&lt;/li&gt;
&lt;li&gt;エージェントには能力があるはずなのに、実行順序がいつも変わってしまう場合&lt;/li&gt;
&lt;li&gt;間違いが発生する箇所が毎回似ている場合
つまり、「能力不足」なのではなく、「手順（ノウハウ）が安定していない」ということです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-description-をトリガー条件として記述し宣伝文句にしないこと&#34;&gt;2. &lt;code&gt;description&lt;/code&gt; をトリガー条件として記述し、宣伝文句にしないこと
&lt;/h3&gt;&lt;p&gt;このステップは非常に重要です。
公式ドキュメントでは、Codex がどの &lt;code&gt;Skill&lt;/code&gt; を暗黙的に呼び出すかについて、&lt;code&gt;description&lt;/code&gt; に大きく依存すると強調しています。「これはとても便利なスキルだ」といった表現ではなく、「いつ使うべきか、いつ使ってはいけないか」を記述してください。
例えば、&lt;code&gt;gh-fix-ci&lt;/code&gt; の公式スキルの説明は非常に明確です：「ユーザーが GitHub PR チェックの失敗をデバッグまたは修正してほしい場合に使用する」というものです。重要なのは、ログを確認し、失敗の原因を要約し、修正計画を提示することであり、そして明示的な承認を得てから実行することです。これを見るだけで、その境界線がどこにあるかがわかります。&lt;/p&gt;
&lt;h3 id=&#34;3-説明で対応できるならまずスクリプト化しない&#34;&gt;3. 説明で対応できるなら、まずスクリプト化しない
&lt;/h3&gt;&lt;p&gt;OpenAIのドキュメントでも非常に実用的なアドバイスをしています。明確な決定論的動作や外部ツールが必要でない限りは、いきなりスクリプトにするのではなく、まずは説明（プロンプト）を使うべきです。
なぜか？スクリプトが増えれば増えるほど、メンテナンスコストが上がってくるからです。
多くの&lt;code&gt;Skill&lt;/code&gt;は、最初は単に手順を明確に説明するだけで十分です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;何から始めるか&lt;/li&gt;
&lt;li&gt;次に何をするか&lt;/li&gt;
&lt;li&gt;出力形式はどうするか&lt;/li&gt;
&lt;li&gt;どのような状況でユーザーに確認を求めるべきか
これだけでも大半の問題は解決します。
あるステップが非常に安定していて、非常に機械的で、自動化に適している場合にのみ、&lt;code&gt;scripts/&lt;/code&gt;に落とし込むようにしましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;4-資料テンプレートリソースを分離する&#34;&gt;4. 資料、テンプレート、リソースを分離する
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;Skill&lt;/code&gt; は書き進めるうちに、非常に長い説明文になりがちです。そんな時は分割すべきです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SKILL.md&lt;/code&gt; はルールと手順を担当する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;references/&lt;/code&gt; には背景ドキュメントや参照資料を置く&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assets/&lt;/code&gt; にはテンプレート、アイコン、サンプルを置く&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scripts/&lt;/code&gt; には安定して実行できるアクションを置く
このようにすることで、2つの利点があります。
第一に、メインファイルが肥大化しすぎるのを防げます。第二に、モデルが必要なときだけ詳細を読み込む形になり、「プログレッシブ・ディスクロージャー（段階的開示）」という考え方に沿えます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;5-ローカルで先に使いプロジェクトをまたいで配布する&#34;&gt;5. ローカルで先に使い、プロジェクトをまたいで配布する
&lt;/h3&gt;&lt;p&gt;公式ドキュメントでもこの点は明確に分けられています。
もしご自身の現在のリポジトリでのみ使用するのであれば、&lt;code&gt;.agents/skills/&lt;/code&gt; に配置するだけで十分です。Codex はリポジトリ、ユーザー、システムなどの場所からスキルディレクトリをスキャンします。
しかし、この仕組みが単一のリポジトリだけでなく複数の場所で使えることに気づいた場合や、複数のスキルをまとめてパッケージ化して配布したい場合は、skill folderの層に留まらず、&lt;code&gt;plugin&lt;/code&gt; を検討すべきです。OpenAI公式ドキュメントの記述も非常に明確で、&lt;code&gt;Skill&lt;/code&gt; はワークフローそのものであり、真にインストールおよび配布に適した単位は &lt;code&gt;plugin&lt;/code&gt; です。&lt;/p&gt;
&lt;h2 id=&#34;スキルが適しているシナリオ&#34;&gt;スキルが適しているシナリオ
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Skill&lt;/code&gt; は多ければ良いというものではなく、以下の種類のタスクに最も適しています。&lt;/p&gt;
&lt;h3 id=&#34;高頻度で繰り返すタスク&#34;&gt;高頻度で繰り返すタスク
&lt;/h3&gt;&lt;p&gt;毎週行う、そして毎回手順がほぼ同じもの。
例えば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PRレビューコメントの処理&lt;/li&gt;
&lt;li&gt;ブログ記事の執筆とフロントマターの追記&lt;/li&gt;
&lt;li&gt;CI失敗の調査&lt;/li&gt;
&lt;li&gt;リリース前のチェック
このような作業は、モデルができないことよりも、毎回説明し直さなければならないことが一番面倒です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;固定フローのタスク&#34;&gt;固定フローのタスク
&lt;/h3&gt;&lt;p&gt;ある事柄には、生まれながらにして順序があるものがあります。
例えば問題の調査をする場合、まずログを確認し、次に範囲を絞り込み、それから計画を立て、そして修正するという流れになります。このような場面では、&lt;code&gt;Skill&lt;/code&gt; が特に適しています。なぜなら、順番を固定できるため、モデルがその場しのぎで対応するのを減らせるからです。&lt;/p&gt;
&lt;h3 id=&#34;専門的な文脈に紐づける必要があるタスク&#34;&gt;専門的な文脈に紐づける必要があるタスク
&lt;/h3&gt;&lt;p&gt;手順が固定されているだけでなく、強い制約を伴うタスクもあります。
例えば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公式ドキュメントのみを参照すること&lt;/li&gt;
&lt;li&gt;特定のレビュー形式で出力しなければならないこと&lt;/li&gt;
&lt;li&gt;チーム内の既存の用語を保持しなければならないこと&lt;/li&gt;
&lt;li&gt;特定のリポジトリの記述または開発規約を遵守しなければならないこと
このような作業は、毎回プロンプトに頼って一時的に指示を出すだけでは、漏れが生じやすいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ツールとプロセスを併用するタスク&#34;&gt;ツールとプロセスを併用するタスク
&lt;/h3&gt;&lt;p&gt;このシナリオは特に典型的なものです。
単に「GitHubに接続する」だけで終わるのではなく、接続した後も、何らかの方法でログを確認し、問題を分類し、修正が必要かどうかを判断し、最後にどのようにフィードバックするかという一連の作業が必要です。つまり、外部接続と内部プロセスが組み合わさって機能しなければなりません。
このような場合、しばしば &lt;code&gt;MCP + Skill&lt;/code&gt; が組み合わさって登場します。&lt;/p&gt;
&lt;h2 id=&#34;スキルとして実装する必要がないシナリオ&#34;&gt;スキルとして実装する必要がないシナリオ
&lt;/h2&gt;&lt;p&gt;逆に、どこまでを「スキル」とするのかを明確に伝える必要があります。そうしないと、何でもかんでも&lt;code&gt;Skill&lt;/code&gt;にしようとしてしまいがちです。&lt;/p&gt;
&lt;h3 id=&#34;一回限りの気軽なタスク&#34;&gt;一回限りの気軽なタスク
&lt;/h3&gt;&lt;p&gt;ユーザーが一時的に質問する場合、通常のプロンプトで十分なことが多いです。&lt;/p&gt;
&lt;h3 id=&#34;あなたが望んでいるのは外部システムへの接続だけだ&#34;&gt;あなたが望んでいるのは「外部システムへの接続」だけだ
&lt;/h3&gt;&lt;p&gt;その場合は、&lt;code&gt;Skill&lt;/code&gt; ではなく &lt;code&gt;MCP&lt;/code&gt; を優先的に検討してください。&lt;/p&gt;
&lt;h3 id=&#34;リポジトリ全体の長期的な振る舞いを制約したい場合&#34;&gt;リポジトリ全体の長期的な振る舞いを制約したい場合
&lt;/h3&gt;&lt;p&gt;これは &lt;code&gt;Skill&lt;/code&gt; の仕事というよりは、&lt;code&gt;AGENTS.md&lt;/code&gt; の仕事に近いです。
したがって、簡単にまとめると以下のようになります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;接続が不足している場合、&lt;code&gt;MCP&lt;/code&gt; を使う&lt;/li&gt;
&lt;li&gt;プロセスが不足している場合、&lt;code&gt;Skill&lt;/code&gt; を使う&lt;/li&gt;
&lt;li&gt;グローバルなルールが不足している場合、&lt;code&gt;AGENTS.md&lt;/code&gt; を使う&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;代表的な事例をいくつか&#34;&gt;代表的な事例をいくつか
&lt;/h2&gt;&lt;p&gt;概念をどれだけ説明しても、実際の事例を見る方が良いです。&lt;/p&gt;
&lt;h3 id=&#34;1-roll-dice最小限の入門ケース&#34;&gt;1. &lt;code&gt;roll-dice&lt;/code&gt;：最小限の入門ケース
&lt;/h3&gt;&lt;p&gt;このケースはOpenAI公式の&lt;code&gt;Agent Skills&lt;/code&gt;ドキュメントからのものです。
非常に小さく、ディレクトリ内にはほとんど&lt;code&gt;SKILL.md&lt;/code&gt;しかなく、エージェントがユーザーからサイコロを振るよう要求された際に、PowerShellの乱数コマンドを呼び出すようにします。
なぜこの例が良いのか？
それは&lt;code&gt;Skill&lt;/code&gt;の最も核となる骨格を直接示しているからです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明確なトリガー条件がある&lt;/li&gt;
&lt;li&gt;明確な実行方法がある&lt;/li&gt;
&lt;li&gt;明確な境界線がある
これは、&lt;code&gt;Skill&lt;/code&gt;が必ずしも大きくなくて良いことを示しています。あることが繰り返し発生し、モデルに無作為な振る舞いをさせたくない場合、それを&lt;code&gt;Skill&lt;/code&gt;として実装できるということです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-gh-address-commentsgithub-コメント処理のワークフロー例&#34;&gt;2. &lt;code&gt;gh-address-comments&lt;/code&gt;：GitHub コメント処理のワークフロー例
&lt;/h3&gt;&lt;p&gt;このケースは、OpenAI 公式の &lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;openai/skills&lt;/code&gt;&lt;/a&gt; リポジトリから来ました。
目的は「GitHubに接続する」ことではなく、「現在のブランチのPRのコメントを処理する」という一連のプロセスを固定化することです。公式バージョンでの手順が非常に典型的です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;まず&lt;code&gt;gh&lt;/code&gt;が認証済みか確認する&lt;/li&gt;
&lt;li&gt;次に、現在のPRのコメントとレビュースレッドを取得する&lt;/li&gt;
&lt;li&gt;これらのコメントに番号を振り、要約する&lt;/li&gt;
&lt;li&gt;ユーザーにどのコメントを処理するか明確に選択させる&lt;/li&gt;
&lt;li&gt;その後で初めて処理を開始する
この例は、&lt;code&gt;Skill&lt;/code&gt; の価値を特に示しています。
多くのエンジニアリングタスクにおいて、難しさは「モデルがGitHubとは何かを知っているか」という点ではなく、「正しい順序で物事を処理できるか」という点にあります。&lt;code&gt;gh-address-comments&lt;/code&gt; が解決しているのは、まさにこのような順序の問題です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3-gh-fix-cici-失敗のエンジニアリングケースの調査&#34;&gt;3. &lt;code&gt;gh-fix-ci&lt;/code&gt;：CI 失敗のエンジニアリングケースの調査
&lt;/h3&gt;&lt;p&gt;これも &lt;code&gt;openai/skills&lt;/code&gt; リポジトリ内の公式スキルです。
これは別の非常に典型的なエンジニアリングタスクを対象としています。それは、PR のチェックが失敗したとき、「直すべきか」「どう直すか」というものです。
この &lt;code&gt;Skill&lt;/code&gt; で定義されているワークフローも非常に代表的です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;まず &lt;code&gt;gh&lt;/code&gt; のログイン状態を確認する&lt;/li&gt;
&lt;li&gt;現在の PR を見つける&lt;/li&gt;
&lt;li&gt;GitHub Actions の失敗したチェックとログを取得する&lt;/li&gt;
&lt;li&gt;失敗した部分を抽出する&lt;/li&gt;
&lt;li&gt;まず修正計画を立てる&lt;/li&gt;
&lt;li&gt;承認を得てから実行する
これは、「CI がなぜ失敗したか見て」という単なるプロンプトでは安定して対応できないシナリオです。なぜなら、権限、ログ、外部ツール、承認の境界線、実行順序など、これらすべてを定義する必要があるからです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;4-リポジトリ固有のスキルチーム独自のノウハウを蓄積する&#34;&gt;4. リポジトリ固有のスキル：チーム独自のノウハウを蓄積する
&lt;/h3&gt;&lt;p&gt;公式なサンプル例以外で、私が考える &lt;code&gt;Skill&lt;/code&gt; のより大きな価値は、実はプライベートリポジトリ内にあります。
例えば、目の前のブログリポジトリにある &lt;code&gt;blog-writer&lt;/code&gt; は、本質的には非常に典型的な repo-scoped skill です。これは「モデルに中国語の書き方を学ばせる」ことを担当しているのではなく、このリポジトリで既に固定された文体、構造、ファクトチェック、出力パス、データ保存形式などをワークフローとして記述したものです。
このような &lt;code&gt;Skill&lt;/code&gt; は、最も現実的な価値を持つことが多いです。なぜなら、すべての人に向けられているわけではなく、「あなたはこのリポジトリで、どのような種類の作業が繰り返し発生し、かつ逸脱しやすいか」という点に特化して解決するものだからです。&lt;/p&gt;
&lt;h2 id=&#34;実際にskillを使うべき時&#34;&gt;実際に「Skill」を使うべき時
&lt;/h2&gt;&lt;p&gt;そこで、最後に最も実用的な問題に戻ります。いつ真剣に &lt;code&gt;Skill&lt;/code&gt; を作るべきでしょうか？
私の答えは以下の通りです。
それは、問題がもはや「モデルの能力不足」ではなく、「毎回同じ行動が安定しない」と感じたときです。
この段階でプロンプトを積み重ねても、得られる利益は通常低くなる一方です。今日一文追加し、明日また一文追加するうちに、プロンプトはまるで出来事の羅列になり、モデルはやはりミスを犯します。
むしろ、それを &lt;code&gt;Skill&lt;/code&gt; として整理し、トリガー条件、手順、境界線、スクリプト、資料などを分けて管理する方が、効果が安定しやすく、再利用性も高まります。
&lt;code&gt;MCP&lt;/code&gt; は外部世界と接続し、&lt;code&gt;Skill&lt;/code&gt; は内部のノウハウを固定化します。
前者は「できるかどうか」を解決し、後者は「どうすれば安定してできるか」を解決します。
これが私が今理解している &lt;code&gt;Skill&lt;/code&gt; です。
それは新しいプロンプトでも、新しいプロトコルでもありません。
むしろ、エージェントに職種マニュアルを渡すようなものです。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/codex/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Agent Skills - Codex | OpenAI Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developers.openai.com/blog/skills-agents-sdk&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Using skills to accelerate OSS maintenance | OpenAI Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://modelcontextprotocol.io/docs/getting-started/intro&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;What is the Model Context Protocol (MCP)? | Model Context Protocol&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/skills&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;openai/skills | GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/skills/blob/main/skills/.curated/gh-address-comments/SKILL.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gh-address-comments/SKILL.md | openai/skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/openai/skills/blob/main/skills/.curated/gh-fix-ci/SKILL.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;gh-fix-ci/SKILL.md | openai/skills&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;プロンプト：AI大規模言語モデルによるプログラミングについて、まずMCPが登場し、次にSkillが登場しました。平易な言葉で、Skillが何か、どのようにSkillを開発するか、どのようなシナリオに適しているか、それぞれ具体的な代表的な事例を挙げて説明してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングの骨子まとめ&#34;&gt;ライティングの骨子まとめ
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「&lt;code&gt;MCP&lt;/code&gt; と &lt;code&gt;Skill&lt;/code&gt; の概念レビュー」として繰り返し書くのではなく、重点を &lt;code&gt;Skill&lt;/code&gt; の役割と使用範囲に置いた。&lt;/li&gt;
&lt;li&gt;「職種マニュアル」「特定作業手順書（SOP）」といった平易な比喩を用いて、抽象的な定義を実際のワークフローに落とし込んだ。&lt;/li&gt;
&lt;li&gt;開発部分は公式ドキュメントの実構造に沿って記述し、&lt;code&gt;description&lt;/code&gt;、&lt;code&gt;progressive disclosure&lt;/code&gt;、&lt;code&gt;instruction-only&lt;/code&gt; といった重要な点を保持した。&lt;/li&gt;
&lt;li&gt;ケーススタディは可能な限り公式ソースを選定し、それぞれ公式ドキュメント内の &lt;code&gt;roll-dice&lt;/code&gt;、および &lt;code&gt;openai/skills&lt;/code&gt; リポジトリ内の &lt;code&gt;gh-address-comments&lt;/code&gt; と &lt;code&gt;gh-fix-ci&lt;/code&gt; を使用した。&lt;/li&gt;
&lt;li&gt;最後に、読者が読み終えた後も混同しないよう、&lt;code&gt;MCP&lt;/code&gt;、&lt;code&gt;Skill&lt;/code&gt;、&lt;code&gt;AGENTS.md&lt;/code&gt; の三者の境界線を改めて整理した。&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>弱いモデルに無理に強いものを適用しない</title>
        <link>https://ttf248.life/ja/p/weaker-models-shouldnt-do-frontier-work/</link>
        <pubDate>Thu, 02 Apr 2026 22:05:00 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/weaker-models-shouldnt-do-frontier-work/</guid>
        <description>&lt;p&gt;最近、いくつかの端的な作業を &lt;code&gt;MiniMax&lt;/code&gt; やローカルモデルに移行させているが、使うほど「最強モデル」という基準で物事を測るのは違うと感じるようになった。&lt;/p&gt;
&lt;p&gt;私の判断は非常にシンプルだ。弱いモデルに無理に難しいタスクを割り当ててはいけない。「MiniMax」のようなモデルは、能力が劣っているのは事実だが、複雑なコーディング、長尺の推論、曖昧な要件の分解といった作業には確かに物足りない。しかし、データクレンジング、ドキュメント作成、提案資料の検索といったタスクであれば、これらは十分にこなせる。同じロジックで、ローカルの12Bクラスのモデルも同様だ。翻訳、フォーマットの書き直し、バッチ処理でのクレンジングなど、むしろそちらが本来適している場所なのだ。&lt;/p&gt;
&lt;p&gt;端的に言えば、モデルに価値がないのではなく、単に間違った場所に配置されているだけだ。&lt;/p&gt;
&lt;h2 id=&#34;本当の問題はモデルがどれだけ強力かではなくどれだけ生きているかである&#34;&gt;本当の問題は、モデルがどれだけ強力かではなく、どれだけ「生きている」かである
&lt;/h2&gt;&lt;p&gt;多くの人が大規模言語モデルについて話すとき、頭の中では最も難しいタスクを思い浮かべがちです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;複雑なエンジニアリングを単独で書くこと&lt;/li&gt;
&lt;li&gt;システム全体を一度に分解すること&lt;/li&gt;
&lt;li&gt;長いコンテキスト内での複数ターンにわたる推論の処理&lt;/li&gt;
&lt;li&gt;検索しながら計画し、実行する
これらはもちろん重要です。しかし、現実の業務で机の上に積み重なっているものの多くは、このような作業ではありません。
むしろ多いのは以下の類です：&lt;/li&gt;
&lt;li&gt;一連の汚れたフィールドをクリーンアップすること&lt;/li&gt;
&lt;li&gt;ばらばらの資料を読みやすいドキュメントに整理すること&lt;/li&gt;
&lt;li&gt;長文を要約、FAQ、アウトラインに変更すること&lt;/li&gt;
&lt;li&gt;中文と英文が混在する内容を統一フォーマットにすること&lt;/li&gt;
&lt;li&gt;複数のウェブページから資料を探し出し、ついでに提案書の草稿としてまとめること
このようなタスクで最も必要なのは、「モデルが天才のように考える」ことではなく、以下の3点です：&lt;/li&gt;
&lt;li&gt;指示追従性が極端すぎないこと（常識的であること）&lt;/li&gt;
&lt;li&gt;出力構造が可能な限り安定していること&lt;/li&gt;
&lt;li&gt;コストが十分に低く、何度も使いたくなるほど低いこと
だからこそ、私は弱いモデルは役に立たないのではなく、単にフラッグシップモデルと同じ戦場に持ち出せないだけだと考えているのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;minimax-が真に得意なこと&#34;&gt;MiniMax が真に得意なこと
&lt;/h2&gt;&lt;p&gt;まず &lt;code&gt;MiniMax&lt;/code&gt; についてです。&lt;/p&gt;
&lt;p&gt;公式は &lt;code&gt;MiniMax-M2.5&lt;/code&gt; の位置づけを非常に高く設定しており、プレスリリースやオープンプラットフォームのドキュメントでは、プログラミング、ツール呼び出し、検索、オフィス生産性といったシナリオに重点を置いています。さらには速度と価格の優位性を強調しています。これらの主張を完全に信じられないわけではありませんが、私はそれを分解して見る方が好みです。&lt;/p&gt;
&lt;p&gt;私にとって、&lt;code&gt;MiniMax&lt;/code&gt; が真に使いやすいのは、「最も複雑な開発タスク」ではなく、以下の点です：&lt;/p&gt;
&lt;h3 id=&#34;データクレンジング&#34;&gt;データクレンジング
&lt;/h3&gt;&lt;p&gt;データクレンジングと一口に言っても、半構造化テキストの肉体労働です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;名称の統一&lt;/li&gt;
&lt;li&gt;フィールドのマッピング&lt;/li&gt;
&lt;li&gt;外れ値のアノテーション&lt;/li&gt;
&lt;li&gt;分類ラベル付け&lt;/li&gt;
&lt;li&gt;表形式フィールドの補完
このような作業が最も恐れるのは、モデルが「愚か」なことではなく、フォーマットが不安定であったり、出力が拡散したりすることです。モデルが &lt;code&gt;JSON&lt;/code&gt;、表、固定テンプレートに従って結果を出力できれば、実は十分な場合が多いです。高性能なモデルももちろん可能ですが、最も高価なモデルをフィールドクレンジングに使うのは、多くの場合費用対効果が悪いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ドキュメント作成&#34;&gt;ドキュメント作成
&lt;/h3&gt;&lt;p&gt;ドキュメント作成は面倒くさい、難しいわけではない。
インターフェースが変わる、プロセスが変わる、フィールドが変更される、といったたびに説明書を修正しなければならない。この過程には、モデルに高い創造性が求められるというよりは、むしろ余計なことをして元の明確な情報を曖昧にしてしまわないように注意することが重要だ。
&lt;code&gt;MiniMax&lt;/code&gt; はこのような作業において、想像以上に信頼できることが多い。特にコンテキスト（文脈）を準備しておけば、真のエンジニアというよりも、実務ができるドキュメントアシスタントのような存在になる。&lt;/p&gt;
&lt;h3 id=&#34;方案資料検索&#34;&gt;方案資料検索
&lt;/h3&gt;&lt;p&gt;公式側も検索やツール呼び出しを推進しているので、この方向性は問題ありません。
多くの場合、私たちが求めているのはモデルに「空から答えを思いつかせる」ことではなく、ウェブページ、ドキュメント、お知らせ、資料などをまず探し出してきて、それから整理してもらうことです。このようなシナリオでは、&lt;code&gt;MiniMax&lt;/code&gt; のような安価なモデルの価値が非常に高くなります。なぜなら、検索、要約、統合といった作業は元々頻繁に行う雑務だからです。
したがって、私の実際の見解は以下の通りです：&lt;code&gt;MiniMax&lt;/code&gt; がダメなのではなく、むしろ生産パイプラインの中での「汚い仕事」「面倒な仕事」「繰り返しの仕事」に向いているということです。雑用をさせるなら、合格点であることが多いですが、すべてを包括的に担当させようとすると、がっかりする確率が高くなります。&lt;/p&gt;
&lt;h2 id=&#34;ローカルの12bモデルは持ち帰るのに最も適したタスクがある&#34;&gt;ローカルの12Bモデルは、持ち帰るのに最も適したタスクがある
&lt;/h2&gt;&lt;p&gt;さらに下を見ると、ローカルデプロイメントは基本的に同じロジックです。
多くの人が「ローカルモデル」と言うと、どうしても一つの疑問が浮かびます。「クラウド上のフラッグシップに取って代われるのか？」と。
しかし、この質問自体が最初から偏っていると思います。
ローカルの&lt;code&gt;12B&lt;/code&gt;程度のモデルが持つ真の価値は、「自分も最強クラスのタスクをこなせることを証明する」ことではなく、安定していて、反復的で、機密性が高く、利益率は低いが頻度の高い作業を持ち帰ることなのです。&lt;/p&gt;
&lt;h3 id=&#34;翻訳&#34;&gt;翻訳
&lt;/h3&gt;&lt;p&gt;これはローカルモデルにとって得意なシナリオの一つです。
&lt;code&gt;Qwen2.5&lt;/code&gt; の公式ブログでも明記されているように、長文生成、構造化データ理解、&lt;code&gt;JSON&lt;/code&gt; 出力などが強化されており、さらに29以上の言語をサポートしています。この組み合わせは、翻訳、バイリンガルでの書き直し、フォーマットの統一、専門用語の標準化といった作業に本質的に適しています。
技術ドキュメント、フィールドの説明、製品紹介、インターフェースコメントなどは、構造が安定しており、専門用語が固定されていることが多いため、ローカルモデルが最もエレガントに翻訳できるとは限りませんが、通常は十分な品質です。&lt;/p&gt;
&lt;h3 id=&#34;データクレンジング-1&#34;&gt;データクレンジング
&lt;/h3&gt;&lt;p&gt;ここがローカルモデルが特に現実味を帯びている点です。
多くの表、ドキュメント、業務資料は、クラウドにアップロードしたくないものがあります。特に内部データ、顧客情報、議事録、未完成の提案書などは、プライバシーや権限が関わるため、ローカルで実行する方がずっと安心できます。
このような状況において、ローカルの「12B」程度のモデルの意義は、「どれだけ賢いか」ではなく、「自分のマシン上で動作し、こうした面倒な作業を安定してこなせるか」という点にあります。&lt;/p&gt;
&lt;h3 id=&#34;固定フォーマットへの書き換え&#34;&gt;固定フォーマットへの書き換え
&lt;/h3&gt;&lt;p&gt;例えば：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;会議議事録を固定テンプレートに整理する&lt;/li&gt;
&lt;li&gt;商品タイトルを統一の命名規則にクレンジングする&lt;/li&gt;
&lt;li&gt;バグの説明を工單形式に書き直す&lt;/li&gt;
&lt;li&gt;中英が混在したテキストを単語バージョンにクレンジングする
このようなタスクは共通の特徴を持っています：ルールが明確、バッチ処理が大きい、繰り返しが多い、単発あたりの価値は高くないが、総量が多いのが面倒。
これこそがローカルモデルが最も適している仕事です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;3060-12gb-で-12b-クラスのモデルを動かせるのか&#34;&gt;3060 12GB で 12B クラスのモデルを動かせるのか
&lt;/h2&gt;&lt;p&gt;この件については、もっと現実的に書く方が良いと思います。「&lt;strong&gt;動かすことはできるが、あまり期待しすぎないでください。&lt;/strong&gt;」という感じです。&lt;/p&gt;
&lt;p&gt;Google は &lt;code&gt;Gemma 3&lt;/code&gt; の公式ドキュメントで、非常に参考になるVRAM使用量の表を公開しています。&lt;code&gt;Gemma 3 12B&lt;/code&gt; を動かすには、おおよそ以下のメモリが必要です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全精度バージョンをロードする場合：約 &lt;strong&gt;20 GB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;中程度の量子化バージョンをロードする場合：約 &lt;strong&gt;12.2 GB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;より低いVRAM使用量のバージョンをロードする場合：約 &lt;strong&gt;8.7 GB&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;公式はまた、これがモデルのロードに必要なメモリ量のみであり、プロンプトや実行時の追加オーバーヘッドは含まれていないと注意喚起しています。&lt;/p&gt;
&lt;p&gt;この一文が非常に重要です。&lt;/p&gt;
&lt;p&gt;これはどういう意味か？
&lt;code&gt;3060 12GB&lt;/code&gt; のようなグラボで &lt;code&gt;12B&lt;/code&gt; クラスのモデルを動かすことが不可能だということではなく、&lt;strong&gt;前提条件がある&lt;/strong&gt;ということです。その前提とは通常以下の通りです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;量子化されたバージョンを使用していること&lt;/li&gt;
&lt;li&gt;コンテキスト（プロンプト）を長すぎないようにすること&lt;/li&gt;
&lt;li&gt;タスクが複雑すぎないこと&lt;/li&gt;
&lt;li&gt;速度が平均的、あるいは遅くても許容できること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;もしあなたがこれらの前提を受け入れる意思があるなら、ローカルで &lt;code&gt;12B&lt;/code&gt; クラスのモデルを動かすことは確かに可能です。少なくとも翻訳、要約、表のクレンジング、固定フォーマットへの変換といったタスクであれば、大げさな要求ではありません。&lt;/p&gt;
&lt;p&gt;また、&lt;code&gt;Qwen2.5-14B-Instruct-GGUF&lt;/code&gt; の公式リポジトリ自体が複数の量子化形式を提供しており、これはすでに考え方を非常に明確に示しています。このクラスのモデルは、本来ローカル推論のエコシステムを念頭に置いて適応されているのです。&lt;/p&gt;
&lt;p&gt;したがって、私の結論は一貫して「3060 12GB が 12B モデルを楽々こなせる」というものではなく、むしろ：
**「このようなモデルを動かすことはできるが、期待値が低く、反復性が高く、プライバシーが重要な作業に向いている」**ということです。&lt;/p&gt;
&lt;h2 id=&#34;安価なモデルとローカルモデルを使うことで節約できるのはapi費用だけではない&#34;&gt;安価なモデルとローカルモデルを使うことで節約できるのはAPI費用だけではない
&lt;/h2&gt;&lt;p&gt;この件について話している人の多くは、まず「お金を節約できる」という反応をします。
もちろん、お金の節約は重要です。しかし、私が思うより大きな価値は、以前は面倒だと避けていた雑務を、思い切って外部に委託できるようになることです。
以前なら、数百件のデータクレンジングのために専用のスクリプトを書くことはなかったかもしれませんし、数十ページの日英資料のフォーマット統一のために手作業で少しずつ修正することもなかったでしょう。また、一時的な提案書のために資料を集める際も、ウェブページを一つ一つ読み込んで整理することさえなかったはずです。
しかし、今は違います。
コストが十分に低く、ハードルが十分に低い限り、「やる価値がない」と思われていたこれらの作業が一気に「やる価値がある」ものになります。あなたは「やるべきか？」と悩むのではなく、まず安価なモデルやローカルモデルに実行させるだけです。
これが私が目にする最も現実的な変化です。
強力なモデルは難題に取り組むことに専念し、弱いモデルは雑務をこなし、ローカルモデルが最終的な保証とバッチ処理を担当する。
このように役割分担することで、ワークフロー全体がスムーズになるのです。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ
&lt;/h2&gt;&lt;p&gt;だから最後に言いたいのは、一つのモデルで全てを解決しようと考えすぎるなということです。
&lt;code&gt;MiniMax&lt;/code&gt; のようなモデルは、能力が弱いという点はあるものの、使い物になりません。これを複雑なエンジニアリング、曖昧な要件定義、多段階の推論にぶつけても、当然ながらがっかりさせられるでしょう。しかし、データクレンジング、ドキュメント作成、ソリューション資料の検索といった作業に使えば、かえって非常に扱いやすいことが多いです。
ローカルで動作する &lt;code&gt;12B&lt;/code&gt; 程度のモデルも同じです。これらは「もうクラウド上のフラッグシップは必要ない」と証明するためではなく、安定していて、反復的で、機密性が高く、バッチ処理の大きいタスクを、地道に自分自身のマシン上に持ち帰るためにあるのです。
つまり、苦手なことを弱いモデルにやらせてはいけないということです。
適切な場所（用途）に置けば、それ自体が現実的な価値を持つわけです。&lt;/p&gt;
&lt;h2 id=&#34;参考資料&#34;&gt;参考資料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.minimax.io/news/minimax-m25&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MiniMax M2.5: Built for Real-World Productivity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://platform.minimaxi.com/docs/guides/text-generation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MiniMax オープンプラットフォーム：テキスト生成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://qwenlm.github.io/blog/qwen2.5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Qwen2.5: A Party of Foundation Models!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://huggingface.co/Qwen/Qwen2.5-14B-Instruct-GGUF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Qwen2.5-14B-Instruct-GGUF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://ai.google.dev/gemma/docs/core&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Gemma 3 model overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;作成上の注記&#34;&gt;作成上の注記
&lt;/h2&gt;&lt;h3 id=&#34;元のプロンプト&#34;&gt;元のプロンプト
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;minimax の大規模言語モデルは、能力が弱いのは弱いが、データクレンジング作業やドキュメント作成、提案資料の検索などを行う分には問題ない。同じロジックで、ローカルに大規模言語モデルをデプロイし、翻訳などの作業やデータクレンジング作業を行うのも良い。モデルのパラメータ数は12b程度で、ローカルの3060 12GBのグラフィックボードでも動かせるはずだ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;ライティングの思考プロセス要約&#34;&gt;ライティングの思考プロセス要約
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;「弱いモデルに無理なタスクを割り当てない」という核となる判断は維持し、モデルランキング比較としては記述しませんでした。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MiniMax&lt;/code&gt; の部分は、公式が定義するプログラミング、検索、オフィス作業といった用途に基づき、その判断をデータクレンジング、ドキュメント作成、資料検索といった現実的なタスクに落とし込みました。&lt;/li&gt;
&lt;li&gt;ローカルモデルの部分では、公式ソースから &lt;code&gt;Qwen2.5&lt;/code&gt; と &lt;code&gt;Gemma 3&lt;/code&gt; の2つを選択しました。一方は多言語対応と構造化出力をサポートし、もう一方は &lt;code&gt;12B&lt;/code&gt; パラメータとVRAM使用量を考慮したものです。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;3060 12GB&lt;/code&gt; に関する記述は、「帯域幅はあるが、あまり期待しすぎないでほしい」というニュアンスを意図的に含め、量子化推論を絶対的な結論として扱わないようにしました。&lt;/li&gt;
&lt;li&gt;最後に、強力なモデル、弱いモデル、ローカルモデルという分類を用いて締めくくり、メインの論旨に焦点を絞りました。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>低価格API中継地点の終着点：3月の大規模言語モデル体験と不可能性の三角形</title>
        <link>https://ttf248.life/ja/p/the-end-of-low-cost-api-relays/</link>
        <pubDate>Mon, 30 Mar 2026 20:00:00 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/the-end-of-low-cost-api-relays/</guid>
        <description>&lt;p&gt;3月を通して、私は様々な大規模言語モデル（LLM）APIのトランジットポイント間を行き来して試していました。&lt;/p&gt;
&lt;p&gt;安さについては、確かに安いものでした。月にあまりお金をかけずに、ChatGPT、Claude、Geminiといった海外のモデルをすべて触ることができ、表面上は非常にコストパフォーマンスの高い解決策を見つけたように思えました。しかし、実際に使ってみるうちに、この道筋が最初から「&lt;strong&gt;品質、安定性、費用対効果&lt;/strong&gt;」という不可能な三角形から逃れられないと感じるようになりました。これら三つが同時に成立するのは難しいのです。&lt;/p&gt;
&lt;p&gt;先週末には、この件はほぼ白日の下に晒されました。2026年3月28日から2026年3月29日までの二日間で、ChatGPT関連のチャネルの風控（リスク管理）が明らかに厳しくなり、Claudeも同様でした。以前はなんとか使えていた低価格なトランジットサービスも突然不安定になったり、完全に機能しなくなったりしました。私にとっては、これは低価格APIトランジットモデルの段階的な終焉を告げるものとなりました。&lt;/p&gt;
&lt;h2 id=&#34;中継ステーションとは何か&#34;&gt;中継ステーションとは何か
&lt;/h2&gt;&lt;p&gt;まず概念を明確にしましょう。
いわゆる&lt;strong&gt;API中継ステーション&lt;/strong&gt;は、本質的にモデルベンダーが公式に提供するサービスではなく、ユーザーと上流のモデルの間にある「転送層」のようなものです。リクエストを中継ステーションに送り、中継ステーションが代わりにOpenAIやAnthropicなどの他のモデルサービスプロバイダーにリクエストを転送し、最後に結果をあなたに返します。
ユーザーの視点から見ると、それはより安価で、より「柔軟な」統一のエントリーポイントのようです。技術的およびビジネスモデルの観点からは、上流のリソースを再パッケージ化し、再配布しているようなものです。
このようなサービスがこれまで利用され続けている理由は非常にシンプルです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;価格が安い&lt;/li&gt;
&lt;li&gt;利用開始のハードルが低い&lt;/li&gt;
&lt;li&gt;モデルの種類が多い&lt;/li&gt;
&lt;li&gt;国内ユーザーにとって、登録、支払い、ネットワーク環境に関する手間を省ける
しかし、問題もまさにこの点にあります。これは公式な経路ではないため、多くの利便性は、安定したライセンスに基づいているのではなく、「余分な層を追加している」ことに本質的に基づいています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;彼らは通常どのように機能しますか&#34;&gt;彼らは通常どのように機能しますか
&lt;/h2&gt;&lt;p&gt;プラットフォームによってアプローチは異なりますが、一般的なパターンはいくつかの種類に大別されます。&lt;/p&gt;
&lt;h3 id=&#34;1-主要な二次ディストリビューション再販&#34;&gt;1. 主要な二次ディストリビューション（再販）
&lt;/h3&gt;&lt;p&gt;一部のプラットフォームは、本質的に自社のアップストリームAPIキーを統一して転送し、そのクレジットをダウンストリームユーザーに分割して提供しています。購入しているのは、OpenAIやAnthropicが直接販売するプランではなく、彼らが提供する一層目のパッケージです。
このモデルの問題点は、アップストリームのキーが制限されたり、クレジットが上限に達したり、ポリシーが調整されたりすると、ダウンストリームでの体験が即座に不安定になることです。&lt;/p&gt;
&lt;h3 id=&#34;2-アカウントプールのローテーション&#34;&gt;2. アカウントプールのローテーション
&lt;/h3&gt;&lt;p&gt;業界でよく使われる「&lt;strong&gt;号池&lt;/strong&gt;」とは、アカウントリソースをプール化して管理することを指します。プラットフォームが複数のアカウントを集約し、リクエストに応じて順番に呼び出すことで、クォータ（割り当て枠）の負荷や不正検知のリスクを分散させます。
ここでの「号池」は、モデルベンダーの公式な専門用語ではなく、より俗語的で裏話的な表現です。これは製品の機能性そのものよりも、リソースのスケジューリング方法に重点を置いています。どのプールの規模が大きいかによって、短期的に安定しているように見えますが、上流側から一斉にクリーンアップ（監視・制限）が始まると、この安定性はあっという間に失われることがあります。&lt;/p&gt;
&lt;h3 id=&#34;3-リバースエンジニアリングによるラッパー化逆アセンブル&#34;&gt;3. リバースエンジニアリングによるラッパー化（逆アセンブル）
&lt;/h3&gt;&lt;p&gt;もう一つの手法として、本質的には公開されている標準の公式APIを利用するのではなく、ウェブページやクライアント側のリクエスト方法を調査し、その呼び出しプロセスを「あたかもAPIであるかのように」再構築してユーザーに提供する方法があります。
この「&lt;strong&gt;リバース（逆行）&lt;/strong&gt;」という言葉は、簡単に言えば、公式が用意した入り口から入るのではなく、裏口や窓、さらにはパイプラインなどからシステム間の通信方法を理解し、自分自身でラッパー層を設けるということです。
この手法の弱点も非常に明白です。今日使えるからといって、明日も使えるとは限りません。ページの構造、認証方式、デバイス検証、行動ポリシーなどが少し変わるだけで、エンドツーエンドの処理全体が機能しなくなる可能性があります。&lt;/p&gt;
&lt;h2 id=&#34;3月の実体験について&#34;&gt;3月の実体験について
&lt;/h2&gt;&lt;p&gt;この3月度の集中的な体験を経て、私が最も感じたのは「安いから良い」という感覚ではなく、「不確実性を継続的に我慢しなければならない」ということです。&lt;/p&gt;
&lt;p&gt;同じ要求であっても、今日のある中継地点（プロバイダー）ではうまく答えられるのに、明日になると知能が落ち始めることがあります。午前中は安定して出力できるのに、夜になるとエラーが出たり、タイムアウトしたり、コンテキストが失われたりします。自分がモデルの能力を買っていると思いがちですが、実際には多くの場面で絶えず変動する「確率的なサービス」を購入しているにすぎません。&lt;/p&gt;
&lt;p&gt;一時的にモデルを試したり、軽い質疑応答を行うだけであれば、この変動は我慢できます。しかし、それを実際のワークフローに組み込むと、問題が非常に明白になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;品質が不安定で、出力レベルが高低差がある&lt;/li&gt;
&lt;li&gt;安定性に欠け、タイムアウトやエラー、途切れが発生しやすい&lt;/li&gt;
&lt;li&gt;コンテキストの連続性が低く、長時間のタスクでの体験が悪い&lt;/li&gt;
&lt;li&gt;プラットフォームを上流（プロバイダー）に切り替えると、モデルの個性やスタイルが漂流する&lt;/li&gt;
&lt;li&gt;同じ時間を費やして問題を調査しても、目に見えないコストは低いわけではない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、安価な中継地点の最大の問題点は、「安くない」ということではなく、本来公式プラットフォームが負うべき「確実性」を、ユーザー自身に再転嫁させている点です。&lt;/p&gt;
&lt;p&gt;表面上は費用を節約しているように見えますが、実際には時間、精神力、そしてワークフローの予測可能性というコストを多く払っているのです。&lt;/p&gt;
&lt;h2 id=&#34;なぜ私はそれが不可能性の三角形に入り込むと言ったのか&#34;&gt;なぜ私はそれが不可能性の三角形に入り込むと言ったのか
&lt;/h2&gt;&lt;p&gt;最近繰り返し使ってみて、このような中継サービスは必然的に「不可能性の三角形」に陥ると感じています。&lt;/p&gt;
&lt;h3 id=&#34;品質&#34;&gt;品質
&lt;/h3&gt;&lt;p&gt;品質を高く保つためには、実際に利用可能なアップストリームモデルの確保、十分なクレジット枠の確保、そしてできるだけ少ないサンプリングやダウングレードが不可欠です。このこと自体が安くはありません。&lt;/p&gt;
&lt;h3 id=&#34;安定性&#34;&gt;安定性
&lt;/h3&gt;&lt;p&gt;安定性を高めるためには、より多くのリスク管理、アカウントの損失、ネットワークの変動、レート制限、バックアップ回線などを処理する必要があり、さらにはより複雑なスケジューリングやフォールバック機構を自前で構築する必要があります。これらはすべてコストになります。&lt;/p&gt;
&lt;h3 id=&#34;お得な価格設定について&#34;&gt;お得な価格設定について
&lt;/h3&gt;&lt;p&gt;最初の2つのことをしっかりと固めれば、価格をこれ以上低く抑え続けることは不可能になります。長期にわたって超低価格を維持できる場合、それはコストが真に解決されていないだけであり、単に先送りされたか、あるいは将来の何らかの集団的な失敗に分散されていることを示していることがよくあります。
そのため、多くの仲介業者は「高い費用対効果」を実現しているように見えますが、実際には脆い均衡を保っているだけであることが多いです。平穏な時には成立しますが、上流側のリスク管理が厳しくなると、この均衡は容易に崩壊します。&lt;/p&gt;
&lt;h2 id=&#34;先週末はほぼ明牌だった&#34;&gt;先週末は、ほぼ明牌だった
&lt;/h2&gt;&lt;p&gt;私に「もうこれ以上深入りするのはやめよう」と決意させたのは、&lt;code&gt;2026-03-28&lt;/code&gt; から &lt;code&gt;2026-03-29&lt;/code&gt; のこのローテーションでした。&lt;/p&gt;
&lt;p&gt;私自身の体感では、ChatGPT関連のチャネルがその二日間で非常に顕著な集中絞り込みを見せ、Claude側のリスク管理も同時に強化されていました。以前は、回線を変えたり、モデルを変えたり、プランを変えたりすることで「なんとか使える」状態を保つことができましたが、それが突然通用しなくなりました。&lt;/p&gt;
&lt;p&gt;ここでは、「業界全体が完全に死んだ」といった断定的な表現は避けたいと思っています。結局のところ、自分たちにはまだ別のチャネルがあると言う人は必ずいるからです。しかし、一般ユーザーの実用価値という観点から見ると、低価格なAPI中継ルートというのは、少なくとも私がこれ以上時間を費やす価値はないと感じています。&lt;/p&gt;
&lt;p&gt;「安い」ということは、「タスクを安定して完了できる」という前提があって初めて意味を持ちます。基本的な信頼性すら維持できなくなれば、安さというのは単なる錯覚になってしまいます。&lt;/p&gt;
&lt;h2 id=&#34;なぜこのパターンは元々脆弱なのか&#34;&gt;なぜこのパターンは元々脆弱なのか
&lt;/h2&gt;&lt;p&gt;表面だけを見ると、メーカーが「意図的に利用を制限している」ように感じられるかもしれません。しかし、深く考えてみると、実はこうしたパターン自体が非常に脆い土台の上に成り立っているのです。&lt;/p&gt;
&lt;p&gt;OpenAIやAnthropicといった企業は、そもそも「二次的なグレーな再販」というロジックで製品を設計したわけではありません。公式の利用規約には、APIキーの売買・譲渡、制限の回避、リバースエンジニアリング、保護措置の迂回などについて、明確な制限が設けられています。OpenAIのサービス規約では、「APIキーの売買または譲渡」「レート制限や保護措置の回避」「使用制限の回避」を禁止行為として明記していますし、Anthropicの商用利用規約も、違反利用、不正アクセス、サービス乱用に対する制約空間を明確に留保しています。&lt;/p&gt;
&lt;p&gt;言い換えれば、これらの仲介業者は、公式が推奨するエコシステムの中でイノベーションを起こしているのではなく、公式なガバナンスの隙間を縫って生き延びようとしているだけです。モデル提供元が真剣に清掃（対策）を始めた場合、このパターンは自然と最初に打撃を受ける運命にあります。&lt;/p&gt;
&lt;p&gt;さらに、非常に現実的な背景があります。多くの海外のモデルサービスには、もともと地域、支払い、アカウントシステム上の障壁が存在します。公式がサポートする地域が限られているため、多くのユーザーが門前払いとなり、それが仲介（中継）需要を生み出しています。しかし、需要があるからといって、そのパターンが盤石であるとは限りません。それは単に、「グレーな代替案」に市場があることを示しているだけであり、長期的な確実性を持っているわけではないのです。&lt;/p&gt;
&lt;h2 id=&#34;最終的な結論&#34;&gt;最終的な結論
&lt;/h2&gt;&lt;p&gt;色々試した結果、今の私の結論はかえってシンプルになりました。
&lt;code&gt;codex&lt;/code&gt; の方がコストパフォーマンスが高いと感じています。少なくとも私自身の使用経験からすると、本番環境に導入する用途にはこちらの方が適しています。国内で大規模なアカウント停止のフィードバックをあまり聞かないこと、そして全体的な心理的負担も低い点も理由の一つです。
もちろん、&lt;code&gt;codex&lt;/code&gt; に制約がないわけではありません。5時間の制限や週ごとの制限は存在しますし、今使うときには、以前のように無計画に何でも質問したり、すべてを任せきりにしたりすることはなくなりました。多くの問題については、まず頭の中で一度シミュレーションしたり、自分で分解してから、今回のクレジットを使うかどうかを判断するようになりました。
こう考えると、制限というのは必ずしも悪いことばかりではありません。客観的に見て、人間に再び思考プロセスに参加することを強制し、問題を整理させ、判断させ、取捨選択させることを強いるためであり、すべての思考を外部に丸投げすることを防いでくれます。以前も書きましたが、モデルが少し「賢くない」ことは、必ずしも悪いことではなく、むしろ利用者に基本的な思考強度を維持するよう促してくれるからです。今振り返ってみても、この判断は依然として正しいと思います。
&lt;code&gt;Claude&lt;/code&gt; は現時点では考慮していません。能力が低いわけではありません。それどころか、非常に強力です。しかし、個人での正規購入であってもアカウント停止の不確実性が残っている以上、今の段階でメインのソリューションとするには適さないと考えています。
国内のモデルについては、引き続き様子を見ることにします。まだ長期的に深くコミットできる段階ではないからです。
そのため、結局は非常に素朴な選択に戻りました。&lt;code&gt;ChatGPT Plus&lt;/code&gt; を購入し、とりあえず使いながら、大規模言語モデル業界が今後どのように進化していくのかを見守る、という形です。多くの場面で、一番安いプランが必ずしも一番お金がかからないわけではなく、一番気が楽な（ストレスの少ない）プランこそが真のコストパフォーマンスを秘めているのです。&lt;/p&gt;
&lt;h2 id=&#34;参考リンク&#34;&gt;参考リンク
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;OpenAI 対応地域：&lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/5347006-which-countries-and-territories-are-supported-by-openai&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/5347006-which-countries-and-territories-are-supported-by-openai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI サービス規約：&lt;a class=&#34;link&#34; href=&#34;https://openai.com/policies/services-agreement/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://openai.com/policies/services-agreement/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic 商用利用規約：&lt;a class=&#34;link&#34; href=&#34;https://www.anthropic.com/legal/commercial-terms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.anthropic.com/legal/commercial-terms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
        </item>
        <item>
        <title>深層解析：C&#43;&#43; における `static lambda` が引き起こすメモリリークとキャッシュ汚染</title>
        <link>https://ttf248.life/ja/p/deep-dive-into-memory-corruption-and-cache-pollution-caused-by-static-lambdas-in-c/</link>
        <pubDate>Mon, 16 Mar 2026 20:18:18 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/deep-dive-into-memory-corruption-and-cache-pollution-caused-by-static-lambdas-in-c/</guid>
        <description>&lt;p&gt;本記事では、C++開発における &lt;code&gt;unordered_map::find&lt;/code&gt; がヒットした後にオブジェクトフィールドが一致しないという奇妙な現象を分析しています。原因は、関数内部で &lt;code&gt;static lambda&lt;/code&gt; を定義し、参照キャプチャによってローカル変数を捕捉することです。これにより、最初の呼び出し後には幽霊参照が発生し、その後の呼び出しで未定義動作（UB）を引き起こし、キャッシュデータを汚染します。この問題を解決するには、明示的なパラメータの渡しを介して暗黙のキャプチャを置き換え、ライフサイクルの管理を標準化し、Sanitizerツールを使用することを推奨します。&lt;/p&gt;
&lt;p&gt;高性能な行情サービスや分散型キャッシュを構築する際に、プログラマーはしばしば「異変」に遭遇します。それは、Keyを使用して &lt;code&gt;std::unordered_map&lt;/code&gt; からオブジェクトを明確に見つけ出すにもかかわらず、その内部フィールドを読み取ると、別のKeyのデータになっているという現象です。この「身分誤認」は、隠れたC++の罠を指しています：**static lambdaとライフサイクルキャプチャの競合による未定義動作（UB）**です。&lt;/p&gt;
&lt;h2 id=&#34;故障パターン長久保存の短寿命引用&#34;&gt;故障パターン：「長久保存」の短寿命引用
&lt;/h2&gt;&lt;p&gt;パフォーマンスを最適化する際、一部の開発者は関数内で &lt;code&gt;static lambda&lt;/code&gt; を定義してクロージャー作成のオーバーヘッドを削減することがあります。しかし、暗黙的なキャプチャによる参照捕獲 &lt;code&gt;[&amp;amp;]&lt;/code&gt; と組み合わせると、爆発的な問題が発生します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;UpdateCache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unordered_map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;std&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// 危険：static は lambda のライフサイクルをプロセスレベルまで延長する
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;// [&amp;amp;] はスタック上のローカル参照 current_input をキャプチャする
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;static&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;patch_func&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 2回目実行時、この参照は無効になっている
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;symbol&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;it&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;patch_func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;技術原理の剖析&#34;&gt;技術原理の剖析
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ライフサイクルズのずれ&lt;/strong&gt;: &lt;code&gt;static&lt;/code&gt; 変数はプログラムがその行に到達した際に初期化され、プロセス全体で一度だけ実行されます。つまり、&lt;code&gt;patch_func&lt;/code&gt; 内でキャプチャされた &lt;code&gt;current_input&lt;/code&gt; の参照は、&lt;strong&gt;最初の呼び出し時に&lt;/strong&gt;スタックフレーム上のメモリのアドレスに固定されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;幽霊参照 (Dangling Reference)&lt;/strong&gt;: 最初の &lt;code&gt;UpdateCache&lt;/code&gt; が完了すると、元のスタックフレームが破棄されます。その結果、&lt;code&gt;patch_func&lt;/code&gt; はすでに無効になったアドレスを読み書きしようとします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隠れたメモリ汚染&lt;/strong&gt;: スタック空間は繰り返し使用されるため、そのアドレスには新しいビジネスデータが格納されている可能性があります。この場合、データを書き込むことで、現在の Key の Value を更新しているように見えますが、実際には「ランダム」なメモリ領域で不正な書き込み操作が行われています。これが、&lt;code&gt;find&lt;/code&gt; の Key が A であり、読み取った Value フィールドが B である理由を説明しています。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;ソリューションとエンジニアリングプラクティス&#34;&gt;ソリューションとエンジニアリングプラクティス
&lt;/h2&gt;&lt;h3 id=&#34;1-隐式捕获消除改用显式参数传递&#34;&gt;1. 隐式捕获消除，改用显式参数传递
&lt;/h3&gt;&lt;p&gt;最稳妥的方法是让 Lambda 保持“无状态”（Stateless），将所有依赖的对象通过参数传递。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-cpp&#34; data-lang=&#34;cpp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 推荐做法：无状态 lambda，显式传递 src
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;patch&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;](&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;auto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Tick&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;second&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;price&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;patch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-静的修飾閉包の慎重な使用&#34;&gt;2. 静的修飾閉包の慎重な使用
&lt;/h3&gt;&lt;p&gt;関数内部で、閉包がローカル変数をキャプチャしていない限り、&lt;code&gt;static&lt;/code&gt; を使用しない方が良いです。現代のコンパイラは非 &lt;code&gt;static&lt;/code&gt; lambda の最適化に非常に優れており、盲目的に &lt;code&gt;static&lt;/code&gt; を使用しても得られるパフォーマンス向上はほとんど無視できる程度でありながら、大きな安全リスクをもたらします。&lt;/p&gt;
&lt;h3 id=&#34;3-強化学制と動的検出&#34;&gt;3. 強化学制と動的検出
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主張チェック&lt;/strong&gt;: 更新ロジック後に、&lt;code&gt;assert(it-&amp;gt;first == it-&amp;gt;second.symbol)&lt;/code&gt;を追加し、開発段階で「同一性不一致」の問題を捕捉します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ツール支援&lt;/strong&gt;: テスト環境で &lt;code&gt;ASan&lt;/code&gt; (AddressSanitizer) と &lt;code&gt;UBSan&lt;/code&gt; (UndefinedBehaviorSanitizer) を有効にします。これらのツールは、無効なスタックメモリへのアクセスを正確に検出し、直ちにエラーを報告します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論
&lt;/h2&gt;&lt;p&gt;C++ における「テーブル参照エラー」はしばしば表象に過ぎず、その裏にある真相はメモリ管理契約の違反である。&lt;strong&gt;キー検索が正しくても、値が信頼できるとは限らない&lt;/strong&gt;。特に、静的変数、グローバル変数、長寿命なコールバック関数などの長寿命オブジェクトを扱う際には、それらが捕捉している参照がスタックフレームの破棄によって失われていないか常に注意する必要がある。&lt;/p&gt;</description>
        </item>
        <item>
        <title>wrk と JMeter の負荷テスト (または パフォーマンス測定)</title>
        <link>https://ttf248.life/ja/p/wrk-vs-jmeter-deep-benchmarking/</link>
        <pubDate>Fri, 19 Dec 2025 01:14:49 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/wrk-vs-jmeter-deep-benchmarking/</guid>
        <description>&lt;p&gt;インターネットシステムにおける負荷テストにおいて、しばしば対照的なスタイルを持つ2つのツールに遭遇します。1つは極めて軽量で、最大限の帯域幅を追求するwrkであり、もう1つは機能が豊富で、実際のビジネスフローをシミュレートするJMeterです。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;提示：コアなアイデアを整理し、科普記事を作成：HTTP 負荷テストツール、wrk vs Jmeter の違いについて、私が知っていること、wrk は 1 つの スレッドで複数の接続を行うテストに偏っており、Jmeter はより短接続モードに重点を置いており、設定によって長接続モードにも調整可能です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;コアアーキテクチャマルチスレッド-vs-イベント駆動&#34;&gt;コアアーキテクチャ：マルチスレッド vs イベント駆動
&lt;/h2&gt;&lt;p&gt;これは両者のパフォーマンス差の根本的な原因です。&lt;/p&gt;
&lt;h3 id=&#34;1-jmeter-伝統的な一人一岗制-thread-per-request&#34;&gt;1. JMeter: 伝統的な「一人一岗」制 (Thread-per-Request)
&lt;/h3&gt;&lt;p&gt;JMeter は Java で開発されており、古典的な &lt;strong&gt;マルチスレッドモデル&lt;/strong&gt; を採用しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ロジック:&lt;/strong&gt; 各コンカレントユーザー（Virtual User）は、JVM 内の物理的なスレッドに対応します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コスト:&lt;/strong&gt; スレッドは非常に高価なリソースです。同時数があっという間に数千に達すると、コンテキストスイッチング (Context Switch) とメモリ消費がテストマシン自体を著しく遅延させ、「ロードマシンがサーバーを押し倒す前に、自分自身が崩壊する」といった現象を引き起こします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-wrk現代的な多面手制-イベント駆動型&#34;&gt;2. wrk：現代的な「多面手」制 (イベント駆動型)
&lt;/h3&gt;&lt;p&gt;wrk は C 言語で記述されており、コアとなるロジックは Redis と同じ &lt;code&gt;ae&lt;/code&gt; イベントループフレームワークを利用しています（&lt;code&gt;epoll/kqueue&lt;/code&gt; を使用）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ロジック:&lt;/strong&gt; wrk は各接続ごとにスレッドを作成しません。代わりに、極少数のスレッド (通常は CPU コア数に相当) のみ起動し、それぞれのスレッド内部で&lt;strong&gt;ノンブロッキング I/O&lt;/strong&gt; を通じて成千もの接続を同時に管理します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利点:&lt;/strong&gt; これが「一つのスレッドで複数の接続」という表現です。スレッド切り替えのオーバーヘッドを大幅に削減し、単一マシンで百万レベルの RPS (リクエスト毎秒) を実現できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;连接モデル短接続と長接続&#34;&gt;连接モデル：短接続と長接続
&lt;/h2&gt;&lt;p&gt;ご指摘の接続パターンについて、より詳細な情報をご提供します。&lt;/p&gt;
&lt;h3 id=&#34;1-jmeter-の重と軽&#34;&gt;1. JMeter の「重」と「軽」
&lt;/h3&gt;&lt;p&gt;JMeter はデフォルトで、実際のユーザーの行動をシミュレートする傾向があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;短接続への偏り：&lt;/strong&gt; デフォルト設定では、JMeter の古いバージョンや特定の構成によっては、積極的に接続を再利用せず、多数の TCP 握手が発生することがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調整可能性：&lt;/strong&gt; 「KeepAlive」を HTTP Request 中にチェックボックスで選択するか、&lt;code&gt;user.properties&lt;/code&gt; ファイルで接続プールパラメータを調整することで、長接続を有効化できます。しかし、たとえ長接続を有効化したとしても、スレッドモデルの制限により、数十万レベルの同時長接続を維持することは困難です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-wrk-の快と狠&#34;&gt;2. wrk の「快」と「狠」
&lt;/h3&gt;&lt;p&gt;wrk が設計されたのは、&lt;strong&gt;HTTP Keep-Alive&lt;/strong&gt; の性能をテストするためです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;長接続戦略：&lt;/strong&gt; wrk はテスト開始時に指定した接続数を確立（&lt;code&gt;-c&lt;/code&gt; オプションを使用）し、テスト中に可能な限りこれらの接続を再利用します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;適用場面：&lt;/strong&gt; Nginx やゲートウェイ（Gateway）、高負荷 API が極端な長接続ストレス下でスループットの限界をテストするのに非常に適しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;比較表&#34;&gt;比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;開発言語&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;C/Lua (スクリプト)&lt;/td&gt;
					&lt;td&gt;Java (GUI)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;比較表-1&#34;&gt;比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;並行モデル&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;イベント駆動 (epoll/kqueue)&lt;/td&gt;
					&lt;td&gt;マルチスレッド (ユーザーあたりスレッド)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;比較表-2&#34;&gt;比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;リソース消費&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;極低、単機スループット巨大&lt;/td&gt;
					&lt;td&gt;比較的高い、大規模同時接続には分散クラスタが必要&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;比較表-3&#34;&gt;比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ビジネス複雑度&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;低い。主に単一URLに焦点を当てている&lt;/td&gt;
					&lt;td&gt;極めて高い。複数ステップスクリプト、アサーション、エクストラクターをサポート&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;比較表-4&#34;&gt;比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;テストシナリオ&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;静的API負荷テスト、容量評価&lt;/td&gt;
					&lt;td&gt;複雑なビジネス連携の負荷テスト、機能回帰テスト&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;深層比較表&#34;&gt;深層比較表
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;wrk&lt;/th&gt;
					&lt;th&gt;Apache JMeter&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;レポート機能&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;テキストのみの要約&lt;/td&gt;
					&lt;td&gt;非常に豊富、各種グラフやHTMLレポートをサポート&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;まとめどちらを選ぶべきか&#34;&gt;まとめ：どちらを選ぶべきか？
&lt;/h2&gt;&lt;p&gt;これらのツールは代替関係ではなく、補完関係にある：&lt;/p&gt;
&lt;h3 id=&#34;選ぶワーク&#34;&gt;選ぶワーク
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;サーバーの&lt;strong&gt;最大スループット&lt;/strong&gt; (RPS) をテストしたい。&lt;/li&gt;
&lt;li&gt;テスト対象は単一の API または静的リソース。&lt;/li&gt;
&lt;li&gt;最小限のテストサーバーで最大のトラフィックを発生させたい。&lt;/li&gt;
&lt;li&gt;Lua スクリプトを使ってリクエストをカスタマイズする経験がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;jmeter-を選択する&#34;&gt;JMeter を選択する
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;複雑なビジネスフロー（例：ログイン → 商品検索 → 購入 → 決済）をシミュレートする必要がある。&lt;/li&gt;
&lt;li&gt;レスポンスタイム分布、エラー率などの詳細な指標を観察するための可視化されたインターフェースが必要である。&lt;/li&gt;
&lt;li&gt;テストでは動的パラメータ（例：前のインタフェースから取得したトークンを次のインタフェースに渡す）を処理する必要がある。&lt;/li&gt;
&lt;li&gt;チームはコマンドラインよりもグラフィカルツールに慣れている。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>パスキーの仕組みと今後の展望について解説</title>
        <link>https://ttf248.life/ja/p/detailed-explanation-of-how-passkeys-work-and-their-future/</link>
        <pubDate>Thu, 04 Dec 2025 22:14:06 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/detailed-explanation-of-how-passkeys-work-and-their-future/</guid>
        <description>&lt;p&gt;背景説明、騰訊のCNBプラットフォームは微信ログインのみをサポートしており、通常のメールアカウント方式は提供されていません。その結果、グループ内で毎日何人かがあれこれ文句を言っていますし、見ていて本当に困ります。騰訊のプロダクトマネージャーが妥協案としてパスキーログインを導入しました。&lt;/p&gt;
&lt;p&gt;毎日、私たちは危険な行為を繰り返しています：パスワードを入力することです。複雑なルール（大文字、小文字、特殊記号、数字）があっても、データ漏洩、フィッシング詐欺、そして「パスワードを忘れてしまった」という悩みが誰一人として解消されません。&lt;/p&gt;
&lt;p&gt;テクノロジー大手（Apple, Google, Microsoft）とFIDOアライアンスが最終的な解決策を提供しました：**パスキー（通行鍵）**です。それは単にパスワードの「代替」ではなく、完全にパスワードを「消滅」させるものです。&lt;/p&gt;
&lt;p&gt;ログインプロセスは、パスワードの検証から、現在使用しているデバイスの信頼性を検証することへと変更されました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;パスキーの仕組みの詳細、管理における利用方法、関連情報を整理し、インターネット公開用の記事を作成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;パスキーとは&#34;&gt;パスキーとは？
&lt;/h2&gt;&lt;p&gt;簡単に言うと、&lt;strong&gt;パスキーはデバイスに保存されているデジタル証明書です。&lt;/strong&gt;
従来の「ユーザー名 + パスワード」の代わりになります。Passkeyに対応しているウェブサイト（Google、GitHub、Adobeなど）にログインする際、文字を入力する必要がなく、顔認証（Face ID）、指紋（Touch ID）、またはデバイスPINコードで確認するだけで、瞬時にログインできます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;主な違い：&lt;/strong&gt; パスワードは&lt;strong&gt;覚えている文字列&lt;/strong&gt;（盗まれたり、推測されたり、忘れたりしやすい）であり、パスキーは&lt;strong&gt;所有している資産&lt;/strong&gt;（暗号化された鍵がデバイスのハードウェアに保存されている）です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;パスキーの仕組み非対称暗号化&#34;&gt;パスキーの仕組み：非対称暗号化
&lt;/h2&gt;&lt;p&gt;パスキーの裏側には、&lt;strong&gt;WebAuthn&lt;/strong&gt; 標準と &lt;strong&gt;FIDO2&lt;/strong&gt; プロトコルがあります。理解するためには、&lt;strong&gt;公開鍵暗号 (Public Key Cryptography)&lt;/strong&gt; について知っておく必要があります。&lt;/p&gt;
&lt;p&gt;パスキーを「鍵」と「錠」のペアだと想像してみてください：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;秘密鍵 (Private Key)：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;どこに保存されますか？&lt;/strong&gt; 自分のデバイス（iPhone のセキュアエンクレーブ、PC の TPM モジュール、パスワードマネージャーなど）に安全に保存されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特性：&lt;/strong&gt; 極めて機密性が高く、&lt;strong&gt;絶対にサーバーに送信されず、デバイスから離れることもありません。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;役割：&lt;/strong&gt; それはあなたの「電子署名ペン」です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;公開鍵 (Public Key)：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;どこに保存されますか？&lt;/strong&gt; ウェブサイト/アプリのサーバーにアップロードされ、保存されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特性：&lt;/strong&gt; 公開されており、機密性はありません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;役割：&lt;/strong&gt; それはあなたの署名を検証する「現行機」です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;ログイン手順の詳細ハンドシェイク&#34;&gt;ログイン手順の詳細（ハンドシェイク）
&lt;/h3&gt;&lt;p&gt;Passkey を使用してログインする際、巧妙な「チャレンジ-レスポンス」メカニズムが実行されます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ログインの開始:&lt;/strong&gt; あなたが「ログイン」をクリックすると、ウェブサイトサーバーはあなたのデバイスに&lt;strong&gt;ランダムな数学の問題 (Challenge)&lt;/strong&gt; を送信します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ローカルでの検証:&lt;/strong&gt; 携帯電話/コンピューターにプロンプトが表示され、生体認証（顔認証/指紋）でロック解除を求められます。
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;注記: このステップは単にデバイスが秘密鍵を使用することを許可するものであり、生体情報はアップロードされません。&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デジタル署名:&lt;/strong&gt; ロック解除が成功すると、デバイスは&lt;strong&gt;秘密鍵&lt;/strong&gt;を使用してその数学の問題に「署名」を行い、署名結果をサーバーに送信します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サーバーでの検証:&lt;/strong&gt; サーバーは、あなたが以前に保存した&lt;strong&gt;公開鍵&lt;/strong&gt;を使用してこの署名を検証します。署名が有効であれば、サーバーは「検証済みのユーザーが秘密鍵を持っていることを確認」し、ログインを許可します。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;パスキーがなぜパスワードよりも安全なのか&#34;&gt;パスキーがなぜパスワードよりも安全なのか？
&lt;/h2&gt;&lt;p&gt;パスキーは、従来のパスワードが抱える3つの主要な問題点（死すべき問題）を解決します：&lt;/p&gt;
&lt;h3 id=&#34;完全な免疫フィッシング攻撃anti-phishing&#34;&gt;完全な免疫「フィッシング攻撃」（Anti-Phishing）
&lt;/h3&gt;&lt;p&gt;これはPasskeyの最も強力な機能です。Passkeyプロトコルにおいて、**オリジンバインディング（Origin Binding）**が強制的に含まれています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;シナリオ：&lt;/strong&gt; ハッカーが偽の&lt;code&gt;g00gle.com&lt;/code&gt;を作成してあなたをだますログインを試みます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結果：&lt;/strong&gt; ユーザーエージェントとシステムは、現在のドメインがPasskey登録されたドメイン&lt;code&gt;google.com&lt;/code&gt;と一致しないことを検出し、認証の開始を&lt;strong&gt;拒否&lt;/strong&gt;します。パスワードを入力する機会すらありません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;サーバー漏洩も無意味&#34;&gt;サーバー漏洩も無意味
&lt;/h3&gt;&lt;p&gt;たとえハッカーがGoogleのサーバーを侵入し、すべてのデータベースを盗んでも、彼らが手に入れるのは単なる&lt;strong&gt;公開鍵&lt;/strong&gt;だけです。&lt;/p&gt;
&lt;p&gt;公開鍵は秘密鍵を導き出すために使用できません。ハッカーが公開鍵を持っていることは、まるで鍵を持っていることと同じですが、開錠するための鍵（秘密鍵）があなたの携帯電話の中にあり、したがってあなたのアカウントにログインできないということです。&lt;/p&gt;
&lt;h3 id=&#34;弱いパスワードは存在しない&#34;&gt;「弱いパスワード」は存在しない
&lt;/h3&gt;&lt;p&gt;ユーザーは、「123456」のような弱いパスワードを設定する必要がなく、鍵はアルゴリズムによって生成される強力な暗号化データで構成されているためです。&lt;/p&gt;
&lt;h2 id=&#34;パスキーがログイン管理を変えるとは&#34;&gt;パスキーが「ログイン管理」を変えるとは
&lt;/h2&gt;&lt;p&gt;これまで、1Password、LastPass、Chromeブラウザなどで長い文字列を記録に頼ってきました。しかし、今、「ログイン管理」は根本的に変化しています。&lt;/p&gt;
&lt;h3 id=&#34;クロスデバイス同期-passkey-sync&#34;&gt;クロスデバイス同期 (Passkey Sync)
&lt;/h3&gt;&lt;p&gt;初期のハードウェアキー (例: YubiKey) は紛失しやすいものです。現在の Passkey はクラウド同期に対応しています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Apple エコシステム:&lt;/strong&gt; iCloud キーチェーンとの同期を通じて。iPhone で作成した Passkey が Mac 上で自動的に利用可能になります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google エコシステム:&lt;/strong&gt; Google パスワードマネージャーとの Android および Chrome の同期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;サードパーティ管理ツール:&lt;/strong&gt; 1Password、Dashlane など、多くのツールが Passkey を完全にサポートしています。これにより、Windows PC で iPhone に保存されている Passkey を使用してログインできるようになります (エコシステムの横断)。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;クロスデバイス認証-qrコードによる&#34;&gt;クロスデバイス認証 (QRコードによる)
&lt;/h3&gt;&lt;p&gt;もし、ネットカフェのPC（Windows）でログインしたいが、あなたのPasskeyがiPhoneにある場合、どうすればいいでしょうか？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ウェブページから「別のデバイスでログイン」を選択します。&lt;/li&gt;
&lt;li&gt;画面にQRコード（FIDO Cross-Device Flow）が表示されます。&lt;/li&gt;
&lt;li&gt;iPhoneのカメラでQRコードをスキャンします。&lt;/li&gt;
&lt;li&gt;携帯電話がBluetoothを通じてPCと近距離接続（現場であることを証明）し、生体認証を行います。&lt;/li&gt;
&lt;li&gt;PCでのログインが成功します。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;秘密の管理から信頼の管理へ&#34;&gt;「秘密の管理」から「信頼の管理」へ
&lt;/h3&gt;&lt;p&gt;将来のログイン管理は、個々の明文パスワードを確認するのではなく、&lt;strong&gt;信頼されたデバイスを管理&lt;/strong&gt;することになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;あなたは次のように確認できます：「私のGitHubアカウントには、iPhoneとMacBookが関連付けられています。」&lt;/li&gt;
&lt;li&gt;携帯電話を紛失してしまった場合でも、サーバー側（またはクラウドアカウント）でそのデバイスの公開鍵へのアクセス権を無効にするだけで済みます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;表格比較パスワード-vs-パスキー&#34;&gt;表格比較：パスワード vs. パスキー
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;従来のパスワード (Passwords)&lt;/th&gt;
					&lt;th&gt;通行キー (Passkeys)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;記憶負担&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;高 (複雑な文字を覚える必要がある)&lt;/td&gt;
					&lt;td&gt;無 (覚えなくてもよい)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;表格比較パスワード-vs-パスキー-1&#34;&gt;表格比較：パスワード vs. パスキー
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;従来のパスワード (Passwords)&lt;/th&gt;
					&lt;th&gt;通行キー (Passkeys)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;フィッシングリスク&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;極高 (騙されて入力してしまう可能性が非常に高い)&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;ゼロ&lt;/strong&gt; (ドメインに強制的に紐付けられるため)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;表格比較パスワード-vs-パスキー-2&#34;&gt;表格比較：パスワード vs. パスキー
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;従来のパスワード (Passwords)&lt;/th&gt;
					&lt;th&gt;通行キー (Passkeys)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;サーバー漏洩&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;危険（撞列/密変更が必要）&lt;/td&gt;
					&lt;td&gt;安全（公開鍵の漏洩は影響なし）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;表格比較パスワード-vs-パスキー-3&#34;&gt;表格比較：パスワード vs. パスキー
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;従来のパスワード (Passwords)&lt;/th&gt;
					&lt;th&gt;通行キー (Passkeys)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ログイン体験&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;遅い (入力またはコピー＆ペースト)&lt;/td&gt;
					&lt;td&gt;速い (ワンクリック生体認証)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;表格比較パスワード-vs-パスキー-4&#34;&gt;表格比較：パスワード vs. パスキー
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;维度&lt;/th&gt;
					&lt;th&gt;従来のパスワード (Passwords)&lt;/th&gt;
					&lt;th&gt;通行キー (Passkeys)&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;依存性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;大脑またはパスブックへの依存&lt;/td&gt;
					&lt;td&gt;デバイス（スマートフォン/コンピューター）への依存&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;現状の課題と未来&#34;&gt;現状の課題と未来
&lt;/h2&gt;&lt;p&gt;Passkey は非常に素晴らしいですが、普及には時間がかかります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;プラットフォームの壁:&lt;/strong&gt; 標準は統一されていますが、Apple、Google、Microsoft がそれぞれのエコシステム内で最もスムーズな体験を提供し、Android 携帯を iPad とペアするなど、クロスエコシステムの移行は可能ですが、わずかな摩擦があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デバイスへの依存:&lt;/strong&gt; 信頼できるすべてのデバイスを紛失し、クラウドバックアップがない場合、アカウントの復元は困難です（通常、リカバリーコードが必要です）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;旧システムとの互換性:&lt;/strong&gt; 多くの古いウェブサイトや社内ネットワークが WebAuthn 標準をサポートしていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ
&lt;/h2&gt;&lt;p&gt;パスキーはパスワードのアップグレード版ではなく、インターネット認証の一種である&lt;strong&gt;根本的な再構築&lt;/strong&gt;です。現代デバイスの生体認証能力と公開鍵暗号技術を活用し、セキュリティを金融レベルまで向上させると同時に、ユーザーエクスペリエンスを極限まで簡素化します。&lt;/p&gt;
&lt;p&gt;一般ユーザーにとって、サポートされているプラットフォーム（Google, Apple, Microsoft, Amazon など）でパスキーをできるだけ早く有効にすることは、個人情報のデジタルセキュリティの投資として最も価値の高いものとなります。&lt;/p&gt;</description>
        </item>
        <item>
        <title>AIは「鈍化」しているのか？パラメータ精度と推論コストの駆け引きを解明</title>
        <link>https://ttf248.life/ja/p/is-ai-getting-dumber-uncovering-the-game-between-parameter-precision-and-inference-costs/</link>
        <pubDate>Thu, 04 Dec 2025 21:58:09 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/is-ai-getting-dumber-uncovering-the-game-between-parameter-precision-and-inference-costs/</guid>
        <description>&lt;p&gt;最近、様々なプログラミング大規模言語モデルの交流圏に浸り、モデルの知能低下（モジュール降智）が最も多く言及される問題となっている。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ローカルデスクトップPCへのデプロイメントは、量子化されたモデルであり、まさに知能低下後のバージョンである。&lt;/li&gt;
&lt;li&gt;vibe coding が非常に人気があるため、現在の大規模言語モデルが出力するコンテンツの中で、コードが最も価値のある産物である可能性はないか？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回のプロンプトは一度最適化され、ちょうどモデルの知能低下を解消したタイミングだった。大規模言語モデルからの回答は、プロンプトの最適化、より詳細なタスク計画、より明確な出力要件であった。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;この問題に対する適切なプロンプト：現在、多くの大手企業が大規模言語モデルサービスを提供しており、ユーザーからモデルの知能低下に関するフィードバックが見られることがある。専門的な観点からは、パラメータの精度、推論コストを考慮して記事を作成する。科普文として、長すぎないようにする。
最適化されたバージョン：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;あなたは経験豊富なAI業界技術専門誌作家です。あなたの目標は、一般読者向けでありながら内容が専門的な中国語の科普記事を書くことです。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;以下の手順で考え、作成してください。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1. 大纲の策定：まず、明確な3段構成の記事大綱（例：導入、精度分析、コストとアーキテクチャ分析、結論）を作成してください。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2. 内容への焦点を当てる：文章は、ユーザーが指摘する「知能低下」現象を深く分かりやすく説明し、コアな分析ポイントは**パラメータの精度（量子化）** と **推論の運用コスト** を中心に展開する必要があります。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;3. 文字数とフォーマット：最終的な記事の長さは600字以内である必要があります。明確な&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;##`タイトルを使用して段落を区切り、**太字**で本文中の重要な専門用語（例：量子化、MoE、FP16）を強調してください。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;はじめに&#34;&gt;はじめに
&lt;/h2&gt;&lt;p&gt;論理を明確にし、科普的な要件を満たすため、以下の構造を策定しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;導入:&lt;/strong&gt; ユーザーが認識する現実を確認し、核心となる矛盾—大規模なユーザー基盤の背景下で、サービスプロバイダーは「知的能力の頂点」と「サービスの可用性」の間でバランスを取る必要がある—を引き出します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;精度分析（コアポイント1）:&lt;/strong&gt; &lt;strong&gt;パラメータ&lt;/strong&gt;と&lt;strong&gt;精度&lt;/strong&gt;の関係を説明します。FP16と量子化（INT8/INT4）を比較し、「画像の圧縮」の類比を用いて、精度が低下するとロジックが劣化する理由を示します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コストとアーキテクチャ（コアポイント2）:&lt;/strong&gt; &lt;strong&gt;推論コスト&lt;/strong&gt;を分析します。MoEアーキテクチャとスパースアクティベーションメカニズムを紹介し、費用削減と高速化のためにモデルが「怠惰」になる方法を説明します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結論:&lt;/strong&gt; このような「知的能力の低下」は、商業化普及の不可避な道筋（三途の川）であるとまとめます。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;本文&#34;&gt;本文
&lt;/h2&gt;&lt;p&gt;最近、多くのユーザーから大規模言語モデルが以前ほど「賢く」なくなったというフィードバックがありました：論理が単純化され、指示の遵守が悪化し、場合によっては意味不明な発言（無駄話）まで発生します。これはすべて錯覚だけではありません。技術的な観点からは、この「知能低下」現象は、大手企業が膨大なユーザーに対処するために、推論コストとサービス速度のバランスを取るための技術的な妥協であると考えられます。&lt;/p&gt;
&lt;h2 id=&#34;精度縮水4kから720pへの代償&#34;&gt;精度「縮水」：4Kから720Pへの代償
&lt;/h2&gt;&lt;p&gt;大規模モデルの「知能」は、主に数千億個の&lt;strong&gt;パラメータ&lt;/strong&gt;に格納されています。理想的な状態においては、これらのパラメータが高精度の &lt;strong&gt;FP16&lt;/strong&gt;（16ビット浮動小数点数）形式で動作し、極微細な意味の違いを捉えることができます。しかし、このような高精度は、膨大な&lt;strong&gt;VRAM&lt;/strong&gt;（ビデオメモリ）の占有と、遅い計算速度をもたらします。&lt;/p&gt;
&lt;p&gt;数億人のユーザーがスムーズに利用できるようにするため、サービスプロバイダーは一般的に&lt;strong&gt;量子化&lt;/strong&gt;（Quantization）技術を採用しています。これは、パラメータの精度を &lt;strong&gt;FP16&lt;/strong&gt; から &lt;strong&gt;INT8&lt;/strong&gt; 甚至 &lt;strong&gt;INT4&lt;/strong&gt; に圧縮する手段です。&lt;/p&gt;
&lt;p&gt;これは、4K高精細映画を720Pストリーミングに圧縮するようなものです。剧情（大まかなロジック）は変わっていませんが、画面の詳細（微細な論理的関連性、複雑な指示の実行詳細）が失われます。このような「有損圧縮」により、モデルが複雑なタスクを処理する際の表現力が低下し、ユーザーに「変に賢くなった感じ」を与えることになります。&lt;/p&gt;
&lt;h2 id=&#34;コスト圧迫脳を部分的に休ませる&#34;&gt;コスト圧迫：脳を「部分的に休ませる」
&lt;/h2&gt;&lt;p&gt;精度だけでなく、&lt;strong&gt;推論の運用コスト&lt;/strong&gt;がもう一つの重要な要素です。AI に質問をするたびに、サーバーは膨大な行列演算を実行し、電気代とハードウェアの劣化は驚くほど大きくなります。&lt;/p&gt;
&lt;p&gt;コストを下げるために、現代の大規模モデルでは、&lt;strong&gt;MoE&lt;/strong&gt;（Mixture of Experts、混合専門家モデル）アーキテクチャが広く採用されています。従来のモデルが毎回すべてのニューロンを活性化するのとは異なり、&lt;strong&gt;MoE&lt;/strong&gt; は &lt;strong&gt;疎な活性化&lt;/strong&gt;戦略を採用し、あなたの質問に対して、システムは関連する「専門家」ネットワークの一部分だけを呼び覚まし、残りは休眠状態に保ちます。&lt;/p&gt;
&lt;p&gt;これは計算量を大幅に削減しますが、&lt;strong&gt;ルーティングアルゴリズム&lt;/strong&gt;（Router）が負荷分散や演算コストの節約のために、あなたの複雑な数学的問題を「文学的専門家」に割り当てるか、速度のために専門家の呼び出し数を犠牲にする場合、出力品質は変動し、低下する可能性があります。&lt;/p&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論
&lt;/h2&gt;&lt;p&gt;したがって、「降智」と呼ばれる現象は、AIが研究室から大規模な商用化へと移行する際の必然的な痛みを伴うものです。&lt;strong&gt;パラメータ精度&lt;/strong&gt;における抑制と&lt;strong&gt;モデルアーキテクチャ&lt;/strong&gt;の最適化は、誰もがAIを使いこなせるように、メーカーが「絶対的な知能」と「コスト効率」の間で模索している微妙なバランスです。&lt;/p&gt;</description>
        </item>
        <item>
        <title>Cloudflareが世界的なネットワーク障害を引き起こし、X（旧Twitter）、ChatGPTなどの主要ウェブサイトがダウン。株価は大幅に下落しました。</title>
        <link>https://ttf248.life/ja/p/cloudflare-experienced-a-global-network-outage-causing-websites-like-x-formerly-twitter-and-chatgpt-to-crash-the-stock-price-suffered-a-setback-ahead-of-the-market-open/</link>
        <pubDate>Tue, 18 Nov 2025 22:34:02 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/cloudflare-experienced-a-global-network-outage-causing-websites-like-x-formerly-twitter-and-chatgpt-to-crash-the-stock-price-suffered-a-setback-ahead-of-the-market-open/</guid>
        <description>&lt;p&gt;このサイトのメインドメインはGitHub Pages、ブログのサブドメインはVercel加速で運用していましたが、バックエンド管理ページが古臭くて退却しました。本来静かに育っていた水面下での記事ですが、ブログ界隈のグループ内の情報が絶えず流れ込み、これは通常では非常に静かな状態です。開いてみたらCFがダウンしており、多くのブロガーさんのサイトが開けなくなっていました。&lt;/p&gt;
&lt;p&gt;インターネットインフラとしての基本的な問題であり、故障がこれほど長く続いているべきではありません。株価の大暴落は予想外でした。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cloudflareの障害により、多くの知名ウェブサイトにアクセスできず、事前に株価下落、関連情報を整理し、記事を作成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;2025年11月18日（火）発表&lt;/strong&gt; — 本日（11月18日）、米国株式市場のオープン前に、主要なグローバルインターネットインフラストラクチャサービスプロバイダーであるCloudflareが大規模なネットワーク障害に見舞われ、数千ものそのサービスの依存している著名なウェブサイトやアプリケーションがダウンまたはアクセス困難になりました。&lt;/p&gt;
&lt;p&gt;この事態を受け、Cloudflare（ニューヨーク証券取引所：NET）の株価はオープン前の取引中に下落しました。&lt;/p&gt;
&lt;h2 id=&#34;-世界規模での障害が主要サービスを次々とダウンさせる&#34;&gt;🌍 世界規模での障害が、主要サービスを次々と「ダウン」させる
&lt;/h2&gt;&lt;p&gt;この障害は火曜早朝（米国東部時間午前7時頃、協定世界時刻午後11時48分頃）に発生し始めました。世界各地のユーザーから、X (旧Twitter)、OpenAI (ChatGPT) の人工知能サービス、Spotify の音楽ストリーミングサービス、League of Legends および Valorant などのゲームプラットフォーム、BitMEX や DefiLlama などの暗号通貨取引所など、多数の人気サービスへのアクセスができないとの報告がありました。
これらのウェブサイトにアクセスしようとしたユーザーは、一般的に「500 Internal Server Error」（サーバー内部エラー）というメッセージが表示されました。Cloudflare はインターネットの「仲介者」として、世界数百万のウェブサイトにコンテンツ配信 (CDN) および DDoS 対策サービスを提供しており、そのネットワーク内のわずかな「不安定さ」が瞬く間に世界規模での連鎖反応を引き起こしました。&lt;/p&gt;
&lt;h2 id=&#34;-市場反応は迅速net-盤前株価下落&#34;&gt;📉 市場反応は迅速、(NET) 盤前株価下落
&lt;/h2&gt;&lt;p&gt;インターネットの重要なインフラストラクチャの一つであるCloudflareサービスの安定性は投資家の関心を強く惹いていた。&lt;/p&gt;
&lt;p&gt;故障消息が伝わった後、資本市場は迅速に反応した。Cloudflare (NYSE: NET) の株式は火曜日の盤前取引において顕著な売り圧力となった。金融データによると、株価は約 &lt;strong&gt;3.5%～4%&lt;/strong&gt; 下落し、前回の取引日（11月17日）の約202.25米ドルからの閉場価格から、一時195米ドル付近まで下落した。&lt;/p&gt;
&lt;p&gt;これは投資家が今回のサービス中断の深刻さと、それが会社名誉や短期収益に与える可能性のある影響に対する懸念を反映したものだ。&lt;/p&gt;
&lt;h2 id=&#34;-公式声明已定位问题正在修复&#34;&gt;🛠️ 公式声明：已定位问题，正在修复
&lt;/h2&gt;&lt;p&gt;Cloudflare 官方迅速在其系统状态页面上确认了这一事件。公司于北京时间今天下午（2023年11月18日 13:09 UTC）更新状态称：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“问题已经确定，正在实施修复。”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;-公式声明问题已定位正在修复&#34;&gt;🛠️ 公式声明：问题已定位，正在修复
&lt;/h2&gt;&lt;p&gt;Cloudflare 的报告表明，此次事件被定性为“全球ネットワークに問題が発生”（Gukan netwāku ni mondai ga hassei）——“全球网络遇到问题”，并伴随“広範な500エラー”（Kōhan no 500 ērā) ——“大范围500错误”。&lt;/p&gt;
&lt;p&gt;Cloudflare 表示，他们正在努力缓解此问题，并且已经看到服务开始恢复，但警告称在修复工作继续进行期间，客户可能仍会观察到“正常よりも高いエラー率”（Nōtō yori takai error-ritsu）——“高于正常的错误率”。&lt;/p&gt;
&lt;p&gt;截至发稿时，部分网站的访问已开始逐步恢复，但全球ネットワークの遅延とエラー率は依然として高水準にある。我们将持续关注事态的后续发展。&lt;/p&gt;</description>
        </item>
        <item>
        <title>MySQL のギャップロックを理解する：原理から金融レベルの選定まで</title>
        <link>https://ttf248.life/ja/p/understanding-mysql-gaps-locks-from-principles-to-enterprise-grade-selection/</link>
        <pubDate>Tue, 18 Nov 2025 22:29:25 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/understanding-mysql-gaps-locks-from-principles-to-enterprise-grade-selection/</guid>
        <description>&lt;p&gt;システムサービス間のデータ同期において、最近の変更により特定のインターフェースのデータ量が増加し、頻繁に死鎖が発生しました。同僚による調査の結果、間隙ロックが原因であることが判明しました。MySQL の利用は少ないため、記録として残します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MySQL の間隙ロック、背景、原理、間隙ロックを閉じる方法、閉じた際の注意点；あなたは経験豊富なデータベース DBA として、私の問題に対して拡張的な分析と補足情報を提供してください。幻読とは何ですか？ 主流の大手企業は RC モードか RR モードを選択しますか？ 私は金融業界の券商システムを担当しており、あなたはそのようなシステムに最適なソリューションを提案してください。上記の質問を整理し、ドキュメントを作成してください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MySQL において、特に高負荷環境下では、「ロック」を回避することはできません。ギャップロックは InnoDB エンジンにおける重要な特性ですが、同時にパフォーマンスボトルネックや死鎖の根源となることもあります。&lt;/p&gt;
&lt;p&gt;この記事では、ギャップロックの核心、利点・欠点を迅速に整理し、あなた（特に金融業界）に対して明確なアーキテクチャ選定のアドバイスを提供します。&lt;/p&gt;
&lt;h2 id=&#34;幻読とギャップロックとは何か&#34;&gt;幻読とギャップロックとは何か？
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;幻読 (Phantom Read):&lt;/strong&gt;
トランザクション中に、例えば &lt;code&gt;ID &amp;gt; 100&lt;/code&gt; の範囲を最初に検索し、10件のデータを取得する。その後、別のトランザクションが &lt;code&gt;ID=101&lt;/code&gt; を挿入してコミットすると、2回目の検索で11件に増加してしまう。この「幻のような」追加されたデータが、その名も「幻読」と呼ばれる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ギャップロック (Gap Lock):&lt;/strong&gt;
MySQL は &lt;strong&gt;RR（可繰り返し読み）&lt;/strong&gt; 隔離レベル下において、「幻読」の問題を解決するために発明された。行自体をロックするのではなく、データの間の「隙間」をロックする。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用:&lt;/strong&gt; 他のトランザクションがその「隙間」に &lt;code&gt;INSERT&lt;/code&gt; を実行できないように防止する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コスト:&lt;/strong&gt; ロック範囲が広がり、コンカレンシー能力が低下し、死鎖を引き起こす可能性がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;間隙ロックを閉じる方法&#34;&gt;間隙ロックを「閉じる」方法
&lt;/h2&gt;&lt;p&gt;最も直接的な方法は、&lt;strong&gt;データベースの分離レベルをRR (Repeatable Read) からRC (Read Committed) に降下させること&lt;/strong&gt;です。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- 現在のセッションの分離レベルをRCに設定
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SESSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transaction_isolation&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;READ-COMMITTED&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- 永続的に変更（my.cnf を修正し、mysqld を再起動する必要があります）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- [mysqld]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;-- transaction-isolation = READ-COMMITTED
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;-关闭の影響即-rc-レベルの特性&#34;&gt;⚠️ 关闭の影響（即 RC レベルの特性）
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;パフォーマンス向上:&lt;/strong&gt; ギャップロックがなくなるため、ロック粒度が細かくなり、同時スループットが大幅に向上します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;死鎖減少:&lt;/strong&gt; ほとんどのギャップロックによる死鎖は解消されます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;幻読/不整合な読みが発生する:&lt;/strong&gt; これは RC レベルの「特性」であり、トランザクション内で二回クエリを実行しても結果が一致しない可能性があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;【必須要件】ROW形式のBinlogとの併用が必要:&lt;/strong&gt;
RC レベルを使用する場合、&lt;strong&gt;必ず&lt;/strong&gt; &lt;code&gt;binlog_format&lt;/code&gt; を &lt;code&gt;ROW&lt;/code&gt; に設定する必要があります。そうしないと、ギャップロックの保護がないため、主従レプリケーション中に主従データが不整合になる可能性があります。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;主要ベンダーの選択rc-または-rr&#34;&gt;主要ベンダーの選択：RC または RR？
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;回答：ほとんどの主要なインターネット企業は RC (Read Committed) + ROW Binlog モードを選択しています。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;理由：&lt;/strong&gt; インターネットビジネス（例：eコマース、ソーシャル）は、極めて高い同時性を追求します。RR のロックスロットによる頻繁なロック待ちや死鎖に耐えられません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;トレードオフ：&lt;/strong&gt; データベースレベルでの「読み取り追跡可能」を放棄し、代わりに&lt;strong&gt;アプリケーション層&lt;/strong&gt;でオプティミスティックロック（バージョン番号、CAS など）などの方法を用いて、重要なビジネス（例：在庫、残高）の論理的一貫性を保証します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;金融業界証券会社における選択の指針&#34;&gt;金融業界（証券会社）における選択の指針
&lt;/h2&gt;&lt;p&gt;データの一貫性要件が極めて高い証券会社システムの場合、&lt;strong&gt;シナリオ別対応&lt;/strong&gt;を推奨します：&lt;/p&gt;
&lt;h3 id=&#34;方案一コア取引システム高同時多接続低遅延&#34;&gt;方案一：コア取引システム（高同時多接続、低遅延）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;推奨：RC (Read Committed) + ROW Binlog + アプリケーション層のオプティミスティックロック&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;シナリオ：&lt;/strong&gt; 注文撮合、注文、資金決済。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;理由：&lt;/strong&gt; 取引システムの同時アクセス負荷は、秒殺サイトに匹敵する。RR の間隙ロックが性能ボトルネックとなり、深刻なロック競合や死鎖を引き起こすことは、取引システムでは容認できない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対策：&lt;/strong&gt; RC を使用して高性能を確保し、アプリケーションコード（例: Java）で &lt;code&gt;UPDATE ... WHERE balance &amp;gt; ?&lt;/code&gt; または CAS バージョン番号メカニズムを使用して資金の安全性を保証し、オーバーサブスクリプションを防ぐ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;方案二清算対帳システムバッチ処理高整合性&#34;&gt;方案二：清算対帳システム（バッチ処理、高整合性）
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;推奨：RR (Repeatable Read)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;シナリオ:&lt;/strong&gt; 期末バッチ対帳、レポート生成、日終清算。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;理由:&lt;/strong&gt; バッチ処理タスクは、「絶対的な整合性」のあるデータスナップショット上で実行する必要があります。それは RR レベルが提供する能力を必要とし、統計プロセス全体を通して「幻読」が発生しないことを保証し、最終勘定帳が正確であることを確認します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;レベル&lt;/th&gt;
					&lt;th&gt;メリット&lt;/th&gt;
					&lt;th&gt;デメリット&lt;/th&gt;
					&lt;th&gt;適用シナリオ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;RR (デフォルト)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;幻読を解決し、データの一貫性が高い&lt;/td&gt;
					&lt;td&gt;并行性が低い、死鎖しやすい（ギャップロック）&lt;/td&gt;
					&lt;td&gt;レポート、決済、データの一貫性要求が極高く、並行性が少ないシナリオ&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;まとめ-1&#34;&gt;まとめ
&lt;/h2&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;レベル&lt;/th&gt;
					&lt;th&gt;メリット&lt;/th&gt;
					&lt;th&gt;デメリット&lt;/th&gt;
					&lt;th&gt;適用シナリオ&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;RC&lt;/td&gt;
					&lt;td&gt;并行性が高く、死鎖が少ない&lt;/td&gt;
					&lt;td&gt;ファントム読み、不整合な読みが得られる&lt;/td&gt;
					&lt;td&gt;高い同時性を持つコアビジネス（例：ECサイト、金融取引）で、ROW Binlogと組み合わせて使用&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;まとめ-2&#34;&gt;まとめ
&lt;/h2&gt;&lt;p&gt;証券会社のコアシステムにおいて、&lt;strong&gt;RC + ROW Binlog&lt;/strong&gt; はパフォーマンスと整合性を両立させる主要なアーキテクチャソリューションですが、データ整合性の保証をアプリケーション層でより多く担うことを要求します。&lt;/p&gt;</description>
        </item>
        <item>
        <title>ローカル開発の苦悩：なぜ `nul` ファイルを削除できないのか？複合型ファイルシステムの問題への解決策</title>
        <link>https://ttf248.life/ja/p/local-development-pain-why-cant-you-delete-nul-files-a-solution-to-the-composite-file-system-problem/</link>
        <pubDate>Sat, 08 Nov 2025 16:37:46 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/local-development-pain-why-cant-you-delete-nul-files-a-solution-to-the-composite-file-system-problem/</guid>
        <description>&lt;p&gt;ソフトウェア開発の日常業務において、私たちはしばしば「厄介な小さな問題」に遭遇します。それらは一見単純に見えますが、数時間という貴重な時間を費やしてしまうこともあります。特に、Windows システム上で特定のファイルを削除する（特に開発ツールチェーンによって意図せず生成されたファイル）ことは、「大惨事」の典型的な例です。&lt;/p&gt;
&lt;p&gt;私もそのような「地獄級」の問題に遭遇しました。ローカルで開発していた際に、プロジェクト内に莫名其妙に &lt;code&gt;nul&lt;/code&gt; という名前のファイルが作成されてしまいました。Windows エクスプローラーや CMD コマンドラインを試しましたが、システムは「ファイルが見つからない」または「削除できません」と表示していました。このファイルはまるで幽霊のように、頑固にもプロジェクトディレクトリに根付いていました。&lt;/p&gt;
&lt;h2 id=&#34;フェーズ１標準的な試行と標準の無効な解決策&#34;&gt;フェーズ１：標準的な試行と「標準」の無効な解決策
&lt;/h2&gt;&lt;p&gt;問題に遭遇したとき、私の第一反応は &amp;ldquo;&lt;code&gt;nul&lt;/code&gt; ファイル&amp;rdquo; です。
&lt;strong&gt;なぜ &lt;code&gt;nul&lt;/code&gt; ファイルが特殊なのか？&lt;/strong&gt;
Windows の歴史を知る開発者は、&lt;code&gt;nul&lt;/code&gt; が「穴」と呼ばれるものだと知っているかもしれません。Windows (およびそれ以前の DOS) システムでは、&lt;code&gt;NUL&lt;/code&gt;、&lt;code&gt;CON&lt;/code&gt;、&lt;code&gt;PRN&lt;/code&gt;、&lt;code&gt;AUX&lt;/code&gt; などの名前は予約されたデバイス名です。&lt;code&gt;NUL&lt;/code&gt; は「空デバイス」（Unix/Linux の &lt;code&gt;/dev/null&lt;/code&gt; に相当）を表します。
Windows のファイルシステム API が、&lt;code&gt;nul&lt;/code&gt; という名前の「ファイル」を操作しようとすると、それは空デバイスを操作しているものとして扱われ、通常のファイル名を操作しようとしているものとは区別されません。したがって、ファイルの削除やリネームなどの標準的なファイル操作はすべて失敗します。
&lt;strong&gt;&lt;code&gt;nul&lt;/code&gt; ファイルがどのように生成されるのか？&lt;/strong&gt;
これは通常、クロスプラットフォーム開発ツール（Git、Node.js スクリプト、Python スクリプトなど）の「問題」によるものです。これらのツールは POSIX (Unix 互換) 標準に基づいており、それらから見ると &lt;code&gt;nul&lt;/code&gt; は単なるファイル名です。Windows 上で実行される場合、API を直接呼び出すのではなく、この Windows で「消化不良」を起こすようなファイルを生成することがあります。
&lt;strong&gt;オンラインで推奨されている「標準的な解決策」&lt;/strong&gt;
私は迅速にインターネットを検索し、私だけが最初にこの問題に遭遇したわけではないことを知りました。コミュニティはいくつかの「高度な」解決策を提唱していました：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;\\.\&lt;/code&gt; 構文の使用:&lt;/strong&gt; CMD で特別な「長いパス」構文を使用して、Windows の名前チェックを回避します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;del &lt;span class=&#34;se&#34;&gt;\\&lt;/span&gt;.&lt;span class=&#34;se&#34;&gt;\C&lt;/span&gt;:&lt;span class=&#34;se&#34;&gt;\y&lt;/span&gt;our&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;roject&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ath&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;ul
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;&lt;strong&gt;Git Bash の使用:&lt;/strong&gt; Git Bash は軽量の Unix 環境を提供し、&lt;code&gt;nul&lt;/code&gt; を特殊なデバイスとして扱わないためです。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm nul
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;&lt;strong&gt;WSL (Windows Subsystem for Linux) の使用:&lt;/strong&gt; WSL に入って Windows ディスクをマウントし、Linux の &lt;code&gt;rm&lt;/code&gt; コマンドを使用してファイルを削除します。&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm /mnt/c/your/project/path/nul
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;しかし、&lt;strong&gt;これらの方法どれも私には効果がありません！&lt;/strong&gt;
WSL でも Git Bash でも、&lt;code&gt;rm nul&lt;/code&gt; を実行しても、「No such file or directory」（ファイルまたはディレクトリが見つかりません）というエラーが発生しました。これは、私が想像していたよりも問題が複雑であることを示唆していました。&lt;/p&gt;
&lt;h2 id=&#34;フェーズ２閃光一瞬それは多重問題の重ね合わせなのか&#34;&gt;フェーズ２：閃光一瞬——それは「多重問題の重ね合わせ」なのか？
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;nul&lt;/code&gt; ファイルが実際に存在する場合、Unixツールはなぜそれを「見つからない」と報告するのか？&lt;/p&gt;
&lt;p&gt;私は疑念を抱き始めた：&lt;strong&gt;問題は &lt;code&gt;nul&lt;/code&gt; ファイル自体だけでなく、その「居場所」、つまり存在するディレクトリにあるのではないか？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;そこで私は直ちにGit Bash（これが重要だ、Windowsのエクスプローラーでは異常が表示されない可能性があるから）を開き、&lt;code&gt;nul&lt;/code&gt; ファイルが存在する&lt;strong&gt;親ディレクトリ&lt;/strong&gt;に移動して、&lt;code&gt;ls -la&lt;/code&gt; (すべてのファイル（隠されたファイルを含む）をリストし、詳細情報を表示) を実行した。&lt;/p&gt;
&lt;p&gt;そこでついに「盲点」を発見した：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;その &lt;code&gt;nul&lt;/code&gt; ファイルが保存されているディレクトリは、その&lt;strong&gt;ディレクトリ名自体に無効な文字が含まれていた！&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;フェーズ2閃きの一瞬マルチ問題の重ね合わせなのか&#34;&gt;フェーズ2：閃きの一瞬——「マルチ問題の重ね合わせ」なのか？
&lt;/h2&gt;&lt;p&gt;私のケースでは、このディレクトリ名はスペースやピリオド（&lt;code&gt;.&lt;/code&gt;）で終わる名前であるか、あるいはWindowsが許可しない特殊文字（&lt;code&gt;?&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;:&lt;/code&gt;など）を含むものである可能性があります。これらはすべて、開発ツールがクロスプラットフォーム同期する際に「持ち込まれた荷物」です。&lt;/p&gt;
&lt;p&gt;例えば、Git Bashでディレクトリが表示されると &lt;code&gt;&amp;quot;my-app &amp;quot;&lt;/code&gt; (末尾のスペースに注意) や &lt;code&gt;&amp;quot;my-app.&amp;quot;&lt;/code&gt; のようになります。
&lt;strong&gt;これが問題の本質です！&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;問題A：&lt;/strong&gt; &lt;code&gt;nul&lt;/code&gt; という「不正な」ファイルがあります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;問題B：&lt;/strong&gt; &lt;code&gt;&amp;quot;my-app &amp;quot;&lt;/code&gt; という「不正な」ディレクトリがあります。
&lt;code&gt;rm /path/to/&amp;quot;my-app &amp;quot;/nul&lt;/code&gt; を実行しようとすると、WindowsシステムとUnixツールが「混乱」します。Windows APIは、この不正な文字を含むパスを正しく解析できないためで、Git BashやWSLは「この不正なディレクトリを見る」ことができますが、内部の &lt;code&gt;nul&lt;/code&gt; ファイルにアクセスしようとすると、パス解析の複合的な問題により失敗する可能性があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;フェーズ3釜底抽薪パスを徹底的に排除する&#34;&gt;フェーズ3：釜底抽薪——パスを徹底的に排除する
&lt;/h2&gt;&lt;p&gt;「ファイルパス」と「ファイル名」という二つの問題が特定されたことで、解決策は明確になりました。&lt;strong&gt;&lt;code&gt;nul&lt;/code&gt; ファイルを削除しようとするのではなく、その「不正な」親ディレクトリを直接削除するのです！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;私の最終的な解決手順は以下の通りです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Git Bashを開く&lt;/strong&gt;: これが唯一、「見えない」か「処理できない」これらの不正な名前を正しく認識し、操作できるツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;問題ディレクトリの親ディレクトリに移動する&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;問題ディレクトリの実際の名称を確認する&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;「究極の削除」を実行する&lt;/strong&gt;: &lt;code&gt;rm&lt;/code&gt; コマンドの &lt;code&gt;-r&lt;/code&gt; (再帰) と &lt;code&gt;-f&lt;/code&gt; (強制) オプションを&lt;strong&gt;引用符&lt;/strong&gt;で囲み、使用してそのディレクトリ全体を削除します。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;コマンドを実行すると、私を悩ませていた、&lt;code&gt;nul&lt;/code&gt; ファイルを含む、本来も不適切な名前のディレクトリが、ついに私のファイルシステムから完全に消去されました。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Keepalived &#43; HAProxy を用いた高可用ロードバランシングの構築</title>
        <link>https://ttf248.life/ja/p/keepalived-haproxy-for-high-availability-load-balancing/</link>
        <pubDate>Fri, 19 Sep 2025 09:45:55 +0800</pubDate>
        
        <guid>https://ttf248.life/ja/p/keepalived-haproxy-for-high-availability-load-balancing/</guid>
        <description>&lt;p&gt;現代インターネットアーキテクチャにおいて、高可用性はシステム設計における重要な検討事項です。本稿では、KeepalivedとHAProxyを使用して高可用なロードバランシングクラスタを構築し、サービスの継続性と信頼性を確保する方法について詳細に解説します。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;実際の構成部分が検証されていないため、本文の構成はAIによって作成されています&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;この画像は「タスク計画」というタイトルで、おそらくタスクのスケジュールやリストを示していると思われます。詳細な翻訳のためには画像の具体的な内容を確認する必要がありますが、一般的な表現として以下のように記述できます。&lt;/p&gt;
&lt;p&gt;タスク計画 (Tasukku Keikaku) - 任務計画 (Tanmoku Keikaku)&lt;/p&gt;
&lt;h2 id=&#34;技術概要&#34;&gt;技術概要
&lt;/h2&gt;&lt;h3 id=&#34;keepalived-の概要&#34;&gt;Keepalived の概要
&lt;/h3&gt;&lt;p&gt;Keepalived は、VRRP（Virtual Router Redundancy Protocol）プロトコルを基盤とした高可用性ソリューションであり、主にサーバーのフェイルオーバーとロードバランシングを実現するために使用されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主な特徴：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;VRRP プロトコル対応:&lt;/strong&gt; 仮想IPアドレスの主/備切り替えの実装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;健康チェック:&lt;/strong&gt; サービスの状態を監視し、自動的に故障トランスファーを実行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;設定の簡素化:&lt;/strong&gt; 設定ファイルのみで複雑な高可用性アーキテクチャを実現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;軽量:&lt;/strong&gt; リソース消費量が少なく、性能に優れている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;動作原理：&lt;/strong&gt;
Keepalived は、VRRP プロトコルを通じて複数のサーバー間で仮想IPアドレスを共有します。正常時には、主サーバーが仮想IPアドレスを持ちサービスを提供し、主サーバーが故障した場合、備サーバーが自動的に仮想IPアドレスを接管し、サービスの停止を防ぎます。&lt;/p&gt;
&lt;h3 id=&#34;haproxy-の概要&#34;&gt;HAProxy の概要
&lt;/h3&gt;&lt;p&gt;HAProxy は、高性能なロードバランサーおよびリバースプロキシサーバーであり、高負荷環境で広く利用されています。
&lt;strong&gt;主な機能：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ロードバランシング:&lt;/strong&gt; 複数のロードバランシングアルゴリズムをサポート&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ヘルスチェック:&lt;/strong&gt; バックエンドサーバーの状態をリアルタイムに監視&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSL終端:&lt;/strong&gt; HTTPS トラフィックの処理をサポート&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;統計モニタリング:&lt;/strong&gt; 詳細な実行状態の統計情報を提供
&lt;strong&gt;利用シーン：&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Web サービス のロードバランシング&lt;/li&gt;
&lt;li&gt;データベース接続プーリング&lt;/li&gt;
&lt;li&gt;マイクロサービスゲートウェイ&lt;/li&gt;
&lt;li&gt;API インターフェース のプロキシ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;アーキテクチャ設計&#34;&gt;アーキテクチャ設計
&lt;/h2&gt;&lt;h3 id=&#34;全体アーキテクチャ&#34;&gt;全体アーキテクチャ
&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;                    ┌─────────────────┐
                    │   Client        │
                    └─────────┬───────┘
                              │
                    ┌─────────▼───────┐
                    │  Virtual IP     │
                    │  (VIP)          │
                    └─────────┬───────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
    ┌─────────▼───────┐              ┌─────────▼───────┐
    │   HAProxy-1     │              │   HAProxy-2     │
    │  (Master)       │◄────────────►│   (Backup)      │
    │  + Keepalived   │   VRRP       │  + Keepalived   │
    └─────────┬───────┘              └─────────┬───────┘
              │                                │
              └──────────┬─────────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
┌───────▼───────┐ ┌──────▼──────┐ ┌───────▼───────┐
│  Web Server 1 │ │ Web Server 2│ │  Web Server 3 │
│   Backend     │ │   Backend   │ │   Backend     │
└───────────────┘ └─────────────┘ └───────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;全体アーキテクチャ-1&#34;&gt;全体アーキテクチャ
&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;                    ┌─────────────────┐
                    │   クライアント        │
                    └─────────┬───────┘
                              │
                    ┌─────────▼───────┐
                    │  仮想IP (VIP)       │
                    └─────────┬───────┘
                              │
              ┌───────────────┼───────────────┐
              │               │               │
    ┌─────────▼───────┐              ┌─────────▼───────┐
    │   HAProxy-1     │              │   HAProxy-2     │
    │  (マスター)       │◄────────────►│   (バックアップ)      │
    │  + Keepalived   │   VRRP       │  + Keepalived   │
    └─────────┬───────┘              └─────────┬───────┘
              │                                │
              └──────────┬─────────────────────┘
                         │
        ┌────────────────┼────────────────┐
        │                │                │
┌───────▼───────┐ ┌──────▼──────┐ ┌───────▼───────┐
│  Web Server 1 │ │ Web Server 2│ │  Web Server 3 │
│   バックエンド     │ │   バックエンド   │ │   バックエンド     │
└───────────────┘ └─────────────┘ └───────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;コンポーネントの説明&#34;&gt;コンポーネントの説明
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;仮想IP (VIP)&lt;/strong&gt;: 顧客がアクセスする統一的なエントリポイント&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HAProxy 主備ノード&lt;/strong&gt;: ロードバランシングサービスを提供し、Keepalivedを使用して高可用性を実現します&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックエンドサーバー&lt;/strong&gt;: 実際にサービスを提供するWebサーバー&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;環境準備&#34;&gt;環境準備
&lt;/h2&gt;&lt;h3 id=&#34;サーバ計画&#34;&gt;サーバ計画
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;役割&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;HAProxy 主ノード&lt;/td&gt;
					&lt;td&gt;192.168.1.10&lt;/td&gt;
					&lt;td&gt;lb-master&lt;/td&gt;
					&lt;td&gt;HAProxy + Keepalived&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;サーバ計画-1&#34;&gt;サーバ計画
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;役割&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;HAProxy 備後端&lt;/td&gt;
					&lt;td&gt;192.168.1.11&lt;/td&gt;
					&lt;td&gt;lb-backup&lt;/td&gt;
					&lt;td&gt;HAProxy + Keepalived&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;サーバー構成&#34;&gt;サーバー構成
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;ロール&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;仮想IP&lt;/td&gt;
					&lt;td&gt;192.168.1.100&lt;/td&gt;
					&lt;td&gt;-&lt;/td&gt;
					&lt;td&gt;VIP&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;サーバー計画&#34;&gt;サーバー計画
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;役割&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Webサーバー1&lt;/td&gt;
					&lt;td&gt;192.168.1.20&lt;/td&gt;
					&lt;td&gt;web1&lt;/td&gt;
					&lt;td&gt;Nginx/Apache&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;サーバー構成-1&#34;&gt;サーバー構成
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;ロール&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Webサーバー2&lt;/td&gt;
					&lt;td&gt;192.168.1.21&lt;/td&gt;
					&lt;td&gt;web2&lt;/td&gt;
					&lt;td&gt;Nginx/Apache&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;サーバー計画-1&#34;&gt;サーバー計画
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;ロール&lt;/th&gt;
					&lt;th&gt;IPアドレス&lt;/th&gt;
					&lt;th&gt;ホスト名&lt;/th&gt;
					&lt;th&gt;サービス&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Webサーバー3&lt;/td&gt;
					&lt;td&gt;192.168.1.22&lt;/td&gt;
					&lt;td&gt;web3&lt;/td&gt;
					&lt;td&gt;Nginx/Apache&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;ソフトウェアのインストール&#34;&gt;ソフトウェアのインストール
&lt;/h3&gt;&lt;p&gt;HAProxy主備サーバに必要ソフトウェアをインストールします：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# CentOS/RHEL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yum install -y haproxy keepalived
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;apt-get install -y haproxy keepalived
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# サービスを起動時に自動開始にする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl &lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt; haproxy keepalived
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;keepalived-設定&#34;&gt;Keepalived 設定
&lt;/h2&gt;&lt;h3 id=&#34;主ノード設定-lb-master&#34;&gt;主ノード設定 (lb-master)
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;/etc/keepalived/keepalived.conf&lt;/code&gt; ファイルを作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! Configuration File &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; keepalived
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;global_defs &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    router_id LB_MASTER
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    script_user root
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    enable_script_security
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyサービスのステータスを確認するスクリプト&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vrrp_script chk_haproxy &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    script &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/check_haproxy.sh&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    interval &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    weight -2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    fall &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    rise &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vrrp_instance VI_1 &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    state MASTER
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    interface eth0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    virtual_router_id &lt;span class=&#34;m&#34;&gt;51&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    priority &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    advert_int &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    authentication &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        auth_type PASS
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        auth_pass mypassword123
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    virtual_ipaddress &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        192.168.1.100/24
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    track_script &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        chk_haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_master &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh master&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_backup &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh backup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_fault &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh fault&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;備中节点配置-lb-backup&#34;&gt;備中节点配置 (lb-backup)
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;/etc/keepalived/keepalived.conf&lt;/code&gt; ファイルを作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;! keepalived の構成ファイル
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;global_defs &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    router_id LB_BACKUP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    script_user root
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    enable_script_security
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vrrp_script chk_haproxy &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    script &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/check_haproxy.sh&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    interval &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    weight -2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    fall &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    rise &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;vrrp_instance VI_1 &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    state BACKUP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    interface eth0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    virtual_router_id &lt;span class=&#34;m&#34;&gt;51&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    priority &lt;span class=&#34;m&#34;&gt;90&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    advert_int &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    authentication &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        auth_type PASS
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        auth_pass mypassword123
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    virtual_ipaddress &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        192.168.1.100/24
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    track_script &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        chk_haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_master &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh master&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_backup &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh backup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    notify_fault &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/keepalived/notify.sh fault&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;haproxy健康チェックスクリプト&#34;&gt;HAProxy健康チェックスクリプト
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;/etc/keepalived/check_haproxy.sh&lt;/code&gt;というHAProxyの健康チェックスクリプトを作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyプロセスが実行中か確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps -C haproxy --no-header &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; wc -l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -eq &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# HAProxyを起動を試行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    systemctl start haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    sleep &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 再度チェックし、まだ実行されていない場合は終了&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps -C haproxy --no-header &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; wc -l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; -eq &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyポートがリッスン中か確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; ! netstat -tuln &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -q &lt;span class=&#34;s2&#34;&gt;&amp;#34;:80 &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;状態通知スクリプト&#34;&gt;状態通知スクリプト
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;/etc/keepalived/notify.sh&lt;/code&gt; という状態通知スクリプトを作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;TYPE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;STATE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$STATE&lt;/span&gt; in
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;MASTER&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Became MASTER&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/keepalived-state.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;BACKUP&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Became BACKUP&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/keepalived-state.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;FAULT&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Fault detected&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/keepalived-state.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    *&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Unknown state: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$STATE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /var/log/keepalived-state.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;esac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;スクリプトの実行権限を設定します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod +x /etc/keepalived/check_haproxy.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod +x /etc/keepalived/notify.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;haproxy-設定&#34;&gt;HAProxy 設定
&lt;/h2&gt;&lt;h3 id=&#34;メイン設定ファイル&#34;&gt;メイン設定ファイル
&lt;/h3&gt;&lt;p&gt;主備ノード上で同じHAProxyの設定ファイル &lt;code&gt;/etc/haproxy/haproxy.cfg&lt;/code&gt; を作成します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;global
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    log 127.0.0.1:514 local0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    chroot /var/lib/haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats socket /run/haproxy/admin.sock mode &lt;span class=&#34;m&#34;&gt;660&lt;/span&gt; level admin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats timeout 30s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    user haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    group haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    daemon
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;defaults
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    mode http
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    log global
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option httplog
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option dontlognull
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option log-health-checks
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option forwardfor except 127.0.0.0/8
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option redispatch
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    retries &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout http-request 10s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout queue 1m
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout connect 10s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout client 1m
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout server 1m
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout http-keep-alive 10s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    timeout check 10s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    maxconn &lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ページ設定の統計&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;listen stats
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;bind&lt;/span&gt; *:8080
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats &lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats uri /stats
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats realm HAProxy&lt;span class=&#34;se&#34;&gt;\ &lt;/span&gt;Statistics
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats auth admin:password123
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    stats refresh 30s
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 前端設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;frontend web_frontend
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;bind&lt;/span&gt; *:80
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    default_backend web_servers
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 後端サーバー設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;backend web_servers
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    balance roundrobin
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    option httpchk GET /health
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    server web1 192.168.1.20:80 check inter &lt;span class=&#34;m&#34;&gt;2000&lt;/span&gt; rise &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; fall &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    server web2 192.168.1.21:80 check inter &lt;span class=&#34;m&#34;&gt;2000&lt;/span&gt; rise &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; fall &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    server web3 192.168.1.22:80 check inter &lt;span class=&#34;m&#34;&gt;2000&lt;/span&gt; rise &lt;span class=&#34;m&#34;&gt;2&lt;/span&gt; fall &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;設定手順&#34;&gt;設定手順
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;グローバル設定:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;log&lt;/code&gt;: 日志設定&lt;/li&gt;
&lt;li&gt;&lt;code&gt;chroot&lt;/code&gt;: セーフティサンドボックス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stats socket&lt;/code&gt;: 管理インターフェース&lt;/li&gt;
&lt;li&gt;&lt;code&gt;daemon&lt;/code&gt;: バックグラウンド実行
&lt;strong&gt;デフォルト設定:&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mode http&lt;/code&gt;: HTTPモード&lt;/li&gt;
&lt;li&gt;&lt;code&gt;balance roundrobin&lt;/code&gt;: ラウンドロビンバランシング&lt;/li&gt;
&lt;li&gt;&lt;code&gt;option httpchk&lt;/code&gt;: HTTPヘルスチェック&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timeout&lt;/code&gt;: 様々なタイムアウト設定
&lt;strong&gt;バックエンドサーバー:&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;check&lt;/code&gt;: ヘルスチェックを有効にする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;inter 2000&lt;/code&gt;: チェック間隔2秒&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rise 2&lt;/code&gt;: 連続2回成功した場合に可用とマークする&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fall 3&lt;/code&gt;: 連続3回失敗した場合に不可用とマークする&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;サービス開始とテスト&#34;&gt;サービス開始とテスト
&lt;/h2&gt;&lt;h3 id=&#34;サービスの起動&#34;&gt;サービスの起動
&lt;/h3&gt;&lt;p&gt;主節点および副節点上でサービスを起動します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyの起動&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl status haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Keepalivedの起動&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start keepalived
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl status keepalived
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;vip認証の確認&#34;&gt;VIP認証の確認
&lt;/h3&gt;&lt;p&gt;仮想IPが正しくバインドされているかを確認します：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 主ノードでIPアドレスを表示&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip addr show
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 以下の様な出力が表示されるはずです：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#     inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#     inet 192.168.1.100/24 scope global secondary eth0:0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;機能テスト&#34;&gt;機能テスト
&lt;/h3&gt;&lt;h4 id=&#34;1-負荷分散テスト&#34;&gt;1. 負荷分散テスト
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# VIPに複数回アクセスし、リクエストの分配状況を監視&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; i in &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;1..10&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    curl -s http://192.168.1.100/ &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep &lt;span class=&#34;s2&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;2-フェイルオーバーテスト&#34;&gt;2. フェイルオーバーテスト
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 主ノードでHAProxyサービスを停止する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl stop haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# VIPがバックノードに切り替わるのを監視する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip addr show
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# サービスの正常性を確認する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://192.168.1.100/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;3-バックエンドサーバー障害テスト&#34;&gt;3. バックエンドサーバー障害テスト
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 一台のWebサーバーを停止する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# web1サーバーで：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl stop nginx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxy統計ページを監視する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl http://192.168.1.100:8080/stats
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;モニタリングとメンテナンス&#34;&gt;モニタリングとメンテナンス
&lt;/h2&gt;&lt;h3 id=&#34;ロギング監視&#34;&gt;ロギング監視
&lt;/h3&gt;&lt;h4 id=&#34;haproxyログ&#34;&gt;HAProxyログ
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyログの確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f /var/log/haproxy.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# アクセス統計の確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;grep &lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/1.1&amp;#34;&lt;/span&gt; /var/log/haproxy.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; tail -20
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;keepalivedログ&#34;&gt;Keepalivedログ
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Keepalivedログの確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f /var/log/messages &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep keepalived
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 状態変化ログの確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -f /var/log/keepalived-state.log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;パフォーマンス監視&#34;&gt;パフォーマンス監視
&lt;/h3&gt;&lt;h4 id=&#34;統計ページ監視&#34;&gt;統計ページ監視
&lt;/h4&gt;&lt;p&gt;HAProxyの統計ページへのアクセス: &lt;code&gt;http://192.168.1.100:8080/stats&lt;/code&gt;
主要指標:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Session Rate&lt;/strong&gt;: 会話レート&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session Total&lt;/strong&gt;: 総会話数&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bytes In/Out&lt;/strong&gt;: 流量統計&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Response Time&lt;/strong&gt;: 応答時間&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Status&lt;/strong&gt;: サーバー状態&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;コマンドライン監視&#34;&gt;コマンドライン監視
&lt;/h4&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyプロセスの状態を確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ps aux &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep haproxy
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ポートのリスニング状態を確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;netstat -tuln &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep -E &lt;span class=&#34;s2&#34;&gt;&amp;#34;(80|8080)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 接続数を確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ss -ant &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep :80 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; wc -l
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;よくあるトラブルシューティング&#34;&gt;よくあるトラブルシューティング
&lt;/h2&gt;&lt;h3 id=&#34;1-vipの切り替え不可&#34;&gt;1. VIPの切り替え不可
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;問題現象:&lt;/strong&gt;
主ノード故障後、VIPがバックアップノードに切り替わらない
&lt;strong&gt;トラブルシューティング手順:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Keepalived設定を確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;keepalived -t -f /etc/keepalived/keepalived.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# VRRP通信を監視&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tcpdump -i eth0 vrrp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ファイアウォール設定を確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;iptables -L &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep vrrp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;解決策:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VRRPプロトコル通信が正常であることを確認&lt;/li&gt;
&lt;li&gt;ネットワークインターフェースの設定を確認&lt;/li&gt;
&lt;li&gt;認証パスワードの一致性を検証&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;2-健康チェック失敗&#34;&gt;2. 健康チェック失敗
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;問題現象:&lt;/strong&gt;
バックエンドサーバーが利用不可としてマークされている
&lt;strong&gt;トラブルシューティング手順:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 手動で健康チェックを実行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -I http://192.168.1.20/health
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxyログを確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;grep &lt;span class=&#34;s2&#34;&gt;&amp;#34;Health check&amp;#34;&lt;/span&gt; /var/log/haproxy.log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;解決策:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;健康チェックURLにアクセス可能であることを確認&lt;/li&gt;
&lt;li&gt;チェック間隔と閾値を調整&lt;/li&gt;
&lt;li&gt;バックエンドサーバーの状態を確認&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;3-負荷分散の不均衡&#34;&gt;3. 負荷分散の不均衡
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;問題現象:&lt;/strong&gt;
リクエストがバックエンドサーバーに均等に分散されない
&lt;strong&gt;トラブルシューティング手順:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 統計ページを確認&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -s http://192.168.1.100:8080/stats
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# アクセスログを分析&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;awk &lt;span class=&#34;s1&#34;&gt;&amp;#39;{print $6}&amp;#39;&lt;/span&gt; /var/log/haproxy.log &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sort &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; uniq -c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;解決策:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;負荷分散アルゴリズムの設定を確認&lt;/li&gt;
&lt;li&gt;サーバーの重み設定を検証&lt;/li&gt;
&lt;li&gt;セッション保持の要件を考慮&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;オプティマイズの提案&#34;&gt;オプティマイズの提案
&lt;/h2&gt;&lt;h3 id=&#34;1-パフォーマンス最適化&#34;&gt;1. パフォーマンス最適化
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# システムパラメータの調整&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;net.core.somaxconn = 65535&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;net.ipv4.tcp_max_syn_backlog = 65535&amp;#39;&lt;/span&gt; &amp;gt;&amp;gt; /etc/sysctl.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sysctl -p
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# HAProxy設定の最適化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# maxconn値を増やす&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# timeoutパラメータを調整する&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 圧縮機能を有効にする&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;2-セキュリティ強化&#34;&gt;2. セキュリティ強化
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 統計ページへのアクセス制限&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# haproxy.cfg に ACL ルールを追加&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;acl allowed_ips src 192.168.1.0/24
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http-request deny &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; !allowed_ips
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# SSL/TLS の有効化&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;bind&lt;/span&gt; *:443 ssl crt /etc/ssl/certs/server.pem
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;redirect scheme https &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; !&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt; ssl_fc &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;3-モニタリングとアラート&#34;&gt;3. モニタリングとアラート
&lt;/h3&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 統合監視システム&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Prometheusによる監視設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Grafanaダッシュボードの設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# アラートルールを設定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;結論&#34;&gt;結論
&lt;/h2&gt;&lt;p&gt;KeepalivedとHAProxyの組み合わせにより、高可用性を持つロードバランシングクラスタを構築しました。この構成には以下の利点があります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;高可用性:&lt;/strong&gt; VRRPプロトコルによる自動フェイルオーバーを実現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロードバランシング:&lt;/strong&gt; スマートなリクエスト分散により、システム性能を向上&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;健康チェック:&lt;/strong&gt; リアルタイムでサービスの状態を監視し、故障ノードを自動的に除外&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メンテナンスの容易さ:&lt;/strong&gt; 設定が簡単で、管理も容易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コスト効率:&lt;/strong&gt; オープンソースソフトウェアを使用することで、運用コストを削減
本番環境へのデプロイ時には、ネットワークセキュリティ、監視アラート、バックアップとリカバリなどの面での整備が必要であり、システムの安定性と信頼性を確保します。&lt;/li&gt;
&lt;/ol&gt;</description>
        </item>
        
    </channel>
</rss>
