🛠️

話題のMarkItDownをCloud Run関数でAPI化してみた

に公開

MarkItDownとは

MarkItDownは、様々なファイルをMarkdownに変換するユーティリティです(インデックス作成、テキスト分析など)。
以下のファイルをサポートしています。

  • PDF
  • パワーポイント
  • ワード
  • エクセル
  • 画像(EXIFメタデータおよびOCR)
  • 音声(EXIFメタデータおよび音声トランスクリプション)
  • HTML
  • テキストベースのフォーマット(CSV、JSON、XML)
  • ZIPファイル(コンテンツを反復処理)

https://github.com/microsoft/markitdown
生成AIの活用が進むにつれて、既存のファイルを生成AIで扱えるようにしたい、そのためにはそれらをテキスト形式に変換したい、というニーズが増してきたと思われます。このMarkItDownはそれを助けてくれる有用なツールと思われます。

課題

私が勤務している会社の業務で使用しているPCにはPythonのインストールができないため、個人のPCを使わない限り個々人でMarkitDownを使用することができません。
このMarkitDownをAPIとして提供することができれば、あとはクライアント側でそれを呼び出せばだれもがMarkitDownを利用できるようになると考え、今回このAPI化に挑戦してみました。
また一度APIとして実行環境を用意しておくと、他のアプリ、例えばDifyから利用するなどより多くのユースケースに対応できるようになります。

実行環境

今回はGoogle CloudのCloud Run関数を使いシンプルに実装します。
リソースはなるべくGoogle Cloudで管理したいため、ビルドにはCloud Build、コンテナイメージの保管場所はArtifact Refistory(Container Registory)を使用しています。

前提

  • 作業するPCに既にgcloud CLIがインストールされており初期セットアップが完了していること
  • Google Cloudプロジェクトも既に用意されていること

作成するもの

作成するファイル一覧

requirements.txt
Dockerfile
.dockerignore
main.py
test
|----run.py
|----要件一覧.xlsx
|----BCPレポート.pdf
requirements.txt
# Custom markdown conversion library
markitdown

# Support for handling multipart form data (file uploads)
python-multipart
Dockerfile
FROM python:3.10-slim-buster

WORKDIR /app

# システムパッケージの更新とクリーンアップ
RUN apt-get update && apt-get install -y \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install -r requirements.txt 
COPY . .

# Cloud Runのデフォルトポート
ENV PORT 8080

CMD functions-framework --target=main --source=main.py --port=${PORT}

.dockerignoreはお使いの環境に合わせて設定してください。

.dockerignore
# Git

# Python

# IDEs and editors

# OS generated files

# Project specific
/test

このmain.pyが今回のメインのプログラムです。
CloudRun関数を使用している場合、エントリーポイントにはmain.pyのmain関数をしているするのが無難なようです(他の関数も指定できるとは思います)。
このAPのエントリーポイント、つまりmain関数へのリクエストのパラーメータであるrequestオブジェクトにはMarkdownにしたいファイルオブジェクトを含めてPOSTリクエストで送ります。

なので本処理では一度ファイルを一時領域に保存してそのファイルパスをmarkitdown.convertメソッドに渡しています。
戻り値はMarkdown形式のテキストそのままです。

main.py
from markitdown import MarkItDown
import io
import shutil
import os
import uuid

def main(request):
    """Cloud Function entry point"""
    try:
        file = request.files.get('file')
        if not file:
            return 'No file uploaded', 400

        # 一時フォルダの作成
        hash_value = str(uuid.uuid4())
        folder_path = f"/tmp/{hash_value}"
        os.makedirs(folder_path, exist_ok=True)

        try:
            # ファイルを一時フォルダに保存
            temp_file_path = os.path.join(folder_path, file.filename)
            file.save(temp_file_path)

            # MarkItDownインスタンスの作成
            md = MarkItDown()
            
            # ファイルを変換
            result = md.convert(temp_file_path)
            
            # text_contentを取得
            markdown_text = result.text_content
            
            return markdown_text
        
        finally:
            # 一時フォルダの削除
            shutil.rmtree(folder_path, ignore_errors=True)

    except Exception as e:
        print(f"Error in main function: {e}")
        return str(e), 500

