非構造化テキストから構造データを抽出するAIワークフロー
日常の業務には、メールやチャットログ、PDF文書などに散在する情報を手作業でExcelやフォームに入力する作業が多く含まれます。このプロセスは時間と労力を消費し、ヒューマンエラーのリスクも高まります。本稿では、qwen2.5:4b-instruct-2507 という小型ながら高性能な言語モデルを活用し、自然言語からの情報抽出を自動化するシステムの構築方法を解説します。
選定理由:なぜこのモデルか?
- 低リソース要件:4GB未満の量子化モデルであり、RTX 3060クラスのGPU搭載ノートPCでもリアルタイム推論が可能。
- 指示遵守能力:インストラクトチューニング済みのため、複雑なタスク指示を正確に理解し、構造化出力(JSONなど)を生成できる。
- 超長文対応:最大80万文字のコンテキスト処理が可能で、レポート全体や長い会話履歴も一括で分析可能。
- 商用利用可:Apache 2.0ライセンスに基づき、自由に改変・商用展開が可能。
環境構築:Ollamaによるローカルデプロイ
大規模モデルのローカル実行を簡素化するツールとして、Ollama を採用します。以下コマンドでモデルを即座に起動できます。
ollama run qwen2.5:4b-instruct-2507
インストール後、http://localhost:11434 でREST APIが有効になります。PythonからHTTPリクエストを送ることで、プログラム内からモデルを利用できます。
API連携による情報抽出モジュール設計
以下のPythonコードは、任意のテキストから指定フィールドをJSON形式で抽出する関数です。
import requests
import re
import json
def extract_registration_data(text_input):
api_url = "http://localhost:11434/api/generate"
instruction_template = f"""
あなたは情報抽出専門のアシスタントです。以下の入力テキストから次の項目を正確に抽出してください:
- name
- phone
- email
- event_title
- notes
【ルール】
- 存在しない項目は空文字列("")で返す
- 出力は純粋なJSONオブジェクトのみ。追加説明不要
- キー名は英語で統一
【入力内容】
{text_input}
【出力形式】
{{"name": "", "phone": "", ... }}
"""
payload = {
"model": "qwen2.5:4b-instruct-2507",
"prompt": instruction_template,
"stream": False,
"options": {"temperature": 0.2}
}
try:
res = requests.post(api_url, json=payload, timeout=45)
if res.status_code == 200:
raw_output = res.json().get("response", "")
# 正規表現でJSON部分を抽出
json_block = re.search(r'\{[^}]+\}', raw_output, re.DOTALL)
if json_block:
return json.loads(json_block.group())
except Exception as e:
print(f"抽出エラー: {e}")
return None
return None
テスト実行例
下記のような自由形式のテキストを入力:
こんにちは。来週の「機械学習入門セミナー」に参加したいです。
田中太郎と申します。電話番号は090-1234-5678、メールはtanaka@example.comです。
資料の事前配布があると助かります。
実行結果:
{
"name": "田中太郎",
"phone": "090-1234-5678",
"email": "tanaka@example.com",
"event_title": "機械学習入門セミナー",
"notes": "資料の事前配布があると助かります"
}
CSVファイルへの自動保存処理
抽出結果を永続化するため、CSVファイルに追記する機能を実装します。
import csv
from datetime import datetime
def append_to_csv(data, filename="registrations.csv"):
field_order = ["name", "phone", "email", "event_title", "notes", "timestamp"]
data["timestamp"] = datetime.now().isoformat()
is_first_entry = not any(True for _ in open(filename, 'r', encoding='utf-8-sig') if _.strip()) \
if __import__('os').path.exists(filename) else True
with open(filename, 'a', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=field_order)
if is_first_entry:
writer.writeheader()
writer.writerow(data)
精度向上のための実践的ヒント
- Prompt最適化:出力形式を厳密に定義し、「余計な説明は不要」と明示する。
- サンプル提示:Few-shot方式で1〜2件の例を含めると、モデルの挙動が安定する。
- 温度パラメータ調整:
temperature=0.1~0.3に設定して、出力の一貫性を確保。 - OCR連携:スキャン画像やPDFはTesseract等でテキスト化した後、モデルに入力。
- チャットツール統合:SlackやTeamsのボット経由で入力を受け付け、結果を即時返信。
応用展開の可能性
本技術は次のような業務にも応用可能です:
- 求人応募者の履歴書から経歴情報を自動登録
- 顧客問い合わせメールの分類と要約生成
- 請求書画像からの金額・日付・宛先抽出
- プロジェクト報告書内のKPI数値の自動収集
計算コストが低く、ネットワーク依存がないローカル実行型である点が、企業内での導入障壁を下げます。繰り返し発生する定型業務こそ、まず自動化すべき領域です。わずかなコードで大きな業務効率改善が見込めるこのアプローチは、現代のオフィス自動化において非常に現実的な選択肢と言えます。