Media > AI活用ユースケース > 品質管理 > 病院の医療安全の担当が過去のインシデント報告を引き、薬剤名・処置名の言い換えも含めて似た事例と当時の対策を探す

病院の医療安全の担当が過去のインシデント報告を引き、薬剤名・処置名の言い換えも含めて似た事例と当時の対策を探す

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

院内から新しいインシデント報告が出るたびに、薬剤の商品名と一般名、院内の略語と処置の正式名をそろえたうえで過去の報告から似た事例を探し、当時の対策と再発の有無を事例番号付きで医療安全管理者に示します。

サマリー
生成AI
Azure OpenAI Service/Claude/Gemini
AIサービス
Azure AI/Google Vertex AI/OpenSearch
対象業界
介護/医療
対象部門
品質管理
対象業務
情報検索/比較検討
主な課題
判断に時間がかかる/属人化している/情報が見つからない
AIで行う処理
検索(RAG)
主な効果
判断支援/属人化解消/検索時間短縮
導入難易度
★★★☆☆
実装レベル
本格構成
費用感
RAG・個別開発(大)
人間の確認
条件付き
現在工数
80h/月
AI導入後
32h/月
想定削減
60%
年間削減
576h
モデル条件による試算値です。実在企業の実績ではありません。

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

導入前(Before)
  1. 報告システムで新しい報告を開き、発生場面・薬剤・処置・患者への影響を読む
  2. 報告に書かれた薬剤名で、過去の報告を検索する
  3. 当たらなければ、思いつく別の名前(一般名、規格付きの名前、略した名前)で検索し直す
  4. 処置名も同じように、略語と正式名で検索し直す
  5. 当たった報告を1件ずつ開き、起き方が近いものを選ぶ
  6. 近い報告の「対策」の欄を読み、その後に同じ部署で同じことが起きていないかを探す
  7. 部署へのコメントと、根本原因分析にかけるかの意見を書く
導入後(After)
  1. 自動毎晩、報告システムが書き出したCSVを取り込み、新しい報告と更新された報告を索引に入れる
  2. 自動取り込みのときに、報告の本文から薬剤・処置・チューブ類・発生場面を取り出し、薬剤は一般名(成分名)に寄せる
  3. 人医療安全管理者が新しい報告を開き、「似た事例を探す」を押す
  4. 自動一般名・処置の正式名・発生場面で絞り、言葉と意味の両方で過去の報告を探す
  5. 自動上位の事例について、似ている点・違う点・当時の対策・その後の再発の有無を事例番号付きでまとめる
  6. 人医療安全管理者が一覧を読み、使う事例を選んで部署へのコメントを書く
  7. 人言い換えが足りなかった名前を、辞書の追加の候補として登録する
各工程の詳しい説明を読む
  1. 報告システムで新しい報告を開き、発生場面・薬剤・処置・患者への影響を読む
  2. 報告に書かれた薬剤名で、過去の報告を検索する
  3. 当たらなければ、思いつく別の名前(一般名、規格付きの名前、略した名前)で検索し直す
  4. 処置名も同じように、略語と正式名で検索し直す
  5. 当たった報告を1件ずつ開き、起き方が近いものを選ぶ
  6. 近い報告の「対策」の欄を読み、その後に同じ部署で同じことが起きていないかを探す
  7. 部署へのコメントと、根本原因分析にかけるかの意見を書く

(a)名前を変えて何度も検索する。 2番から4番がいちばん時間を食います。商品名で書かれた報告は商品名でしか当たらず、どの名前で書かれているかは開くまで分かりません。 後発医薬品に切り替わった薬は、切り替えの前と後で名前が違います。

(b)略語は部署ごとに違う。 「Aライン」「動脈ライン」「観血的動脈圧」、「NG」「経鼻胃管」「マーゲンチューブ」。どれも本文には略して書かれ、略し方は病棟の文化で決まります。

(c)過去の対策を知っている人が限られる。 「3年前にICUで同じことがあり、そのときは指示の出し方を変えた」と覚えているのは、長く医療安全管理室にいる人だけです。その人が休むと、同じ対策が一から議論されます。

