AIと二人三脚でつくる知識辞典——Astroサイト開発の記録

はじめに

「知識の備忘録」というNDC(日本十進分類法)に基づく用語辞典サイトを、Claudeと一緒に作り上げてきました。最初はシンプルな静的サイトだったものが、AIによるコンテンツ自動生成・校閲・品質管理まで備えた本格的なシステムへと進化しています。この記事では、その開発の歩みと、途中で見つけた問題・解決策を日記形式でまとめます。


プロジェクトの概要

サイト名: 知識の備忘録(https://ssg.infopalatte.net)

技術スタック:

  • フレームワーク: Astro 6.1
  • 検索: Pagefind(静的サイト全文検索)
  • コンテンツ: Markdown + Astro Content Collections
  • 分類体系: NDC(日本十進分類法)第10版
  • コンテンツ生成AI: Google Gemini API(gemma-3-27b-it / gemma-4-26b-a4b-it)
  • ローカルLLM校閲: LM Studio + DeepSeek-R1-Distill

現在の辞書エントリ数: 436件以上(自動生成)


開発の歩み

フェーズ1:基盤の構築

最初に取り組んだのは、Astroのコンテンツコレクション設計です。辞書エントリのフロントマターに何を持たせるかを丁寧に考えました。最終的に以下のフィールド構成に落ち着いています。

title: 'AIエージェント'
reading: 'えーあい えーじぇんと'    # ひらがなのみ(五十音ソート用)
definition: '一言で表す定義(40〜80文字)'
summary_box: '読者への一言メモ'
ndc:
  code: '007.13'                    # NDCコード
  path:                             # 階層パス(パンくずリスト用)
    - 0(総記)
    - 00(総記)
    - 007(情報科学)
synonyms: ['AI Agent', '自律型AI']
externalLinks: []
status: 'published'
lastUpdated: '2026-04-11'

NDCコードは図書館の分類体系をそのまま採用しています。これにより「哲学」「歴史」「技術」といった大分類から用語を探せるようになりました。

フェーズ2:AI一括生成スクリプトの開発

手動でエントリを書くのは時間がかかるため、Gemini APIを使った一括生成スクリプトを作りました(bulk-generate.mjs)。用語名をリストに入れると、定義・解説本文・NDCコード・読みがなを自動生成してくれます。

最初のバージョンはシンプルなものでしたが、使いながらいくつかの問題に気づきました。

問題1: NDCコードは返ってくるが、パスが空になる

ndc:
  code: '210'
  # path が空!→ パンくずリストが壊れる

AIは ndc_code を返してくれますが、path["2(歴史)", "20(歴史)", "210(日本史)"] のような配列)は自動生成されません。そこでスクリプト側に buildNdcPath() 関数を実装し、コードからパスを自動構築するようにしました。

問題2: readingフィールドにカタカナが混入する

reading: 'ジンコウチノウ'  # カタカナ → 五十音ソートが壊れる

AIはカタカナで読みを返すことがあります。五十音順ソートのためにはひらがなが必要なので、katakanaToHiragana() 関数で変換し、fix-readings.mjs という専用の修正スクリプトも用意しました。

問題3: JSONパースが不安定

AIの返答にはマークダウンコードブロックや余分な説明文が混入することがあります。単純な JSON.parse() では失敗してしまいます。そこで「ブラケット・カウント方式」の extractJsonRobust() 関数を実装しました。ネストされた {} を1文字ずつ数えることで、確実にJSONブロックを抽出できるようになりました。

フェーズ3:品質管理システムの構築

436件ものエントリを手動で確認するのは現実的ではありません。そこで複数の品質管理スクリプトを整備しました。

Gemini APIによる校閲(verify-and-fix.mjs)

定義・本文・reading・NDCコードを包括的に検証し、問題があれば自動修正します。guideline.txt に校閲ルールを記述しておくと、それに従った判定を行います。

最初のバージョンには致命的なバグがありました。プロンプトが「用語名と定義の2行」しかなく、実質何も校正できていなかったのです。さらに、検証済みの印として全ファイルに verified: true を付与してしまうため、一度処理したファイルが永遠にスキップされてしまいました。

現在は、AIが「問題なし」と判定した場合のみ verified: true を付与し、修正を行ったファイルは次回の校正対象として残すように改善しています。

LM Studioによるガイドライン準拠チェック(audit-content.mjs)

