上級 11 分医療

資料集の要約 医療

端的な回答

ローカルLLMで医療記録を要約するには、コードを使ってFHIRバッチまたはCDA R2ドキュメントから事実を抽出し、それらに番号を付けます。次に、それらの事実だけに基づき、各行に出典の参照を付けて要約を作成させます。その後、プログラムで各参照と各数値が元の資料に存在することを確認し、最後に医師の確認を受けます。ローカル環境は機密性を保護しますが、ハルシネーションを防ぐものではありません。2025年の研究では、文あたり1.47%のハルシネーションが報告されています。

医療記録は正確でも、情報が断片的です。一方、言語モデルが作成する読みやすい要約には、重大な誤りが含まれる可能性があります。本ガイドでは、コードで事実を抽出し、モデルが出典を引用しながらそれを要約し、プログラムによる検証の後に医師が結果を確認するローカルパイプラインを説明します。また、確認すべき制度上の枠組みとして、医療上の守秘義務、医療データのホスティング、ツールの利用目的も取り上げます。

著者 Mohamed Meguedmi·更新 2026-09-30·Windows・macOS・Linuxでテスト済み

#問題:内容は正確でも読みにくい診療記録

患者を引き継ぐ医療従事者は、診療報告書、臨床検査結果、処方箋、書簡を確認する必要があります。これらは複数のソフトウェアで作成されていることがよくあります。ローカルモデルは、診療記録の引き継ぎ用の要約を1ページにまとめることができます。医療の場で通用する手順は常に同じです。決定論的なコードで構造化データを抽出し、その事実だけを基に要約を作成させ、各行に元の事実の識別子を引用させ、プログラムで要約を検証し、最後に医師の確認・承認を受けます。

用語を整理しておくと、よくある混同を避けられます。フランスでは、特に共有医療記録(Dossier Médical Partagé)を通じて交換・共有される医療文書は、フランスのデジタル保健庁(Agence du numérique en santé)が定める医療情報システムの相互運用性フレームワーク(CI-SIS)に従います。その各編では、XMLに基づくHL7標準であるCDA R2形式の文書が規定されています。HL7バージョン2は別の標準で、縦棒で区切られたテキストメッセージを用い、データの転送に使われます。最後に、JSON形式のFHIRは最も新しく、最も処理しやすい交換規格で、主にアプリケーション間のデータ交換で見られます。したがって、まずはお使いのソフトウェアが何を提供するのかを確認する必要があります。

i
共有医療記録へのアクセス
スクリプトからDMPに自由に接続することはできません。アクセスには、医療従事者向けのソフトウェアか、認可された仲介プラットフォームを利用する必要があります。CI-SISのCDA-R2文書の送信に関する仕様では、業務ソフトウェアがDMPとのやり取りやMSSantéによるメッセージの送受信を仲介プラットフォームに委任できることが説明されています。そのため、このガイドでは、お使いのソフトウェアからすでにエクスポートされた文書を扱います。

#基本的な枠組み:医療上の守秘義務、ホスティング、責任

ローカルAIキット

お使いのマシンで、プライベートかつ無料のChatGPTを1時間で構築 — LM Studio、Ollama、Open WebUI、ご自身のドキュメント、クラウド不要。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 30日間返金対応

コードを書く前に、3つの問題を検討する必要があります。1つ目は医療上の守秘義務と健康データの保護です。そのため、これらのデータは管理下にあるインフラで処理しなければなりません。ローカル処理はその具体的な実践方法ですが、ディスクの暗号化、アクセス制限、ログの記録も必要です。2つ目は健康データのホスティングです。公衆衛生法典第L. 1111-8条では、データ管理者または患者に代わって、個人に関する健康データをデジタル媒体上でホスティングする者は、そのための認証を受けなければならないと定められています。

この義務は、常に想定されているように機能しません。デジタルヘルス・エージェンシーが保険会社が引用した内容によると、すべてのシステムが自社の患者のデータのみを保存する場合、ホスティング認証は規制義務ではありません。ただし、第三者のためのホスティング業務を実施する場合を除きます。つまり、自社の患者向けにツールを自宅で実行する診療所は、他の診療所にこのサービスを提供するエディターよりも異なる状況にあります。データ保護に関するコンサルタントまたはデータ保護担当者に、あなたの状況を確認していただけますようお願いいたします。

3つ目の問いは、使用目的です。医療上の判断に役立つ情報を生成するソフトウェアは、標榜する使用目的によっては医療機器の規制対象となる可能性があります。診療記録を再確認するための要約を、内容を読み取る補助として提示し、医師が検証する場合と、治療を提案するツールとでは、その位置づけが異なります。本ガイドは、前者の位置づけにとどまります。

#ローカルスタック