(d)検索に時間を取られて、返しが遅れる。 部署へのコメントは早いほど効きます。探すのに30分かかると、その日のうちに返せる報告が限られます。

  1. 【自動】 毎晩、報告システムが書き出したCSVを取り込み、新しい報告と更新された報告を索引に入れる
  2. 【自動】 取り込みのときに、報告の本文から薬剤・処置・チューブ類・発生場面を取り出し、薬剤は一般名(成分名)に寄せる
  3. 【人】 医療安全管理者が新しい報告を開き、「似た事例を探す」を押す
  4. 【自動】 一般名・処置の正式名・発生場面で絞り、言葉と意味の両方で過去の報告を探す
  5. 【自動】 上位の事例について、似ている点・違う点・当時の対策・その後の再発の有無を事例番号付きでまとめる
  6. 【人】 医療安全管理者が一覧を読み、使う事例を選んで部署へのコメントを書く
  7. 【人】 言い換えが足りなかった名前を、辞書の追加の候補として登録する

3番目が人の操作から始まるのは、意図してのことです。 毎晩すべての報告に自動で事例を付けることもできますが、医療安全管理者が報告を読んでから探すほうが、何を探すかが定まります。

7番目が、この構成を育てる手順です。 辞書に無い言い換えは、使っているうちに見つかります。

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

構成図
院内のインシデント報告システム(毎晩のCSVの書き出し)
   ▼【トリガー】毎晩の取り込み
AWS Lambda
   ├──▶ 患者の識別情報を落とす
   ├──▶ Claude(Amazon Bedrock)── 薬剤・処置・場面の取り出し(構造化出力)
   ├──▶ 薬剤名の対応表で一般名(成分名)に寄せる
   ├──▶ Amazon Titan Text Embeddings V2 ── 本文の埋め込み
   ▼
Amazon OpenSearch Service
   │   kuromoji で日本語を解析/言い換えの辞書(synonym_graph、検索時)
   ▼【人】「似た事例を探す」
ハイブリッド検索(一般名・処置・場面で pre-filter)
   ▼
Claude(Amazon Bedrock)── 似ている点・違う点・当時の対策(事例番号付き)
   ▼
医療安全管理者の画面 ──【人】使う事例を選び、部署へ返す
役割想定する製品代替候補
検索基盤Amazon OpenSearch Service(kuromoji、synonym_graph、ハイブリッドクエリ)Azure AI Search、Vertex AI Search(Agent Search)
埋め込みAmazon Titan Text Embeddings V2(Amazon Bedrock)Cohere Embed、OpenAI の埋め込みモデル
生成AIClaude(Amazon Bedrock の Converse API、構造化出力)Azure OpenAI(Microsoft Foundry)、Gemini API
連携AWS Lambda(CSVの取り込み、画面からの呼び出し)AWS Step Functions
保管Amazon S3(取り込み前のCSV、言い換えの辞書の元ファイル)院内のファイルサーバー

報告システムには、この構成から書き込みません。 読むのは毎晩のCSVだけで、部署へのコメントは医療安全管理者がいつもの報告システムで入れます。

日本語の解析は、すべてのドメインに入っている Japanese(kuromoji)Analysis を使います。 言い換えの辞書は、Amazon OpenSearch Service のパッケージとして取り込みます。テキストファイルを S3 に置いてパッケージとして取り込み、ドメインに関連付けると、analyzers/<パッケージID> を synonyms_path に指定できます。

辞書の更新のしかたが、この構成の運用を決めます。 パッケージを更新しても、関連付けたドメインは自動では新しい版に切り替わらず、明示的に更新を適用します。 そのうえで、updateable: true を付けた検索用のアナライザーだけを使っていれば、索引は自動で更新されます。 索引を作るときのアナライザーで辞書を使うと、索引を閉じて開き直すか、作り直しが要ります。辞書は検索用のアナライザーにだけ置きます。

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

Step1

