2回目ではなく、もう最終回。理由は、この文章に長さにある。。。
これからはAIが必要だ、AIをやれ、と言われる機会が増えてくるが、単にChat GPTを検索エンジンとして使っていたり、議事録の要約に使っているケースが多く、AIが少しは便利にしてくれるが、実際は、それが爆発的に何か改善したかというとそうではない。まぁ、紙を右から左に渡す人が自動化されていなくなった程度かもしれない。(これ、自分の知る、実話で、昔いたNYの会社には、「紙を右から左に渡すだけの仕事」しかしていない人がいた。仕事として定義されていたのが恐ろしいが、AIが出てくる遥か10年以上前にリストラされてしまった。)
コンテナも同じだが、レイヤーが変わったので、その上のレイヤーをやらなければならないからとっつきにくい。上のレイヤーに行けば行くほど、テクニカルな話ではなく、別のカットでの必要性や想像力が必要になる。インフラおじさんだったら、サーバやインスタンスが動いている、メンテできればよく、その中のアプリは知らなくても済んだ、その上のレイヤーに行くとなると、インフラは抽象化されたものとして、扱うことはなく、その中で動いているアプリケーションの知識が必要だし、そらにその上のレイヤーに行けば、そのアプリケーションはビジネスの何のために動いているのかが重要で、アプリケーションがOracle Databaseで動いていようが、MS SQLで動いているかはあまり関係なくなってくる。
閑話休題
スクリプトを作ってて汎用的にできないかと持って汎用的に書いた。そしてたどり着いたのが、MCPという設計方法。
MCPでは、以下のような要素を明確に分離・構造化:
- system:AIに役割を与える(例:栄養士として回答)
- instruction:ユーザーの目的を指示(例:データを日本語で解説)
- input_data:処理対象データ(例:食品の構成や特徴)
- output_format:出力の期待形式(例:Markdown形式のリスト)
- example:回答の例(例:* バナナ:果物でエネルギー補給に適す)
このスクリプトは、MCPに準拠している。早速使ってみる。
動作環境
Ubuntu(ネイティブやWSL2など)あるいは、Macのzsh
AI環境
以下のいずれか
LM Studio (ローカル、リモートサーバ)
Open AI API (インターネット)
実は、スクリプトは両方にそのまま対応している。Open AI APIでかかるコストを考慮(1回2〜3銭程度)、LM StudioのWindowsでの遅さを考慮して、デフォルトのデータはものすごく小さくなっている。
フォルダ構造
mcp-ai/
├── sample-ai.sh # ✅ メイン実行スクリプト
├── template_mcp.json # ✅ 共通テンプレート(role/system指示など)
└── entries/ # ✅ テーマ別 JSONデータ格納ディレクトリ
├── food.json # 食材(栄養士)
├── dogs.json # 犬種(獣医師)
├── plants.json # 観葉植物(園芸アドバイザー)
├── appliances.json # 家電(家電製品の専門家)
└── stationery.json # 文房具(文具店スタッフ)
実際の実行
以下コピーペストだけで試せる。ちょっと長いから、ひたすらコピペ。githubにファイルを置いてもよかったんだけど、そうするとコードを読まないので。
🚀 0. 必要パッケージのインストールおよびディレクトリの作成
apt -y install jq # Ubuntuの場合のみ
mkdir -p mcp-ai/entries
cd mcp-ai
🚀 1. スクリプト:sample-ai.sh(MCP対応)
cat << 'EOF' > sample-ai.sh
#!/usr/bin/env bash
set -euo pipefail
#MODEL="gpt-4.1-nano”
MODEL="gemma-3-12b”
API_SERVER=“192.168.1.70”
SUMMARY_LINES=5
ENTRY_FILE="${1:-}”
TEMPLATE_FILE="./template_mcp.json”
if [[ -z "$ENTRY_FILE" || ! -f "$ENTRY_FILE" ]]; then
echo "❌ エントリJSONが指定されていないか存在しません”
echo "Usage: ./sample-ai.sh entries/appliances.json”
exit 1
fi
if [[ ! -f "$TEMPLATE_FILE" ]]; then
echo "❌ テンプレートファイル(template_mcp.json)が見つかりません”
exit 1
fi
if [[ -n "${OPENAI_API_KEY:-}" && "$MODEL" =~ ^gpt- ]]; then
echo "🔐 OpenAI モード(モデル: $MODEL)”
USE_OPENAI=true
API_URL="https://api.openai.com/v1/chat/completions”
else
echo "🖥️ LM Studio モード(モデル: $MODEL)”
USE_OPENAI=false
API_URL="http://${API_SERVER}:1234/v1/chat/completions”
echo "🌐 モデル一覧:”
curl -s "http://${API_SERVER}:1234/v1/models" | jq -r '.data[].id' | sed 's/^/ - /‘
fi
TOTAL_COUNT=$(jq '.entries | length' "$ENTRY_FILE”)
SUMMARY=$(jq -r '.entries[] | "* \(.name):分類「\(.category)」、特徴「\(.nutrition)」、補足「\(.note)」"' "$ENTRY_FILE" | head -n "$SUMMARY_LINES”)
ACTUAL_COUNT=$(echo "$SUMMARY" | wc -l)
echo "📋 抽出件数: $ACTUAL_COUNT / 指定: $SUMMARY_LINES / 総数: $TOTAL_COUNT”
echo "✅ 抽出済データ:”
echo “$SUMMARY”
ROLE=$(jq -r '.role' "$TEMPLATE_FILE”)
SYSTEM_PROMPT=$(jq -r '.system' "$TEMPLATE_FILE" | sed "s/{{role}}/$ROLE/g”)
USER_PROMPT=$(jq -r '.instruction' "$TEMPLATE_FILE”)
FORMAT=$(jq -r '.output_format' "$TEMPLATE_FILE”)
EXAMPLE=$(jq -r '.example' "$TEMPLATE_FILE”)
# 展開済テンプレートを表示
echo
echo "🧠 SYSTEM_PROMPT(展開済):”
echo “$SYSTEM_PROMPT”
echo "————————————“
echo "🙋 USER_PROMPT:”
echo “$USER_PROMPT”
echo "————————————“
echo "📦 出力形式指定(FORMAT):”
echo “$FORMAT”
echo "————————————“
echo "📎 出力例(EXAMPLE):”
echo “$EXAMPLE”
echo "————————————“
PROMPT_JSON=$(jq -Rs <<<"$USER_PROMPT"$'\n\n'"$SUMMARY"$'\n\n'"出力形式: $FORMAT"$'\n'"例: $EXAMPLE”)
start_time=$(date +%s)
echo
echo "📡 $API_URL $MODEL で推論実行中…”
if $USE_OPENAI; then
RESPONSE=$(
curl -s "$API_URL” \
-H "Content-Type: application/json” \
-H "Authorization: Bearer $OPENAI_API_KEY” \
-d @- <<JSON
{
"model": "$MODEL”,
"messages": [
{ "role": "system", "content": "$SYSTEM_PROMPT” },
{ "role": "user", "content": $PROMPT_JSON }
]
}
JSON
)
else
RESPONSE=$(
curl -s "$API_URL” \
-H "Content-Type: application/json” \
-d @- <<JSON
{
"model": "$MODEL”,
"messages": [
{ "role": "system", "content": "$SYSTEM_PROMPT” },
{ "role": "user", "content": $PROMPT_JSON }
]
}
JSON
)
fi
end_time=$(date +%s)
duration=$((end_time - start_time))
echo
echo "📝 AIの解説:”
echo "$RESPONSE" | jq -r '.choices[0].message.content // .response // "❌ No content returned”'
PROMPT_TOKENS=$(echo "$RESPONSE" | jq -r '.usage.prompt_tokens // empty’)
COMPLETION_TOKENS=$(echo "$RESPONSE" | jq -r '.usage.completion_tokens // empty’)
TOTAL_TOKENS=$(echo "$RESPONSE" | jq -r '.usage.total_tokens // empty’)
if [[ -n "$TOTAL_TOKENS" ]]; then
echo -e "\n🔢 消費トークン数:”
echo " 入力: $PROMPT_TOKENS tokens”
echo " 出力: $COMPLETION_TOKENS tokens”
echo " 合計: $TOTAL_TOKENS tokens”
fi
# ✅ モデル別 単価定義(USD/1K tokens)
declare -A INPUT_RATE OUTPUT_RATE
INPUT_RATE["gpt-4.1-nano"]=0.00010
OUTPUT_RATE["gpt-4.1-nano"]=0.00040
INPUT_RATE["gpt-4o-mini"]=0.00060
OUTPUT_RATE["gpt-4o-mini"]=0.00240
INPUT_RATE["gpt-4.1-mini"]=0.00040
OUTPUT_RATE["gpt-4.1-mini"]=0.00160
INPUT_RATE["gpt-4.1"]=0.00200
OUTPUT_RATE["gpt-4.1"]=0.00800
INPUT_RATE["gpt-4o"]=0.00500
OUTPUT_RATE["gpt-4o"]=0.02000
# JPY為替レート
USD_TO_JPY=145.0
# コスト計算(MCP対象のみ)
if $USE_OPENAI && [[ -n "${INPUT_RATE[$MODEL]:-}" && -n "${OUTPUT_RATE[$MODEL]:-}" ]]; then
# Online Rate (From open.er-api.com)
NEW_VAL=$(curl -s "https://open.er-api.com/v6/latest/USD” |
jq -r '.rates.JPY' 2>/dev/null)
if [[ $NEW_VAL =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
export USD_TO_JPY=“$NEW_VAL”
else
echo "⚠️ Rate can't be updated :USD_TO_JPY=$USD_TO_JPY”
fi
input_tokens=${PROMPT_TOKENS:-0}
output_tokens=${COMPLETION_TOKENS:-0}
input_usd=$(awk "BEGIN { printf \"%.5f\", ${INPUT_RATE[$MODEL]} * $input_tokens / 1000 }”)
output_usd=$(awk "BEGIN { printf \"%.5f\", ${OUTPUT_RATE[$MODEL]} * $output_tokens / 1000 }”)
total_usd=$(awk "BEGIN { printf \"%.5f\", $input_usd + $output_usd }”)
input_jpy=$(awk "BEGIN { printf \"%.2f\", $input_usd * $USD_TO_JPY }”)
output_jpy=$(awk "BEGIN { printf \"%.2f\", $output_usd * $USD_TO_JPY }”)
total_jpy=$(awk "BEGIN { printf \"%.2f\", $total_usd * $USD_TO_JPY }”)
echo -e "\n💰 推定コスト:”
echo " ✅ 為替レートUSD/JPY $USD_TO_JPY”
echo " USD: 入力 \$${input_usd} + 出力 \$${output_usd} = 合計 \$${total_usd}”
echo " JPY: 入力 ¥${input_jpy} + 出力 ¥${output_jpy} = 合計 ¥${total_jpy}”
# OpenAI使用量ページのリンクを表示
🔗 OpenAIの使用量はこちらから確認できます:
👉 https://platform.openai.com/account/usage
🔗 OpenAIの残高はこちらから確認できます:
👉 https://platform.openai.com/settings/organization/billing/overview
fi
echo -e "\n⏱️ 応答時間: $duration 秒"
EOF
chmod +x sample-ai.sh
📄 2. プロンプトテンプレート:template_mcp.json
cat << 'EOF' > template_mcp.json
{
"role": "専門家”,
"system": "あなたは優秀な{{role}}です。以下のルールに従って応答してください。\n\n## 出力ルール:\n- Markdownリスト形式\n- 各行は1行で簡潔に記述\n- 元データの順に並べてください”,
"instruction": "以下のデータを読み取り、それぞれの特徴を日本語で簡潔に説明してください。”,
"output_format": "Markdownリスト(例: * 名称:特徴)”,
"example": "* たまご:動物性食品で高タンパク。加熱すると栄養吸収率が上がる。”
}
EOF
📁 3. テーマ別データファイル(entries/*.json)
以下は、サンプルデータ。データ処理をしやすいように整理されたサンプルデータを作成した。適当なアプリケーションのjsonファイル出力をいきなり読み込ませても使うことはできない。本番運用だとここいらの整形が必要。
- food.json : 栄養士による食材の解説
- dogs.json : ペットアドバイザーによる犬種解説
- plants.json : 園芸アドバイザーによる観葉植物解説
- appliances.json : 家電専門家による製品解説
- stationery.json : 文具店スタッフによる文房具の解説
🍳 食品(food.json)
cat << 'EOF' > entries/food.json
{
"entries": [
{
"name": "たまご”,
"category": "動物性食品”,
"nutrition": "高タンパク・ビタミンB群”,
"note": "加熱すると栄養の吸収が良くなる”
},
{
"name": “牛乳”,
"category": “乳製品”,
"nutrition": "カルシウム・タンパク質・ビタミンB2”,
"note": "アレルギーに注意”
},
{
"name": “バナナ”,
"category": “果物”,
"nutrition": "カリウム・ビタミンB6・食物繊維”,
"note": "エネルギー補給に最適”
},
{
"name": “ほうれん草”,
"category": “野菜”,
"nutrition": "鉄分・ビタミンC・葉酸”,
"note": "茹でるとアクが抜ける”
},
{
"name": "さけ”,
"category": “魚介類”,
"nutrition": "良質な脂質(DHA・EPA)・タンパク質”,
"note": "骨にも注意”
}
]
}
EOF
🐶 犬種(dogs.json)
cat << 'EOF' > entries/dogs.json
{
"entries": [
{
"name": “柴犬”,
"category": “日本犬”,
"nutrition": "忠実で警戒心が強い”,
"note": "独立心が強くしつけに根気が必要”
},
{
"name": "ゴールデン・レトリバー”,
"category": "大型犬”,
"nutrition": "温厚で社交的”,
"note": "運動と被毛ケアが重要”
},
{
"name": "トイ・プードル”,
"category": "小型犬”,
"nutrition": "賢くしつけやすい”,
"note": "毛が抜けにくいがトリミングが必要”
},
{
"name": "ミニチュア・ダックスフンド”,
"category": "小型犬”,
"nutrition": "活発で好奇心旺盛”,
"note": "腰に負担がかかりやすい”
},
{
"name": "シベリアン・ハスキー”,
"category": "中~大型犬”,
"nutrition": "見た目は精悍で運動量が多い”,
"note": "暑さに弱い”
}
]
}
EOF
🌿 観葉植物(plants.json)
cat << 'EOF' > entries/plants.json
{
"entries": [
{
"name": “パキラ”,
"category": "樹木系”,
"nutrition": "耐陰性があり育てやすい”,
"note": "風水で金運アップと言われる”
},
{
"name": "モンステラ”,
"category": "葉物系”,
"nutrition": "独特な葉の形が特徴”,
"note": "明るい日陰を好む”
},
{
"name": “サンスベリア”,
"category": "多肉植物系”,
"nutrition": "空気清浄効果が期待される”,
"note": "乾燥に強い”
},
{
"name": “ポトス”,
"category": "つる性植物”,
"nutrition": "初心者向け”,
"note": "水やり頻度は控えめでOK”
},
{
"name": “ドラセナ”,
"category": "樹木系”,
"nutrition": "直立した葉がインテリアに映える”,
"note": "直射日光は避ける”
}
]
}
EOF
🔌 家電(appliances.json)
cat << 'EOF' > entries/appliances.json
{
"entries": [
{
"name": “冷蔵庫”,
"category": "キッチン家電”,
"nutrition": "食品保存に必須”,
"note": "省エネ性能に差がある”
},
{
"name": "電子レンジ”,
"category": "キッチン家電”,
"nutrition": "時短調理に便利”,
"note": "ターンテーブル式とフラット式がある”
},
{
"name": "洗濯機”,
"category": "生活家電”,
"nutrition": "ドラム式と縦型で使い勝手が違う”,
"note": "乾燥機能付きが人気”
},
{
"name": "掃除機”,
"category": "生活家電”,
"nutrition": "吸引力・静音性が重要”,
"note": "コードレスの普及が進む”
},
{
"name": "炊飯器”,
"category": "キッチン家電”,
"nutrition": "多機能モデルが増えている”,
"note": "圧力式か否かで炊きあがりが変わる”
}
]
}
EOF
✏️ 文房具(stationery.json)
cat << 'EOF' > entries/stationery.json
{
"entries": [
{
"name": “シャープペンシル”,
"category": “筆記具”,
"nutrition": "芯を変えるだけで繰り返し使用可能”,
"note": "芯の硬さで書き心地が変わる”
},
{
"name": “消しゴム”,
"category": "筆記補助具”,
"nutrition": "鉛筆やシャーペンの字を消せる”,
"note": "柔らかさで使い勝手が違う”
},
{
"name": “定規”,
"category": "測定具”,
"nutrition": "長さや直線を測るのに使用”,
"note": "透明タイプが多い”
},
{
"name": "のり”,
"category": "接着具”,
"nutrition": "紙と紙を接着する”,
"note": "液体、スティック、テープ式がある”
},
{
"name": “ホチキス”,
"category": "綴じ具”,
"nutrition": "複数枚の紙をまとめる”,
"note": "針のサイズに注意”
}
]
}
EOF
🧪 実行方法(事前準備)
LM Studioを使う場合
スクリプトを変更して、モデル名とサーバIPアドレスを入れる。LM Studioと同じ環境で動かすならば、localhost
MODEL="gemma-3-12b”
API_SERVER=“192.168.1.70”
Open AI APIを使う場合
スクリプトを変更して、モデル名を指定する。
MODEL="gpt-4.1-nano”
Open AI APIを設定
また実行する前に、以下の環境変数でOpen AI APIのAPIキーを登録する。
export OPENAI_API_KEY=“XXXXXXXXXXXXXXX”
🧪 実行方法
以下のコマンドで動かす。Open AI APIのAPIが環境変数で登録されているかどうか、Open AI APIで動くか、LM Studioで動くかが自動的に決まる。
./sample-ai.sh entries/food.json
./sample-ai.sh entries/appliances.json
./sample-ai.sh entries/plants.json
./sample-ai.sh entries/dogs.json
./sample-ai.sh entries/stationery.json
実行結果例
以下、トークンの利用量とパフォーマンスを兼ねて、food.jsonをそれぞれの環境でやった例。また、接続先でメッセージも変わっているのに注目。
LM Studio (M4 MacBook Air 32GB)
GPUが100%振り切る。CPUは、それほどでもない。
~/mcp-ai# ./sample-ai.sh entries/food.json
🖥️ LM Studio モード(モデル: gemma-3-12b)
🌐 モデル一覧:
- google/gemma-3-12b:2
- mistralai/mistral-7b-instruct-v0.3
- gemma-2-2b-jpn-it
- text-embedding-nomic-embed-text-v1.5
- google/gemma-3-12b
📋 抽出件数: 5 / 指定: 5 / 総数: 5
✅ 抽出済データ:
* たまご:分類「動物性食品」、特徴「高タンパク・ビタミンB群」、補足「加熱すると栄養の吸収が良くなる」
* 牛乳:分類「乳製品」、特徴「カルシウム・タンパク質・ビタミンB2」、補足「アレルギーに注意」
* バナナ:分類「果物」、特徴「カリウム・ビタミンB6・食物繊維」、補足「エネルギー補給に最適」
* ほうれん草:分類「野菜」、特徴「鉄分・ビタミンC・葉酸」、補足「茹でるとアクが抜ける」
* さけ:分類「魚介類」、特徴「良質な脂質(DHA・EPA)・タンパク質」、補足「骨にも注意」
🧠 SYSTEM_PROMPT(展開済):
あなたは優秀な専門家です。以下のルールに従って応答してください。
## 出力ルール:
- Markdownリスト形式
- 各行は1行で簡潔に記述
- 元データの順に並べてください
————————————
🙋 USER_PROMPT:
以下のデータを読み取り、それぞれの特徴を日本語で簡潔に説明してください。
————————————
📦 出力形式指定(FORMAT):
Markdownリスト(例: * 名称:特徴)
————————————
📎 出力例(EXAMPLE):
* たまご:動物性食品で高タンパク。加熱すると栄養吸収率が上がる。
————————————
📡 http://192.168.1.70:1234/v1/chat/completions gemma-3-12b で推論実行中…
📝 AIの解説:
* たまご:動物性食品で高タンパク・ビタミンB群。加熱により栄養吸収が向上する。
* 牛乳:乳製品でカルシウム・タンパク質・ビタミンB2が豊富。アレルギーに注意が必要。
* バナナ:果物でカリウム・ビタミンB6・食物繊維が豊富。エネルギー補給に最適。
* ほうれん草:野菜で鉄分・ビタミンC・葉酸が豊富。茹でるとアク抜きが可能。
* さけ:魚介類で良質な脂質(DHA・EPA)・タンパク質が豊富。骨に注意が必要。
🔢 消費トークン数:
入力: 273 tokens
出力: 140 tokens
合計: 413 tokens
⏱️ 応答時間: 12 秒
LM Studio (12th Gen Core i7 64GB RAM Windows)
GPUは使われず、CPUもそれほど使われず。パフォーマンスはApple Siliconと比較すると10倍近く悪い。さらに出力トークンが少し多い。無料なので構わないが。これは、出力の改行コードなどもトークンに入っているのでは?
~/mcp-ai# ./sample-ai.sh entries/food.json
🖥️ LM Studio モード(モデル: gemma-3-12b)
🌐 モデル一覧:
- google/gemma-3-12b
- text-embedding-nomic-embed-text-v1.5
📋 抽出件数: 5 / 指定: 5 / 総数: 5
✅ 抽出済データ:
* たまご:分類「動物性食品」、特徴「高タンパク・ビタミンB群」、補足「加熱すると栄養の吸収が良くなる」
* 牛乳:分類「乳製品」、特徴「カルシウム・タンパク質・ビタミンB2」、補足「アレルギーに注意」
* バナナ:分類「果物」、特徴「カリウム・ビタミンB6・食物繊維」、補足「エネルギー補給に最適」
* ほうれん草:分類「野菜」、特徴「鉄分・ビタミンC・葉酸」、補足「茹でるとアクが抜ける」
* さけ:分類「魚介類」、特徴「良質な脂質(DHA・EPA)・タンパク質」、補足「骨にも注意」
🧠 SYSTEM_PROMPT(展開済):
あなたは優秀な専門家です。以下のルールに従って応答してください。
## 出力ルール:
- Markdownリスト形式
- 各行は1行で簡潔に記述
- 元データの順に並べてください
————————————
🙋 USER_PROMPT:
以下のデータを読み取り、それぞれの特徴を日本語で簡潔に説明してください。
————————————
📦 出力形式指定(FORMAT):
Markdownリスト(例: * 名称:特徴)
————————————
📎 出力例(EXAMPLE):
* たまご:動物性食品で高タンパク。加熱すると栄養吸収率が上がる。
————————————
📡 http://192.168.1.25:1234/v1/chat/completions gemma-3-12b で推論実行中…
📝 AIの解説:
* たまご:動物性食品、高タンパク・ビタミンB群を豊富に含む。加熱により栄養吸収が向上する。
* 牛乳:乳製品であり、カルシウム・タンパク質・ビタミンB2を含有。アレルギーに注意が必要。
* バナナ:果物で、カリウム・ビタミンB6・食物繊維が特徴的。エネルギー補給に適している。
* ほうれん草:野菜として、鉄分・ビタミンC・葉酸を多く含む。茹でることでアク抜きが可能。
* さけ:魚介類に分類され、DHA・EPAなどの良質な脂質とタンパク質を含む。骨の除去が必要。
🔢 消費トークン数:
入力: 273 tokens
出力: 152 tokens
合計: 425 tokens
⏱️ 応答時間: 54 秒
Open AI API
すごく速い。トークンの利用量が一番多いが、一般的には、一番少ない。圧縮などが効いているとか。下世話なリアルタイム為替でコストも表示。実はブログを発行してから、速攻でつけた後付けの機能。(昔、2chで話題になったXXX計測ソフト作った。というネタばりのスピード感だった。それよりはずっと高尚だがw)
~/mcp-ai# ./sample-ai.sh entries/food.json
🔐 OpenAI モード(モデル: gpt-4.1-nano)
📋 抽出件数: 5 / 指定: 5 / 総数: 5
✅ 抽出済データ:
* たまご:分類「動物性食品」、特徴「高タンパク・ビタミンB群」、補足「加熱すると栄養の吸収が良くなる」
* 牛乳:分類「乳製品」、特徴「カルシウム・タンパク質・ビタミンB2」、補足「アレルギーに注意」
* バナナ:分類「果物」、特徴「カリウム・ビタミンB6・食物繊維」、補足「エネルギー補給に最適」
* ほうれん草:分類「野菜」、特徴「鉄分・ビタミンC・葉酸」、補足「茹でるとアクが抜ける」
* さけ:分類「魚介類」、特徴「良質な脂質(DHA・EPA)・タンパク質」、補足「骨にも注意」
🧠 SYSTEM_PROMPT(展開済):
あなたは優秀な専門家です。以下のルールに従って応答してください。
## 出力ルール:
- Markdownリスト形式
- 各行は1行で簡潔に記述
- 元データの順に並べてください
————————————
🙋 USER_PROMPT:
以下のデータを読み取り、それぞれの特徴を日本語で簡潔に説明してください。
————————————
📦 出力形式指定(FORMAT):
Markdownリスト(例: * 名称:特徴)
————————————
📎 出力例(EXAMPLE):
* たまご:動物性食品で高タンパク。加熱すると栄養吸収率が上がる。
————————————
📡 https://api.openai.com/v1/chat/completions gpt-4.1-nano で推論実行中…
📝 AIの解説:
* たまご:動物性食品で高タンパク・ビタミンB群。加熱で栄養吸収が良くなる。
* 牛乳:乳製品でカルシウム、タンパク質、ビタミンB2を含む。アレルギーに注意。
* バナナ:果物でカリウム、ビタミンB6、食物繊維を豊富に含みエネルギー補給に適している。
* ほうれん草:野菜で鉄分、ビタミンC、葉酸が豊富。茹でるとアクが抜ける。
* さけ:魚介類で良質な脂質(DHA・EPA)とタンパク質を含む。骨にも注意が必要。
🔢 消費トークン数:
入力: 342 tokens
出力: 191 tokens
合計: 533 tokens
💰 推定コスト:
✅ 為替レートUSD/JPY 144.632355
USD: 入力 $0.00003 + 出力 $0.00008 = 合計 $0.00011
JPY: 入力 ¥0.00 + 出力 ¥0.01 = 合計 ¥0.02
🔗 OpenAIの使用量はこちらから確認できます:
👉 https://platform.openai.com/account/usage
🔗 OpenAIの残高はこちらから確認できます:
👉 https://platform.openai.com/settings/organization/billing/overview
⏱️ 応答時間: 2 秒
結果からすると、明らかにWindowsだとNVIDIAなどのGPUがないと不利。
Open AI APIでのモデルごとのコスト例
モデルを変えて、./sample-ai.sh entries/food.jsonを改めて実行してみた。こういう初物は、肌感覚でもかかるお金を知らないと行けないような気がする。(以前、AzureのFWを立ち上げて、1週間で1ヶ月の部門の予算を突破させたことがある身としては。)
為替レート:1 USD = 145 JPY
モデル名 (context length) | 入力 (tokens) | 出力 (tokens) | 合計 (tokens) | 入力 (USD) | 出力 (USD) | 合計 (USD) | 入力 (JPY) | 出力 (JPY) | 合計 (JPY) | 応答時間 | $5での実行回数 |
---|---|---|---|---|---|---|---|---|---|---|---|
gpt-4.1-nano (4,096) | 342 | 186 | 528 | $0.00003 | $0.00007 | $0.00010 | ¥0.00 | ¥0.01 | ¥0.01 | 1 秒 | 50000 回 |
gpt-4.1-mini (8,192) | 342 | 193 | 535 | $0.00014 | $0.00031 | $0.00045 | ¥0.02 | ¥0.04 | ¥0.07 | 2 秒 | 11111 回 |
gpt-4o-mini (8,192) | 342 | 191 | 533 | $0.00021 | $0.00046 | $0.00067 | ¥0.03 | ¥0.07 | ¥0.10 | 3 秒 | 7463 回 |
gpt-4.1 (128,000) | 342 | 188 | 530 | $0.00068 | $0.00150 | $0.00218 | ¥0.10 | ¥0.22 | ¥0.32 | 2 秒 | 2294 回 |
gpt-4o (128,000) | 342 | 186 | 528 | $0.00171 | $0.00372 | $0.00543 | ¥0.25 | ¥0.54 | ¥0.79 | 2 秒 | 921 回 |
より安価・高速なのは gpt-4.1-nano。精度が求められる場面では gpt-4.1 や gpt-4o が有効。ちなみに、このブログのレベルだと、gpt-4.1-nanoでもgpt-4oでも答えはほぼ一緒。
🔧 カスタマイズ方法
いくつか例を出してやってみたが、もちろん自作もできる。
テーマを追加したい
cp entries/food.json entries/mytopic.json
vi entries/mytopic.json # 内容を変更
./sample-ai.sh entries/mytopic.json
出力件数を調整したい
モデルによっては、受け取れるトークンの数の制限があるので、リミットをつけている。リミットを変更するには以下を行う。
samples-ai.sh の先頭で指定:
SUMMARY_LINES=5
これで、終わり。
最後に、このスクリプトのキモについて説明をする。実は以下
jq -r ‘
.entries[] |
"* \(.name):分類「\(.category)」、特徴「\(.nutrition)」、補足「\(.note)」”
' "$ENTRY_FILE" | head -n “$SUMMARY_LINES”
jsonファイルをどうやって抽出、整理するかにかかっている。つまりデータをAIに食わせるデータ整形が一番大変。jsonファイルは構造が定義されているだけで中身の定義はそれぞれ。なので、何かの出力を持ってくる時は、jsonの整形の仕方にかかっている。正しく、ジェイソンの切り裂き方。単に、厚切りではダメなのである。
次回のはあるか?
画像判別のネタもあるんだが、書いていくのがめちゃくちゃ大変なので、ブログでの公開はここまで。
AIは、使う目的とかテーマがないと何もできない。会議議事録の要約といった用途の場合、外的要因で落ちてきた目的なだけで、ほんと自分の仕事の代わりをしているだけなのかもしれない。多分、それが、AIで仕事を奪われると言われる所以で、AIを使って何かをしている?もっと言えば、創造的な仕事をしていれば、AIが出てきても仕事は奪われないのではと思う。
それにしても、これ疲れるなぁ。外がクソ暑いから立てこもっていたからAIに頼ってかけたが、普段だったらここまでブログにはしないわw