TechBlogの自動レビューのためのLLM選定
はじめに
現在、WAND(先端技術開発グループ)ではTechBlogの記事のレビュー・投稿の自動化、記事のGitHubの管理に取り組んでいます。
この背景として、TechBlogを書いてもレビュープロセスに時間がかかり、執筆者のモチベーションが損なわれてしまうという課題があり、TechBlogが続かない一因となっていました。また、記事をGitHubの管理下に置き、運用を自動化できるといったメリットもあります。
そこで、記事のレビューにLLMを導入しました。ここで問題になるのが「レビューにどのLLMを使うか」という点です。この記事では、2025年6月現在でのTechBlogのレビューに向いたLLMはどれかという点を検証します。
記事レビューに求める要件
記事のレビューをLLMで自動化しようとしたとき、求められる要件は以下の通りです。
- セキュリティ的に問題がある内容、機密の可能性がある内容を指摘できること
- 記事に添付されている画像(スクショ)も含めて判定できること
- 誤字脱字の修正能力が高いこと
2点目のスクショも含めたいのは、例えばAWSのマネジメントコンソールのスクショなど、AWSアカウントIDが意図せずに公開されてしまうリスクが一定存在するためです。したがって、単なるテキストだけのLLMではなく、マルチモーダルLLM(VLM)が必要になります。
これはNice to haveですが、アプリのデモに動画を添付することもあるため、動画も含めてレビューできれば理想的です。
セキュリティ的・コンプライアンス的に問題のある内容を指摘できること
1点目の「セキュリティ的・コンプライアンス的に問題がある内容を指摘できること」について簡単に検証します。最新のOpenAI、Geminiなど一定性能があるモデルを使えば、要件の1点目を満たせることがわかっています。例えば、以下はセキュリティ的に問題のある記事例です(GPT o4-mini-highで生成)。
問題のある記事での実験
セキュリティ・コンプライアンス的に問題のある記事の例
タイトル:
超高速!AWS Lambda ですぐ使えるサーバーレス画像処理サービス構築ガイド
本文:
最近話題のサーバーレスで、画像処理をポチっとデプロイしてみました。
以下の手順で、3分以内に動かせます!
-
AWS CLI にアクセスキーを直書き
# これは実際のアクセスキーではなくサンプルです(編集注) export AWS_ACCESS_KEY_ID=AKIAEXAMPLE123456 export AWS_SECRET_ACCESS_KEY=secretkeyEXAMPLE987654
-
Lambda 関数(Python)
import boto3 import os s3 = boto3.client('s3') def handler(event, context): bucket = event['bucket'] key = event['key'] obj = s3.get_object(Bucket=bucket, Key=key) data = obj['Body'].read() # TODO: ファイルサイズチェックなしで一気に処理 result = process_image(data) s3.put_object(Bucket=bucket, Key='processed/'+key, Body=result) print("Processed", key) # PIIや機密情報もそのままログに出力
-
注意点まったくなし!
- IAM ロールは
AdministratorAccess
を付与 - データは暗号化しない(暗号化設定不要!)
- エラー処理もログも全部ガンガン出力
- GDPR/個人情報保護法やPCI-DSSなどのコンプライアンスは「あとでやる」でOK
- IAM ロールは
これで「誰でも」すぐに画像処理が始まります。ぜひお試しを!
これをレビューすると当然のように「問題がある」と指摘されます(レビューはOpenAI o1の結果)。
以下の点において、外部にそのまま公開すると問題が発生し得る可能性があります:
1. AWS の認証情報(アクセスキー)が記事に直接記載されている
- "export AWS_ACCESS_KEY_ID=AKIAEXAMPLE123456"
- "export AWS_SECRET_ACCESS_KEY=secretkeyEXAMPLE987654"
これらが実際に有効なキーである場合、第三者に不正利用されるリスクがあります。たとえ例示用/無効化したキーであっても、外形上は「本物のキー」に見えるため、公開前に明確にダミーであることがわかる形(例えばすべて X で置き換えるなど)にすることが望ましいです。
2. IAM ロールに AdministratorAccess が付与されている
すべての操作が可能なロールを安易に公開してしまうと、セキュリティリスクを高める内容とみなされる場合があります。構築例として紹介するだけであっても、「セキュリティ上のベストプラクティスに反する設定」という認識が必要です。
3. 個人情報や機密情報のログ出力リスク
コード中のコメントで「# PIIや機密情報もそのままログに出力」と明記されていますが、これは実運用上かなり危険な行為です。万一こちらのコードをそのまま利用してしまうと、個人情報保護や機密情報漏洩に対する重大なリスクを伴います。
4. 暗号化設定・コンプライアンス対策の欠如
- データ暗号化をしていない、かつログ出力を制限していない
- GDPR、PCI-DSS、個人情報保護法等のコンプライアンス要件を「あとでやる」と記載
こうした運用方針は一般的には好ましくなく、外部公開するテック記事としては不用意に見える可能性があります。少なくとも「データ暗号化」「アクセス制限」「コンプライアンスへの配慮が必要」といった点について注意喚起をした方が望ましいです。
5. スクリーンショットに含まれる情報
記事末尾に添付するスクリーンショットの内容によっては、AWS アカウント ID や個人名等が写り込んでいる場合があります。そうした情報は公開前にマスキングや伏せ字処理を施すことが推奨されます。
まとめると、本記事内では「AWS のアクセスキー(と思われる文字列)やセキュリティ上の危うい設定」が明示的に書かれており、スクリーンショットも含め、外部公開するには以下を検討すべきです:
• アクセスキーを無効化・伏せ字にする。
• IAM ロールの不要に広範な権限付与やログ出力方針について注意喚起を加える。
• 個人情報等がログに出ないような実装上の注意を加筆する。
• スクリーンショットで機密や個人情報が含まれていないか確認・加工する。
以上の修正・対策を行わずにそのまま公開すると、セキュリティリスクやコンプライアンス上の問題が生じる可能性が高いと考えられます。
スクショに問題があっても指摘可能
同様に、パスワードベタ打ちの記事やスクショで検証したところ(詳細は割愛)、OpenAI o1では「以下の点について、外部公開は慎重に検討したほうがよいと思われます。」、Gemini 2.5 Proでは「現状のまま外部公開することは絶対に避けてください。」とそれぞれ正しくレビューされました。
冒頭に「OpenAIやGeminiのような(一定の性能を持った)最新のモデルを使えば1点目は満たせる」と書いた背景は上記のとおりです。
モデル別の対応モダリティ
要件の2点目以降について見ていきましょう。OpenAI、Google、Anthropicのモデルを比較したときに、2025年6月現在での対応モダリティ(テキスト、画像、動画)は以下のようになります。
テキスト | 画像 | 動画 | |
---|---|---|---|
Google Gemini 2.5 Pro | ✓ | ✓ | ✓ |
OpenAI GPT 4.1 / o3 | ✓ | ✓ | |
Anthropic Claude Sonnet 4 | ✓ | ✓ |
2025年6月現在では、動画を直接扱えるのはGeminiだけということになります。この点から、Geminiは一歩リードしていると言えます。
Geminiは大容量動画をAPIで扱えるか
Cloud Storageの必要性
ここで問題になるのは、「Geminiは数百MBの大容量の動画をbase64エンコードの単一APIで判定できるのか」という点です。
Vertex AIの公式ドキュメントでは、最初にGoogle Cloud Storageにアップロードしてから推論しています。しかし、バケットにアップロードすると、バケットの管理の手間も増えます。また、レビュー中のコンテンツをバケットに保存していいのかという別の課題も発生し、今回のケースではよくても、汎用的に使える技術ではなくなってしまいます。そのため、動画もbase64エンコードでAPI推論できるのが理想です。
長尺動画の推論実験
以下の長尺動画(元サイズ100MB)を5秒ごとに区切り、Vertex AIのgemini-2.5-pro
でキャプション生成させます。どこまでが1個のAPIで送れるかを確かめます。
こちらの動画を使用しました。以下のようなコードで推論します。
from vertexai.generative_models import GenerativeModel, Part
model = GenerativeModel(model_name="gemini-2.5-pro")
with open(video_path, "rb") as f:
video_data = f.read()
contents = [
"この動画をタイムスタンプごとに説明して",
Part.from_data(data=video_data, mime_type="video/mp4")
]
response = model.generate_content(contents=contents)
print(f"[{video_path}] Response:\n{response.text}\n")
長尺動画の推論結果
すべて成功。ファイルサイズは100MBですが、JSON形式(base64)にする際のオーバーヘッドなども含めてペイロードが増加しています。
ファイル名 | ペイロードサイズ | 成功 |
---|---|---|
clip_0_005s.mp4 | 1,348,427 | Success |
clip_0_010s.mp4 | 2,866,464 | Success |
: | : | : |
clip_0_585s.mp4 | 174,136,151 | Success |
最終ケースでは以下のようなレスポンスになりました。
はい、承知いたしました。この動画の内容をタイムスタンプごとに説明します。
* **00:00 - 00:03** カメラは地面すれすれの低い位置から、砂利道を前方に見上げるアングルでスタートします。道の両脇には緑の草が生い茂っています。
* **00:03 - 00:16** カメラがゆっくりと上昇し始めます。視点が高くなるにつれて、左手には坂の上のシャレー風の家、右手には農家風の大きな建物と緑の牧草地が見えてきます。砂利道はその間を奥へと 続いています。
* **00:16 - 00:28** カメラがさらに上昇すると、左上から強い太陽光が差し込み、大きなレンズフレア(虹色の光)が発生します。ドローンからの空撮のような視点に移り変わっていきます。
* **00:28 - 00:54** カメラは完全に空中から、眼下の家々や砂利道、そして周囲に広がる緑豊かな丘陵地帯を俯瞰します。太陽のフレアがまだ見えています。
* **00:54 - 01:35** 高い高度から、広大な田園風景をゆっくりと前進しながら映し出します。パッチワークのような畑や牧草地、点在する家々、遠くの山並みが見えます。
* **01:35 - 02:53** カメラは高度を下げ、丘の上の細い舗装路に沿って進みます。道路の右側には麦畑が広がり、赤いポピーの花が点々と咲いています。左側は緑の草地や畑です。
* **02:53 - 03:29** カメラは麦畑のすぐ上をゆっくりと飛行します。風に揺れる緑の麦の穂と、鮮やかな赤いポピー、時折見える青い花がクローズアップされます。その後、再び少し上昇し、広大な景色を 映します。
* **03:29 - 04:38** カメラは旋回しながら、さらに広範囲の景色を映し出します。遠くには雪を頂いたアルプスのような山脈も見えてきます。再び丘陵地帯と家々、畑の上空を飛行し、太陽のフレアが目立 ちます。
* **04:38 - 05:41** 再び高度を下げながら、丘の上の道路と、ポピーが咲く麦畑に近づいていきます。
* **05:41 - 06:21** カメラは麦畑の真上に移動し、真下のアングルになります。一面の麦の穂と、点在するポピーや他の花々の上をゆっくりと進みます。
* **06:21 - 07:13** 真下を向いたままゆっくりと上昇します。道路と畑が小さくなり、周囲の広大な田園風景が再びフレームに入ってきます。
* **07:13 - 08:44** カメラはゆっくりと下降しながら、丘陵地帯、畑、村、森、遠くの雪山を含むパノラマ風景を映し続けます。
* **08:44 - 09:44** カメラは右方向にパン(旋回)しながら、広大な谷、畑、丘、森、そして遠くの山々を広範囲に映し出します。最後は森の上空からの景色で映像が終わります。
100MBの動画に対して、GeminiはCloud Storageなしで推論することが可能でした。
LLMのペイロード制限
少し要件とはずれますが、そもそもLLMのAPIのペイロード制限はどの程度でしょうか。添付ファイルなど、1個の記事が巨大になることがあるため、各種LLMのAPIがどの程度のペイロード制限があるかを検証します。
ペイロード制限の実験
フリー素材のJPEG 50枚(92.2MB)、それをPNG変換した50枚(896MB)を、Base64文字列として1枚ずつペイロードに加え、どこからエラーになるか調べます。比較したモデルは以下の通り。
- Gemini (Vertex AI):
-
gemini-2.5-pro
(GA版) -
gemini-2.5-flash
(GA版)
-
- Anthropic:Claude 4 Sonnet
- Anthropic版:
claude-4-sonnet-20250514
- Amazon Bedrock版:
apac.anthropic.claude-sonnet-4-20250514-v1:0
(Cross-region Inferenceの東京リージョン)
- Anthropic版:
- OpenAI
gpt-4.1
-
o3
(Reasoning Effort=high)
ペイロード制限の結果
モデル | ペイロード制限 |
---|---|
Gemini | 全体で約500MiBのハードリミット(制限)を確認 |
Anthropic | Anthropic版:画像1枚あたり5MB、全体で25MiBまでの厳しい制限 Bedrock版:画像1枚あたり5MB、全体で20MiBとさらに本家より厳しい |
OpenAI | 全体で約200MiBのハードリミット(制限)を確認 |
詳細な結果
モデル | 画像形式 | 成功枚数/総枚数 | 成功時のサイズ | 失敗時のサイズ | 備考 |
---|---|---|---|---|---|
Gemini (Vertex AI)gemini-2.5-pro / gemini-2.5-flash
|
JPEG | 50/50 | 全て成功 | - | - |
PNG | 26/50 | 503MiB | 526MiB | 27枚目で失敗 | |
Anthropic版 Claude 4 Sonnet |
JPEG | 13/50 | 24.4MiB | 25.6MiB | 14枚目で失敗 |
PNG | 0/50 | - | - | 1枚あたり5MB制限 | |
Amazon Bedrock版 Claude 4 Sonnet |
JPEG | 10/50 | 17.4MiB | 20.0MiB | 11枚目で失敗 |
PNG | 0/50 | - | - | 1枚あたり5MB制限 | |
OpenAIgpt-4.1 / o3
|
JPEG | 50/50 | 全て成功 | - | - |
PNG | 12/50 | 195MiB | 230MiB | 13枚目で失敗 |
ペイロード制限の点からも、やはりGeminiが頭一つ抜けている形になりました。Anthropicのモデルは、TechBlogのレビューにおいてもリミットに到達する可能性が高いため、実用には厳しいでしょう。
LLMの校正能力
最後に要件の3点目である、LLMの校正能力を見てみましょう。これについては日本語の評価データセットがあります。
日本語の校正評価データセット
日本語Wikipedia入力誤りデータセット (v2) は、京都大学が公開しているWikipediaの編集履歴から獲得した日本語入力誤りデータセットです(CC-BY-SA 3.0)。これには入力誤り評価データ(ゴールドデータ)があり、校正のBefore/Afterのペアになっています。以下のフォーマットになっています。
{"page": "109", "title": "ロシア", "pre_rev": "27200973", "post_rev": "27259801", "pre_text": "モンゴル西端から北に伸びるたごく狭い範囲に加え、カスピ海沿岸に見られる。", "post_text": "モンゴル西端から北に伸びたごく狭い範囲に加え、カスピ海沿岸に見られる。"}
LLMの校正能力の評価方法
入力誤りデータセットから最初の100件を抽出し、
-
pre_text
だけ見せてLLMに誤字脱字を修正させる(ゼロショット) - LLMの修正結果と
post_text
を比較し、編集距離・ゴールドデータとの一致率を評価する
評価対象モデル
Gemini 2.5 Proが本当に最善かを確かめたいので、OpenAIのモデルと比較します。
- Google
gemini-2.5-pro
- OpenAI
gpt-4.1
- OpenAI
o3
システムプロンプトは「ユーザーから与えられた文章の誤字脱字を修正してください」とします。
校正の評価指標
LLMによる校正結果と、評価データセットのゴールドデータを比較し、2種類の評価指標を定義します。
-
exact_match_ratio
:行単位でゴールドデータに完全に一致した行の割合。高いほど良い。 -
avg_normalized_edit_distance
:各行の文字レベル編集距離を正解文長で正規化した値の平均。低いほど良い。
定量評価
いずれの評価指標においても、Gemini 2.5 Pro(gemini-2.5-pro
)が最良の結果となりました。評価指標は校正を3回したときの平均です。
モデル | mean exact_match_ratio(↑) | mean avg_normalized_edit_distance(↓) |
---|---|---|
gemini-2.5-pro | 0.4333 | 0.0358 |
gpt-4.1 | 0.2600 | 0.0727 |
o3 | 0.0000 | 0.1189 |
OpenAIのモデルは、Gemini 2.5 Proより大きく劣る結果となりましたが、推論モデルのo3(o3
)よりも通常のGPT4.1(gpt-4.1
)のほうが良い結果となりました。しかし、Gemini 2.5 Proは推論モデルであるため、これが原因ではなさそうです。
o3がなぜ最も悪かったのかという仮説について書いておきます。OpenAIのモデルが日本語特有の文化(例:英数字を全角で書く)を理解しておらず、ゴールドデータとの乖離が起きてしまうという点が確認できました。これはGPT 4.1でも見受けられますが、推論モデルのo3の思考プロセス(推論パラメーター:Reasoning Effort=highと、長く思考するように設定)によって、文化に対する不理解がより強く出てしまったのではないかと考えられます。
校正能力の定性評価
差分を比較できるサイトで修正結果を比較してみます。左がLLMによる修正結果、右がゴールドデータです。
Gemini 2.5 Proの場合
一部送り仮名に誤りはあるものの、非常に自然な校正になっています。
OpenAI GPT 4.1
OpenAIの中では最も良かったケース。全角→半角など、日本語特有の書き方に対して余計な修正を行っており、その結果、ゴールドデータとの乖離が起きています。OpenAIのモデルがスコアを落としている理由は「直しすぎ」が原因です。
結論
2025年6月現在、Gemini(特にGemini 2.5 Pro)がTechBlogのレビューに最も適しているという結論になりました。この理由としては、セキュリティ課題を指摘できる能力はもちろんのこと、対応モダリティの多さ(動画対応)、APIで扱えるペイロード容量の大きさ、誤字脱字の修正能力の高さが挙げられます。
今後のモデル進化によって最適なモデルは日々変わるため、この記事のアプローチがモデル選定の参考になれば幸いです。
Discussion