処理の起点を決める

起点は2つあります。毎晩の取り込みと、医療安全管理者のボタンです。

毎晩の取り込みは、報告システムが書き出したCSVが S3 に置かれたことで動きます。新しい報告だけでなく、更新された報告も入れ直します。 報告は出された後に、所属長の確認、分析、対策の入力と何度も書き足されるからです。対策の欄が埋まった報告が索引に入っていないと、「当時の対策」が空のまま並びます。

ボタンは、医療安全管理者が報告を読んだ後に押します。何度でも押せるようにします。

Step2

入力データを集める

データ中身取得元
新しい報告発生日時・部署・発生場面・概要の区分・患者への影響の程度・本文(何が起きたか、なぜ起きたか)報告システムのCSV
過去の報告上記に加えて、分析の結果・対策・対策の実施日・所属長のコメント事例の索引
薬剤名の対応表商品名・規格・一般名(成分名)・薬価基準収載医薬品コード・院内の採用の有無薬価基準収載品目リストと採用薬の一覧から作る
言い換えの辞書略語・正式名・部署ごとの呼び方(処置、チューブ類、機器、検査)医療安全管理室が作るテキストファイル
名称類似薬の一覧院内で取り違えの注意を出している薬の組み合わせ薬剤部の一覧

質を決めるのは、真ん中の2つです。 薬剤名の対応表の元にするのは、厚生労働省が公開している薬価基準収載品目リストです。区分、薬価基準収載医薬品コード、成分名、規格、品名、メーカー名の項目があり、薬価基準に収載されている約1万3千品目が載っています。院内の採用薬の一覧と突き合わせ、採用している品目だけの表にします。

名称類似薬の一覧は、言い換えに混ぜないために持ちます。 この一覧にある組み合わせが辞書に入っていないかを、辞書を更新するたびに機械で確かめます。

Step3

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

取るものどこからどう取るか
近い事例事例の索引ハイブリッドクエリ(本文の match + 埋め込みの knn)、一般名・処置・場面で filter、上位10件
同じ部署の続き事例の索引近い事例と同じ部署・同じ一般名で、その事例の対策の実施日より後の報告
名前の似た薬の事例事例の索引名称類似薬の一覧で相手の一般名に置き換えた別の検索(取り違えの報告のときだけ)

検索パイプラインと検索の形は、次のようになります。

PUT /_search/pipeline/incident-hybrid
{
  "phase_results_processors": [
    { "normalization-processor": {
        "normalization": { "technique": "min_max" },
        "combination": { "technique": "arithmetic_mean",
                         "parameters": { "weights": [0.6, 0.4] } } } }
  ]
}

POST /incidents/_search?search_pipeline=incident-hybrid
{
  "size": 10,
  "_source": ["case_id", "occurred_on", "dept_type", "scene", "category",
              "generic_names", "strengths", "procedures", "impact_level",
              "summary", "cause", "countermeasure", "countermeasure_on"],
  "query": {
    "hybrid": {
      "filter": { "bool": { "filter": [
        { "terms": { "generic_names": ["ヘパリンナトリウム"] } },
        { "term":  { "scene": "持続注入_流量設定" } }
      ] } },
      "queries": [
        { "match": { "body": { "query": "シリンジポンプ 流量 1桁 設定 ダブルチェック CV",
                               "analyzer": "ja_search_synonym" } } },
        { "knn": { "body_vector": { "vector": [0.0], "k": 30 } } }
      ]
    }
  }
}

filter は1つの検索の形で書き、複数の条件は bool にまとめます。 ハイブリッドクエリの最上位の filter は OpenSearch 3.0 で入ったもので、すべての検索に同じ絞り込みをかけます。ハイブリッドクエリは検索の最上位に置くもので、function_score などで包むとエラーか正規化が飛ばされることがあるとされています。新しい報告を上にしたいときは、表示の段で並べ替えます。

weights は合計を1.0にします。 薬剤と処置の言葉の一致が効く題材なので、言葉の側を重くします。min_max では、結果が1件しかない検索ではその1件が1.0になります。件数が少ないときは、画面に件数を一緒に出します。

