情報畑でつかまえてロゴ
本サイトは NTTテクノクロスが旬の IT をキーワードに
IT 部門が今知っておきたい最新テクノロジーに関する情報をお届けするサイトです

SONiCとTelemetry, AIで作るクローズドループ基盤(5) ~LLM基盤と全体検証編~

本シリーズではSONiCとTelemetry, AIを用いたクローズドループ基盤について紹介します。本記事ではStreamlit/LLMを用いたチャットボットの作成と全体検証について扱います。

はじめに

こんにちは、NTTテクノクロスの山口です。

本連載では、SONiCとTelemetry、AIを活用した簡易なクローズドループ基盤の構築とその動作例について紹介します。
これまでの記事で「監視」「判断」「制御」を連動させる仕組みの準備はできました。
一方で時に異常や問題が発生した際には「なぜそうなったのか」分析が必要となります。

今回はその分析業務を支援する、LLMを使った問い合わせ支援基盤の構築について紹介します。

nw_ad3-1.png

図1 全体像の概要と本記事の範囲概要

また、すべての機能部を用いた検証の実施と結果についても本記事で紹介したいと思います。
そもそもの実施するシナリオの概要や各機能部/コンポーネントの役割概要については、第1回の「本連載で作る環境と検証シナリオ」章を参照ください。

【目次】

記事 章 節 項
第1回 クローズドループとは - -
本連載で作る環境と検証シナリオ - -
構築環境と手順に関する前提 - -
完成した環境での検証結果概要 - -
第2回 環境の作り方
(各サーバ設定)
1. 全体像 -
2. SONiC -
3. 試験トラヒック用サーバ -
4. 監視/制御サーバ -
第3回 環境の作り方
(監視/可視化基盤)
1. 全体像と全体設定 -
2. Telegraf A. 構築・起動手順
B. 動作確認
3. Prometheus A. 構築・起動手順
B. 動作確認
4. Grafana A. 構築・起動手順
B. 動作確認
【補足】
5. Prometheusによる
   ルールベース異常判定の準備
A. 設計・方針整理
B-1. 構築手順(ルール定義)
B-2. 構築手順(Prometheus)
B-3. 構築手順(Alertmanager)
C. 起動と動作確認
D. その他
第4回 環境の作り方
(AIによる判断と制御基盤)
1. 全体像 -
2. AI利用に関する設計と事前準備 ① AIに関する設計
② データの収集
③ AIの学習用データの選定/抽出
3. 学習ツール ④ データの加工(前処理)~
⑥ 精度確認(モデルの評価)
4. 推論ツール ⑦ AIモデルの利用(推論)
5. 経路切り替えツール -
6. 定期実行の実現 -
第5回
(今回)
環境の作り方
(LLMによる問い合わせ支援基盤)
1. 全体像 -
2. チャット機能 A. 構築・起動手順
B. 動作確認
検証シナリオの実施と結果 1. AIを用いたクローズドループ環境検証 Ⅰ. 手順概要
Ⅱ. 手順実施と結果
【補足】
2. ルールベース異常判定の検証
Ⅰ. 手順概要
Ⅱ. 手順実施と結果

※ 本記事の内容を用いた開発・運用は、必ずご自身の責任と判断によって行ってください。
    開発・運用の結果について、いかなる責任も負いません。

環境の作り方(LLMによる問い合わせ支援基盤)

1.全体像

今回はまず「監視/制御サーバ」上に配置する「LLMによる問い合わせ支援基盤」について扱います。

nw_ad3-2.png

図2 本節の対象

利用するライブラリのバージョンなどは第1回の「構築環境と手順に関する前提」章を参照ください。

はじめに本基盤の必要性について少し紹介したいと思います。
「はじめに」章にも記載の通り「監視/可視化基盤」と「AIによる判断と制御基盤」により、NW状態を監視し、必要に応じて設定投入されるクローズドループ環境が出来上がりました。
しかしAIが異常と判定した際に「その判定は妥当なのか」分析を行う場合や自動制御範囲外のメンテナンスや設定を行う際に「今NWがどういう状態になっているのか」を把握する必要性があります。

クローズドループ環境の開発者はよく仕組みを理解しており分析/把握にそこまで時間を要しないかもしれませんが、このような環境を運用するのは開発者と同一メンバとは限りません。
保守/運用を行うメンバが、何か起きた際に「なぜ?」と分析ができる、また分析を容易にする仕組みがあると非常に便利でしょう。
このような問い合わせ/質問に対して回答をするタスクはLLMの得意分野といえます。

また、商用NW環境では、より複雑な構成で、様々な情報を収集しています。
【監視入門 第2回】でも紹介した通り、1台に不具合が発生すると連鎖的に複数台で問題が発生し、そこから更には別の問題も発生する、といったケースもあり得ます。

nw_ad3-3.png

図3 1つの問題から複数機器でアラートが発生する簡易例

こうなるとみるべきデータが大量になってしまう為、解析効率化の観点でもLLMを活用できるとよいでしょう。

LLMへの問い合わせはスクリプトなどからも実行できますが、ある程度直感的に操作できる「使いやすさ」も重要です。
「監視/可視化基盤」と「AIによる判断と制御基盤」は、NW監視や制御・自動化を実現するうえで、なくてはならない基盤ですが、「LLMによる問い合わせ支援基盤」は任意で利用する位置づけにとどまり、保守者から見ると必ずしも利用する必要性が高いものではありません。
LLMを有効活用できると非常に便利である点はご認識の通りかとは思いますが、LLM利用のハードルが高いと、利用の必要性の観点からも「用意したが使われない」結果になりかねません。
したがって利用の心理的ハードルを下げる意味でも「使いやすさ/わかりやすさ」は重視するべきでしょう。