三つの構成要素で十分です。まず、文書を読み取るためのPythonです。FHIRの一括データにはjsonモジュール、CDA文書にはlxmlを使い、バージョン2のメッセージがある場合には、HL7 v2.xメッセージのパーサーと説明されているhl7ライブラリを使います。次に、モデルを提供するOllamaです。90億パラメータのQwen 3.5のサイズは6.6 GBで、公称コンテキスト長は256,000トークンです。Mistral Small 24Bのサイズは14 GBで、公称コンテキスト長は32,000トークンです。最後に、OllamaのJSONスキーマを使い、検証可能な形式でモデルに応答させます。

これらのモデルは、いずれも提供元による臨床用途での検証を受けていません。医療分野のフランス語を扱う能力は、以下の手順を用いて、ご自身の診療記録で評価してください。最初のモデルには8 GBのグラフィックスカードで十分ですが、2つ目のモデルは、特にコンテキストが長い場合、より多くのビデオメモリを必要とします。

#文書を読み込む:FHIRのバッチとCDA文書

FHIRのBundleは、リソースの集合を格納するコンテナです。これを扱う最も簡単な方法は、JSONをそのまま読み込み、種類ごとにリソースを取り出すことです。これにより、対応するFHIRのバージョンが異なるライブラリに依存せずに済みます。採用した各事実には、短い識別子(F1、F2…)と読みやすいテキストを付けます。これによって、後から要約の各文の出典をたどれるようになります。

FHIR(R4)のデータの一括処理で事実を抽出
import json

def libelle(cc):
    if not cc:
        return None
    if cc.get('text'):
        return cc['text']
    c = (cc.get('coding') or [{}])[0]
    return c.get('display') or c.get('code')

def faits_fhir(chemin):
    lot = json.load(open(chemin, encoding='utf-8'))
    faits = []
    for e in lot.get('entry', []):
        r = e.get('resource', {})
        t = r.get('resourceType')
        if t == 'Condition':
            texte = f"Diagnostic : {libelle(r.get('code'))} (début {r.get('onsetDateTime', 'date inconnue')})"
        elif t == 'MedicationStatement':
            dose = (r.get('dosage') or [{}])[0].get('text', 'posologie non précisée')
            texte = f"Traitement : {libelle(r.get('medicationCodeableConcept'))}, {dose}"
        elif t == 'Observation':
            v = r.get('valueQuantity', {})
            texte = f"Résultat : {libelle(r.get('code'))} = {v.get('value')} {v.get('unit', '')} ({r.get('effectiveDateTime', 'date inconnue')})"
        elif t == 'AllergyIntolerance':
            texte = f"Allergie : {libelle(r.get('code'))}"
        elif t == 'Procedure':
            texte = f"Acte : {libelle(r.get('code'))} ({r.get('performedDateTime', 'date inconnue')})"
        else:
            continue
        faits.append({'ref': f'F{len(faits) + 1}', 'type': t, 'texte': texte})
    return faits

CDA文書では、有用なテキストは構造化された本文の各セクションにあります。各セクションには、タイトル、コード、自由記述のテキストブロックがあります。以下のコードは、そのテキストをタイトルとともに抽出し、患者の識別情報を含む文書ヘッダーは取り込みません。CDAの名前空間はHL7バージョン3のものです。

CDA R2ドキュメントのセクションを抽出
from lxml import etree

NS = {'h': 'urn:hl7-org:v3'}

def sections_cda(chemin):
    racine = etree.parse(chemin).getroot()
    for s in racine.iterfind('.//h:structuredBody//h:section', NS):
        texte = s.find('h:text', NS)
        if texte is None:
            continue
        code = s.find('h:code', NS)
        yield {
            'titre': (s.findtext('h:title', default='', namespaces=NS) or '').strip(),
            'code': code.get('code') if code is not None else None,
            'texte': ' '.join(''.join(texte.itertext()).split()),
        }
→
要約する前に抽出する
未加工の文書をモデルにそのまま渡すことは、決してしないでください。XML文書の大部分はタグと識別子で構成されているため、コンテキストを消費し、有用な情報を埋もれさせます。パイプラインでは、まず診療記録を番号付きの事実リストに変換し、そのリストを要約します。

#どの事実を取り上げ、どの程度慎重に扱うべきか

再構成のためのFHIR向けの有用なリソース
リソース読み取れる情報よくある落とし穴
Condition診断、開始日、状態解消済みの病状に対する診断や誤った診断が、履歴に残っていることがあります
MedicationStatement医薬品、用法・用量、期間中止された治療が、中止済みと記録されていない場合があります
Observation臨床検査や測定の結果、単位、日付単位も基準値も示されていない数値を比較する
AllergyIntolerance物質、反応、重症度未入力だからといって、アレルギーがないとは限らない
Procedure実施された医療行為とその日付おおよその日付、または日付の欠落
DocumentReference添付ファイル(診療報告書などであることが多い)エンコードされたコンテンツ、または別途取得が必要なリンク先のコンテンツ