一般名の絞り込みで3件に満たなければ、filter から一般名を外して場面だけで探し直します。どの段の結果かを match_level として画面に渡します。

Step4

AIへ渡す前に整形する

  1. 患者の識別情報を落とす … CSVの患者ID・氏名・生年月日の列は索引に入れません。本文に書かれた氏名は、職員名簿と患者の氏名の表記の型で検出して伏せます
  2. 薬剤・処置・場面を取り出す … Claude で本文から薬剤名(書かれたまま)、規格、処置、チューブ類、機器、発生場面を取り出します
  3. 一般名に寄せる … 取り出した薬剤名を、薬剤名の対応表で一般名に引き当てます。引き当ては表で行い、AIにはさせません
  4. 規格は別の項目に持つ … 一般名に寄せても、規格(濃度・含量)は strengths に残します
  5. 引き当たらない名前を残す … 対応表に無い名前は unmatched_drug_names に入れ、薬剤師の確認の一覧に回します
  6. 埋め込みを作る … 本文(何が起きたか、なぜ起きたか)と対策をつなげて埋め込みます。Titan Text Embeddings V2 の入力は8,192トークン・5万字までで、文書は段落や節に分けることがすすめられています
  7. 言い換えの辞書を検証する … 辞書を更新するたびに、名称類似薬の一覧の組み合わせが同じ行に入っていないかを確かめます

4番目を軽く見ないでください。 濃度の違う製剤の取り違えは、成分が同じでも重い事故になりえます。一般名に寄せるのは探すためで、規格の違いを消すためではありません。

言い換えの辞書は、Solr 形式のテキストで書きます。

CV, 中心静脈カテーテル, 中心静脈ライン
Aライン, 動脈ライン, 観血的動脈圧ライン
NGチューブ, 経鼻胃管, マーゲンチューブ
PCA, 自己調節鎮痛

この辞書を synonym_graph に置くのは、日本語では言い換えがほぼすべて複数の語になるからです。 kuromoji は「中心静脈カテーテル」を複数の語に分けます。synonym_graph は複数の語からなる言い換えを扱えますが、検索用のアナライザーでだけ使うものとされています。また、synonym_analyzer を指定しなければ、言い換えの規則も、その前に置いた分かち書きとフィルタで処理されます。 本文と同じ処理を規則にもかけるので、kuromoji の分け方と辞書の書き方が食い違いません。

"analysis": {
  "filter": {
    "ja_synonym": { "type": "synonym_graph",
                    "synonyms_path": "analyzers/F111111111",
                    "updateable": true }
  },
  "analyzer": {
    "ja_index":          { "type": "custom", "tokenizer": "kuromoji_tokenizer",
                           "filter": ["kuromoji_baseform", "lowercase"] },
    "ja_search_synonym": { "type": "custom", "tokenizer": "kuromoji_tokenizer",
                           "filter": ["kuromoji_baseform", "lowercase", "ja_synonym"] }
  }
}

stop のフィルタを synonym_graph の後ろに置かないでください。 後ろに置くと、言い換えの照合の後で語が消えて、言い換えの組み立てが壊れるとされています。

Step5

AIに処理させる

AIの仕事は2か所です。取り込みのときの「取り出し」と、検索の後の「並べ方」です。

段させることさせないこと
取り出し本文から薬剤名・規格・処置・チューブ類・機器・発生場面を、書かれた文字列のまま取り出す一般名への引き当て、名前の補正
並べ方上位の事例ごとに、新しい報告と似ている点・違う点、当時の対策、その後の同じ部署の報告の有無を、事例番号付きで書く原因の判断、対策の良し悪しの評価、根本原因分析にかけるかの判断

取り出しで名前を補正させないのは、引き当ての誤りを追えなくするからです。 「ヘパリン」と書かれていれば「ヘパリン」と取り出し、引き当ては表に任せます。表に無い名前が unmatched_drug_names に残ることが、辞書を育てる材料になります。