ローカルで動くDeepSeek-R1モデルを使って、ハルシネーション・ねじれ文・よみがなのルール違反をチェックします。インターネット接続不要でプライベートに動作するのが利点です。

当初は接続URLがハードコードされており、他のマシンでは動きませんでした。現在は .envLM_STUDIO_URL を参照するよう改修しています。

CSVエクスポート(convert-to-csv.mjs)

Accessで辞書データを管理したい場合のためにCSV変換スクリプトも用意しました。

最初のバージョンには重大なバグがありました。YAMLでシングルクォートをエスケープする場合は '' と書くのですが(例: title: 'It''s OK')、正規表現でパースすると It で切れてしまっていたのです。gray-matter ライブラリを使った正確なパースに変更して解決しました。また、AccessやExcelで文字化けしないよう、BOM付きUTF-8で出力するようにもしています。

フェーズ4:Git導入と運用フロー整備

プロジェクトが大きくなってきたので、Gitによるバージョン管理を導入しました。

.gitignoreの整備

これが意外と見落としがちです。最初の .gitignore には以下が漏れていました。

  • audit_report.log — LM Studioのチェックレポート(毎回変わる)
  • dictionary_for_access.csv — 自動生成のCSV(毎回変わる)
  • src/data/link-map.json — ビルド時に自動生成される
  • scripts/ndlsh-tsv.tsv 等 — 大容量のNDLマスタデータ(数百MB)

これらをコミットしてしまうとリポジトリが肥大化したり、秘密情報が漏れたりするリスクがあります。

コミットメッセージの規約

チームで作業する場合に備えて、Conventional Commits スタイルを採用しています。

feat: add 90 world history dictionary entries
fix: correct reading field katakana in cognitive-bias.md
refactor: improve bulk-generate ndc path generation
docs: update README with git workflow

推奨フロー

# 用語生成 → 品質チェック → コミット
npm run bulk-generate
npm run check-syntax    # YAML構文チェック
npm run fix-readings    # カタカナ修正
npm run fix-ndc-path    # ndc.path欠損修正
git add src/content/dictionary/
git commit -m "feat: add history terms"

詰まったポイントと解決策まとめ

問題原因解決策
NDCパスが空になるAIはコードのみ返すbuildNdcPath() でスクリプト側で生成
readingにカタカナ混入AI生成の癖fix-readings.mjs で一括変換
JSONパース失敗AI応答に余分なテキスト混入ブラケット・カウント方式で抽出
全件にverified:true付与バグ問題なし判定時のみ付与するよう修正
CSV文字化けYAMLエスケープの正規表現バグgray-matter に切り替え+BOM出力
LM StudioのURLハードコード設計ミス.env から読み込むよう変更
.gitignoreに自動生成ファイル漏れ見落とし明示的に追加

今後の展望

現在取り組んでいること、またはこれから検討していることをメモしておきます。

関連用語の自動リンク強化
scripts/dictionary-map.json にキーワードを登録することで、記事本文の用語を自動リンクする仕組みは動いています。ただし436件分のキーワードをすべて登録するのは手間がかかるので、build-dictionary-map.js で自動生成する方向で改善したいと思っています。

OGP画像の動的生成
現在は全ページ共通のデフォルト画像を使っています。用語タイトルを埋め込んだOGP画像をSatoriで動的生成できれば、SNSシェア時の見栄えが大幅に改善するはずです。

GitHub Actionsによる自動ビルド
現在はローカルでビルドしてサーバーにアップロードしていますが、mainブランチへのプッシュをトリガーにして自動デプロイする仕組みを組みたいと思っています。


おわりに

AIとの対話を通じて、単なるサイト構築にとどまらず、コンテンツ生成・品質管理・運用の仕組みまで一緒に考えることができました。バグを見つけてもらったり、スクリプトの設計を提案してもらったりしながら、少しずつ良いものになっていく過程はとても楽しいものでした。

特に印象に残っているのは、「モデル名が存在しない」と指摘したところ、実は2026年3月に公開されたばかりの新しいモデルで、Claudeの学習データのカットオフ(2025年8月)より後だったというエピソードです。AIも知らないことがあるということを改めて実感しました。

同じようなAIアシストによるコンテンツ管理サイトを作っている方の参考になれば幸いです。


使用技術: Astro / Pagefind / Gemini API / LM Studio / DeepSeek-R1 / NDC(日本十進分類法)

コメント

タイトルとURLをコピーしました