最後の列は、ほかの列よりも重要です。モデルは与えられた事実を読み取りますが、何が欠けているかは分かりません。中止された治療がそのように記されていなければ、要約では継続中の治療として扱われます。そのため、コードにはステータスと日付を含め、プロンプトでは日付のない事実やステータスが不確かな事実を明示するよう求める必要があります。情報がないこと自体は情報ではありません。要約でも、その点を明示する必要があります。

#ソースを引用した要約を作成し、その後それを検証する

プロンプトでは番号付きの事実を提示し、要約の各行が使用した事実の参照(例:[F3][F7])で終わることを要求します。患者名は含まれておらず、年齢と性別で十分であり、身元情報は業務用ソフトウェア内に保持されます。回答の形式は自由ですが、セクションごとに構造化されており、1ページで読みやすいようになっています。

番号付きの事実に基づく要約
import requests

SYSTEM = open('system_med.txt', encoding='utf-8').read()

def synthese(faits, age, sexe, modele='qwen3.5:9b'):
    liste = '\n'.join(f"[{f['ref']}] {f['texte']}" for f in faits)
    r = requests.post('http://localhost:11434/api/chat', json={
        'model': modele, 'stream': False,
        'messages': [{'role': 'system', 'content': SYSTEM},
                     {'role': 'user', 'content': f'Patient : {age} ans, {sexe}.\n\nFAITS :\n{liste}'}],
        'options': {'temperature': 0.1, 'num_ctx': 16384}})
    return r.json()['message']['content']

その後、コードで検証します。2つのチェックで重大なエラーの大部分を検出できます。引用された参照がすべて事実リストに存在することと、要約内の数値がすべて事実に記載されていることです。事実にない数値が突然現れるのは、特に検査値や投与量について、捏造や転記ミスを示す典型的な兆候です。

要約のプログラムによる検証
import re

def verifier(synthese, faits):
    refs_ok = {f['ref'] for f in faits}
    citees = set(re.findall(r'\[(F\d+)\]', synthese))
    def nombres(t):
        t = re.sub(r'\[F\d+\]', ' ', t).replace(',', '.')
        return set(re.findall(r'\d+(?:\.\d+)?', t))
    source = nombres(' '.join(f['texte'] for f in faits))
    return {
        'references_inconnues': sorted(citees - refs_ok),
        'nombres_absents_de_la_source': sorted(nombres(synthese) - source),
        'lignes_sans_reference': [l for l in synthese.split('\n') if l.strip().startswith('-') and not re.search(r'\[F\d+\]', l)],
    }

#システムプロンプト

system_med.txt
Tu prépares une synthèse de reprise de dossier pour un médecin.
Tu ne poses AUCUN diagnostic, tu ne proposes AUCUN traitement ni modification de traitement.
Tu utilises UNIQUEMENT les faits fournis. Tu n'ajoutes aucune donnée.
Chaque ligne de la synthèse se termine par les références des faits utilisés, par exemple [F3][F7].
Si un fait n'a pas de date, ou si un statut est incertain, tu l'écris explicitement.
Si des faits semblent contradictoires, tu les signales sans trancher.
Si une information attendue est absente, écris : non renseigné.

SECTIONS : Pathologies, Traitements en cours, Allergies, Derniers résultats,
Actes et antécédents, Points à vérifier.

「確認すべき点」のセクションは、実際に最も役立ちます。不明確な点(終了日が記載されていない治療、単位のない結果、矛盾する2つの値)を、滑らかな文章にまとめて曖昧さを覆い隠すのではなく、医師に尋ねる質問に変えてくれます。

#使用前に信頼性を評価してください

信頼は、宣言するだけで得られるものではありません。2025年にnpj Digital Medicineに掲載された研究では、臨床記録の生成における言語モデルのエラーを測定しました。臨床に携わる医療従事者がアノテーションした12,999文のうち、1.47%の文にハルシネーション、3.45%に情報の欠落が見られました。また、ハルシネーションの44%は重大と判断されました。つまり、修正されなければ診断や患者への対応に影響する可能性があるということです。これらの数値は、別のタスクを別のモデルで実行した結果であり、ご自身のタスクやモデルの数値ではありません。文単位のエラー率が低くても、文書全体で見ると依然として懸念が残ることを示しています。