並べ方では、違う点を必ず書かせます。 似た事例を並べると、似ている点だけが目に入ります。規格が違う、時間帯が違う、病棟の体制が違うといった違いが、当時の対策がそのまま使えるかを決めます。

Step6

指示内容を固定する

あなたは病院の医療安全管理室で、新しいインシデント報告に似た過去の事例を整理する立場です。
渡された【新しい報告】と【過去の事例】だけを使ってください。推測で補わないでください。

【すること】
1. 過去の事例ごとに、新しい報告と似ている点と違う点を、それぞれ1〜3個書く
   - 違う点には、規格(濃度・含量)、時間帯、部署、使った機器、患者の状態の違いを優先して書く
2. 過去の事例の「対策」の欄に書かれた対策を、そのまま短く写す
3. 【その後の報告】に同じ部署・同じ一般名の報告があれば、その事例番号を書く

【厳守事項】
- 事例番号は【過去の事例】にあるものだけを使ってください。番号を作らないでください。
- 対策の欄が空の事例は、countermeasure を「記載なし」にしてください。
  分析や所属長のコメントから対策を推し量って書かないでください。
- 原因の判断、対策が効いたかどうかの評価、根本原因分析にかけるべきかは書かないでください。
- 薬剤名は【過去の事例】に書かれたままの表記で写してください。
  別の名前に言い換えたり、名前の似た薬を同じ薬として扱ったりしないでください。
- 患者を特定できる情報を書かないでください。
- 似ている点が1つも無い事例は、similarity を「低い」にして、理由を書いてください。

【新しい報告】{new_report}
【過去の事例】{cases}
【その後の報告】{followups}
【この検索の絞り込みの段】{match_level}

「名前の似た薬を同じ薬として扱わない」を書いているのは、要約の段で混ざるからです。 検索の段で辞書から外しても、要約で「同じ薬の事例」とまとめると意味がありません。

「対策を推し量らない」も同じ理由です。 分析の欄には「確認が不十分だった」と書かれていることが多く、何も言わなければ「確認を徹底する」と対策を作ります。記録に無い対策が「当時の対策」として並ぶのが、いちばん避けたい失敗です。

Step7

出力形式を固定する

Bedrock の Converse API の outputConfig.textFormat に JSON スキーマを渡し、次の形で受け取ります。

{
  "report_id": "",
  "match_level": "generic_and_scene | scene_only",
  "cases": [
    { "case_id": "",
      "similarity": "高い | 中程度 | 低い",
      "common_points": [""],
      "different_points": [""],
      "drug_names_as_written": [""],
      "countermeasure": "",
      "countermeasure_on": "",
      "followup_case_ids": [""] }
  ],
  "lookalike_cases": [ { "case_id": "", "note": "" } ]
}

1つ目の理由は、事例番号を機械で確かめられることです。 返ってきた case_id と followup_case_ids が、検索で渡した番号の中にあるかを Lambda で照合し、無い番号があればその事例を画面に出しません。

2つ目は、名前の似た薬の事例を別の枠に分けられることです。 取り違えの報告のときだけ、lookalike_cases に名称類似薬の検索の結果を入れます。同じ一覧に混ぜると、成分の同じ事例と名前の似た事例の区別が画面から消えます。

3つ目は、drug_names_as_written で引き当てを目で確かめられることです。 一般名で絞って当たった事例でも、本文にどの名前で書かれていたかが並びます。

スキーマには数値の minimum・maximum や文字列の長さの制約を書きません。 Bedrock の構造化出力はそれらに対応しておらず、スキーマに含めると400のエラーになります。新しいスキーマは最初のコンパイルに数分かかることがあり、コンパイルされた形は24時間キャッシュされます。

Step8

システムへ連携する

