本文へスキップ
公式

Ollama + RDKit でローカル化学アシスタントを構築

RDKit で分子物性を計算し、明示的な Python 接続スクリプトを通じてローカル Ollama モデルに記録済みの結果を説明させます。

難易度: 中級 費用: 無料 プライバシー: ローカル ~30 分
セットアップ開始

できるようになること

  • SMILES から分子式、分子質量、TPSA を計算。
  • ローカル言語モデルで計算済みの結果を説明。

構築するもの

対象範囲

Python スクリプトが RDKit 記述子を計算し、ループバックの Ollama 対話 API に結果を渡します。小規模な CLI アシスタントであり、MCP の自動統合ではありません。Python 3.11、RDKit 2025.3.1、ローカル Ollama を使用します。説明用モデルは qwen2.5:3b(約 1.9 GB、Qwen ライセンス)を選び、取得後の digest と Ollama の版を記録します。必要なハードウェアはモデルと文脈長に依存し、GPU 性能は保証しません。

ローカル実行

初期導入とモデル取得には接続が必要です。このスクリプトの 127.0.0.1 とローカルモデルを使用すれば、計算と推論は手元で行われます。説明に誤りがあり得るため、先に表示する RDKit JSON を計算結果の根拠とします。

分子の決定論的計算

RDKit

構成リソース

RDKit

分子の決定論的計算 · ==2025.3.1

同梱 Python 接続スクリプトが呼び出します。Ollama は別途導入する実行環境です。

上流のライセンスとクライアント・サービスの利用条件を確認してください。

リソースを見る

互換性

クライアントOSアーキテクチャバージョン要件
Python macOS指定なし>= 3.11
Python Windows指定なし>= 3.11
Python Linux指定なし>= 3.11
Local AI / Ollama macOS指定なし構成リソースの要件を参照
Local AI / Ollama Windows指定なし構成リソースの要件を参照
Local AI / Ollama Linux指定なし構成リソースの要件を参照

セットアップとテスト

1. Python と Ollama を準備

全プラットフォーム

Python 3.11 と公式の OS 別 Ollama を導入します。Ollama を開き、Linux では公式手順に従い、未起動なら ollama serve を実行します。ローカルモデルを選択します。

公式出典

期待される結果

ローカル Ollama が利用でき、版を記録する。

2. 独立した Python 依存環境を導入

macOS

新しい作業ディレクトリで実行します。macOS/Linux 用です。Windows では別の手順を使用します。

python3.11 -m venv .venv
.venv/bin/python -m pip install rdkit==2025.3.1
.venv/bin/python -m pip freeze
公式出典

期待される結果

導入が完了し、解決された版を記録する。

3. 独立した Python 依存環境を導入

Linux

新しい作業ディレクトリで実行します。macOS/Linux 用です。Windows では別の手順を使用します。

python3.11 -m venv .venv
.venv/bin/python -m pip install rdkit==2025.3.1
.venv/bin/python -m pip freeze
公式出典

期待される結果

導入が完了し、解決された版を記録する。

4. Windows に Python 依存環境を導入

Windows

PowerShell で仮想環境のインタープリターを直接使用します。

py -3.11 -m venv .venv
.\.venv\Scripts\python.exe -m pip install rdkit==2025.3.1
.\.venv\Scripts\python.exe -m pip freeze
公式出典

期待される結果

導入が完了し、解決された版を記録する。

5. 説明用ローカルモデルを取得

全プラットフォーム

Ollama 導入後に実行し、モデルの digest を検証記録に残し、ライセンスを確認します。

ollama --version
ollama pull qwen2.5:3b
ollama list
公式出典

期待される結果

ローカルモデルが一覧に表示され、クラウドモデルを選んでいない。

6. Python 接続スクリプトを保存

全プラットフォーム

作業ディレクトリに local_chemistry_assistant.py として保存します。値を計算してからモデルに渡し、モデル生成コードは実行しません。