ビルド

関数名はmarkitdown-apiとしていますが、なんでも良いです。
my-project-idの部分は今回使用するGoogle CloudのプロジェクトIDにしてください。

command
gcloud builds submit --tag gcr.io/my-project-id/markitdown-api

デプロイ

Powershellで実行したので改行は"`"にしています。こちらはお使いの環境によって適宜変更して下さい。
こちらは余談ですが、--sourceや--imageを指定せずともデプロイができる理由をGemini2.0に聞いてみました。

なぜsourceを指定しなくもデプロイできるのか?

gcloud functions deploy コマンドでは、明示的にイメージ名を指定していません。しかし、Cloud Functions (第2世代) は、gcloud builds submit でビルドされた最新のイメージを暗黙的に使用する仕組みになっています。

もう少し詳しく説明します。

gcloud builds submit コマンドを実行すると、Artifact Registry にイメージがプッシュされます。この際、イメージにはタグ(gcr.io/your-project-id/markitdown-api など)が付けられます。

gcloud functions deploy コマンドを --gen2 オプション付きで実行すると、Cloud Functions はコンテナイメージベースのデプロイメントを想定します。

このとき、Cloud Functions は以下のルールで使用するイメージを決定します。

同じプロジェクト内で、同じ名前のイメージを探す: つまり、gcloud builds submit で使用したプロジェクト ID (your-project-id) とイメージ名 (markitdown-api) を元に、Artifact Registry 内の最新のイメージを探します。

最新のタグのイメージを使用: 同じ名前のイメージが複数存在する場合、最も新しいタグが付いたイメージを使用します。通常、gcloud builds submit はビルドごとに新しいイメージを作成し、新しいタグを付けるため、常に最新のイメージが使用されることになります。

つまり、gcloud functions deploy コマンドで明示的にイメージ名を指定する必要はありません。Cloud Functions が暗黙的に最新のイメージを見つけて使用してくれるのです。

もし、特定のバージョンのイメージを使用したい場合は、--source オプションではなく、--source オプションの代わりに --image オプションを使用し、イメージの完全なパス(例: gcr.io/your-project-id/markitdown-api:v1.0.0)を指定することができます。