つなぎ先方式内容
報告システム毎晩のCSVの書き出し(読み取りのみ)新しい報告と更新された報告
Amazon S3CSVと辞書の元ファイルの置き場置かれたことで Lambda が動く
Amazon OpenSearch ServiceLambda からの索引への登録と検索事例の索引、言い換えの辞書(パッケージ)
Amazon BedrockConverse API(Claude)、Titan の埋め込み取り出し、並べ方、埋め込み
医療安全管理者の画面院内のネットワークからだけ開ける画面検索の結果と事例の一覧

電子カルテにはつなぎません。 報告の本文で足りるものだけを扱い、患者の診療の記録をこの構成に入れないことで、扱う情報の範囲を報告システムと同じに保ちます。

Step9

人が確認する

  1. 事例を選ぶ … 医療安全管理者が一覧を読み、部署への返しに使う事例を選びます。similarity が「高い」でも、違う点を読んでから使います
  2. 事例を開いて確かめる … 使う事例は、報告システムで原文を開きます。画面の要約だけで部署に返しません
  3. 引き当てを確かめる … unmatched_drug_names の一覧を、兼任の薬剤師が週に1回見て、対応表に足すかを決めます
  4. 辞書の追加を決める … 第5章の7番目で登録された言い換えの候補を、月に1回まとめて辞書に足します

2番目を省かないでください。 要約は短くするために言い切ります。部署に「過去にこういう対策をした」と返すときは、その対策の原文を見てからにします。

Step10

例外に対処する

起きること対応
薬剤名が対応表に無いunmatched_drug_names に入れ、一般名の絞り込みを外して探す。薬剤師の確認の一覧へ
1つの名前が複数の一般名に当たる(配合剤など)すべての一般名で terms に入れる。どれで当たったかを画面に出す
一般名の絞り込みで3件に満たない場面だけで探し直し、match_level を scene_only にする
辞書の更新後に検索の結果が変わらないパッケージの更新の適用と関連付けの状態(Active)を確かめる
辞書に名称類似薬の組み合わせが入った更新を止め、その行を外すまで適用しない
構造化出力が返らない検索の結果だけを一覧で出し、要約の欄を空けて「要約なし」と表示する
返ってきた事例番号が検索の結果に無いその事例を画面に出さず、ログに残す
CSVの取り込みが途中で失敗した失敗した行から再開できるよう、報告ごとに取り込みの状態を持つ
Step11

記録を残す

  • 検索のたびの、新しい報告の番号、絞り込みの条件、match_level、返った事例番号と点数
  • Claude に渡した事例と、返ってきた JSON の全文
  • 医療安全管理者が選んだ事例と、選ばなかった事例
  • unmatched_drug_names と、薬剤師が対応表に足したかどうか
  • 言い換えの辞書の版と、適用した日時
  • 薬剤名の対応表の版(元にした薬価基準収載品目リストの適用日)

辞書と対応表の版を残すのは、検索の結果が版で変わるからです。 「先月は当たったのに今月は当たらない」ときに、どの版で探したかが分からないと、原因を追えません。

04実装レベルの3段階

最小構成:書き出した報告を、手で作った対応表で一般名に寄せて表計算で探す / 薬剤名の言い換え
半自動化:上記+OpenSearch に索引を作り、言い換えの辞書とハイブリッド検索で探す / 検索と言い換え
本格構成:上記+毎晩の取り込みで薬剤・処置を取り出し、検索の後に事例ごとの似た点・違う点・当時の対策を並べる / 探すところから、事例の整理まで

半自動化で、1件30分が20分程度になります。 名前を変えての検索がなくなりますが、当たった事例を1件ずつ開いて対策を読む作業が残ります。本格構成で12分になり、この段階が本記事の想定です。 辞書は半自動化の段階で育てます。 本格構成に進む前に、1〜2か月使って言い換えの候補を集めておくと、要約の段に渡す事例の質が上がります。

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

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

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

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

AI活用について相談する

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

向いている
  1. 病床が数百床ある急性期病院で、院内のインシデント報告が年に数千件出ており、医療安全管理室が報告ごとに過去の似た事例を探してから部署に返している場合。報告システムの検索が文字の一致だけで、商品名で書かれた報告と一般名で書かれた報告、略語で書かれた処置と正式名で書かれた処置が別のものとして扱われている場合。AWS を使える院内の情報システムの担当か委託先がいる場合。
