朝日新聞社 メディア研究開発センターの山内です。
Typolessの研究開発をしています。
Typolessは朝日新聞社の膨大な記事校正履歴データを学習したAIと新聞社の校正ルール辞書を搭載したハイブリッドな文章校正ツールです。
自分は社内データを活用したモデル開発を担当しており、その中で避けて通れないのが アノテーション です。
高品質なデータがほしいけれど、人手アノテーションはとにかく大変…。
そこで、自分専用のアノテーション支援アプリをClaude CodeのSkills機能を使って1日で作った ときの話を書きます。
なぜアノテーションがつらいのか
例えばこんなJSONがあります:
{
"_item_id": "sample_001",
"_line_number": 1,
"before_edit": "彼は高校2年生だ。自宅から学校までは電車で30分かかる。彼は毎日学校に通っている。",
"after_edit": "彼は高校2年生だ。自宅から学校までは電車で30分かかる。彼は毎日学校へ通っている。"
}
パッと見てどこが変わったかを、判断して保存するまでに自分は 20秒くらい かかりました。
この例ですと、ほぼ同じの文章で変化は「に → へ」レベルのみですが、こういうものを何件もやるとなると、目視比較はかなり消耗します。
困っていたポイントはざっくりこの2つです。
-
目視比較がしんどい・見落としが怖い
長文や細かい助詞の変更はすぐ見落とす -
コピペ作業での単純ミス
行ずれ/貼り間違いなど、後から気付きにくい
「できるだけ見落としを減らしたい」「人手ミスを減らしたい」というのがモチベーションでした。
作ったもの:差分ハイライト付きレビューアプリ
画面イメージ
機能はシンプルです:
- 左:編集前テキスト
- 右:編集後テキスト
- 差分を自動ハイライト(追加=緑、削除=赤)
- OK/NG/スキップボタン
- 判定前の確認ダイアログ(誤操作防止)
- 履歴一覧+取消(Undo)
流れとしては、
- 差分だけ目で追う
- OK or NG or スキップを押す
- 必要ならダイアログで再確認
- 次のサンプルへ
という感じです。
これだけでも「どこが変わったか探す時間」がほぼゼロになりました。
Claude Code + Skills での開発フロー
開発はほぼ Claude Code に手伝ってもらいました。
Skills は、特定のタスクやプロジェクトの知識をパッケージ化し、Claude Codeが毎回その文脈を読み込んだ状態でタスクを実行できるようにする仕組みです。
-
まず、自分の要望をYAMLでざっくり書く
- 左右を比較したい
- 差分ハイライト
- OK/NG/スキップ
- DB保存・履歴・取消 など
-
それをClaude Codeに読み込ませて
skill-creatorを呼ぶ -
.claude/skills/annotation-review-app/SKILL.mdが自動生成される -
以降は「このSKILLに沿って実装して」と投げるだけ
SKILL.mdには、ディレクトリ構成、API設計、UIの構成案などがまとまっていて、半分仕様書・半分ガイド みたいな役割をしてくれます。
技術スタック
今回はまず動かすことを優先して:
- フロントエンド:Vanilla JS + Vite
- バックエンド:FastAPI(Python)
- DB:SQLite
というシンプルな構成にしました。
差分ハイライトの仕組み
外部ライブラリは使わず、最長共通部分列(LCS) を使って文字単位で差分を出しています。
- 両方に共通する部分 → そのまま表示
- beforeにしかない → 削除(赤・取り消し線)
- afterにしかない → 追加(緑)
というルールでCSSを当てるだけですが、細かい助詞の違いやピンポイントな修正も、直感的に見分けられるようになりました。
DB保存と履歴管理
判定結果はSQLiteに保存しています。
-
item_id(サンプルID) -
decision(ok / ng / skip) - 元データ(JSON)
- タイムスタンプ
などを1レコードにしておき、必要に応じてJSONファイルとしてエクスポートします。
履歴画面からは、
- OK/NG/スキップでフィルタ
- 「取消」ボタンで判定の取り消し
といった操作ができます。
アプリ画面
効果:1件20秒 → 5秒へ
このアプリを使うと、冒頭のようなサンプルなら 1件あたり約5秒 で判定できるようになりました。
ざっくりですが、1件あたり20秒 → 5秒くらいの短縮になりました(内容にもよりますが)。
なにより、
- 差分を目で探さなくていい
- コピペがいらない
- OK/NGの押し間違いも確認ダイアログで減らせる
ので、精神的な負荷がかなり下がりました。
失敗談:保存されていなかった問題
もちろん、良いことばかりではなく、ちゃんとやらかしました。
開発初期、保存処理が一部うまく動いていないのに気づかず、
1. 画面上はそれっぽく動いている
2. しかしDB側には一部しか保存されていない
3. 気づいたときには、かなりの件数をやり直し…
「ちゃんと保存されているつもりでアノテーションしていた」という、まあまあ心が折れるパターンでした。
原因を振り返ると、
- 保存処理のエラーハンドリングが甘かった
- UI上で「保存成功っぽく見える」だけの実装にしてしまっていた
- Claudeが自動生成したテストを、深く確認せずに信用してしまった
というあたりが効いていました。
そこで、
- 保存APIのリトライ・エラー表示を強化
- 一括保存時のレスポンス結果をUIに明示
- 履歴画面で「本当に保存されているか」をいつでも確認できるようにする
といった改善を行いました。
テストとの付き合い方
テストについても、正直に言うと ほとんどClaudeに書いてもらいました。
- 機能を追加するたびに =>「この機能用のテストコードも書いて」とお願いする
- 生成されたテストをベースに、必要なところだけ手直し
という進め方です。
ただ、今回の保存ミスのように、「AIの書いたテスト=完璧」ではないことも痛感しました。
今後はとくに、[保存、削除、エクスポート]のような 重大な処理については、人間側の視点でテストケースを追加する ことが重要だと感じました。
AIのテストは「たたき台」としては最高ですが、最後の確認は必要ですね。
今後の展望
作ってみて、「まだまだ広げられそうだな」と感じている方向性がいくつかあります。
1. データ分析への応用
判定ログがたまれば、
- OK/NGの比率・推移
- NGになりやすいパターン
- 作業者ごとの差
などを分析できます。
グラフ化すれば、単なるツールから データ品質の分析基盤 に近づきます。
2. チームで使えるようにする
ユーザ管理を入れれば、
- アカウント・権限管理
- 進捗管理
などができ、チームでのアノテーションにも展開できます。
おわりに
人手アノテーションはどうしても「しんどい」側面が強い作業ですが、ツールを自作して、自分の作業フローに合わせて最適化していくと、体験はかなり変わると実感しました。
アプリ開発経験がほぼなかった自分でも、AIのサポートがあれば、1日で「ちゃんと実用になる」ツールまで持っていけました。
- 既存アプリに「あとちょっとこの機能があれば…」と思うことが多い人
- アノテーションやレビュー作業に時間を取られている人
- Claude Code / Copilot など AI コーディングツールに興味がある人
ぜひ一度 「自分専用の業務ツールをAIと一緒に作る」 ことを試してみてほしいです。
この記事が、どこかで同じようにアノテーションで苦しんでいる方の参考になれば幸いです。




