考察とは名ばかりで感想?

最近は主にゲーム(戦略系)と資産運用(FXで食ってくぞ!)

【アニメ配信情報をAIで調べるシリーズ】圧縮プロンプトをレベルアップ!入出力をJSONでキッチリ構造化しちゃいました

新アニメの配信情報を調べるのは手間がかかる…。そんなお悩みをAIで解決する方法を考えたのが前回

kurutto115.hatenablog.com

しかしこの方法には課題がありました。調査する量が増えるほどに、調査結果に間違いが増え、書式などの指示が無視されてしまいます。能力の高いモデルを使えばマシですが、できれば課金しないで済ませたい!

そこで今回採用したアプローチはプロンプトと調査結果をJSON形式にすること。果たしてその結果は如何に

プロンプト

{
  "task": "For each anime in the provided list, generate a JSON object with its broadcast/streaming info. One JSON object per anime. Output JSON objects as One text. No other text is needed.",
  "rules": {
    "source_priority": ["Official sites/SNS", "News/TV Station/Platform sites"],
    "output_schema": {
      "description": "The required JSON structure for each anime is as follows:",
      "json_structure": {
        "タイトル": "string",
        "地上波最速": {
          "放送局": "string",
          "曜日": "string",
          "時間": "string (24h format, e.g., '26:30')"
        },
        "最速配信": {
          "配信サービス": ["string"],
          "曜日": "string",
          "時間": "string (24h format, e.g., '26:30')"
        }
      }
    },
    "missing_data_handling": {
      "description": "Default values for missing fields, categorized by data type.",
      "defaults": {
        "object": null,
        "string": "",
        "array": \[\]
      }
    }
  },
  "season_cour": "e.g., `2025夏`"
}

※ はてなブログでは中身の無い半角[]のペアが表示出来ないようで、上記のプロンプトではエスケープとして\を記入しておいた。実際にプロンプトを利用する際はエスケープ無しで利用して良い

使い方

調査タイトル一覧を作成

調べたいアニメのタイトルをリストにしてテキストファイルに保存しておきます

