Media > AI活用ユースケース > 総務 > 市役所のホームページのよくある質問を、住民がふだん使う言い方でも引けるようにし、0件だった検索語の記録から同義語辞書の追加案を毎月作る

市役所のホームページのよくある質問を、住民がふだん使う言い方でも引けるようにし、0件だった検索語の記録から同義語辞書の追加案を毎月作る

実装ステータス:構成例 技術的に実現可能な構成として設計したもの。自社未検証

市のホームページのFAQ検索で0件だった検索語を毎月集め、住民の言い方と行政の言い方のずれを見つけます。同義語辞書の追加案とFAQの追加候補を作り、担当課の承認を経て辞書に反映します。

サマリー
生成AI
Azure OpenAI Service/Claude
AIサービス
Azure AI/OpenSearch
対象業界
自治体
対象部門
総務
対象業務
台帳・マスタ管理/集計・分析
主な課題
人手が足りない/問い合わせが多い/情報が見つからない
AIで行う処理
検索(RAG)
主な効果
対応スピード向上/工数削減/検索時間短縮
導入難易度
★★★☆☆
実装レベル
本格構成
費用感
RAG・個別開発(大)
人間の確認
条件付き
現在工数
60h/月
AI導入後
20h/月
想定削減
67%
年間削減
480h
モデル条件による試算値です。実在企業の実績ではありません。

01導入前 / 導入後の業務フロー

導入前(Before)
  1. 月初に、広報課の担当が検索語の記録から前月の0件の検索語を書き出す
  2. 件数の多い順に並べ、1つずつ、住民が何を探していたのかを考える
  3. FAQの一覧を開き、その検索語に当たりそうなFAQを探す
  4. 当たりそうなFAQがあれば、同義語辞書に足す言葉の案を書く。無ければFAQの追加を担当課に頼む案を書く
  5. 案を課ごとにまとめ、担当課にメールで確認を頼む
  6. 返事が来たものを、同義語辞書のファイルに書き足して反映する
導入後(After)
  1. 自動毎月1日に、前月の検索語の記録から0件の検索語を集め、表記をそろえてまとめる
  2. 自動個人の情報らしい検索語(数字の並び、氏名らしい語)を除き、件数だけを残す
  3. 自動検索語ごとに、文字の重なりで探す索引と言葉で探す索引から、近いFAQの候補を20件ずつ取る
  4. 自動Claude API が、検索語ごとに扱いを分け、同義語の追加案と根拠のFAQを返す
  5. 自動追加案を入れた試験用の索引で、確認用の検索語の順位が崩れないかを確かめる
  6. 人広報課の担当が、追加案と確認の結果を見て、課ごとの承認の依頼にまとめる
  7. 人担当課が、自分の課のFAQにかかわる追加案を承認するか直す
  8. 自動承認された同義語を辞書のファイルに足し、検索に反映する
各工程の詳しい説明を読む
  1. 月初に、広報課の担当が検索語の記録から前月の0件の検索語を書き出す
  2. 件数の多い順に並べ、1つずつ、住民が何を探していたのかを考える
  3. FAQの一覧を開き、その検索語に当たりそうなFAQを探す
  4. 当たりそうなFAQがあれば、同義語辞書に足す言葉の案を書く。無ければFAQの追加を担当課に頼む案を書く
  5. 案を課ごとにまとめ、担当課にメールで確認を頼む
  6. 返事が来たものを、同義語辞書のファイルに書き足して反映する

(a)件数の多い数十件で終わる。 600種類を毎月全部見ることはできず、上から数十件を見たところで月が替わります。 件数の少ない検索語の中に、同じ意味の言い方が何通りもあることには気づけません。

(b)意味を考えるのに時間がかかる。 「はんこ 登録」「ごみ 大きい」「赤ちゃん お金」。住民が何を探していたかを、行政の言葉に置き換えるのは、その制度を知っている人でないと難しい作業です。 広報課の担当は、すべての制度を知っているわけではありません。

(c)足した同義語が別の検索を壊す。 「手当」を「児童手当」と同じにすると、「障害者手当」を探した住民にも児童手当のFAQが上に出ます。足すたびに他の検索がどう変わるかを、確かめる手段がありません。