向いていない
  1. 報告が年に数百件で、医療安全管理者が過去の事例をほぼ覚えている規模の病院。報告がまだ紙で、本文と対策が電子データとして残っていない場合(先に報告の電子化から始めます)。患者の情報を院外のクラウドに置くことを院内の規程で認めていない場合。なお、事故の原因の判断、医療事故に当たるかどうかの判断、医療事故調査制度の報告の要否の判断は、この構成では代替できません。過去の記録を探して並べるまでです。

07最小構成で試す方法

  1. 過去1年の報告から、薬剤に関わる報告を200件書き出す(患者の識別情報の列は外す)
  2. 薬剤部の採用薬の一覧と薬価基準収載品目リストから、その200件に出てくる薬の対応表を手で作る
  3. 医療安全管理者が、最近探した10件について「本当は当たってほしかった過去の報告」を挙げる
  4. 書き出した200件を、商品名のままの場合と一般名に寄せた場合の2通りで、表計算の検索で引いてみる
  5. 当たってほしかった報告がどれだけ拾えたかを比べる

3番目が、この試しの物差しです。 何が「似た事例」かは医療安全管理者が決めることで、機械で測る前に人が答えを持っておきます。

出てきた内容判断
一般名に寄せると当たってほしかった報告が増えた対応表の整備と OpenSearch の構築に進む
薬剤より処置の略語で外れている言い換えの辞書が先。 部署ごとの呼び方を集める
どちらでも当たらない本文の書き方がまちまち。意味の検索を足す効果を確かめる

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

問題対策
辞書を更新しても検索が変わらないパッケージの更新をドメインに適用する。 検索用のアナライザーに updateable: true を付ける
索引を作るときのアナライザーに辞書を入れた辞書の更新のたびに作り直しになる。検索用だけに置く
名前の似た薬が同じ事例として並ぶ辞書に名称類似薬を入れない。 更新のたびに機械で確かめる
一般名に寄せて規格の違いが消える規格を strengths に別に持ち、違う点に出す
stop を synonym_graph の後ろに置いた言い換えの組み立てが壊れる。前に置くか外す
ハイブリッドクエリを function_score で包んだ正規化が飛ばされることがある。並べ替えは表示の段で
当時の対策が空のまま並ぶ対策が書き足された報告を入れ直していない。更新された報告も毎晩取り込む
要約が対策を作る「記載なし」を指示し、対策の欄の原文と照合する
スキーマに数値の制約を書いて400になるBedrock の構造化出力は minimum・maximum に非対応。制約は Lambda で確かめる
日本語の意味の検索が効かないTitan Text Embeddings V2 は英語に最適化され、日本語はプレビュー。言葉の側を重くし、自院の報告で確かめる

上の3行が、この構成の失敗のほとんどです。 辞書は便利な分だけ、入れてはいけないものが入ったときの影響が大きくなります。

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

この構成で扱うデータ: インシデント報告の本文(患者の状態、行った処置、薬剤、職員の行動)、部署と発生日時、分析と対策です。

  1. 患者の識別情報を索引に入れない … 患者ID・氏名・生年月日の列を落とし、本文の氏名も伏せます。本文には病名や処置が書かれており、伏せても要配慮個人情報に近い情報が残ることを前提にします
  2. 報告した職員を責める材料にしない … 似た事例の一覧は、対策を考えるための材料です。報告者の名前で検索する機能を作りません。 報告が減れば、この仕組みの元のデータが痩せます
  3. 院内のネットワークからだけ届くようにする … OpenSearch のドメインと画面を、院内の閉じたネットワークの中に置きます
  4. データを置く地域を決めておく … Bedrock のモデルと推論プロファイルが、どの地域でデータを処理するかを確かめ、院内の規程と照らします
  5. 原因と対策は人が決める … この構成は過去の記録を並べるだけです。医療事故に当たるかの判断や、医療事故調査制度に関わる判断は、病院の管理者と医療安全管理委員会が行います