(これだけでも面倒なのでAIにやらせる方法は前回書きました

DeepResearchを実行

対話型AIにタイトル一覧のテキストファイルを添付し、上のプロンプトを入力してDeep Researchします

(プロンプトの最下部に放送クールを提示する箇所があるので、調べるアニメに応じて「2025夏」などと書いておきます)

Deep Researchが終了すると、調査結果がJSON形式で出力されます

結果をまとめる

出力されたJSONデータをファイルに保存し*1、それを対話型AIに添付して表に変換させます

補足

精度向上を狙って前回のプロンプトからは大分機能を省きました。上記のスクショではBS最速放送も調べさせてますが、結果が芳しくなかったのでそれすら省略。それと調査対象のアニメに番号を振って、出力ではタイトルの代わりにIDとしてその番号を使うことで出力サイズを減らし、精度の向上を狙ったのですが逆効果でした。上のプロンプトは普通にタイトルで出力するようにしています

それと出力にJSONを使うよう指示しているわけですが、JSONをテキストとして出力するよう明示しています。これを書かないと何も表示されない危険があります。プロンプトを送信した後で表示されるDeep Researchの調査計画がJSONを作成して終わりで、テキストとして表示すると書かれていない場合はその旨を手動で追加しましょう

解説

JSONとは

そもそもJSONって何なんでしょう?  JSONはデータを構造化するテキストの書式で、JavaScript Object Notationの略…ってこの説明じゃわけわかめですよね

データの構造化というのは、例えば表にまとめることです

名前 年齢 使用言語
太郎 38 日本語、英語

こうすると視覚的に分かりやすい一方、人間にはこれで良くてもコンピューターが扱うには面倒なわけです。だからこの表もウェブページとしてはHTMLで表現されているのですが

<table>
  <tr>
    <td>名前</td>
    <td>年齢</td>
    <td>使用言語</td>
  </tr>
  <tr>
    <td>太郎</td>
    <td>38</td>
    <td>日本語、英語</td>
  </tr>
</table>

人間にはごちゃごちゃしてきましたね?*2 まだシンプルな表なので理解が追いつきますが、これが健康診断の結果で、数値が10個くらい並んでたらどれがどれやらになっちゃう。それがJSONを使うと、こう!

{
  "名前": "太郎",
  "年齢": 38,
  "使用言語": ["日本語", "英語"]
}

これなら人間にもコンピューターにも分かりやすい。しかもタグとか無いのでシンプル且つ軽量で互換性も高い。なのでプログラミング言語を問わず使われるようになりました(その名の通り元はJavaScript用です)

加えて色々なデータを扱えます。上記の例だと文字列、数値、文字列のリストを使ってますね。更に入れ子構造に出来たりもするのでかなり応用が利きます

出力をJSONにする利点

最終的にはこういう表を作りたいんですよ

タイトル 地上波最速 BS最速 最速配信 ニコ動 dアニ
追放者食堂へようこそ! MX 木 24:00 BS11 木 24:30 dアニ/Lemino/アニメタイムズ
木 22:30
[無料/プレ限]
日 22:30
木 22:30

ところがいきなりAIにこれを作らせようとすると、細々した書式を指示する必要があります。地上波最速は「局 曜日 時間」の形式で、最速配信が複数ある場合は”/”で区切り、ニコニコ動画で最新話無料の場合は…などなど。優秀なモデルはちゃんと従ってくれますが、調べる量が増えるほどに指示を無視されるようになりますし、細かい指示が増えるほど調査結果の精度も落ちていきます

そこで表ではなくJSONだとこうなります

{
  "タイトル": "追放者食堂へようこそ!",
  "地上波最速": {
    "放送局": "MX",
    "曜日": "木",
    "時間": "24:00"
  },
  "BS最速": {
    "放送局": "BS11",
    "曜日": "木",
    "時間": "24:30"
  },
  "最速配信": {
    "配信サービス": ["dアニ","Lemino","アニメタイムズ"],
    "曜日": "木",
    "時間": "22:30"
  },
  "ニコ動": {
    "最新話無料": True,
    "プレミアム会員 見放題": True,
    "曜日": "日",
    "時間": "22:30"
  },
  "dアニ": {
    "曜日": "木",
    "時間": "22:30"
  }
}

これならJSONの雛形を渡して空欄を埋めてねで終わりです。書式はJSONから表にするときに何とでもできます。こういう後処理しやすいのもJSONの利点ですね

それと今後の応用なんですが、出力の精度を上げるために複数回に分けて調査するのを考えてまして、それをやる場合直接表で出力するといよいよ書式の整合を取るのが課題になっていくんですね。最悪個人利用だから書式がバラバラでも気にしないと決め込む手もあると思いきや、地上波最速で1列の表もあれば局、曜日、時間の3列で出力される場合もあるみたいなケースだと表を合体させられないのでお手上げになります。だったらJSONで出力させてデータを統合してから書式も整えれば良いんです

入力をJSONにする利点

前回作ったプロンプトにはマークダウンを利用していました。マークダウンというのは次のような、記号で簡単に見出し、箇条書き、太字などの書式を指示できる表記法です

## 目的

アニメの放送・配信情報を調査する。出力は**表のみ**とすること

## ルール

- 情報源

-+ 公式サイト/SNS

-+ ニュースサイト、放送局/配信サービスの公式サイト

- 書式

-- 時間:24時間表記(例:25:00)

-- 情報が無い場合の表記:「情報無し」

## 出力形式

| タイトル | 地上波最速 | BS最速 | 最速配信 |
| :----- | :----- | :----- | :----- |
| [アニメタイトル] | [局 曜日 時間] | [局 曜日 時間] | [サービス 曜日 時間] |

## 調査対象

- アニメA

- アニメB

HTMLなどと比べてシンプルで軽量。そのため人が見ても理解、編集しやすく、各種wikiやブログで同様の記法が盛んに用いられていますね。この特徴からAIにも理解しやすく、トークン量も少なく済ませることができるのでプロンプトにも利用されています

そもそもマークダウン抜きにしてもプロンプトに見出しや箇条書き、太字などを使うと、単純に全部文章で説明するよりもAIが理解しやすくなるわけです(人間が読む場合と一緒ですね)。これもある種の構造化であり、であればJSONが使えるわけですね?

{
  "目的": "アニメの放送・配信情報を調査する。出力は表のみとすること",
  "ルール": {
    "情報源": [
      "公式サイト/SNS",
      "ニュースサイト、放送局/配信サービスの公式サイト"
    ],
    "書式": {
      "時間": "24時間表記(例:25:00)",
      "情報が無い場合の表記": "情報無し"
    }
  },
  "出力形式": {
    "タイトル": "アニメタイトル",
    "地上波最速": ["局", "曜日", "時間"],
    "BS最速": ["局", "曜日", "時間"],
    "最速配信": [["サービス"], "曜日", "時間"]
  },
  "調査対象": [
    "アニメA",
    "アニメB"
  ]
}

というわけで上のマークダウンをJSONにするとこうなります。より厳密でAIに誤解されにくいのが利点。他にも様々なプログラムで扱いやすいので前処理しやすかったり、複雑な指示も的確に表現できるので、複数の対応する入出力例を与える*3とか段階的な検討手順を与える*4などの技法が使いやすかったりします

(プロンプトもJSONにしてみて気付いたんですが、オブジェクト指向プログラミングでデータだけじゃなくサブルーチンも、クラス作って色々定義したオブジェクトとして呼び出すの、あれもプロンプトと一緒で構造化してるわけかぁ〜!)

プロンプトの仕様

というわけでJSONにした今回のプロンプト、それだけだとどんな内容か分かりにくいので日本語のマークダウンにすると次のようなものになります

## タスク

添付の一覧記載の各アニメに対して、放送・配信情報のJSONオブジェクトを作成する。アニメ1作品ごとにJSONオブジェクトが1つ。出力はJSONをテキスト形式で1つにまとめ、それ以外の文章は不要

## ルール

- 情報源の優先順位

 1. 公式サイト/SNS

 2. ニュースサイト、放送局/配信サービスの公式サイト

- 出力形式: アニメ1作品ごとに次の構造のJSONとする

(JSONの構造については略。ここで時間は24時間表記だと指示している)

- 情報が無い場合: データの種類に応じて次の値で埋める。オブジェクト -> null, 文字列 -> "", 配列 -> []

## 放送シーズン

(例:2025夏)

最初からJSONでプロンプトを作るのはややこしいので、平文かマークダウンで書いてからAIにJSON化させると良いでしょう

まとめ

今回は出力をJSONにすることで、書式をコントロールしやすくできました。一方で出力を安定させようと前回より機能を大幅に削減しましたが、それでも精度はあまり向上できず…*5

そこで(既に少々触れましたが)、調査を複数回に分けて結果を後で統合することにより精度を上げようと目論んでいます。更にそれらを自動で行う仕組みも…? 次回の記事を乞うご期待!

おまけ

JSONにしたプロンプトが今一精度を上げられなかったので、そこら辺がまだマシなマークダウンのプロンプトをおまけで書いとこうと思います

## Task
Generate a Markdown table of anime broadcast/streaming info. Output the table ONLY, no other text.

## Rules
- **Sources**: 1.Official sites/SNS > 2.News/TVStation/Platform sites
- **Formatting**:
  - Time: 24h format (e.g., 25:00).
  - Missing data: `情報なし`
- **Table Columns**: `| タイトル | 地上波最速 | 最速配信 |`

## Season/Cour (Optional)
[例:2025年夏]

## Anime Title
[ここに調査したいアニメのタイトルを記入]

以前より機能を削減した結果、モデルがGemini 2.5 Flashでも精度はバッチリです!(BS最速は犠牲になったのだ…)。まあその分書式が完全にAIにお任せになってしまい、わざわざ放送開始日を書かれたりするんですが

*1:結果をコピペしたテキストファイルを作って拡張子.jsonで保存すれば良い

*2:書式設定を省略してだいぶスッキリしてもこれ

*3:Few-shotプロンプティングという手法

*4:Chain of Thoughtと呼ばれる手法

*5:出力の形式がきっちり定まった分、AIが楽できなくなってるのかもしれません