生成AIでJSONを生成させたいことってありますよね。
Claude.ai
で試してみます。
JSONのサンプルデータを作成してください。
上手に生成してくれました。
ただ、プログラム内部で使用したい場合、JSONの前後の文字が余計ですよね。
余計な出力を行わず、JSON「だけ」を生成させる方法を紹介します。
アシスタントプロンプトに「事前入力」
生成AIのモデルには、ユーザープロンプトだけでなく、アシスタントプロンプトを任意で指定できるモデルがあります。Claude 3.5やAmazon Novaはこれらに対応しています。
JSON形式で出力したい場合、JSONの先頭文字の「{
」をアシスタントプロンプトとして指定することで、生成AIが生成する文字列を制御します。
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サンプルデータを提示します:
- 基本的なユーザー情報
{ "id": 1, "name": "山田太郎", "age": 30, "email": "yamada@example.com", "isActive": true }
- ネストされた配列を含むデータ
{ "company": "株式会社サンプル", "employees": [ { "id": 1, "name": "鈴木一郎", "department": "営業" }, { "id": 2, "name": "佐藤花子", "department": "開発" } ] }
- 複雑な構造のデータ
{ "project": { "name": "新製品開発", "budget": 10000000, "team": { "leader": { "name": "田中次郎", "role": "プロジェクトマネージャー" }, "members": [ {"name": "山本三郎", "position": "デザイナー"}, {"name": "中村四郎", "position": "エンジニア"} ] }, "timeline": { "start": "2023-07-01", "end": "2024-06-30" } } }
- 商品情報
{ "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インチ" } } ] }
- 天気情報
{ "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データを選択または参考にしてください。
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プログラムの生成などにも応用が可能ですね。