(d)検索語に個人の情報が混ざる。 住民が検索窓に氏名や電話番号、番号の並びを打ち込むことがあります。書き出した一覧をそのままメールで課に回すと、その情報も一緒に広がります。

(e)担当課の返事がそろわない。 確認を頼んでも、返事が来る課と来ない課があります。返事を待つあいだ、辞書は足されないまま次の月が来ます。

  1. 【自動】 毎月1日に、前月の検索語の記録から0件の検索語を集め、表記をそろえてまとめる
  2. 【自動】 個人の情報らしい検索語(数字の並び、氏名らしい語)を除き、件数だけを残す
  3. 【自動】 検索語ごとに、文字の重なりで探す索引と言葉で探す索引から、近いFAQの候補を20件ずつ取る
  4. 【自動】 Claude API が、検索語ごとに扱いを分け、同義語の追加案と根拠のFAQを返す
  5. 【自動】 追加案を入れた試験用の索引で、確認用の検索語の順位が崩れないかを確かめる
  6. 【人】 広報課の担当が、追加案と確認の結果を見て、課ごとの承認の依頼にまとめる
  7. 【人】 担当課が、自分の課のFAQにかかわる追加案を承認するか直す
  8. 【自動】 承認された同義語を辞書のファイルに足し、検索に反映する

5番目が、この設計の分かれ目です。 同義語は足した瞬間に全部の検索に効きます。追加案ごとに、他の検索の順位が崩れないことを機械で確かめてから人に回します。 第3章の(c)を、人の注意ではなく試験で防ぎます。

4番目のAIに、追加してよいかは決めさせません。 AIが出すのは「この言い方はこのFAQのことだと思われる」という案と根拠です。住民の言い方を行政の言葉と同じに扱ってよいかは、制度を持つ担当課が決めます。

02今回想定するシステム構成

構成図
住民 ── 市のホームページの検索窓(生成AIは置かない)
   ▼
Amazon OpenSearch Service ── FAQの索引
   │   検索のときだけ同義語を使う解析器(synonym_graph、updateable)
   │   文字の重なりで探す項目(ngram)
   ▼
検索語の記録(検索語・件数・0件かどうか)
   │
   ▼【トリガー】毎月1日
AWS Lambda ── 集計・表記のそろえ・個人の情報の除外(プログラム)
   ▼
OpenSearch ── 検索語ごとに近いFAQの候補(ngram と kuromoji)
   ▼
Claude API ── 扱いの分類と同義語の追加案(構造化出力)
   ▼
試験用の索引 ── 確認用の検索語で順位を確かめる
   ▼
承認の一覧 ──【人】広報課 → 担当課
   ▼
同義語辞書のファイル(S3)→ パッケージの更新 → 検索に反映
役割想定する製品代替候補
検索基盤Amazon OpenSearch Service(synonym_graph、カスタムパッケージ、kuromoji、ngram)Azure AI Search
生成AIClaude API(0件の検索語の扱いの分類と同義語の追加案)Azure OpenAI(Microsoft Foundry)
連携AWS Lambda(集計、候補の検索、試験用の索引での確認、辞書のファイルの更新)AWS Step Functions
保管Amazon S3(同義語辞書のファイル、承認の記録)庁内のファイルサーバー

ホームページの作成システムとFAQの本文には、この構成から書き込みません。 FAQの追加が要るものは、担当課への依頼の一覧を作るまでです。FAQを書くのは担当課です。

住民の画面に生成AIを置かないのは、意図してのことです。 市のホームページは、子どもを含む誰もが使います。生成AIの答えを住民に出すと、誤った制度の説明がそのまま届きます。 検索の結果に出るのは、担当課が書いたFAQだけです。

同義語は synonym_graph のトークンフィルタで持たせます。 複数の語からなる同義語を扱え、語どうしの関係が大事な場面に向くとされています。規則の書き方は既定で Solr の形式で、expand が既定で true のとき、「引っ越し, 転居」のように並べた語は互いに置き換わります。expand を false にするか、=> を使う一方向の規則にすると、置き換わる向きを決められます。