そこで今回はLLMに問い合わせを行う為のGUI(チャット画面)を用意したいと思います。
Streamlitを使うと簡単にLLM活用に向けたGUIが用意できます。
この辺もぜひ手順なども見ながら感じていただけるとよいかと思います。
なお利用するLLMは第1回の「本連載で作る環境と検証シナリオ」章にも記載の通りOpenAI社のクラウドモデルを利用します。

nw_ad3-4.png

図4 今回の作成ツールの内容

通常のWebアプリケーションでは、GUIなどのフロントエンドと、データ処理やAPI呼び出しといった裏方のロジックを担当するバックエンドは分けて実装することが多いかと思いますが、今回は1つのPythonツールにまとめて実装します。

2.チャット機能

A.構築・起動手順

ここからは構築・起動について紹介します。

まずは監視/制御サーバ上で、「LLMによる問い合わせ支援基盤」用にディレクトリを作成します。
  ※ 本連載上では「監視/可視化基盤」「AIによる判断と制御基盤」「LLMによる問い合わせ支援基盤」が1つのVMにまとめて載っていますが、それぞれの基盤で必要な資材は明示的に分けて管理しましょう。

$ mkdir /home/admin/llm $ cd /home/admin/llm

本基盤のアプリも「AIによる判断と制御基盤」と同様にPythonを利用しますが、Python用の仮想環境も「環境/Podを分ける」ことも加味し、わけておきます。

# LLM基盤用の仮想環境用意と設定 $ python3 -m venv llmenv $ source llmenv/bin/activate (llmenv) $ python -m pip install --upgrade pip (llmenv) $ vim requirements.txt --- streamlit openai ---
(llmenv) $ pip install -r requirements.txt

次にアプリを作ります。

(llmenv) $ vim app.py
import os import streamlit as st from openai import OpenAI
MODEL_OPTIONS = {     "通常の質問/低コスト:GPT-5 mini": "gpt-5-mini",     "難しい質問/高コスト:GPT-5.5": "gpt-5.5", }
SYSTEM_PROMPT = """あなたはネットワーク監視と制御、AIのスペシャリストです。 質問に対して分かりやすく極力簡潔に日本語で回答してください。"""
def generate_response(client, model):     stream = client.responses.create(         model=model,         instructions=SYSTEM_PROMPT,         input=st.session_state.messages,         max_output_tokens=2048,         store=False,         stream=True,     )
    # ストリームで返ってきた結果を随時表示する     for event in stream:         if event.type == "response.output_text.delta":             yield event.delta
st.set_page_config(     page_title="LLM問い合わせチャット", )
st.title("LLM問い合わせチャット")
if "messages" not in st.session_state:     st.session_state.messages = []
if not os.getenv("OPENAI_API_KEY"):     st.error("OPENAI_API_KEYが設定されていません。")     st.stop()
client = OpenAI(     timeout=120,     max_retries=1, )
# サイドバーの設定 with st.sidebar:     st.header("LLM設定")
    # モデル選択プルダウン     selected_label = st.selectbox(         "モデル",         options=list(MODEL_OPTIONS.keys()),         index=0,     )
    # 画面表示名からAPI用モデルIDへ変換     model = MODEL_OPTIONS[selected_label]
    # 履歴クリアボタン     if st.button(         "会話履歴をクリア",         use_container_width=True,     ):         st.session_state.messages = []         st.rerun()
# 過去の会話表示 for message in st.session_state.messages:     with st.chat_message(message["role"]):         st.markdown(message["content"])
# ユーザプロンプト用のテキストボックス prompt = st.chat_input(     "メッセージを入力してください",     height=120,     )
if prompt:     # ユーザの入力内容をセッション内の会話履歴に追加     st.session_state.messages.append(         {             "role": "user",             "content": prompt,         }     )
    # ユーザの入力内容をチャット画面に表示     with st.chat_message("user"):         st.markdown(prompt)
    # LLMの回答をチャット画面に表示     with st.chat_message("assistant"):         try:             answer = st.write_stream(                 generate_response(                     client=client,                     model=model,                 )             )
            # LLMの回答が取得できた場合、セッション内の会話履歴に追加             if answer:                 st.session_state.messages.append(                     {                         "role": "assistant",                         "content": answer,                     }                 )
        except Exception as error:             # 失敗したメッセージは履歴から削除             st.session_state.messages.pop()
            print(f"OpenAI API error: {error}")             st.error(                 "OpenAIへの問い合わせに失敗しました。"             )

今回は画面を作っているので実際に出来上がる画面をみたほうがソースコードの理解もしやすいかと思います。
以下が出来上がる画面ですので、ソースコードと見比べて、どの部分がどこのコードに紐づくのか見てみると良いでしょう。

nw_ad3-5.png

図5 app.pyで作成した画面

GUI(Streamlit)以外は、シンプルにOpenAIモデルを呼び出して、回答を随時表示(ストリーム表示)しているのみです。
Streamlitを活用することで非常に短いコードでLLM利用に向けた画面が作れました。
ただし、LLMとのやり取り(会話履歴)はセッションに記録している(DBに登録していない)為、起動しなおしたりすると履歴が消えてしまうので注意しましょう。

また、前述の通り利用者は開発者ではなく保守者となる為、直感的にわかりやすいUIとすることが重要です。
LLMの選択についても単にモデル名だけ表示するのではなく、どう選ぶとよいのかわかるように文言を付与すると親切かと思います。

以下を実行すると、実際に利用ができるようになります。

# APIキー設定 (llmenv) $ export OPENAI_API_KEY="APIキー"
# チャットボットアプリ起動 (llmenv) $ streamlit run app.py --server.address 0.0.0.0 --server.port 8501 --server.headless true --browser.gatherUsageStats false --theme.primaryColor="#2563EB"

アプリ起動時に指定しているオプションの意味合いについては以下の通りです。

