PyPDFで特許文書を読み込み、Ollamaのローカルモデルで意味ベクトル化。ネットに出さずに「似た特許」を引き当て、質問に答えるところまでを、手元のMacで動かした記録です。
設計から動作確認まで。途中でつまずいた2つの壁と、その回避も含めて。
まずQdrant前提のフル版・Docker設定・デモの4ファイルを生成。理想形を先に置いた。
Ollamaは稼働中。しかしDocker未導入で docker: command not found。Qdrantを諦めず、pickleで代替するLite版へ方針転換した。
externally-managed-environment でpipが拒否。仮想環境を切って解決。
nomic-embed-text をpull。テキストを768次元ベクトルに変換する準備が整った。
PyPDF・Ollama・埋め込み・LLM・ベクトルストアの全てが接続確認済み。検索まで一気通貫で動いた。
言い換えのクエリでも、意味の近い特許を引けるか。3問で確かめた。
// スコア = コサイン類似度。0.7以上で実用域。言い換えたクエリでも狙った特許が1位に来ている。
# 仮想環境を有効化 $ source ~/Downloads/patent_rag_venv/bin/activate # PDFをインデックス(単体 / ディレクトリ一括) $ python3 patent_rag_lite.py index /path/to/patent.pdf $ python3 patent_rag_lite.py index /path/to/pdf_directory/ # 類似特許を検索 $ python3 patent_rag_lite.py search "リチウムイオン電池の急速充電" # 質問応答(RAG) $ python3 patent_rag_lite.py ask "この技術の特徴は何ですか?" # PDF分析 / インデックス情報 $ python3 patent_rag_lite.py analyze /path/to/patent.pdf $ python3 patent_rag_lite.py info
PyPDFで特許PDFから本文テキストを抽出。純Python実装で依存が軽い。
nomic-embed-textで文章を768次元に。意味の近さを数値で扱えるようにする。
コサイン類似度でベクトル間の角度を比較し、意味的に近い文書を順位付け。
deepseek-r1:8bが検索結果を根拠に自然言語で回答。ハルシネーションを抑える。
ベクトルはpickleでローカル保存。Qdrant導入時はそのままフル版へ移行可能。
抽出・埋め込み・生成すべてが手元で完結。機密特許を外部に出さない。
先行技術調査で扱う出願前の情報は、外部APIに投げた瞬間にリスクになる。抽出も埋め込みも生成もすべて手元で回るこの構成なら、機密性を保ったまま「似た特許」を横断的に探せる。
二次電池・パワー半導体のように出願が密集する領域ほど、この横断検索が効いてくる。Lite版で回し、量が増えたらそのままQdrantのフル版へ——という増築のしやすさも設計の狙い。
ここでは埋め込みを部品として使った。なぜ距離を測ると意味の近さが出るのか——その前提のほうを、Word2Vec 以前の認知科学の側から立ち上げた教材が別にある。概念を多次元空間の点として置き、カテゴリーを凸領域として扱い、類似度を距離の単調減少関数と読む。二次電池やパワー半導体のように言い回しが割れる領域で横断検索が効くのは、「二つの典型例の中間も同じカテゴリーに属する」という性質そのものに乗っているから。