辞書はカスタムパッケージとしてドメインに関連付けます。 同義語のファイルを S3 に置き、パッケージとして取り込みます。AWS KMS の鍵で保護したファイルは読めないので、S3 の管理する鍵で暗号化します。 対応しているのは1つのファイルで済む辞書だけです。

辞書の更新は、検索のときだけ使う解析器で updateable を true にしておくと自動で反映されます。 S3 に新しいファイルを置いただけでは反映されず、パッケージを更新してドメインに適用する手順が要ります。updateable は検索のときの解析器にしか使えず、索引を作るときの解析器に入れると、手で索引を作り直すことになります。

本文の解析には Japanese (kuromoji) Analysis を使います。 Amazon OpenSearch Service の全ドメインに入っています。Sudachi Analysis も日本語向けに推奨された任意のプラグインとして載っていますが、辞書を関連付け直しても次の Blue/Green デプロイまで反映されないとされています。毎月辞書を変える本記事の使い方では、同義語を別のファイルにして updateable で反映する形にします。

03どうやって実装するのか

Step1

処理の起点を決める

毎月1日の朝に、前月分をまとめて動かします。 0件の検索語は日々出ますが、1件ずつ動かすと、同じ言い方の別の書き方がまとまらないまま追加案になります。 1か月分を集めてから、表記をそろえて数えます。

承認の締切は、毎月15日に置きます。 承認された分だけをその日に辞書へ反映し、返事の無い課の追加案は翌月に持ち越します。 返事を待って全体を止めないようにします。

臨時の起点も1つ用意します。 大きな制度の始まりや災害のときは、新しい言い方の検索が急に増えます。0件の件数が前の週の数倍になったら、その週の分だけを同じ手順で回します。

Step2

入力データを集める

データ中身取得元
0件の検索語検索語、前月の件数、最初と最後に出た日検索語の記録
FAQの候補FAQの番号・題名・本文の冒頭・担当課・分類FAQの索引(OpenSearch)
いまの同義語辞書規則の一覧と、各規則を承認した課と日同義語辞書のファイル
過去の判断前に却下した追加案と理由承認の記録
確認用の検索語よく使われる検索語と、上位3件に出るべきFAQの組広報課で作る一覧

質を決めるのは、4行目の過去の判断です。 一度却下した言い方を、AIは毎月同じように提案してきます。却下の理由と一緒に渡すと、同じ提案が止まります。

5行目の確認用の検索語は、最初に200組ほど作ります。 「住民票」「ごみ 収集日」「保育園 申込」のように、件数の多い検索語と、そのとき出るべきFAQの組です。これが、同義語を足しても他の検索が崩れないことを確かめる物差しになります。

Step3

データの取得方法を決める

取るものどこからどう取るか
0件の検索語検索語の記録前月分を集め、表記をそろえて数える
文字の重なりで近いFAQFAQの索引の ngram の項目検索語をそのまま match で当てる
言葉で近いFAQFAQの索引の kuromoji の項目検索語を語に分けて、どれかの語に当たれば取る
試験の結果試験用の索引追加案を入れた解析器で、確認用の検索語を検索する

候補を2つの索引から取るのは、0件の理由が2通りあるからです。 1つは「ごみ大きい」のように語の切れ目が合わないもの、もう1つは「赤ちゃん お金」のように言葉そのものが違うものです。前者は文字の重なりで、後者は言葉の一部の一致で拾います。

文字の重なりで探す項目は、次のように作ります。

