10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

生成AIでJSON「だけ」の出力を強制させる(Claude 3.5 / Amazon Nova対応)

Posted at

生成AIでJSONを生成させたいことってありますよね。

Claude.aiで試してみます。

JSONのサンプルデータを作成してください。

上手に生成してくれました。
ただ、プログラム内部で使用したい場合、JSONの前後の文字が余計ですよね。

image.png

image.png

余計な出力を行わず、JSON「だけ」を生成させる方法を紹介します。

アシスタントプロンプトに「事前入力」

生成AIのモデルには、ユーザープロンプトだけでなく、アシスタントプロンプトを任意で指定できるモデルがあります。Claude 3.5やAmazon Novaはこれらに対応しています。

JSON形式で出力したい場合、JSONの先頭文字の「{」をアシスタントプロンプトとして指定することで、生成AIが生成する文字列を制御します。

Amazon Bedrockで実行する例(事前入力しない場合)
import boto3

client = boto3.client("bedrock-runtime")

response = client.converse(
    modelId="us.anthropic.claude-3-5-haiku-20241022-v1:0",
    messages=[
        {
            "role": "user",
            "content": [{"text": "JSONのサンプルデータを作成してください。"}],
        }
    ],
)
出力

以下に、さまざまな種類のJSONサンプルデータを提示します:

  1. 基本的なユーザー情報
{
  "id": 1,
  "name": "山田太郎",
  "age": 30,
  "email": "yamada@example.com",
  "isActive": true
}
  1. ネストされた配列を含むデータ
{
  "company": "株式会社サンプル",
  "employees": [
    {
      "id": 1,
      "name": "鈴木一郎",
      "department": "営業"
    },
    {
      "id": 2, 
      "name": "佐藤花子",
      "department": "開発"
    }
  ]
}
  1. 複雑な構造のデータ
{
  "project": {
    "name": "新製品開発",
    "budget": 10000000,
    "team": {
      "leader": {
        "name": "田中次郎",
        "role": "プロジェクトマネージャー"
      },
      "members": [
        {"name": "山本三郎", "position": "デザイナー"},
        {"name": "中村四郎", "position": "エンジニア"}
      ]
    },
    "timeline": {
      "start": "2023-07-01",
      "end": "2024-06-30"
    }
  }
}
  1. 商品情報
{
  "products": [
    {
      "id": 101,
      "name": "スマートフォン",
      "price": 59800,
      "specs": {
        "color": ["ブラック", "ホワイト"],
        "storage": ["128GB", "256GB"],
        "camera": "1200万画素"
      }
    },
    {
      "id": 102,
      "name": "ノートパソコン",
      "price": 89000,
      "specs": {
        "cpu": "Core i7",
        "memory": "16GB",
        "display": "15.6インチ"
      }
    }
  ]
}
  1. 天気情報
{
  "location": "東京",
  "current": {
    "temperature": 25.5,
    "humidity": 70,
    "windSpeed": 5.2,
    "condition": "曇り"
  },
  "forecast": [
    {
      "date": "2023-07-15",
      "highTemp": 28,
      "lowTemp": 22,
      "description": "晴れ"
    },
    {
      "date": "2023-07-16",
      "highTemp": 26,
      "lowTemp": 20,
      "description": "一時雨"
    }
  ]
}

これらのサンプルは、JSONの様々な使用方法と構造を示しています。用途や必要に応じて、適切なJSONデータを選択または参考にしてください。

Amazon Bedrockで実行する例(事前入力する場合)
import boto3

client = boto3.client("bedrock-runtime")

response = client.converse(
    modelId="us.anthropic.claude-3-5-haiku-20241022-v1:0",
    messages=[
        {
            "role": "user",
            "content": [{"text": "JSONのサンプルデータを作成してください。"}],
        },
        {
            "role": "assistant",           # アシスタントプロンプト
            "content": [{"text": "{"}],    # `{`とだけ入力
        }
    ],
)

出力


  "users": [
    {
      "id": 1,
      "name": "山田太郎",
      "age": 35,
      "email": "yamada.taro@example.com",
      "address": {
        "city": "東京",
        "street": "渋谷区恵比寿",
        "zipCode": "150-0013"
      },
      "hobbies": ["読書", "旅行", "料理"],
      "isActive": true
    },
    {
      "id": 2, 
      "name": "鈴木花子",
      "age": 28,
      "email": "suzuki.hanako@example.com",
      "address": {
        "city": "大阪",
        "street": "梅田",
        "zipCode": "530-0001"
      },
      "hobbies": ["音楽", "ダンス"],
      "isActive": false
    }
  ],
  "company": {
    "name": "テクノロジー株式会社",
    "foundedYear": 2010,
    "departments": [
      "開発部",
      "営業部",
      "人事部"
    ],
    "totalEmployees": 250
  },
  "products": [
    {
      "id": "A001",
      "name": "スマートフォン",
      "price": 59800,
      "features": {
        "color": ["黒", "白", "青"],
        "storage": [64, 128, 256]
      }
    }
  ]
}

いい感じですね。

事前入力した「{」は、生成した文字列には含まれないので、注意

「事前入力」と「停止シーケンス」を使う

「事前入力」だけでもおおよそうまくいくのですが、もう少し汎用性のある指定方法が、Amazon Novaのドキュメントにありました。

参考:https://docs.aws.amazon.com/nova/latest/userguide/prompting-structured-output.html

「事前入力」に加え、「停止シーケンス」も使用する方法です。

停止シーケンスとは、生成AIに「この文字を出力したら生成を停止して」と伝えるための設定です。

「事前入力」で生成する文字列の先頭を決め、「停止シーケンス」で生成する文字列の終端を決めます。それぞれに指定する値は以下のとおりです。

  • 事前入力: ```json
  • 停止シーケンス: ```

そうです。Qiitaでもおなじみの「Markdown記法でJSONを生成させる」のです。

import boto3

client = boto3.client("bedrock-runtime")

response = client.converse(
    modelId="us.anthropic.claude-3-5-haiku-20241022-v1:0",
    messages=[
        {
            "role": "user",
            "content": [{"text": "JSONのサンプルデータを作成してください。"}],
        },
        {
            "role": "assistant",                # アシスタントプロンプト
            "content": [{"text": "```json"}],   # 「```json」を指定
        },
    ],
    inferenceConfig={"stopSequences": ["```"]},   # 停止シーケンスを指定
)

出力

{
    "users": [
        {
            "id": 1,
            "name": "山田太郎",
            "age": 35,
            "email": "yamada@example.com",
            "isActive": true,
            "address": {
                "street": "東京都渋谷区",
                "zipCode": "150-0001"
            },
            "hobbies": ["読書", "映画鑑賞", "音楽"]
        },
        {
            "id": 2,
            "name": "鈴木花子", 
            "age": 28,
            "email": "suzuki@example.com",
            "isActive": false,
            "address": {
                "street": "大阪市北区",
                "zipCode": "530-0001"
            },
            "hobbies": ["料理", "旅行"]
        }
    ],
    "company": {
        "name": "サンプル株式会社",
        "founded": 2010,
        "departments": ["営業", "開発", "人事"]
    }
}

この方法の場合は、生成AIの出力がJSONそのものになるので、先頭の「{」がかけることもありません。

Amazon Novaモデルの場合、どうも「停止シーケンスの文字列まで出力に含める」仕様のようです。
そのため、「```」が生成AIの出力に含まれるので取り除いて使用する必要があります。

この方法であれば、JSON出力だけでなく、Pythonプログラムの生成などにも応用が可能ですね。

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?