1行あたり1.5%の誤り率で30行の要約を作成し、誤りが独立していると仮定すると、約3分の1のケースで少なくとも1つの誤りを含むことになります。これは教育的な数量級の目安であり、予測ではありません。したがって、以下のプロトコルを適用します。これは「50件のケースでゼロエラー」という基準に置き換わります。この基準はほとんど何も証明しません。なぜなら、50件のケースで観察されたゼロエラーは、95%の信頼水準で実際の約6%の誤り率と両立しうるからです(3の法則、3を50で割った値)。

  1. 01
    匿名化した診療記録のサンプルを用意する
    複数の疾患を持つ患者、多数の治療、古い検査結果など、さまざまな診療記録を用意してください。診療の枠外で使用する場合は、使用する前に必ず、個人を特定できる情報と不要なデータを取り除いてください。
  2. 02
    医師による注釈を依頼する
    各要約文は「正しい」「不正確」「省略」「誤り」として分類されます。臨床判断に影響を与える可能性のある誤りを明確に区別してください。
  3. 03
    カテゴリ別・重大度別に数える
    診療記録ごとの重大なエラーの件数は、平均エラー率よりも重要です。始める前に、担当医と閾値を決めてください。
  4. 04
    欠落の測定も行う
    アレルギーや治療の情報が抜けた要約は、ぎこちない文章よりも危険です。
  5. 05
    変更ごとに再実行
    モデル、プロンプト、エクスポート形式のいずれを変更した場合も、その都度評価を再実行する必要があります。
!
処方支援には使わない
このツールを、治療法、投与量、またはその調整の提案に決して使わないでください。要約は内容を読み取るための補助であり、それを確認して承認する医師が引き続き責任を負います。

#本番運用:記録、アクセス、対象範囲

生成のたびにログを記録する
日付、モデルのバージョン、提供された事実の一覧、生成された要約を、安全に保護された場所に保存してください。これにより、医師が読んだ内容を再現できます。
アクセスの制御
推論サーバーは外部から接続できない状態にする必要があります。ディスクは暗号化され、アカウントは利用者個人にひも付けられています。
ソースを表示
インターフェースには要約が表示され、各行に元となった事実が併記されます。ワンクリックで確認できる医師は、実際に確認します。
利用範囲を限定する
利用範囲を広げる前に、まずは診療所や組織の内部で、少人数の利用から始めてください。他の組織にサービスを提供すると、ホスティングに関する立場が変わります。
人による確認・承認が明示されるようにする
要約は、診療担当者が署名または承認してから診療記録に追加します。署名または承認がない場合は、診療記録に含めてはいけません。
FAQ
ローカルLLMで診療記録を要約できますか?+
はい、技術的には可能です。まずコードで構造化データを抽出し、その事実だけに基づいて要約を作成させます。また、要約をプログラムでチェックし、医師に妥当性を確認してもらい、アノテーション付きの診療記録でシステムを評価する必要があります。ローカルでの実行は機密性の問題を解決しますが、信頼性の問題は解決しません。
DMPはFHIR形式でドキュメントを提供していますか?+
フランスの相互運用性フレームワークの各部では、XMLに基づくCDA R2形式の医療文書と、それらをDMPまたはMSSantéへ送信する方法が説明されています。FHIRは主にアプリケーション間の情報交換に使われます。お使いのソフトウェアが何をエクスポートするか確認してください。パイプラインが依存するのは、その出力形式であり、元の情報源ではありません。
診療所内で使うツールにも、HDS認証を受けたホスティング事業者が必要ですか?+
必ずしも必要ではありません。Relyensが引用したANSによると、医療機関が自院の患者のデータのみを保管する場合、認証は義務付けられません。第三者のためのホスティングを行う場合は、認証が義務付けられます。具体的な状況については、コンサルタントまたはデータ保護担当者に確認してください。
医療テキストにはどのローカルモデルを選ぶべきですか?+
出発点となる選択肢は二つです。8 GBのグラフィックカードでQwen 3.5 9B(6.6 GB、公表コンテキスト長256,000トークン)を使うか、より多くのメモリを用意してMistral Small 24B(14 GB)を使うかです。どちらも臨床的に検証されていません。ご自身の診療記録について両モデルが作成した要約に医師が注釈を付けたものを比較して選び、特に情報の抜けや重大な誤りを継続的に確認してください。
LLMは臨床検査の結果をでっち上げることがありますか?+
はい。臨床記録の生成に関する研究ではハルシネーションが観察されており、そのうちかなりの割合が重大と判断されています。そのため、このパイプラインでは各行に参照元を付けることを必須とし、要約中のすべての数値が元の事実に含まれているかを確認し、疑わしい点が残っていれば医師に知らせます。人による妥当性の確認は引き続き不可欠です。
このようなツールは医療機器とみなされるのでしょうか?+
そのツールが公表している使用目的によって異なります。医師の確認を受ける診療記録の読解支援ツールは、診断や治療を提案するツールとは異なり、規制の適用も同じではありません。内部利用の範囲を超えて導入する前に、規制の専門家にツールの規制上の分類を判断してもらってください。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。