PUT /faq
{
  "settings": {
    "index.max_ngram_diff": 1,
    "analysis": {
      "tokenizer": {
        "faq_bigram": { "type": "ngram", "min_gram": 2, "max_gram": 3, "token_chars": ["letter", "digit"] }
      },
      "filter": {
        "faq_synonyms": {
          "type": "synonym_graph",
          "synonyms_path": "analyzers/F111111111",
          "updateable": true
        }
      },
      "analyzer": {
        "faq_ja_index":  { "type": "custom", "tokenizer": "kuromoji_tokenizer" },
        "faq_ja_search": { "type": "custom", "tokenizer": "kuromoji_tokenizer", "filter": ["faq_synonyms"] },
        "faq_ngram":     { "type": "custom", "tokenizer": "faq_bigram" }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": { "type": "text", "analyzer": "faq_ja_index", "search_analyzer": "faq_ja_search",
                 "fields": { "ngram": { "type": "text", "analyzer": "faq_ngram" } } },
      "body":  { "type": "text", "analyzer": "faq_ja_index", "search_analyzer": "faq_ja_search" }
    }
  }
}

min_gram と max_gram の差は、既定で1までです。 差を広げるときは index.max_ngram_diff を上げます。synonyms_path の値は、パッケージを関連付けたときに表示される識別子です。

同義語は search_analyzer の側にだけ入れます。 索引を作るときの解析器に入れると、辞書を変えるたびに全部のFAQを入れ直すことになります。

検索語の記録は、検索の画面の側で1回の検索ごとに残します。 残すのは、検索語・日時・結果の件数・1件目に出たFAQの番号だけです。住民を見分ける情報(IPアドレスや閲覧の履歴)は、この記録に入れません。 振り返りに要るのは「どの言葉で0件だったか」だけだからです。

試験の結果は、追加案ごとに次の形で残します。

{
  "rule": "引っ越し, 転居 => 転入, 転出",
  "checked_queries": 200,
  "broken": [
    { "query": "転出 証明", "expected_faq": "FAQ-0312", "rank_before": 1, "rank_after": 4 }
  ],
  "new_hits": [ { "query": "引っ越し 手続き", "top_faq": "FAQ-0311" } ]
}

broken が空でない追加案は、承認の一覧で赤く表示します。 new_hits は、その追加案で0件だった検索語がどのFAQに当たるようになるかを示し、担当課が承認の前に結果を目で確かめる材料にします。

Step4

AIへ渡す前に整形する

  1. 表記のそろえ … 全角と半角、大文字と小文字、前後の空白、記号をそろえ、同じ検索語として数えます
  2. 個人の情報の除外 … 4桁以上の数字の並び、電話番号やメールアドレスの形、住所の番地らしい並びを含む検索語は、本文を捨てて件数だけを残します
  3. 件数の足切り … 前月に1回しか出なかった検索語は、翌月に持ち越して2か月分で数えます
  4. 既知の言い方の除外 … いまの同義語辞書と、過去に却下した言い方に当たる検索語を分けておきます
  5. 候補の取得 … 検索語ごとに、ngram と kuromoji の2つの項目からFAQの候補を20件ずつ取り、重複を除きます

2番目は、AIに渡す前に必ずプログラムで行います。 検索窓に打ち込まれた氏名や番号は、住民が誤って入れたものです。AIに渡さず、記録の上でも本文を残しません。 除いた件数だけを月の報告に載せます。

3番目を省くと、打ち間違いの検索語が追加案の大半を占めます。 1回きりの打ち間違いを同義語にしても、次に同じ打ち間違いをする住民はほとんどいません。

Step5

AIに処理させる

させるのは、0件の検索語ごとに扱いを分け、同義語の追加案と根拠のFAQを書くことです。 扱いは次の6つに分けます。

扱い中身
synonym住民の言い方が、候補のFAQの行政の言葉と同じ意味。同義語の追加案を書く
one_way住民の言い方が、行政の言葉より広い。一方向の規則(=>)の案を書く
variant表記ゆれ・送り仮名・略し方の違い。同義語の追加案を書く
typo打ち間違い。同義語にせず、件数だけ記録する
no_faq候補に当たるFAQが無い。FAQの追加を担当課に頼む案を書く
out_of_scope市の業務ではない(国や県、民間の手続き)
させること中身
扱いの分類上の6つのどれか
追加案の作成同義語の規則の形で書く。足す語は検索語と候補のFAQの言葉から取る
根拠の付与当てはまると考えたFAQの番号を、候補の中から選ぶ
理由の説明担当課が判断できるよう、1〜2文で書く
させないこと理由
追加してよいかの判断担当課が、制度の言葉として認めてよいかを決める
候補に無いFAQの指定渡した候補の番号だけを使う
制度の説明住民向けの文は書かせない。FAQを書くのは担当課
対象の広い語の同義語化「手当」「申請」「届」のような語を、特定の制度と同じにしない
個人の情報の推測除外した検索語の中身を推し量らない