オプション 説明
server.address アプリの利用を受け付けるIPアドレス。
server.port 受け付けるポート番号。
server.headless ブラウザの自動起動をするかどうか。しない指定をしている。
gatherUsageStats Streamlitの利用情報を取得するかどうか。しない設定をしている。
theme.primaryColor GUIの表示/テーマに関連する。初期値だと質問文の送信ボタンがLLMに送信可能になると赤くなるが、赤は「できない」意味合いが強い為、青に変更している。

theme.primaryColorの差分については以下の通りです。

nw_ad3-6.png

図6 theme.primaryColorの差分について

なおオプションで指定しているものはconfigファイルで扱うこともできます。

B.動作確認

起動したら「http://{VMのIPアドレス}:8501」にアクセスしてみましょう。
前述の画面が表示されるかと思います。

動作確認として何か送ってみましょう。

nw_ad3-7.png

図7 作成した画面の動作確認例

問題なく応答が返ってきましたので、正しく動いていることを確認できました。

これですべての機能部の準備完了です。
次は作ってきた機能部を使ってシナリオ(検証)を実施してみましょう。

[補足1] LLM/問い合わせ支援基盤をより使いやすくするために

今回はセッション上に会話履歴を残しながら問い合わせを行う、というシンプルなものでした。
より使い勝手の良いものとするのであれば、まずはDBを配置することをオススメします。
DBを配置すれば「認証(アカウントごとの管理)」「会話履歴の保存永続化」「会話のスレッド化」「プロンプトのテンプレート登録/共有」「RAG」など、様々なことが対応可能になります。
  ※ RAGについては【LLM活用入門 シリーズ】も参照ください。

また、テキストだけでなく、画像や手順ファイルを添付できるようにすると使い勝手の向上や利用できるケースも増えるかと思います。

問い合わせ基盤をAIエージェント化するのも良いでしょう。
今回は問い合わせする人が自分で質問文に「モデルの情報(メタデータ)」や「異常情報(異常レポート)」を記載していました。
AIエージェント化することで、自律的にこれらの情報を参照したりPrometheusから当該期間のデータを取得したりRedmineのようなチケット/問い合わせ・課題管理システムがあればそこから過去の類似事象をとってきて分析に活用したり、必要に応じてチケットを登録/更新するなど、より高度な分析や処理がチャットボット経由で簡単にできるようになります。
その際にはMCPやSkillsなどを使うと効果的でしょう。 nw_ad3-7-1.png

図8 AIエージェントの利用イメージ

AIエージェントは便利である一方で、注意点もあります。
まず、他システムと連携する際には、他システムの本来業務に影響を与えないように注意しましょう。

nw_ad3-8.png

図9 AIエージェントによる他システム連携で気を付けること

また、AIエージェントが利用できる範囲や権限については十分に考える必要があります。

nw_ad3-9.png

図10 他システム連携における権限設定の一例

上のように利用用途と合わせて、どこまで必要か整理しましょう。
また、操作によっては人が判断するタイミングを設ける、といった整理も必要です。

利用するモデルについては今回はクラウドモデルを利用しましたが、保有する環境にGPUなどが載った基盤があるのであればローカルLLMを活用できるようにするのも良いかもしれません。

なお、今回はSONiC1台が対象でしたが、複数のNW機器から上がったアラートや情報を分析させる場合などを想定するとNW構成図のような設備情報もLLMに渡せると分析の精度が上がるかと思います。


[補足2] 利用状態の監視について

「AIによる判断と制御基盤」と似たような補足となりますが、LLM利用についても利用量(入力トークンや出力トークン)、回答時間などをPrometheusで管理しておけるとよいでしょう。
どのモデルがどれだけ利用されているのかであったり、処理のエラー率/使いたいときに使えているのかなどを確認することができます。
特にAIエージェントについては自律的に処理を行う都合、想定より利用トークンが増えるケースもあります。
想定通りの動作/運用となっているのかチェックする仕組みがあることが理想です。(今回はそこまでは扱いません)


検証シナリオの実施と結果

1. AIを用いたクローズドループ環境検証

Ⅰ. 手順概要

環境の準備ができたので、検証シナリオの実施とその結果を見ていきましょう。
検証シナリオは以下の手順で実施します。

No. 内容 目的 期待動作
1 SONiCへ通常トラヒックが流れている状態の可視化画面を確認する。 検証開始時の状態確認。
(パケットの流量を正しく可視化できているか、環境が正しくできているかを確認する。)
可視化画面にて、SONiCに通常量のトラヒックが流れていることが確認できる。
2 試験トラヒック用サーバで通常パケット出力スクリプトを停止し、異常トラヒック出力スクリプトを実行する。 通常から異常状態への変化疑似。 スクリプトが問題なく実行できる。
3 6~7分程度待った後、異常トラヒック出力スクリプトを停止し通常パケット出力スクリプトを実行する。 事象が解決したことの疑似(通常状態に戻す)。
  ※ 最低6分待つのは経路切り替えツールの切り替え抑止機能を確認するため。
スクリプトが問題なく実行できる。
4 再度、可視化画面を確認し、通信内容の変化を確認する。 監視/可視化基盤の検証結果確認。 可視化画面でこれまでの経緯が追える。
5 経路切り替え履歴ログや異常判定レポートを確認する。 AIによる判定と制御基盤の検証結果確認。 経路切り替え履歴ログからも経緯が追える。
AIが異常と判定した材料である異常判定レポートが確認できる。
6 異常判定レポートや利用モデルの情報(メタデータ)を用いて何があったかをLLMによる問い合わせ支援基盤で確認する。 LLMによる問い合わせ支援基盤の検証結果確認。 AIがなぜ異常と判定したか見解をわかりやすく確認できる。

Ⅱ. 手順実施と結果

