Downloads整理・次世代版構想:PDF解析とClaude Vision統合
はじめに
現行のDownloadsフォルダ自動整理システムは、ファイル名ベースの判定で3段階の信頼度スコアリングを実現しています。しかし、ファイル名だけでは判定しきれないケースが多く、次世代版ではPDF解析とClaude Visionを統合した内容ベースの判定を目指します。
現行システムの課題
ファイル名依存の限界
現在の判定ロジック:
def classify_file(filename):
score = 0
category = None
# キーワードマッチング
if '請求書' in filename or 'invoice' in filename.lower():
score = 90
category = '03_書類/見積・請求'
elif '契約' in filename or 'contract' in filename.lower():
score = 85
category = '03_書類/契約書'
# ...
return category, score
問題点:
– ファイル名が「Screenshot 2026-03-29.png」だと判定不能
– 「document.pdf」のような汎用名では分類できない
– 内容を見ずに判断するため誤分類リスクあり
中信頼度の多発
実際の運用結果(2026-03-29 04:00):
- 高信頼度: 0件
- 中信頼度: 4件(全て移動実行)
- 低信頼度: 0件
中信頼度ばかりになる = ファイル名だけでは確信を持てない証拠。
次世代版の設計
Phase 1: PDF内容解析
PyPDF2やpdfplumberでテキスト抽出し、内容から判定します。
import pdfplumber
def extract_pdf_content(filepath):
try:
with pdfplumber.open(filepath) as pdf:
text = ""
for page in pdf.pages[:3]: # 最初の3ページ
text += page.extract_text() or ""
return text
except Exception as e:
return None
def classify_pdf_by_content(filepath):
content = extract_pdf_content(filepath)
if not content:
return classify_file(os.path.basename(filepath)) # フォールバック
content_lower = content.lower()
# 請求書判定
if '請求書' in content or '合計金額' in content:
if '株式会社' in content or '御中' in content:
return ('03_書類/見積・請求', 95)
# 契約書判定
if '契約書' in content or '甲乙' in content:
return ('03_書類/契約書', 90)
# プロジェクト資料
if '提案書' in content or 'proposal' in content_lower:
return ('01_進行中プロジェクト', 80)
return (None, 50) # 不明
Phase 2: 画像解析(Claude Vision)
スクリーンショットやデザイン画像を Claude Vision で判定します。
def analyze_image_with_claude(filepath):
"""
Claude Visionで画像内容を解析
"""
import anthropic
import base64
with open(filepath, 'rb') as f:
image_data = base64.b64encode(f.read()).decode('utf-8')
client = anthropic.Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
message = client.messages.create(
model="claude-3-sonnet-20240229",
max_tokens=300,
messages=[{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": image_data
}
},
{
"type": "text",
"text": "この画像の内容を分類してください。以下のカテゴリから選んでください:\n- デザイン/UI(Webデザイン、UI設計)\n- 開発関連(エラー画面、コード)\n- 書類(請求書、契約書)\n- プレゼン資料\n- その他\n\nカテゴリ名のみ回答してください。"
}
]
}]
)
category_text = message.content[0].text.strip()
# カテゴリマッピング
mapping = {
'デザイン/UI': ('04_メディア/デザイン', 85),
'開発関連': ('02_開発/スクリーンショット', 80),
'書類': ('03_書類/その他', 75),
'プレゼン資料': ('01_進行中プロジェクト', 80)
}
return mapping.get(category_text, (None, 50))
Phase 3: ハイブリッド判定
ファイル名・PDF内容・画像解析を統合します。
def classify_file_advanced(filepath):
filename = os.path.basename(filepath)
ext = os.path.splitext(filename)[1].lower()
# Step 1: ファイル名ベース(高速)
category_name, score_name = classify_file(filename)
# Step 2: 内容解析(PDF)
if ext == '.pdf':
category_content, score_content = classify_pdf_by_content(filepath)
# スコアの高い方を採用
if score_content > score_name:
return category_content, score_content
# Step 3: 画像解析(重い処理なので最後)
if ext in ['.png', '.jpg', '.jpeg'] and score_name < 70:
category_image, score_image = analyze_image_with_claude(filepath)
if score_image > score_name:
return category_image, score_image
return category_name, score_name
インテリジェントなフォルダ作成
サブフォルダの自動生成
内容に基づいて詳細なサブフォルダを作成します。
def generate_subfolder(category, content_info):
"""
カテゴリと内容情報からサブフォルダパスを生成
例:
- 03_書類/見積・請求/2026年3月/
- 01_進行中プロジェクト/クロスリンク/求人システム/
"""
base_folder = category
# 日付ベース(書類系)
if '書類' in category:
year_month = datetime.now().strftime('%Y年%m月')
return f"{base_folder}/{year_month}"
# プロジェクト名ベース(進行中プロジェクト)
if '進行中プロジェクト' in category and 'project_name' in content_info:
project = content_info['project_name']
return f"{base_folder}/{project}"
return base_folder
ファイル名の自動リネーム
内容から意味のある名前を生成します。
def generate_smart_filename(original_name, content_info):
"""
内容から賢いファイル名を生成
例:
- Screenshot.png → クロスリンク様_請求書_2026-03.png
- document.pdf → ワークスキル実践講座_提案書_v2.pdf
"""
ext = os.path.splitext(original_name)[1]
parts = []
if 'company' in content_info:
parts.append(content_info['company'])
if 'document_type' in content_info:
parts.append(content_info['document_type'])
if 'date' in content_info:
parts.append(content_info['date'])
if parts:
return "_".join(parts) + ext
return original_name
パフォーマンス最適化
段階的処理
コストの低い処理から順に実行します。
- ファイル名チェック(0.001秒)
- PDF解析(0.5-2秒)
- Claude Vision(3-5秒 + API料金)
キャッシング
同じファイルを再解析しないよう、結果をキャッシュします。
import hashlib
import json
def get_file_hash(filepath):
with open(filepath, 'rb') as f:
return hashlib.md5(f.read()).hexdigest()
def load_cache(cache_file='file_analysis_cache.json'):
if os.path.exists(cache_file):
with open(cache_file) as f:
return json.load(f)
return {}
def classify_with_cache(filepath):
cache = load_cache()
file_hash = get_file_hash(filepath)
if file_hash in cache:
return cache[file_hash]
result = classify_file_advanced(filepath)
cache[file_hash] = result
save_cache(cache)
return result
まとめ
ファイル名だけでなく内容を解析することで、分類精度を大幅に向上できます。次世代版では:
- PDF内容解析で書類の自動分類
- Claude Visionで画像の文脈理解
- インテリジェントなサブフォルダ生成
- 内容ベースのファイル名リネーム
これらを段階的に実装していきます。
関連記事:
– ダウンロードフォルダ自動整理の構築
– OpenClaw Cronジョブ活用術
– Python仮想環境共有テクニック