4行目がいちばん起きやすい失敗です。 「手当」で0件だった検索語に、AIは「手当, 児童手当」と書きます。そうすると、障害や介護の手当を探した住民にも児童手当のFAQが上に出ます。 広い語は one_way で、どの制度にも当てはまる一覧のページへ向けるか、追加しないかを担当課が選びます。

Step6

指示内容を固定する

あなたは市役所のホームページの担当で、住民がFAQの検索で0件だった言葉を振り返る立場です。
検索語ごとに扱いを分け、同義語辞書の追加案を作ってください。
追加してよいかは決めないでください。決めるのは担当課です。

【扱いの選び方】
- synonym ...... 住民の言い方が、候補のFAQの言葉と同じ意味
- one_way ...... 住民の言い方のほうが意味が広い。「住民の言い方 => FAQの言葉」の一方向にする
- variant ...... 表記ゆれ・送り仮名・略し方の違い
- typo ......... 打ち間違い。同義語にしない
- no_faq ....... 候補の中に当てはまるFAQが無い
- out_of_scope . 市の業務ではない
迷ったら no_faq を選んでください。synonym を選ばないでください。

【厳守事項】
- FAQの番号は、渡した候補の中からだけ選んでください。
- 規則に書く語は、検索語か、候補のFAQの題名・本文に出てくる語だけにしてください。
  どちらにも無い語を足さないでください。
- 「手当」「申請」「届」「証明」「補助」のように、複数の制度にまたがる語を、
  1つの制度の語と同じ扱い(synonym)にしないでください。one_way か no_faq にしてください。
- 過去に却下した言い方は、却下の理由が変わっていない限り提案しないでください。
- 制度の内容を説明しないでください。理由は、なぜこのFAQだと考えたかだけを書いてください。
- 検索語に数字の並びや人の名前らしい語があれば、扱いを out_of_scope にして、内容に触れないでください。

【0件の検索語と件数】{queries}
【検索語ごとのFAQの候補(番号・題名・本文の冒頭・担当課)】{candidates}
【いまの同義語辞書】{current_synonyms}
【過去に却下した言い方と理由】{rejected}

「迷ったら no_faq」と書いているのは、synonym が増えすぎると辞書が壊れるからです。 no_faq の誤りは、担当課がFAQを見て「あるよ」と返せば直ります。synonym の誤りは、承認をすり抜けると全部の検索に効いてしまいます。 誤るなら、直しやすいほうに誤らせます。

規則に書く語を、検索語とFAQの語に限っているのも同じ理由です。 限らないと、AIは気を利かせて「転居, 引っ越し, 移転, 住所変更, 転籍」のように語を足します。「転籍」は戸籍の手続きで、住所の手続きとは別です。

Step7

出力形式を固定する

Claude API の構造化出力で、次の形のJSONを受け取ります。

{
  "month": "2026-09",
  "items": [
    {
      "query": "",
      "count": 0,
      "treatment": "synonym | one_way | variant | typo | no_faq | out_of_scope",
      "rule": "",
      "target_faq_ids": [],
      "owner_sections": [],
      "reason": ""
    }
  ]
}

1つ目の理由は、target_faq_ids を照らせることです。 出てきた番号が、その検索語に渡した候補に含まれているかを、プログラムで確かめます。 含まれていなければ、その追加案を除きます。

2つ目は、rule をそのまま試験にかけられることです。 規則は辞書のファイルと同じ書き方の1行で受け取り、プログラムが形式を確かめてから、試験用の索引の解析器に足して、確認用の検索語を検索します。 上位3件から外れたFAQが出たら、その追加案に印を付けます。

3つ目は、owner_sections で承認の宛先が決まることです。 候補のFAQの担当課をプログラムが入れ、承認の依頼は課ごとにまとめて送ります。 1つの追加案が複数の課のFAQにかかるときは、全部の課の承認を要件にします。