ここからは各手順ごとに操作と結果をみていきましょう。

No.1 SONiCへ通常トラヒックが流れている状態の可視化画面を確認する

この手順は、大きく「通常トラヒックを流す」のと「可視化画面を確認する」の2手順にわかれます。

前者の「通常トラヒックを流す」は、第2回の「試験トラヒック用サーバ」の準備手順通り進めていれば不要です。
当該手順の中で、既にパケット出力を実施済みのためです。

環境を作った方でまだiperfによる負荷パケット出力をしていない方は、以下を実施しましょう。

### 試験トラヒック用サーバで実施 ## iperfクライアント(パケット出力側) # iperfによる通常時パケット出力を行うスクリプト起動 $ sudo ./loop_iperf_normal.sh
## iperfサーバ(パケット受信側)での待ち受け # ns-serv-a側(10.10.99.1で待ち受け) $ sudo ip netns exec ns-serv-a iperf3 -s -B 10.10.99.1 # ns-serv-b側(10.10.99.1で待ち受け) $ sudo ip netns exec ns-serv-b iperf3 -s -B 10.10.99.1

後者の「可視化画面の確認」も、第3回の監視/可視化基盤の準備でTelemetry収集を開始し、Grafanaでの可視化した状態を確認していましたが、こちらは検証をする前に再度状態を確認しておきましょう。
想定通りであれば、GrafanaのDashboardをみると取得した情報(SONiCに流れるトラヒック量=IFカウンターの値)が見られるはずです。
「http://{監視VMのIP}:30300」にアクセスし、作成したDashboardを開き、値が表示されているか、またSONiCに通常量のトラヒックが流れているか確認します。

nw_ad3-10.png

図11 可視化画面(GrafanaのDashboard)の結果例(通常負荷時)

このようにグラフのカウンターが上がっていれば想定通りです。(グラフは積み上げで表示しています)
Grafanaで想定通りにグラフが表示されていたら、No.1は完了です。

No.2 試験トラヒック用サーバで通常パケット出力スクリプトを停止し、異常トラヒック出力スクリプトを実行する

次は試験トラヒック用サーバでかけている「loop_iperf_normal.sh」を CTRL + C で止めたうえで、異常トラヒックを流しましょう。

### 試験トラヒック用サーバで実施 $ sudo ./loop_iperf_anomaly.sh

Grafanaによる可視化画面(グラフ)もそれにあわせて変化するはずです。
異常トラヒック出力スクリプトを実行後、次の手順に行く前に6~7分待ちます。

No.3 6~7分程度待った後、異常トラヒック出力スクリプトを停止し通常パケット出力スクリプトを実行する

異常トラヒック出力スクリプトを実行後、6-7分経過したら、loop_iperf_anomaly.shを CTRL + C で止めたうえで、通常トラヒック(loop_iperf_normal.sh)を再度流しましょう。

### 試験トラヒック用サーバで実施 $ sudo ./loop_iperf_normal.sh
No.4 再度、可視化画面を確認し、通信内容の変化を確認する

これまでの結果を早速Grafana画面でみてみましょう。

nw_ad3-11.png

図12 本検証実施後の可視化画面の結果例

グラフの情報から、トラヒック量が増えた後、経路が切り替わっていることがわかります。
また、その後5分程度は異常状態が続くものの、経路切り替えが抑止され、抑止時間を超えた後に再度経路切り替えが発生したということもトラヒックグラフから見て取れます。

異常発生(トラヒック量が増えて)から対処までは概ね1分、多く見積もって1分半程度で経路が切りかわった、と確認できます。
AIによる異常判定ツール(推論ツール)が1分に1回で、トラヒックが上がったタイミングと推論タイミングのズレにより、理論上は最大約2分ほどかかる可能性があるので、この値は妥当かと思います。

nw_ad3-12.png

図13 トラヒック上昇と推論タイミングのズレについて

No.5 経路切り替え履歴ログや異常判定レポートを確認する

この手順では「経路切り替え履歴ログ」と「異常判定レポート」の2つを確認します。

まずは経路切り替えツールが出す、経路切り替え履歴ログをみてみましょう。

$ cat /home/admin/managed/log/route_switch.log 2026-07-03 00:28:03,251 ANOMALY-20260703T002800Zにより、宛先10.10.99.1をeth3からeth4に切り替えました。 2026-07-03 00:29:02,488 ANOMALY-20260703T002900Zによる経路切替は、前回の切替から5分未満のため抑止しました。 2026-07-03 00:30:02,712 ANOMALY-20260703T003000Zによる経路切替は、前回の切替から5分未満のため抑止しました。 2026-07-03 00:31:02,828 ANOMALY-20260703T003100Zによる経路切替は、前回の切替から5分未満のため抑止しました。 2026-07-03 00:32:02,014 ANOMALY-20260703T003200Zによる経路切替は、前回の切替から5分未満のため抑止しました。 2026-07-03 00:33:02,197 ANOMALY-20260703T003300Zによる経路切替は、前回の切替から5分未満のため抑止しました。 2026-07-03 00:34:02,721 ANOMALY-20260703T003400Zにより、宛先10.10.99.1をeth4からeth3に切り替えました。 2026-07-03 00:35:02,833 ANOMALY-20260703T003500Zによる経路切替は、前回の切替から5分未満のため抑止しました。

想定通り最初の経路切り替えから概ね5分抑止され、その後、また経路切り替えが起きています。
二度目の切り替え後1分後は、まだ異常なトラヒック量が流れていた為、抑止が動いていますが、それ以降は通常トラヒックに戻っている為、通知が発生していません。

経路切り替え判断(=異常判定)をしたAIの結果である異常レポートも確認してみましょう。
ここでは1回目の異常レポートも見てみます。

