slack-explorer-mcpでは、該当メッセージのpermalink URLをレスポンスで返さずに、利用側のAI Agentで組み立ててもらっている。なぜなら、permalinkをメッセージごとに返してしまうとトークン消費量が非常に多くなってしまうからだ。permalinkは他で返しているデータで再構築できるため省略し、利用側で組み立ててもらうことでトークン節約をしている。しかし、この方法だとうまくいったりうまくいかなかったりという現象が起きていた。
slack-explorer-mcpは現状はonelineのJSON形式で巨大なレスポンスを返している。これを人間にも読みやすい改行・インデントありのJSON形式にすることでLLMにとっても精度が上がるのかを知りたくなった。
そこで今回は、データの整形方法(改行・インデントの有無)がLLMの回答精度に与える影響を検証した。検証のテストケース量やデータ量は少ない状態(リストデータ数が100個、テストケースが16個程度)なので参考程度にしてほしい。
実験した場所: shibayu36/playground/extract-slack-url-eval
結論
検証の結果、次の3つのことが分かった。
- 改行・インデントで読みやすい形に整形しても特に精度は上がらない
- LLMモデルが強くなればなるほど整形による精度の差がなくなっていく
- RAGにおいてはトークン効率が最も良いフォーマットを選んでおけば良さそう
ちなみに最近データフォーマットによる回答精度に差があるが、LLMモデルが強くなると差がなくなるという議論を見かけた。こちらは改行やインデント有無ではなく、MarkdownやCSV、JSONLなどデータフォーマットの差での検証をしているが、似たような結論になっていそうだ。
検証方法
promptfooというツールを使って検証した。
まずテストのためのRAGデータとして、slack-explorer-mcpが返すメッセージ検索のレスポンスを模したダミーデータを用意した。そのデータに対して次の3つの形式を用意した。
- oneline JSON: 改行やインデントなしのJSON形式
- pretty JSON: 改行・インデントありで整形したJSON形式
- CSV: カンマ区切りのCSV形式。改行を含みトークン効率の良い形式だとどうなるか確認するため
実際のダミーデータ例はこんな感じ。詳しくはmessages-pretty.jsonを参照。
{ "workspace_url": "https://example.slack.com", "messages": { "matches": [ { "user": "U012ABC3DEF", "text": "BigQuery materialized viewの重複排除についての詳細な調査結果を共有します\n\n調査の結果、以下のことが分かりました:", "ts": "1756096495.765749", "channel": { "id": "C01ABC2DE", "name": "general" } }, { "user": "U023DEF4GHI", "text": "了解です!", "ts": "1756096501.234567", "channel": { "id": "C01ABC2DE", "name": "general" }, "thread_ts": "1756096495.765749" }, ...
プロンプトは次のように、Slackのpermalinkを生成するための情報を含めて、permalink URLのみ出力するようにした。
Your role is to construct the permalink URL for a single Slack message specified by the user from Slack message data. Use the information below to construct the permalink URL. # How to construct the permalink Response includes workspace_url, channel.id, and ts (timestamp) which can be used to construct Slack permalinks: - Regular message (no thread_ts field): {workspace_url}/archives/{channel.id}/p{ts without dot} - Thread reply (has thread_ts field): Same URL with ?thread_ts={thread_ts}&cid={channel.id} # Output format Output only the permalink URL. # Slack message information {{RAG data}} # Let's begin Please construct the Slack permalink URL according to the instructions below. {{input}}
テストケースは16個用意。例えばinputに入るテストケースはこのようなものがある。全テストケースはこちらを参照。
- 3番目のメッセージのURLが知りたい
- BigQueryについて話しているメッセージのURL
さらに検証モデルとしては、モデル性能差による違いも見るため、最新モデルと、少し古いモデルを選定した。
- gpt-5-2025-08-07(最新)
- gpt-4.1-mini-2025-04-14(少し古い小型モデル)
- claude-sonnet-4-5-20250929(最新)
- claude-3-7-sonnet-20250219(少し古い)
結果
16テストケースにおける正答率は次のとおりだった。
| モデル | oneline JSON | pretty JSON | CSV |
|---|---|---|---|
| gpt-5 | 100% (16/16) | 100% (16/16) | 100% (16/16) |
| gpt-4.1-mini | 62.50% (10/16) | 43.75% (7/16) | 68.75% (11/16) |
| claude-sonnet-4-5 | 62.50% (10/16) | 68.75% (11/16) | 75% (12/16) |
| claude-3-7-sonnet | 56.25% (9/16) | 56.25% (9/16) | 43.75% (7/16) |
gpt-5は全フォーマットで驚異の正答率100%で、フォーマットによる差が全くなかった。他のモデルでは、それぞれ精度が高いフォーマットはバラバラ。
この結果から、改行・インデントを入れると精度が上がるということはなく、さらにモデルが強くなればフォーマットによる差がなくなっていくことが確認できた。
まとめ
今回の検証から、RAGでLLMにリストデータを渡すとき、改行・インデントで読みやすい形に整形しても特に精度は上がらない事が分かった。またLLMモデルが強くなれば、フォーマットによる差はなくなっていく。現在のgpt-5でも正答率100%だったため、今後はさらに差がなくなっていくだろう。
この結果から、逆説的にRAGにおいてはトークン効率が最も良いフォーマットを選んでおけば良いと言える。今回のRAGデータでは
- oneline JSON: 6,479トークン
- pretty JSON: 9,144トークン
- CSV: 4,784トークン
となっており、CSV形式が最もトークン効率が良いため、slack-explorer-mcpでもCSV形式を採用しても良さそうだ。