command
gcloud functions deploy markitdown-api `                                     
--gen2 `
--region asia-northeast1 `
--runtime python310 `
--entry-point main `
--trigger-http `
--allow-unauthenticated `
--timeout=540

テスト

ここまでで作成してデプロイした関数をPythonプログラムから呼び出して実行します。もしそもそもPythonを実行できない環境の場合は別の方法を考える必要がありますが、この記事ではその方法の用意は割愛します。

テストモジュール

run.py
# -*- coding: utf-8 -*-
import sys
import requests

# 出力のエンコーディングをUTF-8に設定
sys.stdout.reconfigure(encoding='utf-8')

url = 'https://asia-northeast1-gleaming-bot-274716.cloudfunctions.net/markitdown-api/'
filePath = r"test\BCGレポート.pdf"  # raw stringを使用してエスケープシーケンスを回避

try:
    with open(filePath, 'rb') as f:
        files = {'file': f}
        response = requests.post(url, files=files)
        
        # レスポンスのエンコーディングをUTF-8に設定
        response.encoding = 'utf-8'
        
        print("Status Code:", response.status_code)
        print("Response Headers:", response.headers)
        print("Response Text:", response.text)
        
        # エラーレスポンスの詳細を表示
        if response.status_code != 200:
            print("Error Details:")
            print(response.text)
except FileNotFoundError:
    print(f"ファイルが見つかりません: {filePath}")
except requests.exceptions.RequestException as e:
    print(f"リクエスト中にエラーが発生しました: {e}")

テスト実行

command
powershell -Command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; & python test/run.py | Out-File -Encoding utf8 test/result.md"

Excelファイルで実験

テストに使用したExcelファイル

テスト実行結果

正常実行された場合はレスポンスとしてMarkdown形式のテキストデータとして出力します。
下の図はMarkdownビューワーで表示したものです。

なお、Excelファイルには複数シートが存在するのですが、別シートもちゃんと出力されます。

Markdownテキストはこちら
Status Code: 200
Response Headers: {'content-type': 'text/html; charset=utf-8', 'X-Cloud-Trace-Context': '8de13dacdee1d06deff4a7c7dc1c2844;o=1', 'Date': 'Sat, 28 Dec 2024 13:22:26 GMT', 'Server': 'Google Frontend', 'Content-Length': '14876', 'Alt-Svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000'}
Response Text: ## シナリオ1
| シナリオStep1 何が売れたか見える化する | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | 作成者 | 真悪 陀運 |
| --- | --- | --- | --- | --- | --- |
| NaN | NaN | シナリオ概要 | このシナリオでは何が売れたかを可視化します。なおこのセルは結合されています。セルの結合をするとExcelとしての機能が大きく失われ、ドキュメントのメンテナンス性を大きく損ねるので止めましょう。というか文書をExcelで作成・管理すること自体もうそろそろ卒業しませんか? | 作成日 | 2024-12-28 00:00:00 |
| 販売管理 | NaN | NaN | NaN | NaN | NaN |
| プロセス | 手順 | 要求ID | 手順・要件 | ユースケース | ビジネスルール |
| CASE010-010 販売する野菜を決める | NaN | NaN | NaN | NaN | NaN |
| NaN | 2 | NaN | 商品マスタの一覧を照会し、販売候補の野菜がまだシステム上に登録されていないことを確認する。 | CASE010-010-UC01\n販売対象商品の一覧を照会する | NaN |
| NaN | NaN | CASE010-010-2-R010 | 商品マスタの一覧は、当初は取り扱う商品数が10種類に満たないため、検索条件などは設けず登録されているすべての商品マスタを表示する。 | NaN | NaN |
| NaN | NaN | CASE010-010-2-R020 | 商品マスタの一覧には、商品ID、商品名、標準販売単価を表示する。 | NaN | NaN |
| NaN | 3 | NaN | 販売候補の野菜の名前、標準の販売価格を販売対象としてシステムの商品マスタに記録する。 | CASE010-010-UC02\n販売対象商品を追加する | NaN |
| NaN | NaN | CASE010-010-3-R010 | 販売対象の野菜を記録する際に、システムは野菜を一意に識別する商品IDを店長が任意に決め、商品マスタに記録する。先頭は”FW”で以後は英数字とする。 | NaN | CASE010-010-BL01商品ID書式確認 |
| NaN | NaN | CASE010-010-3-R020 | 指定された商品IDが商品マスタにすでに存在していないことをシステムは保証する。 | NaN | CASE010-010-BL02商品ID存在確認 |
| NaN | 3a-1 | NaN | 誤ってシステムに記録した商品を商品マスタから除外する。 | CASE010-010-UC01\n販売対象商品の一覧を照会する\nCASE010-010-UC03\n販売対象商品から除外する | NaN |
| NaN | NaN | CASE010-010-3a-R010 | 誤って記録した商品の削除は商品マスタの一覧から、削除対象の商品を選んで削除できる。 | NaN | NaN |
| NaN | NaN | CASE010-010-3a-R020 | 仕入、販売の実績がある商品は削除できないようにする。(仕入伝票明細、販売伝票明細に該当する商品IDがある) | NaN | CASE010-010-BL03商品削除可否判定 |     
| NaN | 3b-1 | NaN | 販売対象の商品マスタの一覧から対象の商品を選び、標準単価を変更する。 | CASE010-010-UC01\n販売対象商品の一覧を照会する\nCASE010-010-UC04\n販売対象商品の標準単価を変える | NaN |
| NaN | NaN | NaN | 以後、販売を記録する(CASE010-100 #2販売商品の記録)際の商品選択時に初期表示される標準単価の表示が変わること。 | CASE010-100#2参照 | NaN |
| NaN | NaN | CASE010-010-3b-R010 | 標準単価の変更は商品マスタの一覧から、変更対象の商品を選び、標準単価のみを変更できる。 | NaN | NaN |
| NaN | NaN | CASE010-010-3b-R020 | 販売対象の野菜を管理する商品マスタには値引き前の標準の販売単価を保持する。標準の販売単価は値引きしない販売での消費税込みの販売単価とする。 | NaN | NaN |
| CASE010-100 閉店後に1日の販売を確認する | NaN | NaN | NaN | NaN | NaN |
| NaN | 1 | NaN | まだ記録していない販売メモを、新たな販売伝票としてシステムに記録する。 | CASE010-100-UC01\n販売伝票の一覧を照会する\nCASE010-100-UC02\n販売伝票を新たに作成する | NaN |   
| NaN | NaN | CASE010-100-1-R010 | 販売メモがまだシステムに記録されていないことを確認するため、販売伝票の一覧は、記録が新しいものから順に一覧に表示されるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-100-1-R020 | 販売伝票の一覧には、販売伝票番号、販売日、販売日時(記録した日時)、販売数合計、販売額合計が表示されるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-100-1-R030 | 販売伝票の一覧から新たな伝票を記録できるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-100-1-R040 | 販売メモの販売1回につき販売伝票を記録する。 | NaN | NaN |
| NaN | NaN | CASE010-100-1-R050 | 販売メモに販売伝票番号を記載して後に照合できるようにするため、システムは販売伝票を新たに作成した時に販売伝票番号を自動で採番する。販売伝票番号はSalesの省略で”SL”で始まり、西暦、24時間表記でゼロパディングした年月日時分16桁とする。 | NaN | CASE010-100-BL01販売伝票番号採番 |
| NaN | 2 | NaN | 販売メモのすべての商品分、商品、販売単価、数、販売額をシステムに記録する。 | CASE010-100-UC11\n販売伝票と販売明細を照会する\nCASE010-010-UC01\n販売対象商品の一覧を照会す る\nCASE010-100-UC12\n販売商品を選び明細に追加する | NaN |
| NaN | NaN | CASE010-100-2-R010 | 販売伝票には販売メモの販売内容に基づき、販売した商品ごとの商品、販売単価、販売数、販売額を販売伝票明細として記録できる。 | NaN | NaN |
| NaN | NaN | CASE010-100-2-R020 | 販売伝票の販売数合計、販売額合計は、販売伝票明細の追加、削除に伴い販売伝票明細の販売数と販売額をシステムが自動で集計する。 | NaN | CASE010-100-BL02販売明細集計 |
| NaN | NaN | CASE010-100-2-R030 | 販売伝票明細の野菜は「販売する野菜を決める」でシステムに登録した野菜の商品から選べること。(販売メモを書くときも野菜の種類で書いておく。) | NaN | NaN | 
| NaN | NaN | CASE010-100-2-R040 | 販売伝票明細の販売価格は「販売する野菜を決める」でシステムに登録した野菜の標準販売価格を表示し、値引き時は値引き後の消費税込み単価に訂正できる。 | NaN | CASE010-100-BL03販売額計算 |
| NaN | 2a-1 | NaN | 誤ってシステムに記録した商品を販売伝票明細の一覧から選び、販売伝票から削除する。 | CASE010-100-UC11\n販売伝票と販売明細を照会する\nCASE010-100-UC13\n販売明細から商品を除外する | NaN |
| NaN | NaN | CASE010-100-2a-R010 | 商品、販売単価、販売数を間違えたときは、未確定の販売伝票であれば、対象商品を販売伝票明細の一覧から選び削除できる。 | NaN | CASE010-100-BL04販売伝票削除 可否判定 |
| NaN | NaN | CASE010-100-2a-R020 | 修正する場合、一度商品の販売伝票明細を削除してから再度対象商品の販売伝票明細を追加して記録する。(販売伝票明細の修正はできない。) | NaN | NaN |        
| NaN | 2b-1 | NaN | 返品時の販売メモは、商品の販売数をマイナスした販売伝票を記録する。 | CASE010-100-UC11\n販売伝票と販売明細を照会する\nCASE010-010-UC01\n販売対象商品の一覧を照会する\nCASE010-100-UC12\n販売商品を選び明細に追加する | NaN |
| NaN | NaN | CASE010-100-2b-R010 | 返品時は販売伝票明細の販売数に返品された数をマイナスで記録する。 | NaN | NaN |
| NaN | 3 | NaN | 販売メモと、システムに記録した販売伝票を照合する。 | CASE010-100-UC11\n販売伝票と商品明細を照会する | NaN |
| NaN | NaN | CASE010-100-3-R010 | 販売を記録した後、販売した商品ごとに、販売単価、販売数、販売額が表示され、販売メモと照合できる。 | NaN | NaN |
| NaN | NaN | CASE010-100-3-R020 | 販売を記録した後、販売伝票番号、販売日時、販売額合計が表示され、販売メモと照合できる。 | NaN | NaN |
| NaN | NaN | CASE010-100-3-R030 | 販売メモに該当する販売伝票番号を後から突き合わせできるように、販売メモに記載した販売伝票番号で販売伝票を検索できるようにする。 | NaN | NaN |

## シナリオ2
| シナリオSte2 仕入れ管理 | Unnamed: 1 | Unnamed: 2 | Unnamed: 3 | 作成者 | 真悪 陀運 |
| --- | --- | --- | --- | --- | --- |
| NaN | NaN | シナリオ概要 | このシナリオでは仕入れ管理を行います。なおこのセルは結合されています。セルの結合をするとExcelとしての機能が大きく失われ、ドキュメントのメンテナンス性を大きく損ねるので止めましょう。というか文書をExcelで作成・管理すること自体もうそろそろ卒業しませんか? | 作成日 | 2024-12-28 00:00:00 |
| NaN | NaN | NaN | NaN | NaN | NaN |
| プロセス | 手順 | 要求ID | 手順・要件 | ユースケース | ビジネスルール |
| CASE010-030 仕入れた野菜を店に入庫する | NaN | NaN | NaN | NaN | NaN |
| NaN | 2 | NaN | まだ記録していない購入明細を新たな仕入伝票としてシステムに記録する。 | CASE010-030-UC01\n仕入伝票の一覧を照会する\nCASE010-030-UC02\n仕入伝票を新たに作成する | NaN |     
| NaN | NaN | CASE010-030-2-R010 | 購入明細がまだシステムに記録されていないことを確認するため、仕入伝票の一覧は、記録が新しいものから順に一覧に表示されるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-030-2-R020 | 仕入伝票の一覧には、仕入伝票番号、仕入日、仕入日時(記録した日時)、仕入数合計、仕入額合計が表示されるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-030-2-R030 | 販売伝票の一覧から新たな伝票を記録できるようにする。 | NaN | NaN |
| NaN | NaN | CASE010-030-2-R040 | 買付時に仲卸業者から発行される購入明細ごとに1つの仕入伝票を記録する。 | NaN | NaN |
| NaN | NaN | CASE010-030-2-R050 | 購入明細に仕入伝票番号を記載して後に照合できるようにするため、システムは仕入伝票を新たに作成した時に仕入伝票番号を自動で採番する。仕入伝票番号はPurchase の省略で”PC”で始まり、西暦、24時間表記でゼロパディングした年月日時分16桁とする。 | NaN | CASE010-030-BL01仕入伝票番号採番 |
| NaN | 2a-1 | NaN | 誤って新たにシステムに作成した仕入伝票を仕入伝票の一覧から選び取消する。 | CASE010-030-UC01\n仕入伝票の一覧を照会する\nCASE010-030-UC03\n仕入伝票を取消する | NaN |    
| NaN | NaN | CASE010-030-2a-R010 | 確定する前の仕入伝票は、仕入伝票の一覧から削除対象の仕入伝票を選んで取消できる。 | NaN | CASE010-030-BL04仕入伝票削除可否判定 |
| NaN | 3 | NaN | 購入明細のすべての商品分、仕入れた野菜、仕入数、仕入単価、仕入額をシステムに記録する。 | CASE010-030-UC11\n仕入伝票と仕入明細を照会する\nCASE010-010-UC01\n販売対象商品の 一覧を照会する\nCASE010-030-UC12\n仕入商品を選び明細に追加する | NaN |
| NaN | NaN | CASE010-030-3-R010 | 仕入伝票明細には、購入明細の商品ごとの購入内容に基づき、仕入れた商品ごとに商品、商品特徴、仕入単価、仕入数、仕入額を記録できる。 | NaN | NaN |
| NaN | NaN | CASE010-030-3-R020 | 仕入伝票の仕入数合計、仕入額合計は、仕入伝票明細の追加、削除に伴い仕入伝票明細の仕入数と仕入額をシステムが自動で集計する。 | NaN | CASE010-030-BL02仕入明細集計 |
| NaN | NaN | CASE010-030-3-R030 | 仕入伝票明細の商品は商品マスタに記録している野菜から選べる。 | NaN | NaN |
| NaN | NaN | CASE010-030-3-R040 | 仕入伝票明細に色や種別を商品特徴として記録できる。 | NaN | NaN |
| NaN | NaN | CASE010-030-3-R050 | 仕入伝票明細の仕入数は、仕入れた野菜の本数を記録する。 | NaN | NaN |
| NaN | NaN | CASE010-030-3-R060 | 仕入伝票明細の仕入単価は、税込の仕入単価を記録する。 | NaN | NaN |
| NaN | NaN | CASE010-030-3-R070 | 仕入伝票明細の商品ごとの仕入額は仕入単価 × 仕入数でシステムが自動計算する。 | NaN | CASE010-030-BL03仕入額計算 |
| NaN | 3a-1 | NaN | 誤ってシステムに記録した商品を仕入伝票明細の一覧から選び、仕入伝票から削除する。 | CASE010-030-UC11\n仕入伝票と仕入明細を照会する\nCASE010-030-UC13\n仕入明細から商品を除外する | NaN |
| NaN | NaN | CASE010-030-3a-R010 | 確定する前の仕入伝票は、商品ごとの仕入伝票明細の一覧から誤った記録をした商品の仕入伝票明細を一覧から選び削除できる。 | NaN | CASE010-030-BL04仕入伝票削 除可否判定 |
| NaN | 4 | NaN | 購入明細と、システムに記録した仕入伝票を照合する。 | CASE010-030-UC11\n仕入伝票と仕入明細を照会する | NaN |
| NaN | NaN | CASE010-030-4-R010 | 仕入伝票を記録した後、記録した仕入伝票の仕入日時、仕入方法、仕入額合計を購入明細と照合できる。 | NaN | NaN |
| NaN | NaN | CASE010-030-4-R020 | 仕入伝票を記録した後、商品ごとの仕入伝票明細の商品、商品特徴、仕入単価、仕入数、仕入額を購入明細と照合できる。 | NaN | NaN |
| NaN | NaN | CASE010-030-4-R030 | 購入明細に該当する仕入伝票番号を後から突き合わせできるように、購入明細に記載した仕入伝票番号で仕入伝票を検索できるようにする。 | NaN | NaN |
| CASE010-130 翌日に仕入れる野菜と数を決める | NaN | NaN | NaN | NaN | NaN |
| NaN | 1 | NaN | 過去2週間の商品ごとの販売数、仕入数の推移と現在庫から翌日の野菜の仕入を決定する。 | CASE010-130-UC01\n販売と仕入の推移を照会する | NaN |
| NaN | NaN | CASE010-130-1-R010 | 当日から2週間前までの日別に、商品ごとの仕入数と販売数を集計し一覧で表示する。 | NaN | NaN |
| NaN | NaN | CASE010-130-1-R020 | 一覧は商品別に日を縦に1日の仕入数、販売数を横に表示し、日は今日から14日前までを今日から過去の順で表示する。 | NaN | NaN |

セルに書かれている文字列は漏れなく抽出していますが、空白のセルはNaNという表記で出力されています。また、テスト文書にはセル結合も含まれていますがこちらも出力可能です。

PDFファイルで実験

テストに使用したPDFファイル

生成AIに対する各国政府の対応 および 生成AIが業務に与える影響と企業の対応

実行結果

全てのページをテキスト抽出できましたが、長いので1ページだけ抜粋

Markdown

各国ごとに生成AIのリスクへの許容度が異なり、生成AIへの対応にはパターンが存在
各国政府のAIへの取組

A

民間主導での
積極活用

B

政府の介入に
よる活用推進

C

リスクも踏まえた
バランス型

国の例

主な取組み
民間での積極的な開発・活用を背景に、産業領域の民間での推進に委ね、公共分野のみ政府が介入
• 規制に向けてIT企業大手トップとの初の協議が2023年9月に実施されたが、法整備はまだ着手段階

一定のリスクに目配りをしつつ、政府が一定介入し、産業振興 / 自国内の活用を推進

• シンガポール:企業の利活用におけるリスクおよび対応方針を策定。公務員に対し、ChatGPTを大規模に導入。
• 韓国: 生成AI技術に対応したAI倫理の標準ルールを策定。ChatGPTなどに対抗する韓国独自の生成AIの

構築を目指す方針を表明。

• 中国: 政府批判につながるコンテンツ等の生成について生成AI提供者を規制。

一方、AI基盤の国家標準システム確立に向け、政府が主要民間企業を指定企業として設定

プライバシーの侵害や誤ったアウトプットなどの生成AIのリスクを念頭に厳しい規制・ルールを導入。
一方で、域内間でのAI活用促進およびAI基盤開発も順次着手

• EU:欧州議会は23年6月にAIを規制する法案「AI Act」の草案を過半数で可決。年内に具体化の方針。

域内でのデータ連携基盤を整備するとともに、それと互換するAI基盤モデルの開発を支援

• ドイツ:ISO等のグローバル標準の策定をリード
• フランス:倫理的規制の整備を進め、カナダとパートナーシップ締結
• イギリス:科学・AI大国としての地位の保持を目的に、自国内企業によるAI基盤モデル開発支援

各国とも生成AIの活用には一定の戦略を具体化しているものの、人材面ではあまり目立った動きは見られない。
シンガポールでは積極的に複数の取組を実施 (次ページにて詳細)

出所: ボストン コンサルティング グループ分析

5

.
d
e
v
r
e
s
e
r

s
t
h
g
i
r

l
l

A

.
p
u
o
r
G
g
n
i
t
l
u
s
n
o
C

n
o
t
s
o
B

y
b

3
2
0
2
©
t
h
g
i
r
y
p
o
C

テキストはちゃんと抽出されているのですが、例えばPDFの元ファイルでは「A民間主導での積極活用」に取り組んでいる国の例はアメリカ(を国旗アイコンで表示)で、主な取り組みとして「主な取組み
民間での積極的な開発・活用を背景に、産業領域の民間での推進に委ね、公共分野のみ政府が介入
• 規制に向けてIT企業大手トップとの初の協議が2023年9月に実施されたが、法整備はまだ着手段階」という情報の塊であることが分かりますが、MarkItDownの出力ではこれらの情報が欠落はしていなものの、文章内の行としては離れているため、文章からは結局意味が正しく読み取れなくなってしまっています。

まとめ

MarkItDownは元ファイルのテキスト情報を安定的に抽出することができる一方、段落の塊ごとの読み取り、段落やインデントに意味があった場合の表現などは行うことはできません。ですがMarkItDownの仕組み上対応が難しい問題だと思われます。このあたりは生成AIとの組み合わせによる読み取り精度の向上の余地があると思います。


それはともかく、既存のドキュメントをMarkdownテキスト形式で出力する、という需要は今後益々高まると思われます。その際にMarkItDownの活用は有力な選択肢となりますし、今回実装してみたような仕組みによりMarkItDownをより多くの人やアプリから使えるようになります。

Discussion