「先月のAWSコスト、なんで予測より20%も高いんだ?」
月初のミーティングでCFOや上司からこう聞かれて、冷や汗をかいた経験はありませんか?
実務の現場では、急成長するサービスの裏でクラウドコストが爆発し、その原因特定に丸一日費やすようなケースも珍しくありません。AWS Cost ExplorerやQuickSightのグラフを何十枚もめくり、タグをフィルタリングし、Excelでピボットテーブルを回す……。まさに「泥沼」の作業です。
「もっと直感的に、チャットで同僚に聞くようにデータ分析ができたらいいのに」
そう思ったことは一度や二度ではないはずです。朗報です。今はそれができます。しかも、Pythonの基礎知識さえあれば、週末の数時間で自分専用のツールが作れてしまう時代なのです。
本記事では、生成AI(LLM)を活用して、自然言語でクラウドコストを分析できる「対話型FinOpsダッシュボード」の作り方を、コード付きで徹底解説します。
使うのはPython、Streamlit、そしてPandasAI。SQLを書く必要も、複雑なBIツールを構築する必要もありません。「EC2のコストが急増した理由は?」と入力すれば、AIがデータを掘り下げ、グラフを描いて教えてくれる。そんな未来のFinOps環境を、まずはプロトタイプとして手元に構築してみましょう。
準備はいいですか? エディタを開いて、さっそく始めましょう。
1. なぜ「対話型」がFinOpsの正解なのか
技術的な実装に入る前に、少しだけ「なぜこれを作るのか」というビジネスと技術の接点についてお話しさせてください。ここを理解しておくと、ツールが完成した後の活用イメージが段違いに湧くはずです。
固定ダッシュボードの限界と「探索的分析」の必要性
Tableau、PowerBI、そしてAWS QuickSightといったBIツールは、企業のデータ可視化において中心的な役割を果たしています。特にAWS QuickSightは、2026年1月時点でサードパーティAIエージェントとの連携や自然言語クエリ機能(Amazon Q in QuickSight等)を強化しており、以前に比べれば格段に柔軟性が向上しました。
しかし、FinOpsの現場、特に異常検知(Anomaly Detection)と原因究明(Root Cause Analysis: RCA)においては、依然として「固定ダッシュボード」だけでは対応しきれない場面が存在します。
既存の高機能なBIツールであっても、以下のような課題に直面することは珍しくありません:
- 事前の設計が必要: 「どの軸で分析するか」をあらかじめ定義しておく必要があり、想定外の切り口(例:特定のタグとインスタンスタイプの組み合わせ等)で即座に分析するには、新たな設定やフィルタリング操作が必要です。
- コストと学習曲線: 高度なAI機能を持つBIプランはコストがかさむ場合があり、また全メンバーがその機能を使いこなせるわけではありません。
- データのサイロ化: AWSとGCP、Azureなどマルチクラウドのコストデータを単一のビューで、かつ自由な粒度で横横断分析するには、複雑なデータパイプラインの構築が必要です。
突発的なコストスパイク(急増)が発生した際、その原因は「特定のインスタンスタイプの起動」かもしれないし、「GKE Autopilotモードでの予期せぬスケーリング」かもしれないし、あるいは「データ転送量の増加」かもしれません。原因が未知であるからこそ、多角的にデータを切り刻んで調べる「探索的データ分析(EDA)」が不可欠なのです。
生成AIが埋める「クエリ作成スキル」のギャップ
ここで、生成AI(LLM)を組み込んだ自作アプリの出番です。
LLMをデータ分析に活用する最大のメリットは、思考の速度でデータを問い合わせられることにあります。特に最新のLLMは、コンテキスト理解能力が飛躍的に向上しており、曖昧な質問からでも意図を汲み取ることが可能です。
- 「先月と比べて、どのサービスのコストが一番増えた?」
- 「EC2の中で、コストが高い上位5つのUsageTypeを教えて」
- 「そのUsageTypeの日次推移を棒グラフにして」
これらをSQLクエリやPythonコードに変換して実行するのは、熟練のエンジニアでも時間がかかります。しかし、自然言語インターフェースであれば一瞬です。これにより、エンジニアだけでなく、経理担当者やPMでも、専門的なクエリ言語を覚えることなく自力で原因を深掘りできるようになります。経営層と現場のコミュニケーションロスをなくす意味でも、非常に強力なアプローチです。
本チュートリアルのゴール:自然言語でグラフを描画する
今回目指すのは、以下のような挙動をするWebアプリです。特定のSaaSに依存せず、Pythonとオープンソースライブラリを活用して構築します。
- データアップロード: CSVファイル(AWSのCost ExplorerやGCPのBilling Exportから出力されたデータ)をアップロードする。
- 対話的分析: チャット欄に「先月のサービス別コストを円グラフで表示して」と入力する。
- 自動実行: AIが裏側でPythonコードを生成・実行し、画面にグラフを描画する。
- 深掘り: さらに「そのうちEC2の内訳は?」と続けて質問し、分析を深める。
これをStreamlit(フロントエンド構築)とPandasAI(データ分析エージェント)を使って実装します。PandasAIはバックエンドでLLM(OpenAIのGPTシリーズや、GoogleのGemini最新モデルなど)と連携し、自然言語をPandasの処理に変換します。
このアプローチなら、高価なBIツールを契約せずとも、驚くほど少ないコード量で、自分たちのチームに最適化されたFinOps分析環境を手に入れることができます。「まず動くものを作る」精神で、一気に組み上げていきましょう。
2. 環境構築:10分で整える分析基盤
では、手を動かしていきましょう。まずは開発環境のセットアップです。今回はPythonを使います。
必要なライブラリのインストール
プロジェクト用のフォルダを作成し、仮想環境を作ることを強くお勧めします。依存関係の衝突を防ぐためです。
# プロジェクトディレクトリの作成
mkdir finops-dashboard
cd finops-dashboard
# 仮想環境の作成と有効化 (Mac/Linux)
python -m venv venv
source venv/bin/activate
# Windowsの場合
# python -m venv venv
# .\venv\Scripts\activate
次に、必要なライブラリをインストールします。OpenAIのモデルやSDKは急速に進化しており、最新の機能(推論能力の向上や新しいAPI仕様)を利用するためには、ライブラリも常に最新の状態に保つことが重要です。
requirements.txt を作って以下を記述しましょう。
streamlit
pandas
pandasai
openai
python-dotenv
matplotlib
seaborn
そしてインストールコマンドを実行します。
pip install -r requirements.txt
- Streamlit: PythonスクリプトだけでWebアプリを作れるフレームワーク。
- PandasAI: PandasのDataFrameに生成AI機能を付加するライブラリ。
- OpenAI: GPTモデルを利用するためのSDK。OpenAIの最新モデル(ChatGPTの最新モデル系など)や機能に対応するため、定期的なアップデートが推奨されます。
APIキーの取得と安全な管理方法
このツールはOpenAIのAPIを使用します。APIキーをお持ちでない場合は、OpenAIの公式サイトから取得してください。
セキュリティは最優先事項です。APIキーをコードに直接書くのは絶対にNGです。.env ファイルを作成し、そこに環境変数として保存します。
# .envファイル
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
.gitignore ファイルを作成し、.env を記述してGitの管理対象から外すのも忘れないでくださいね。
サンプルデータの準備
手元にAWSのCost & Usage Report (CUR) があればそれを使っても良いですが、データが大きすぎたり機密情報が含まれていたりする場合もあるでしょう。
ここでは、チュートリアル用にシンプルなCSV構造を定義します。cost_data.csv という名前で以下の内容を保存してください。
Date,Service,Region,UsageType,Cost,Currency
2023-10-01,AmazonEC2,us-east-1,BoxUsage:t3.medium,12.50,USD
2023-10-01,AmazonRDS,us-east-1,RDS:GP2-Storage,4.20,USD
2023-10-01,AmazonS3,us-west-2,TimedStorage-ByteHrs,1.10,USD
2023-10-02,AmazonEC2,us-east-1,BoxUsage:t3.medium,12.50,USD
2023-10-02,AmazonEC2,us-east-1,BoxUsage:m5.large,45.00,USD
2023-10-02,AmazonRDS,us-east-1,RDS:GP2-Storage,4.20,USD
...
日付、サービス名、リージョン、使用タイプ(インスタンスタイプなど)、コスト、通貨。これだけのカラムがあれば、十分高度な分析が可能です。
3. 実装Step1:自然言語をデータ処理コードに変換する
いきなり画面を作る前に、まずはコアとなるロジック、つまり「自然言語をPandasの処理に変換する部分」を実装してみましょう。ここが動けば、勝ったも同然です。
PandasAIの基本:DataFrameとLLMの接続
analysis_core.py というファイルを作って、実験してみます。ここでは、コーディング能力と指示追従性が強化されたOpenAIの最新モデルを活用することを想定します。
import os
import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI
from dotenv import load_dotenv
# 環境変数の読み込み
load_dotenv()
# データの読み込み
df = pd.read_csv("cost_data.csv")
# LLMの設定
# ※より複雑な分析を行う場合は、コーディング能力の高い最新モデルの指定を推奨します
llm = OpenAI(api_token=os.environ["OPENAI_API_KEY"])
# SmartDataframeの初期化
sdf = SmartDataframe(df, config={"llm": llm})
# 質問してみる
response = sdf.chat("サービスごとの合計コストを高い順に教えて")
print(response)
このコードを実行すると、PandasAIは以下のプロセスを自動で行います。
- DataFrameのカラム情報(スキーマ)とユーザーの質問をLLMに送る。
- LLMが「データを集計するためのPythonコード」を生成して返す。
- PandasAIがそのコードをローカル環境で実行する。
- 結果を表示する。
すごいでしょ? 自分で df.groupby('Service')['Cost'].sum().sort_values(...) と書かなくても、AIが勝手にやってくれるんです。
特に、OpenAIの最新モデル(ChatGPTの上位モデル等)では、コーディングタスクや論理的推論能力が大幅に向上しています。これにより、以前のモデルでは生成に失敗することがあった「複雑な条件分岐を含む集計」や「多段階のデータ処理」も、より正確なコードに変換されるようになっています。
LLMが理解しやすいデータスキーマの定義
ただし、AIの性能が上がったとはいえ万能ではありません。カラム名が曖昧だと間違った解釈をするリスクは残ります。例えば Cost が税込みなのか税抜きなのか、UsageType とは何なのか、といったコンテキストです。
精度を上げるコツは、データフレーム自体はシンプルに保ちつつ、質問文の中で補足するか、あるいは後述する「メタデータ」を与えることです。最新のモデルは長文理解(コンテキストウィンドウ)も強化されているため、詳細な定義を与えれば、それだけ精度の高い回答が返ってきます。
また、コスト分析では「日付」の扱いが肝になります。CSV読み込み時に日付型に変換しておくのがベストプラクティスです。
# 日付カラムをdatetime型に変換(重要!)
df['Date'] = pd.to_datetime(df['Date'])
これを忘れると、時系列分析(例:「先週と比較して」)がうまく機能しません。型定義を明確にすることで、LLMはより確実な時系列処理コードを生成できます。
4. 実装Step2:StreamlitでチャットUIを構築する
ロジックの確認ができたら、いよいよWebアプリ化です。Streamlitを使えば、HTMLやCSSを一切書かずにモダンなチャットUIが構築できます。
app.py というファイルを作成し、以下のコードを記述していきましょう。
チャット入力欄と履歴表示の実装
ここでは、ユーザーとの対話履歴を保持し、自然なチャット体験を提供する実装を行います。また、バックエンドのLLMとしてOpenAIのモデルを使用しますが、FinOpsのような数値分析ではモデルの推論能力が重要になります。
import streamlit as st
import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI
from dotenv import load_dotenv
import os
import matplotlib.pyplot as plt
# 設定とデータのロード
load_dotenv()
st.set_page_config(page_title="AI FinOps Dashboard", layout="wide")
st.title("🤖 AI FinOps Dashboard")
# サイドバーでファイルアップロード
uploaded_file = st.sidebar.file_uploader("コストCSVをアップロード", type=["csv"])
if uploaded_file is not None:
# データの読み込み
df = pd.read_csv(uploaded_file)
df['Date'] = pd.to_datetime(df['Date'])
# LLMの初期化
# APIキーは環境変数から読み込みます。
# 複雑な分析を行う場合は、model引数でChatGPTの最新モデル(ChatGPTクラス以上)を指定することを推奨します。
llm = OpenAI(api_token=os.environ.get("OPENAI_API_KEY"))
# SmartDataframeの設定
sdf = SmartDataframe(df, config={"llm": llm})
# チャット履歴の初期化
if "messages" not in st.session_state:
st.session_state.messages = []
# 過去のメッセージを表示(リロード時も履歴を維持)
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
# ユーザー入力の受け付け
if prompt := st.chat_input("分析したい内容を入力してください(例:日別のコスト推移を見せて)"):
# ユーザーのメッセージを表示
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.write(prompt)
# AIの応答生成
with st.chat_message("assistant"):
with st.spinner("AIがコストデータを分析中..."):
try:
# PandasAIによる分析実行
response = sdf.chat(prompt)
# 結果の表示
st.write(response)
# 会話履歴に保存(グラフ画像の場合は別途処理が必要ですが、ここではテキスト/表を保存)
st.session_state.messages.append({"role": "assistant", "content": response})
except Exception as e:
st.error(f"分析中にエラーが発生しました: {e}")
st.caption("ヒント: より具体的な指示を出すか、データの形式を確認してください。")
else:
st.info("👈 左のサイドバーからAWSコストのCSVファイルをアップロードしてください。")
分析結果(グラフ・表)の動的レンダリング
PandasAIでグラフを表示させる場合、デフォルトではグラフ画像を生成してそのパスを返します。Streamlit上でこれをシームレスに表示するには、いくつかのポイントがあります。
特にOpenAIの最新モデル(ChatGPTの最新モデル世代など)を利用する場合、指示追従性が大幅に向上しているため、「サービス別のコストを棒グラフで可視化して」といった自然言語の指示だけで、適切なパラメータを持つ matplotlib のコードを生成・実行してくれます。
グラフ描画のコツは以下の通りです:
- プロンプトでの明示: 「グラフで表示して」「推移をプロットして」と明確に伝えます。
- 表示ロジック: 上記コードでは
st.write(response)が万能に働きます。PandasAIがDataFrameを返せば表として、テキストを返せば文章として表示されます。 - 画像表示: PandasAIの設定で画像の保存先を指定するか、Streamlitのキャッシュディレクトリを利用することで、生成されたチャートを表示できます(※上記の基本コードでは、テキストと表の表示を優先しています)。
エラーハンドリング:AIが答えられない時の挙動
生成AIを用いた開発で避けて通れないのがエラーハンドリングです。特に「先月のコストは?」と聞かれた際、データセットに「先月」のデータが含まれていない場合や、AIが質問の意図を解釈できない場合があります。
上記のコードでは try-except ブロックを使用し、エラー発生時にアプリがクラッシュするのを防いでいます。最新のLLMはエラーからの自己復旧能力(Self-Correction)も向上していますが、ユーザーに対しては「何が起きたか」を分かりやすく伝える st.error や st.caption を活用して、次のアクションを促す設計が重要です。
5. 精度向上:AIに「FinOpsの文脈」を教える
プロトタイプは動きましたか? おめでとうございます!
しかし、実務で使い始めると、「なんか計算が合わないな」「用語が通じないな」という場面に出くわすでしょう。
これはAIがあなたの会社のデータの「文脈」を知らないからです。ここからは、AIを「新人アシスタント」から「熟練のFinOpsアナリスト」に育てるチューニングを行います。
カスタムプロンプトによるドメイン知識の注入
PandasAIなどのライブラリには、カスタムプロンプトを設定したり、データフレームにメタデータ(説明書き)を付与したりする機能があります。これを使って、AIに役割とルールを与えましょう。
クラウドサービスは常に進化しています。例えば、2026年1月時点のAWSアップデートだけでも、AWS Configでの新リソースタイプ(Route 53 DNSSECなど)のサポート追加や、Amazon Connect、Redshiftの機能拡張など、多くの変更が行われています。AIモデルの学習データが追いついていない最新の仕様や、組織固有の略語については、プロンプトを通じて補完する必要があります。
from pandasai.prompts import AbstractPrompt
class FinOpsPrompt(AbstractPrompt):
template = """
あなたは熟練したFinOpsアナリストです。
以下のデータフレームを使って、ユーザーの質問に答えてください。
<dataframe>
{df_head}
</dataframe>
ルール:
1. コストは常に小数点第2位まで表示してください。
2. 通貨はUSDとして扱ってください。
3. 「EC2」と言われたら「AmazonEC2」のこととして処理してください。
4. 「RI」は「Reserved Instances」、「SP」は「Savings Plans」として扱ってください。
5. 異常値を聞かれたら、平均から2標準偏差以上離れた値を提示してください。
質問: {query}
"""
# SmartDataframe初期化時にカスタムプロンプトやコンテキストを適用
# ※ライブラリのバージョンにより実装方法が異なるため、最新ドキュメントを確認してください
sdf = SmartDataframe(df, config={
"llm": llm,
"custom_whitelisted_dependencies": ["matplotlib", "seaborn"],
"description": "これはAWSのコストデータです。ServiceカラムはAWSサービス名、Costは米ドルです。2026年以降の新しいリソースタイプが含まれる可能性があります。"
})
このように description やシステムプロンプト的な指示を与えることで、AIの回答精度は劇的に向上します。特に「EC2 = AmazonEC2」のようなシノニム(同義語)定義や、FinOps特有の略語(RI, SPなど)の定義は、ユーザー体験を良くするために必須です。
コスト異常検知のための定型質問テンプレート
毎回プロンプトを考えるのが面倒な場合、UI側に「よくある質問ボタン」を作っておくと便利です。FinOpsの現場では、見るべき指標はある程度決まっています。
col1, col2, col3 = st.columns(3)
if col1.button("今月のコスト概要"):
prompt = "今月の総コストと、前月比の増減率を教えて。また、コスト増加率が最も高いサービスを1つ挙げて。"
# ...処理へ
if col2.button("トップ5サービス"):
prompt = "コストが高いサービス上位5つを棒グラフで表示して。凡例にはサービス名を含めること。"
# ...処理へ
if col3.button("異常値チェック"):
prompt = "日次コストが急激に跳ね上がっている日(異常値)と、その主な原因となっているサービス・利用タイプを特定して解説して。"
# ...処理へ
これなら、クリック一発で高度な分析が走ります。
バックエンドのLLM(ChatGPTやClaude、Geminiの最新モデルなど)は急速に進化していますが、それでも「何を聞けばいいか分からない」というユーザーの課題は残ります。こうしたテンプレートを用意することで、ツールは単なる検索窓から「自分専用の司令塔」へと進化します。
6. 次のステップとセキュリティへの配慮
最後に、このツールを個人のPCからチーム全体で使えるようにするための考慮事項、特にセキュリティについてお話しします。プロトタイプから実運用へ移行する際、データの取り扱いは最も重要な検討事項の一つです。
機密データをLLMに送らないためのプライバシー設定
「コストデータとはいえ、社外のAIサーバーにデータを送るのは不安だ」という懸念は、組織での導入時によく挙がる課題です。
PandasAIの仕組み上、データの中身(行データ)の一部(ヘッド部分など)は、スキーマ理解のためにLLMに送信されます。しかし、データ全量を送るわけではありません。それでも、厳格なセキュリティポリシーがある場合は、以下の対策を検討することをお勧めします。
- Azure OpenAIを利用する: エンタープライズ契約であれば、入力データがモデルの再学習に使われないことが保証されています。PandasAIはAzure OpenAIにも対応しており、セキュリティとコンプライアンスを重視する組織に適しています。
- ローカルLLMを使う: Ollamaなどを活用し、Llamaモデルの最新版(Llamaモデル等)のような高性能なオープンモデルをローカル環境で稼働させれば、データは社外に出ません。ただし、実用的な推論速度を得るためには、GPUを搭載したマシンスペックが必要です。
- Enforce Privacyモード: PandasAIにはプライバシーモードがあり、データの統計情報(カラム名や型情報)だけを送り、実際の値を送らずにコード生成させる設定も可能です。ただし、具体的な値を条件にする質問(例:「コストが100ドル以上のサービスは?」)などは精度が落ちる可能性があるため、トレードオフを考慮する必要があります。
社内公開時の認証機能追加
チームに公開する場合、streamlit-authenticator などのライブラリを使って、簡易的なログイン画面を実装することは必須と言えます。URLを知っているだけで誰でもコスト情報が見られる状態は、ガバナンスの観点から避けるべきです。
まとめ
ここまでのステップを振り返ってみましょう。
- 環境構築: Pythonと必要なライブラリをセットアップ。
- PandasAI: 自然言語を分析コードに変換するエンジンの実装。
- Streamlit: 直感的な対話型UIの構築。
- チューニング: FinOpsのコンテキストをプロンプトに注入。
この4ステップで、あなたの手元には強力な分析ツールが生まれました。もう、月末のコスト報告作成に多くの時間を費やす必要はありません。「コストが高い」という課題に対して、その場でこのツールを開き、「なぜ高いのか」「どのリソースが要因か」をAIと共に解明し、データに基づいた改善策を提案できます。
FinOpsの本質は単なる「コスト削減」ではありません。「クラウドへの投資対効果を最大化すること」です。データへのアクセスを民主化し、エンジニア一人ひとりがコスト意識を持って開発に取り組めるようにする。このダッシュボードは、そのような文化を醸成するための有効な手段となるはずです。
まずは手元のCSVデータから始めて、徐々に機能を拡張していくことをお勧めします。小さな成功体験の積み重ねが、組織全体のコスト最適化へとつながっていきます。
さあ、次はあなたの番です。今すぐターミナルを開いて、pip install から始めましょう!
コメント