Step8

システムへ連携する

つなぎ先方式内容
検索語の記録毎月1日の書き出し0件の検索語と件数
Amazon OpenSearch Service_search(ngram と kuromoji の項目)検索語ごとのFAQの候補
Claude APIMessages API の構造化出力扱いの分類と追加案
試験用の索引追加案を入れた解析器で作る索引確認用の検索語の順位の確認
承認の一覧庁内の表計算か業務の画面課ごとの承認と却下
S3 とカスタムパッケージファイルの更新、パッケージの更新と適用承認された同義語の反映
Step9

人が確認する

  1. 広報課が全体を見る … 扱いの分かれ方と、試験で印が付いた追加案を先に見ます
  2. 担当課が自分の課の追加案を見る … 住民の言い方を、その制度の言葉と同じに扱ってよいかを決めます
  3. 却下の理由を書く … 却下するときは、理由を一言書きます。翌月からAIに渡す材料になります
  4. no_faq を課の宿題にする … FAQを足すか、足さないかを決めます
  5. 反映の後に確かめる … 反映した翌週に、追加した言い方で実際に検索し、FAQが出るかを見ます

2番目を省かないでください。 「保険証」を「資格確認書」と同じにしてよいか、「はんこ」を「印鑑登録」と同じにしてよいか。制度の担当でないと、言い換えてよい範囲が分かりません。

目標は、600件をならして1件2分です。 typo と out_of_scope は件数を見るだけで終わり、synonym と one_way は候補のFAQと試験の結果を見て数分かかります。

Step10

例外に対処する

起きること対応
候補のFAQが1件も取れないAIに渡さず no_faq として課の宿題の一覧に入れる
FAQの番号が候補に無いその追加案を除く。ログに残す
規則の形式が誤っている試験に回さず、広報課の確認の一覧に入れる
試験で確認用の検索語の順位が崩れる追加案に印を付け、どの検索語が崩れたかを添えて回す
担当課の返事が締切までに無い翌月に持ち越す。承認の無いものは反映しない
パッケージの適用が終わらない前の版の辞書のまま運用し、適用の状態を確かめ直す
0件の件数が急に増えた臨時の起点で、その週の分だけを回す
構造化出力が refusal や max_tokens で終わる受け付けずに件数を分けて再実行する
Step11

記録を残す

  • 前月の0件の検索語と件数(個人の情報を除いた後のもの)と、除いた件数
  • 検索語ごとに渡したFAQの候補
  • Claude API の出力と、使った指示の版
  • 試験の結果(崩れた確認用の検索語と順位)
  • 担当課の承認・却下と理由、承認した日と担当
  • 反映した辞書の版と日、パッケージの適用の記録

辞書の版を残すのは、戻せるようにするためです。 反映した後に苦情や問い合わせが増えたら、前の版に戻して、どの規則が原因かを試験用の索引で探します。

04実装レベルの3段階

最小構成:0件の検索語とFAQの一覧を手元のAIに渡し、追加案を作らせる / 毎月の振り返りの下ごしらえ
半自動化:上記+検索語の集計と個人の情報の除外、検索語ごとのFAQの候補の取得 / 600件全部への候補の付与
本格構成:上記+構造化出力、試験用の索引での確認、課ごとの承認の一覧、辞書の自動の反映 / 0件の集計から辞書の反映までの全体

半自動化で、1件6分が4分程度になります。 候補のFAQは出ますが、追加案を書き、他の検索が崩れないかを確かめる作業が手作業で残ります。本格構成で2分になり、この段階が本記事の想定です。 段階を飛ばさないでください。 半自動化で2か月回すと、個人の情報の除外で落としすぎている形と、候補が取れない検索語の傾向が分かります。そこを直してから、試験と自動の反映を足します。

05工数削減シミュレーション