$ cat anomaly_reports/ANOMALY-20260703T002800Z.json {   "anomaly_id": "ANOMALY-20260703T002800Z",   "timestamp": "2026-07-03T00:28:00+00:00",   "actual_bps": 2518576.8000000003,   "predicted_bps": 922430.0625,   "error_bps": 1596146.7375000003,   "anomaly_threshold_bps": 399626.73557078006,   "missing_lag_values": 0,   "is_anomaly": true }

見解は追えなくはないですが少しわかりづらいので、この結果をもとに次の手順でLLMに見解を出してもらいましょう。

ちなみに今回の異常判定ツールの作りでは、異常と判定された場合、経路変更がされなくても異常レポートが生成されます。
どの異常通知でIF切り替えをしたかは経路切り替え履歴ログ(route_switch.log)を確認しましょう。

No.6 異常判定レポートや利用モデルの情報(メタデータ)を用いて何があったかをLLMによる問い合わせ支援基盤で確認する

本検証の最後の手順です。
モデルの学習情報(メタデータ)や異常レポートも活用して、異常判定の見解を聞いてみましょう。

作った「LLMによる問い合わせ支援基盤」(http://{VMのIPアドレス}:8501)にアクセスして、以下のようなプロンプト(質問文)を入れてみます。

### 指示 現在NW監視でXGBoostによるトラヒック異常検知/予兆検知を行っている。 その際に以下のように異常が発生した。 なぜ異常と判定されたか見解を回答してほしい。
### 制約 途中見解などは不要で、保守者向けの見解のみ回答すること。
### モデルの学習記録 {   "model_created_at": "2026-07-01T11:05:11.824120+00:00",   "training_data_start": "2026-01-11T00:00:00+00:00",   "training_data_end": "2026-07-01T05:59:30+00:00",   "source_records": 720,   "training_samples": 576,   "validation_samples": 144,   "frequency": "30s",   "lag_count": 6,   "lookback_seconds": 180,   "validation_ratio": 0.2,   "validation_mae_bps": 139003.86522172028,   "anomaly_percentile": 99,   "anomaly_threshold_bps": 399626.73557078006,   "bps_min": 90000.0,   "bps_max": 1280000.0,   "bps_mean": 658422.9200523959,   "bps_median": 657381.9869135,   "model_parameters": {     "n_estimators": 100,     "max_depth": 3,     "learning_rate": 0.1,     "random_state": 42,     "n_jobs": 1   },   "model_file": "/home/admin/xgboost/model/xgboost_model.json",   "training_data_file": "traindata.json" }
### 異常時の結果 {   "anomaly_id": "ANOMALY-20260703T002800Z",   "timestamp": "2026-07-03T00:28:00+00:00",   "actual_bps": 2518576.8000000003,   "predicted_bps": 922430.0625,   "error_bps": 1596146.7375000003,   "anomaly_threshold_bps": 399626.73557078006,   "missing_lag_values": 0,   "is_anomaly": true }

結果は以下の通りです。

nw_ad3-13.png

図14 LLMの回答例

LLMに今回のシナリオの内容は伝えていないですが、与えた情報から妥当かつわかりやすい回答を得ることができました。

これで検証シナリオは終了です。

本検証の総評/AIを用いたクローズドループ環境検証

この検証の総評は「トラヒックグラフの結果から監視結果を基に異常を検知し、あらかじめ定めた制御を自動実行する、一連のクローズドループ処理およびLLMによる分析の効率化を実現できた」ということでしょう。

このように「監視/可視化基盤」「AIによる異常判定」「判定結果による制御」を連携させることで、シナリオに応じた最適な状態を自動的に維持し続けるNW管理基盤が作成できます。
またLLMを活用することで、異常時の分析やオペレーションを効率化を目指せます

今回は簡易な例ではありましたが、第1回で紹介した「NWの状態可視化」「NW監視と制御の連携と自動化による対処早期化」「NW異常時の状態把握の早期化」の実現イメージも見えたのであれば幸いです。

[補足3] NW領域におけるLLMのその他の活用例

今回は異常が発生した際の分析をユースケースの中心として説明しました。
また、補足欄にてAIエージェント化することで、一部オペレーションを効率的に対処できるようになる点についても触れました。

LLMの特徴は柔軟性が極めて高い点です。
したがって、使い方次第でユースケースは他にも考えられます。
例えば「複雑なシステム/NW構成」に関する質疑応答や過去の事例を用いた机上訓練案の作成(教育用途)があげられます。
NWやそれに伴うシステム群は、通信断が起きないように頑強に作られている一方、複雑になりやすく、特有の技術が使われている場合もあります。
これらを理解することにも苦労がありますが、その上でトラブルシュートとなると極めて難易度が高くなることが想像に難くありません。
早期のキャッチアップやチームの能力向上を目指すツールとしてもLLMは有用です。

他にも第3回で可視化する際に利用したPromQLを考えさせたり、Prometheus用の異常ルールを作ってもらうという使い方もあるでしょう。
もちろん検証は必要ですが、これにより保守者が見たいと思った情報を柔軟に可視化できるようになる可能性があります。

このように当てはめられるユースケースは幅広です。


【補足】2. ルールベース異常判定の検証

ここからは、補足としてPrometheusによるルールベースの異常検知の実行例を紹介します。
長くなるのでこの補足は節と項にわけて紹介します。
  ※ 設計や条件、事前準備は第3回「【補足】5. Prometheusによるルールベース異常判定の準備」にて紹介しているので、必要に応じてご確認ください。

Ⅰ. 手順概要/ルールベース異常検証

ルールベースの異常検知に関する検証シナリオは以下の手順で実施します。

No. 内容 目的 期待動作
1 SONiCへ通常トラヒックが流れている状態の可視化画面とPrometheusのアラート画面、Alertmanager画面を確認する。 検証開始時の状態確認。 パケットが想定通り流れていること、アラートが上がっていないことを確認できる。
2 試験トラヒック用サーバで通常パケット出力スクリプトを停止し、ルールベースの異常検知用トラヒックをかける。 通常からルールベースで検知する異常状態への変化疑似。 スクリプトが問題なく実行できる。
3 Prometheusの画面とAlertmanagerの画面を確認し、アラートAが発生していることを確認する。 ルールベース異常が検知できているかの確認。 アラートAが上がっている、またその状態を確認できる。
4 経路切り替えを実施し、その後にアラートB・アラートCが発生していることを確認する。 経路切り替えによる状態の変化にアラートが追従できているかの確認。 アラートBが上がっている、複数のアラートを紐づけたアラートCが上がっている、またその状態を確認できる。
5 アラートCの条件を除いてPrometheus再起動を挟まずに設定反映する。 設定反映手順の確認。 Prometheus Podの再起動を挟まずに設定反映がされる(アラートCが消える)。

  ※ 各アラートがどのような内容かについては「監視/可視化基盤」節の補足をご確認ください。

なお、本シナリオはcronによるAI推論ツールの定期起動はオフにして実施します。
理由としては、以下のように(AI推論ツールの起動タイミングによりますが)ルールベースの異常値(5M)に到達する前にAIが異常と判定し、経路を切り替えてしまう場合があるためです。

nw_ad3-14.png

図15 ルールベースの異常値に到達する間に経路が切り替わる例

Ⅱ. 手順実施と結果/ルールベース異常検証

では、ここから各手順をみていきます。

No.1 SONiCへ通常トラヒックが流れている状態の可視化画面とPrometheusのアラート画面、Alertmanager画面を確認する

本手順は「SONiCへ通常トラヒックが流れている状態の可視化画面の確認」と「Prometheusのアラート画面の確認」「Alertmanager画面を確認」の3つにわけられます。

1つ目の「SONiCへ通常トラヒックが流れている状態の可視化画面の確認」は、「AIを用いたクローズドループ環境検証」の手順No.1と同様である為、記載省略とします。

可視化画面の確認が済んだら、2つ目の「Prometheusのアラート画面の確認」に進みます。
「http://{監視VMのIP}:30090」にホストマシンからブラウザでアクセスし、Alerts画面を確認します。

nw_ad3-15.png

図16 PrometheusのAlerts画面(異常発生前)

上の画面のように、それぞれのルールが「INACTIVE」となっていれば、アラートは上がっておらず、想定通りの動作となります。

次に3つ目の手順である「Alertmanager画面を確認」をしましょう。
「http://{監視VMのIP}:30093」にアクセスしてAlertmanagerも確認してみます。

nw_ad3-16.png

図17 Alertmanagerの画面(異常発生前)

想定通りPrometheusが検知していないので、その先のAlertmanagerにも特に何もアラート表示がされていないことを確認できました。
これで検証開始時の状態確認は完了です。

No.2 試験トラヒック用サーバで通常パケット出力スクリプトを停止し、ルールベースの異常検知用トラヒックをかける

次に試験トラヒック用サーバでかけている「loop_iperf_normal.sh」を CTRL + C で止めたうえで、ルールベース異常用のトラヒックを流しましょう。

### 試験トラヒック用サーバで実施 $ sudo ./loop_iperf_rulebase.sh

Grafanaの可視化画面も確認すると、以下の画面のように流量が増えていることが確認できるはずです。

nw_ad3-17.png

図18 可視化画面でのトラヒックの増加確認

No.3 Prometheusの画面とAlertmanagerの画面を確認する

再びPrometheusのAlerts画面を確認してみましょう。

nw_ad3-18.png

図19 PrometheusのAlerts画面(異常発生後/経路切り替え前)

先ほどとかわり、アラートAが「FIRING」になっています。
これはアラート検知したことを意味します。

Alertmanagerの画面もみてみましょう。

nw_ad3-19.png

図20 Alertmanagerの画面(異常発生後/経路切り替え前)

先ほどと変わり、アラート表示がされました。
deviceとincidentでグループ化しているため、対象機器とアラート内容でまとめられます。
なお、今回はUI表示までですが、設定を変えることでメールなどで通知することができます。

No.4 経路切り替えを実施し、その後にアラートB・アラートCが発生していることを確認する

この手順は「経路の切り替え」と「アラート確認」の2つにわかれます。

まず「経路切り替え」ですが、今回は前述の通りcronによる推論ツール定期実行を止めているため、自動で経路切り替えがされません。
そのため、SONiCにて直接経路切り替えコマンドを実行するか、経路切り替えツールの試験モードにより手動で切り替えます。

### どちらか実施 ## SONiCにて直接変える場合 $ sudo ip route replace 10.10.99.1/32 via 10.10.12.1 dev eth4
## 経路切り替えツールの試験モードで切り替える場合 (myenv) $ python /home/admin/managed/route_switch.py --test

切り替えができたら、アラート確認に進みます。

切り替え後、少し待ってPrometheusの画面を確認してみます。

nw_ad3-20.png

図21 PrometheusのAlerts画面(異常発生後/経路切り替え後)

経路切り替えによりルートA(特に出力IF)にはパケットが流れなくなっているため、アラートAはINACTIVEに戻っています。
一方、ルートBに今度は大量のパケットが流れるようになったため、アラートBが上がりました。
また、直近5分でアラートA・Bの両方が上がっている、という条件のアラートCが上がっています。

あわせてAlertmanagerの画面もみてみます。

nw_ad3-21.png

図22 Alertmanagerの画面(異常発生後/経路切り替え後)

アラートCの内容が確認できました。
アラートAとBについては表示抑止が働いています。(Alertmanagerの設定(inhibit_rules)で抑止をかけています)

このように単発のアラートだけでなく、関連するアラートは関連付けして管理/通知するとよいでしょう。
PrometheusやAlertmanagerによりこのようなルール付けや管理が可能となります。

なお、本番環境ではメール通知などを利用するかと思いますが、Prometheusが出力するアラートとAlertmanagerが出力するアラート通知はわけて考える必要があります。
理由としては、Prometheusが出力するアラートは、異常状態が継続する限り送信を続けるためです。
一方メールなどで人に通知する役割を持つAlertmanagerによるアラート通知は、Prometheusの通知の度に送信するのは現実的ではありません。
Prometheusによるアラートは「異常となった時間帯を知らせる情報」、Alertmanagerは「異常の発生を人に通知したタイミング」と考えるとわかりやすいかと思います。

少し横道にそれますが、Prometheusが連続的にアラートを飛ばしているかもみてみましょう。

nw_ad3-22.png

図23 可視化画面にてState timelineでみたアラート情報

上の画面はGrafanaにて「State timeline」を指定した際のアラートの可視化結果です。
ステータスが変わったタイミング(例: INACTIVE→FIRING)だけ送付されるのだとすると、異常と判定されたときと「解消した」と判定されたタイミングの2回のみが可視化されるかと思いますが、画面をみると2回だけでなく、もっと長い期間でアラートA/B/Cそれぞれで継続的にアラート発報されていることがわかるかと思います。

例えば上の画面の08:12:45~08:13:30頃はアラートBが続いています。
上の画面をテーブル表示に切り替えた結果を以下に表示します。

nw_ad3-23.png

図24 可視化画面にてテーブル表示でみたアラート情報

アラートBに関して複数のレコードが見られます。
このことからもアラートBが一定時間FIRING状態を継続していたことがわかります。

ちなみにアラートAとBそれぞれの間隔に間がある(歯抜けとなっている)のはアラート条件となっている5Mを超える場合と超えないタイミングがあった為(iperfでパケット出力してもがたつきがある点は第2回でご紹介の通りです)と考えられます。

また、本来の監視であれば可視化画面上でもアラート履歴やステータス表示画面があると便利でしょう。
一応現構成でも前述の「State timeline」のような形式を含む最低限の確認はできます。
一方で「どのアラートが、何時から何時まで発生した」とシンプルに情報をまとめて示すようなログの表示や各アラートのステータス管理、アラート通知の管理も含めて行おうとする場合、構成の拡張が必要となる場合があります。

現構成でできることは、「State timeline」形式の表示以外だとTable形式を指定することで、例えば以下のようなことができます。

# 現時点で異常と判定されているアラート情報 ALERTS{alertstate="firing"}
# 直近24時間で異常と判定されたアラートの表示 max_over_time(ALERTS{alertstate="firing"}[24h])

直近24時間で異常と判定されたアラートをGrafana(可視化画面)上で表示した例を以下に示します。

nw_ad3-24.png

図25 Dashboardに直近24hに異常と判定されたアラート表示を組み込んだ画面

ただしこれは履歴そのものではありません。
あくまで「異常扱いとなったかどうか」であり、同じ異常が24h以内に2回発生していたとしても1つとして表示されます。

また、Grafana上は時刻情報があるように見えますが、これは検索したタイミングの時刻であり、異常扱いとなったタイミングではありません。
実際、アラートA~Cは異常となったタイミングはそれぞれ異なるはずですが、すべて同じ時間になっています。

これらのクエリはPromQLである為、Prometheus上でも確認できます。

nw_ad3-25.png

図26 Prometheusにて直近24hに異常と判定されたアラートを表示した例

話を戻して、最後の手順と動作の確認をしましょう。

No.5 アラートCの条件を除いてPrometheus再起動を挟まずに設定反映する
最後に以下を実行してみましょう。

# アラートCを自動生成するConfigMapファイルの対象外とする(prometheus_rulesフォルダの外におく)。 $ mv prometheus_rules/traffic-alert-c-correlation.yaml ./
# ConfigMapファイルの再作成 $ kubectl -n telemetry create configmap prometheus-rules \     --from-file=./prometheus_rules \     --dry-run=client -o yaml > prometheus-rules.yaml
# ConfigMap再反映。ApplyされてPrometheus Podから更新版定義ファイルが見えるようになるまで少し時間がかかる為、本コマンド実行後少し待つ。 $ kubectl apply -f prometheus-rules.yaml
# 一定時間経過後、反映コマンド実施 $ curl -X POST http://127.0.0.1:30090/-/reload

上手くいっていればPrometheusのAlerts画面が以下のようになるはずです。

nw_ad3-26.png

図27 設定変更後のPrometheusのAlerts画面

アラートCに関する表示が消えていることが確認できます。
prometheus.yamlに対しApplyをかけていないので、Prometheus Podの再起動をせずに設定反映ができました。

これでルールベース検知に関する動作確認も終了です。

本検証の総評/ルールベース異常判定検証

本検証ではOSSを用いたルールベース検知の実現やアラームの関連付けやエスカレーションなどができることを確認しました。

第1回でも紹介した通り、ルールベース検知とAIを用いた検知はそれぞれ一長一短があるので、実際の運用では組み合わせて利用していけると良いかと思います。

[補足4] 情報の統合管理とセキュリティ分野について

今回のクローズドループ基盤ではTelemetry情報のみを対象にデータを収集/分析/判断をしていました。
より高度化する場合には【監視基盤 第2回】でも触れたように、SyslogやxFlow情報、SNMP Trapなど様々な情報を取得/管理の上、分析処理ができると良いでしょう。

このような考え方はNW分野だけでなく、セキュリティ分野でも同様です。
その代表例が「SIEM」や「SOAR」でしょう。

SIEMは各種認証ログ(例:Radius)やFW(ファイアーウォール)ログ、IDS(不審通信や攻撃通信を検知する仕組み)/IPS(不審通信や攻撃通信を検知し、遮断などの対処を行う仕組み)情報などを統合管理し、分析や異常検知を行う仕組みです。
(今回の例でいうと、「監視/可視化基盤」や「AIによる判断」が近い役割を持つと考えられます。)

また、その情報をもとに対処(通信遮断や通知など)を行うのが「SOAR」です。
(今回の例でいうと、異常判定後に経路切替を行う制御基盤に近い役割を持つと考えられます。)

最近はEDR(ユーザが利用するPCや端末の動作を監視し、異常を発見する仕組み)に加え、NDR(NW通信を監視し、不審な挙動を検知する仕組み)を組み合わせたXDRであったり、SASE(クラウド上でNW機能とセキュリティ機能を提供する考え方)のように、NW分野とセキュリティ分野の融合も進んでいます。
今回のクローズドループ基盤も拡張したり一部を流用することでSIEM/SOARのような使い方/仕組みに近づけることもできるかと思います。
今回扱った「監視/判断/処理の自動化」という考え方は、通信事業者だけでなく、一般企業においても重要なテーマとなり得ます。


[補足5] OSS基盤を利用する事の注意点

今回はOSSを多く利用しているので、それに関する注意点を補足します。

OSSはソースコードが公開されているため、利用者や開発者が内容を確認しやすい一方で、攻撃者も同じコードを解析できます。
近年は生成AIや自動解析技術の発展により、公開されたソースコードから未知の脆弱性を発見されるリスクも高まっていると考えられます。

そのため、OSSを利用する場合は、利用しているOSSや依存ライブラリ、そのバージョンを把握し、脆弱性情報が出た際に影響有無を確認できる状態にしておくことが重要です。
このような管理には、上記のような情報を一覧化するSBOMを用いる方法が有効です。

ただしSBOMは、あくまでソフトウェア構成要素を把握するためのものであるため、SBOMに加えて脆弱性情報の監視やパッチ適用手順の整備なども組み合わせる必要があります。

おわりに

本連載では5回にわたって、SONiCとTelemetryを土台に、OSSや簡易なPythonツールを活用して「監視」「判断」「制御」の連携/自動化によるクローズドループ環境の実現例をご紹介しました。
あわせて、LLMを使った分析効率化の例についても紹介しました。
構成や検証結果だけでなく、環境の作り方とあわせて意識したい設定やポイントについても触れたので、クローズドループのイメージ(監視や制御の連携)やNW上でのAI活用などをある程度細かくイメージすることができたのではないでしょうか。

一方で構成自体は手順簡略化のために簡易な作りとしており、実運用で使うには課題も多く残っています。
一例が以下となります。

No. 区分 内容
1 構成 Kafkaを構成に組み込んでいない為、負荷集中時のバッファリングができず収集データが増えると欠損が出る可能性が上がる。
2 構成 監視/制御サーバ、あるいはk3sクラスタの冗長化がされていない。(監視/制御サーバがNW管理の単一障害点(SPOF)となっている)
3 構成 AIによる判断ツールや制御ツール、LLMによる問い合わせ支援基盤をPod化できていない。
4 構成 AIモデルの定期的更新とデプロイ(CI/CD)を含めていない。
5 監視 監視/制御サーバのマシンそのものの監視(ノード監視)やKubernetesリソース監視(指定したReplica数通りにPodが起動しているかなど)がされていない。
6 監視 AIによる判断の結果やLLM利用に関する情報を監視情報として管理/可視化できていない。
7 監視 アラートの履歴管理が弱い。アラート通知の条件が整理されておらず、履歴としても管理/可視化されていない。
8 機能 LLMによる問い合わせ基盤では、会話履歴はセッション内のみの保持で、認証機能も用意していない。
9 セキュリティ TelemetryをTLSなしで利用している、経路切り替えツールに認証情報をそのまま書いている、経路切り替えツールが内部処理で利用するstateファイルやログファイルの権限を制限していないなど、セキュリティ面が簡易化されている。
10 操作性 取得データや可視化条件などを変える際にConfigやツールの追加/追記/変更などが必要であり、わかりづらい(直感的に操作できるGUIがあるとよい)。

シナリオ自体も簡易なものでしたが、構成/作りも実際に商用で利用する際には(要件に応じて)更なる細部検討や拡張が必要です。

また、今回は監視から制御まで人を介さない自動化をシナリオで実施しましたが、必ずしも完全制御が正とは言えません。
実施するシナリオや入れる設定によっては「人が判断する」という仕組みを組み込むことも重要です。

このような構成の実現には、従来の「NW」「監視」「制御」といったNWのそれぞれの領域/担当が三位一体となって連携することが不可欠です。
また、「AI/LLM」といった最新技術を取り入れることで、より柔軟で強靭なNWの実現に繋げていけると考えています。

一方で「補足」でも触れた通り、「NW」「監視」「制御」「AI/LLM」といった分野は突き詰めると1つ1つ極めて奥深い領域でもあります。
NTTテクノクロスには各領域に関する有識者/経験者、各領域を一気通貫で見られる人材も在籍しています。

もし本記事や本記事の内容、ネットワーク全般に関するご質問やご相談などありましたら以下からお問い合わせください。
今回も最後までご覧いただきありがとうございました。

本件に関するお問い合わせ

NTTテクノクロス
フューチャーネットワーク事業部

山口 佳輝

お問い合わせ

連載シリーズ
テクノロジーコラム
著者プロフィール
山口 佳輝
山口 佳輝

<<<<著者プロフィール>>>>

フューチャーネットワーク事業部
 第一ビジネスユニット
  山口 佳輝(YAMAGUCHI YOSHIKI)

NWに関係したシステム開発を担当しています

>>>>>>>>><<<<<<<<<