誤りが起きた場合のリスクは、似ていない事例の対策をそのまま使うことと、名前の似た別の薬の事例を同じ薬の事例として扱うことの2つです。 どちらも「違う点」を読み、原文を開く手順で防ぎます。

10まず何から始めるか

1週目:書き出しの列を確かめる

報告システムのCSVに、本文・分析・対策・対策の実施日・更新日時が含まれるかを確かめます。対策の列が出ないなら、それを出すところから始めます。

2週目:200件で試す

第8章のとおり、薬剤に関わる200件で、商品名のままと一般名に寄せた場合を比べます。当たってほしかった報告を、医療安全管理者が先に挙げておきます。

3週目:言い換えの辞書の最初の版を作る

各病棟のリスクマネージャーに、処置・チューブ類・機器の呼び方を聞いて、辞書の最初の版を作ります。同時に、薬剤部の名称類似薬の一覧を受け取ります。

4週目:索引を作る

OpenSearch のドメインを作り、辞書をパッケージとして関連付け、2万5千件を取り込みます。この時点では要約を出さず、検索の結果の一覧だけを使います。

2か月目: 毎晩の取り込みと、薬剤・処置の取り出しを足します。unmatched_drug_names の件数を毎週数えます。3か月目以降: 事例ごとの似た点・違う点・当時の対策を並べる段を足し、1件30分が何分になったかを実測します。辞書の追加が月に数件まで落ち着いた時点で、この構成は完成です。


11関連ユースケース

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

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

技術仕様確認日:2026-10-15/最終更新:2026-10-15
確認した内容情報源確認日
辞書のテキストファイルを S3 からパッケージとして取り込み、ドメインに関連付けて analyzers/<ID> を synonyms_path に指定できること。パッケージの更新は明示的に適用すること。updateable: true の検索用アナライザーだけなら自動で索引が更新され、索引用のアナライザーでは閉じて開くか作り直しが要ることAWS: Importing and managing packages2026-10-15
Japanese(kuromoji)Analysis がドメインに含まれることAWS: Plugins by engine version2026-10-15
synonym_graph が複数の語からなる言い換えを扱い、検索用のアナライザーでだけ使うこと。規則がその前の分かち書きとフィルタで処理されること。stop を後ろに置くと組み立てが壊れることOpenSearch: Synonym graph token filter2026-10-15
ハイブリッドクエリの検索が最大5つで、filter が1つの検索の形であること。最上位に置くもので、function_score などで包むとエラーか正規化が飛ばされることがあることOpenSearch: Hybrid query2026-10-15
ハイブリッドクエリの最上位の filter が 3.0 で入り、すべての検索に適用されることOpenSearch: Hybrid search with pre-filtering2026-10-15
正規化の既定が min_max で、結果が1件の検索ではその文書が1.0になること。weights の合計が1.0であることOpenSearch: Normalization processor2026-10-15
Titan Text Embeddings V2 の入力が8,192トークン・5万字までで、文書を段落や節に分けることがすすめられること。英語に最適化され、日本語を含む100を超える言語がプレビューであることAWS: Amazon Titan Text Embeddings models2026-10-15
Converse API の outputConfig.textFormat で JSON スキーマに沿った出力が得られること。数値・文字列の長さの制約に非対応で400になること。最初のコンパイルに数分かかり、24時間キャッシュされることAWS: Structured outputs(Amazon Bedrock)2026-10-15
薬価基準収載品目リストに区分・薬価基準収載医薬品コード・成分名・規格・品名・メーカー名の項目があり、約1万3千品目が載っていること。令和8年10月14日適用の版が公開されていること厚生労働省: 薬価基準収載品目リスト及び後発医薬品に関する情報について2026-10-15

事故の原因の判断、医療事故に当たるかの判断、対策の決定は、病院の管理者と医療安全管理委員会が行ってください。 本記事は上記の公式ページで確認できた範囲だけを扱っています。

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

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

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

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