Py初めてのPython

Day 6AIを動かす

ミニ実装: 問い合わせを分類するツール

問い合わせをカテゴリ分けするツールを作りながら、役割・制約・JSON固定のプロンプト設計と安全の基本を学ぶ。

作るもの: 分類ツール

次は、お客さんからの問い合わせ文を「質問」「クレーム」「要望」などのカテゴリに分ける分類ツールを作ります。要約と違って、答えは決まった選択肢の中から選ばせたいので、出力の形をきっちり指定するのがコツです。

プロンプト設計の3本柱

望む結果を安定して得るには、プロンプトに次の3つを書きます。これがLesson 3の「条件つき指示」を一段しっかりさせた形です。

  1. 役割: AIに立場を与える(例: 『あなたは問い合わせを分類する担当者です』)
  2. 制約: 守るべきルール(例: 『カテゴリは指定した3つから必ず1つ選ぶ。推測で新しいカテゴリを作らない』)
  3. 出力形式: 返す形を固定する(例: 『JSON形式だけで返す。前後に説明文を付けない』)

なぜ出力形式をJSONで固定するのか

プログラムがAIの応答を使うには、機械が読める決まった形が必要です。JSON(データを表す標準的なテキスト形式)で固定すると、応答をそのままPythonの辞書に変換して次の処理に渡せます。自由な文章のままだと、毎回書き方が変わって取り出しに失敗します。

PYTHON
import os
import json
from anthropic import Anthropic

client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

CATEGORIES = ["質問", "クレーム", "要望"]

def classify(text: str) -> dict:
    prompt = (
        "あなたは問い合わせを分類する担当者です。\n"
        "次の問い合わせを、必ず以下のいずれか1つに分類してください: "
        + "、".join(CATEGORIES) + "。\n"
        "新しいカテゴリを作らないこと。判断に迷う場合は category を \"質問\" にすること。\n"
        "出力はJSONのみ。形式: {\"category\": \"...\", \"reason\": \"...\"}\n\n"
        "問い合わせ: " + text
    )
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=200,
        messages=[{"role": "user", "content": prompt}],
    )
    raw = response.content[0].text.strip()
    data = json.loads(raw)  # JSON文字列をPythonの辞書に変換
    return data

result = classify("届いた商品が壊れていました。交換してほしいです。")
print(result["category"])  # 例: クレーム
役割・制約・JSON固定の3点をプロンプトに書き、応答をjson.loadsで辞書に変換する

検算: 想定外の答えをはじく

JSONで返せと指示しても、AIが形式を外したり、指定外のカテゴリを返すことがゼロではありません。だからコード側で『本当に想定した形か』を確認します。これが分類ツールにおける検算です。

PYTHON
def classify_safe(text: str) -> dict:
    data = classify(text)
    # 検算1: category が想定した3つのどれかか
    if data.get("category") not in CATEGORIES:
        return {"category": "要確認", "reason": "想定外のカテゴリが返された"}
    return data

# 実務では json.loads が失敗する場合の try/except も足す
AIの答えをそのまま信じず、想定した選択肢に入っているか確かめてから使う

検算なし

AIの応答をそのまま後続処理へ。想定外の値やJSON崩れでプログラムが止まる、または誤ったまま進む。

PYTHON
category = classify(text)["category"]
save_to_db(category)  # 変な値でもそのまま保存

検算あり

想定した選択肢か確認し、外れたら『要確認』に回す。誤りが下流に漏れない。

PYTHON
data = classify_safe(text)
if data["category"] == "要確認":
    send_to_human(text)  # 人に回す
else:
    save_to_db(data["category"])

安全の基本: キーとハルシネーション

  • APIキーは環境変数から読み、コードや公開リポジトリに絶対に置かない
  • AIの答えは必ず『想定した形・値か』を検算してから使う
  • 判断に迷う入力は、AIに無理やり決めさせず『要確認』として人に回す道を用意する
  • 個人情報や機密を含む文章をそのまま送ってよいか、送信前に確認する

AIは『わからない』でも自信満々に答える

AIは判断がつかないときでも、それらしいカテゴリを堂々と返すことがあります。だから『迷ったら質問にする』『想定外なら要確認に回す』という逃げ道をプロンプトとコードの両方に用意しておくと安全です。

AIにはこう聞く

「この分類プロンプトに、役割・制約・出力形式(JSON固定)が揃っているかレビューして。抜けがあれば指摘して」と頼むと、プロンプト設計の質を上げられます。さらに『json.loadsが失敗したときのtry/exceptを足して』と頼めば、検算も堅くなります。

読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。

理解度チェック

答えられれば、面接で説明できる状態に一歩近づきます。

Q1

分類ツールの出力形式をJSONで固定する主な理由はどれ?

Q2

分類結果に対する「検算」として、コード側で行うべきことはどれ?

Q3

プロンプト設計の「役割・制約・出力形式」の3本柱と、コード側の「検算」がなぜ両方必要なのかを説明してください。

記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。