前提値(モデル条件)
対象人数
3 名
月間件数
600 件
1件あたり現在時間
6 分
1件あたり導入後時間
2 分
現在  600件 × 6分 ÷ 60 = 60 時間/月
導入後 600件 × 2分 ÷ 60 = 20 時間/月
月間削減時間
40h
削減率
67%
年間削減時間
480h
年間金額換算(時間単価3,500円)
168万円
モデル条件による試算であり、実際の効果は業務内容・運用方法によって異なります。

自社条件で導入効果を整理したい方へ

このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。

AI活用について相談する

06向いている企業・向いていない企業

向いている
  1. よくある質問(FAQ)を千件以上ホームページに載せている市区町村で、サイト内の検索で0件になる検索語が毎月数百種類出ている場合。住民の言い方(「引っ越し」「ごみの日」「赤ちゃんの手当」)と、FAQに書かれた行政の言い方(「転入届」「収集日」「児童手当」)がずれていて、電話の問い合わせが減らない場合。検索語の記録を取れるか、取れるように改修できる場合。AWS を使っているか、使える場合。
向いていない
  1. FAQが数十件で、一覧から目で探せる場合。サイト内の検索をホームページの作成システムの標準の機能だけで運用しており、辞書を足せない場合(先に検索の仕組みを替える必要があります)。住民の質問に生成AIが文章で答える窓口を作りたい場合(本記事は、住民の画面に生成AIを置かない構成です)。なお、どの言い方を同義語として認めるか、FAQに何を書くかの判断は、この構成では代替できません。

07最小構成で試す方法

  1. 前月の0件の検索語のうち、件数の多い順に50件を選ぶ(個人の情報らしい検索語は先に除く)
  2. FAQの題名と担当課の一覧を書き出す
  3. 手元のAIサービスに検索語の一覧とFAQの一覧を渡し、「検索語ごとに、当てはまるFAQの番号を一覧の中から選び、同じ意味か、より広い意味か、当てはまるFAQが無いかに分けてください。複数の制度にまたがる語を、1つの制度と同じにしないでください」と指示する
  4. 出てきた内容を、広報課と2〜3の課で見て、使えそうな案の数を数える
出てきた内容判断
担当課が「そのとおり」と言う案が半分以上あった候補の検索と試験の仕組みづくりに進む
広い語を1つの制度と同じにした指示と試験で直る。構成は有効
FAQの題名だけでは当てはまるかが分からないFAQの本文の冒頭も渡す形にする

試すときは、制度の担当と広報課の両方に案を見てもらってください。 広報課が「そのとおり」と思った案を、制度の担当が「それは別の手続き」と返すことがあります。その食い違いの数が、承認の手順を省けない理由になります。

08実装時につまずきやすいポイント

問題対策
辞書を S3 に置いたのに反映されないパッケージの更新とドメインへの適用が要る
辞書を変えるたびに索引を作り直している同義語を検索のときの解析器に入れ、updateable を true にする
S3 の辞書ファイルが読めないKMS の鍵で保護したファイルは読めない。S3 の管理する鍵にする
広い語を同義語にして他の検索が崩れるone_way に分け、試験用の索引で確かめる
並べた語が意図しない向きにも置き換わるexpand の既定は true。一方向にするなら => で書く
ngram の索引が作れないmin_gram と max_gram の差は既定で1まで。index.max_ngram_diff を上げる
打ち間違いが追加案の大半を占める1回きりの検索語は翌月に持ち越して数える
検索語の個人の情報がAIに渡る除外はAIに渡す前にプログラムで行う
課の返事が来ず止まる締切を決め、返事の無いものは翌月に持ち越す

上の3行が、この構成の失敗のほとんどです。 どれも「辞書を足したのに効かない」という同じ見た目で出ます。最初に、テスト用の1語だけを足して、反映の手順を通しで確かめてください。

09セキュリティ・AIガバナンス上の注意点