"""RDKit calculations followed by explanation using a local Ollama model.

Sources: https://www.rdkit.org/docs/GettingStartedInPython.html
         https://docs.ollama.com/api/chat
This example has been source-reviewed, but has not been executed.
"""
import argparse
import json
import urllib.error
import urllib.request

from rdkit import Chem, rdBase
from rdkit.Chem import Descriptors, rdMolDescriptors


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("smiles")
    parser.add_argument("--model", default="qwen2.5:3b")
    parser.add_argument("--prompt", default="Explain the supplied molecular descriptors and their limits.")
    args = parser.parse_args()
    if not args.smiles.strip():
        parser.error("Empty SMILES; no model request was sent.")
    molecule = Chem.MolFromSmiles(args.smiles)
    if molecule is None:
        parser.error("Invalid SMILES; no model request was sent.")
    results = {
        "smiles": args.smiles,
        "rdkit_version": rdBase.rdkitVersion,
        "formula": rdMolDescriptors.CalcMolFormula(molecule),
        "molecular_weight_g_mol": Descriptors.MolWt(molecule),
        "tpsa_square_angstrom": rdMolDescriptors.CalcTPSA(molecule),
    }
    print(json.dumps(results, ensure_ascii=False, indent=2), flush=True)
    request = urllib.request.Request(
        "http://127.0.0.1:11434/api/chat",
        data=json.dumps({
            "model": args.model,
            "stream": False,
            "messages": [
                {"role": "system", "content": "Explain only the supplied RDKit results. Preserve their numbers and units. Do not invent measurements, toxicity, efficacy or additional calculations. Reply in the user's language."},
                {"role": "user", "content": args.prompt + "\nRDKit results:\n" + json.dumps(results)},
            ],
        }).encode("utf-8"),
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))
        with opener.open(request, timeout=180) as response:
            body = json.load(response)
        message = body.get("message", {}).get("content")
        if not isinstance(message, str) or not message.strip():
            raise ValueError("Ollama did not return message.content.")
        print(message)
    except (urllib.error.URLError, ValueError, TimeoutError) as error:
        parser.exit(1, "Local Ollama request failed; RDKit results remain available above. " + str(error) + "\n")


if __name__ == "__main__":
    main()
公式出典

期待される結果

スクリプトを .venv と同じ作業ディレクトリに保存。

7. アスピリンの処理を実行

全プラットフォーム

macOS/Linux は .venv/bin/python、Windows は ..venv\Scripts\python.exe を使用します。--prompt で下記の指示を渡します。

.venv/bin/python local_chemistry_assistant.py "CC(=O)Oc1ccccc1C(=O)O" --prompt "RDKit が計算したアスピリンの結果を説明してください。分子式、質量、TPSA の値と単位を保持し、計算記述子と実験結果を区別してください。"
公式出典

期待される結果

先に RDKit JSON の C9H8O4、約 180.16 g/mol、TPSA 約 63.6 Ų を確認します。説明の数値が一致し、根拠のない毒性・効果の主張がないことを調べます。これは期待する確認であり、今回の実測結果ではありません。

8. 不正入力を拒否

全プラットフォーム

上記の OS 別インタープリターで入力を not-a-smiles に変えて実行します。

.venv/bin/python local_chemistry_assistant.py "not-a-smiles"
公式出典

期待される結果

Ollama への要求前に不正 SMILES エラーで終了する。

トラブルシューティング

  • 接続拒否:Ollama またはローカルサービスを起動し、11434 ポートを確認。
  • モデル不足:正確なタグを取得し ollama list を確認。
  • 遅延やメモリ不足:文脈を短くするか小さなローカルモデルに変更し記録。
  • RDKit import 失敗:導入と実行で同じ仮想環境を使用。
  • 説明の数値不一致:説明を採用せず RDKit JSON を根拠とする。
  • 不正 SMILES:元入力を修正し、モデルに分子を作らせない。
まだ動作しません

代替案

モデルを使わず RDKit の JSON だけを利用できます。クラウド説明サービスに変更する場合はプライバシー条件を別途記録してください。