AI に渡すデータの token 数は json より yaml のほうが大幅に少ない

# AI の利用料金は token 数で決まります

## 無料アプリに AI 機能をつけてしまった...

弊社では ブラウザだけで使える無料統計ソフト Reactive stat を提供しています。
信頼性の高い R で統計解析し、その結果を AI が解説します！

https://www.emuyn.net/stats

### 当初の AI 機能は token 数の比較的少ない解説のみでした

リリースした時点でのAI機能は、**R** からの出力をAIに解説させるというものだけでした。
この機能では比較的トークン数は少なめでした。

解析内容にもよりますが、INPUT TOKENS	800程度、OUTPUT TOKENS 500程度です。

### 統計アプリで解析手法を AI に提案させる機能で token 数激増

ところが、統計アプリで解析手法を AI に提案させる機能をつけたところ、token数が異常に増えてしまいました。

その理由は、アプリが扱える解析手法のリストをあらかじめ渡しておかなければならないことと、解析対象となるデータの特徴量を渡さなければならないからです。

当初は、json 文字列でそれらのデータを渡していました。
具体的な内容は別記事に書いていますのでご参照ください。

[統計アプリで解析手法を AI に提案させてみた](https://qiita.com/emuyn/items/27ec61461591728f8986)

## token 数を減らすには？

当初は標準であるという理由だけで json で渡していましたが、より簡潔な yaml を使った方が少なくて済むということに気づきました。

実際に AI に渡していた情報の一部で試してみました。

```json:json
[
  {
    "category": "名義変数の解析",
    "items": [
      {
        "label": "1標本の比率の検定",
        "methods": [
          "1標本の比率の検定"
        ],
        "link": "https://www.emuyn.net/stats/one_sample_proportion_test"
      },
      {
        "label": "分割表の作成と群間の比率の比較",
        "methods": [
          "カイ二乗検定",
          "Fisherの正確確率検定"
        ],
        "link": "https://www.emuyn.net/stats/two_way_table"
      },
      {
        "label": "対応のある比率の比較(McNemar検定)",
        "methods": [
          "McNemar検定"
        ],
        "link": "https://www.emuyn.net/stats/mcnemar_test"
      },
      {
        "label": "対応のある3群以上の比率の比較 (Cochran Q 検定)",
        "methods": [
          "Cochran Q 検定"
        ],
        "link": "https://www.emuyn.net/stats/cochran_q_test"
      }
    ]
  },
  {
    "category": "連続変数の解析",
    "items": [
      {
        "label": "1標本の平均値のt検定",
        "methods": [
          "1標本の平均値のt検定"
        ],
        "link": "https://www.emuyn.net/stats/single-sample_t-test"
      },
      {
        "label": "対応のない群間の検定",
        "methods": [
          "t検定",
          "F検定",
          "ANOVA",
          "Bartlett検定",
          "Levene検定",
          "Tukey HSD",
          "Mann-Whitney U検定",
          "Kruskal-Wallis検定",
          "Jonckheere-Terpstra検定"
        ],
        "link": "https://www.emuyn.net/stats/not_paired_tests"
      },
      {
        "label": "対応のある群間の検定",
        "methods": [
          "対応のある t検定",
          "Wilcoxon の符号順位検定",
          "反復測定ANOVA",
          "フリードマン検定",
          "Wilcoxonの符号順位検定を用いたペアワイズ比較"
        ],
        "link": "https://www.emuyn.net/stats/paired_tests"
      },
      {
        "label": "相関と回帰",
        "methods": [
          "散布図",
          "相関係数",
          "回帰直線",
          "Pearsonの積率相関係数",
          "Spearmanの順位相関係数",
          "単回帰"
        ],
        "link": "https://www.emuyn.net/stats/relation_inspector"
      },
      {
        "label": "散布図行列",
        "methods": [
          "散布図行列",
          "相関関係"
        ],
        "link": "https://www.emuyn.net/stats/scatterplot_matrix"
      }
    ]
  }
]
```

そのまま yaml に変換したもの

```yaml:yaml
- category: 名義変数の解析
  items:
    - label: 1標本の比率の検定
      methods:
        - 1標本の比率の検定
      link: https://www.emuyn.net/stats/one_sample_proportion_test
    - label: 分割表の作成と群間の比率の比較
      methods:
        - カイ二乗検定
        - Fisherの正確確率検定
      link: https://www.emuyn.net/stats/two_way_table
    - label: 対応のある比率の比較(McNemar検定)
      methods:
        - McNemar検定
      link: https://www.emuyn.net/stats/mcnemar_test
    - label: 対応のある3群以上の比率の比較 (Cochran Q 検定)
      methods:
        - Cochran Q 検定
      link: https://www.emuyn.net/stats/cochran_q_test

- category: 連続変数の解析
  items:
    - label: 1標本の平均値のt検定
      methods:
        - 1標本の平均値のt検定
      link: https://www.emuyn.net/stats/single-sample_t-test
    - label: 対応のない群間の検定
      methods:
        - t検定
        - F検定
        - ANOVA
        - Bartlett検定
        - Levene検定
        - Tukey HSD
        - Mann-Whitney U検定
        - Kruskal-Wallis検定
        - Jonckheere-Terpstra検定
      link: https://www.emuyn.net/stats/not_paired_tests
    - label: 対応のある群間の検定
      methods:
        - 対応のある t検定
        - Wilcoxon の符号順位検定
        - 反復測定ANOVA
        - フリードマン検定
        - Wilcoxonの符号順位検定を用いたペアワイズ比較
      link: https://www.emuyn.net/stats/paired_tests
    - label: 相関と回帰
      methods:
        - 散布図
        - 相関係数
        - 回帰直線
        - Pearsonの積率相関係数
        - Spearmanの順位相関係数
        - 単回帰
      link: https://www.emuyn.net/stats/relation_inspector
    - label: 散布図行列
      methods:
        - 散布図行列
        - 相関関係
      link: https://www.emuyn.net/stats/scatterplot_matrix
```

### 結果

| 形式 | トークン数 |
|:----:|:-----:|
| JSON | 約 620 |
| YAML | 約 430 |

この例では、YAMLを使用することで、JSONと比較して約30％のトークンを節約できています。もちろん、この割合は、データの構造や内容によって異なりますが、一般的には、YAMLを使用することで10％から30％程度のトークン数を削減できるようです。

### 実際の変化

これまで json で渡していた事前情報とデータの特徴量を yaml にした実際の例は以下の通り。
 Anthropic の dash board から取得した数値です。

| 形式 | 入力トークン数 |
|:----:|:-----:|
| JSON | 4626 |
| YAML | 3275 |

YAMLを使用することで、JSONと比較して**トークン数が29%減少**しました。

与えた prompt には事前情報やデータの特徴量以外に、自然言語での様々な指示と、ユーザーが入力する "何を調べたいのか" の文章もあり、そこは変わっていないのですから、この減少は相当なものです。

### yaml にしたことでAIの回答に問題は生じませんでした

AIからの出力は毎回異なるので厳密なことはわかりませんが、解析手法の名前とそのURLの対応を間違ったりすることはありませんので、構造化されたデータとしてきちんと認識されているのは間違いないです。

### 使ったライブラリ

json から yaml への変換には、定番の ```js-yaml``` というサードパーティのライブラリを使用しました。

## エコになりました

Anthropic に支払う利用料金は減少し、レスポンスも早くなりました。消費電力も減ってエコになりました。