この構成で扱うデータ: 住民が検索窓に打ち込んだ言葉と件数、FAQの題名と本文です。検索語の大半は個人の情報を含みませんが、氏名・電話番号・番号の並びが混ざることがあります。

  1. 個人の情報はAIに渡す前に除く … 数字の並びや連絡先の形を含む検索語は、本文を捨てて件数だけを残します。誤って打ち込まれた情報を、庁内のメールや外部のAIに広げません
  2. 住民の画面に生成AIを置かない … 住民が見るのは、担当課が書いたFAQだけです。子どもを含む誰もが使う画面に、生成AIの答えを出しません
  3. 追加は担当課の承認を要件にする … 承認の無い追加案は、試験の結果が良くても反映しません
  4. 反映の前に試験で確かめる … 確認用の検索語の順位が崩れる追加案は、印を付けて人に回します
  5. 辞書の版を残して戻せるようにする … 反映の後に問題が出たら、前の版に戻します
  6. 外部の生成AIの取り扱いを確かめる … 渡すのは個人の情報を除いた検索語とFAQの公開されている文だけですが、庁内の情報セキュリティの規程で、外部のサービスに渡してよい情報の区分を確かめます

誤りが起きた場合のリスクは、住民が違う制度のFAQに案内されることと、検索語に混じった個人の情報が広がることの2つです。 前者は承認と試験で、後者はAIに渡す前の除外で防ぎます。

10まず何から始めるか

1週目:検索語の記録を確かめる

サイト内の検索で、検索語と件数と0件かどうかが記録されているかを確かめます。記録されていなければ、まず記録を始めます。 1か月分がたまるまで、次の段階に進めません。

2週目:50件で試す

件数の多い0件の検索語50件で、手元のAIに追加案を作らせます。広報課と2〜3の課で見て、使える案の数を数えます。

3週目:承認の手順と確認用の検索語を決める

課ごとの承認の担当と締切を決めます。あわせて、確認用の検索語を200組作ります。

4週目:辞書の反映を通しで確かめる

同義語のファイルをカスタムパッケージにし、検索のときの解析器で updateable にします。テスト用の1語を足し、S3 → パッケージの更新 → 適用 → 検索で出るまでを通しで確かめます。

2か月目: 集計と個人の情報の除外、候補の取得を作り、追加案を出します。3か月目以降: 試験用の索引での確認と承認の一覧を足し、1件6分が何分になったかを実測します。毎月の追加案が、担当課の承認を経て辞書に入る流れが3か月続いた時点で、この構成は完成です。


11関連ユースケース

12この仕組みを理解するための記事

13技術仕様の確認日・参考情報

技術仕様確認日:2026-10-14/最終更新:2026-10-15
確認した内容情報源確認日
synonym_graph が複数の語からなる同義語を扱えること、synonyms か synonyms_path が要ること、規則の形式が既定で Solr であること、expand の既定が true で、false のときは並べた語が先頭の語に置き換わることOpenSearch: Synonym graph token filter2026-10-14
ngram のトークナイザが文字の重なりで分けること、min_gram の既定が1、max_gram の既定が2、差の上限が index.max_ngram_diff(既定1)で決まることOpenSearch: N-gram tokenizer2026-10-14
同義語などの辞書を S3 からカスタムパッケージとして取り込むこと、KMS の鍵で保護したファイルは読めないこと、1ファイルの辞書だけに対応すること、S3 のファイルを替えただけでは更新されないこと、検索のときの解析器で updateable を true にしていればパッケージの更新の適用後に自動で反映されること、updateable が検索のときの解析器にだけ使えることAWS: Importing and managing packages in Amazon OpenSearch Service2026-10-14
Japanese (kuromoji) Analysis が全ドメインに入っていること、Sudachi Analysis が日本語向けに推奨された任意のプラグインで、辞書の関連付け直しが次の Blue/Green デプロイまで反映されないことAWS: Plugins by engine version in Amazon OpenSearch Service2026-10-14
構造化出力を output_config.format で指定すること、数値の制約に対応しないこと、refusal・max_tokens で終わるとスキーマに合わないことがあることClaude: Structured outputs2026-10-14

どの言い方を同義語として認めるか、FAQに何を書くかは、制度を持つ担当課が判断してください。 本記事は上の公開情報で確認できた範囲だけを扱っています。

実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。

自社の業務に使えるAI活用候補を整理します

このユースケース(UC-1532)についてのご相談はこちらから。

AI活用について相談する
目次