中級 20 分Python

Python・LangChain・OllamaでローカルAIエージェントを構築する

PythonとLangChain、およびOllamaを用いたローカルAIエージェントは、単なるチャットボットではありません。関数の呼び出し、ファイルの読み取り、または回答のための複数ステップの連鎖を、自律的に判断して実行するプログラムです。このガイドでは、約20分で動作するエージェントを段階的に構築します。モデルはQwen 3.5 9Bを使用し、完全にあなたのマシン上で動作します。APIキーは不要で、サードパーティへのデータ送信も一切ありません。

著者 Mohamed Meguedmi·更新 2026-08-27·Windows・macOS・Linuxでテスト済み

#なぜPythonでローカルAIエージェントを作るのか?

LangChainにおけるエージェントとは、単純なループです。LLMが質問とツールの一覧を受け取り、ツールの呼び出し(または呼び出しなし)を選択し、結果を読み取って、回答可能になるまで繰り返します。「意思決定」の仕組みはすべて、モデルが構造化されたツール呼び出しを出力できる能力に集約されています。

これを Ollama を用いてローカルで実行すると、具体的には 2 つのことが変わります。データは決してマシン外に出ず、各呼び出しのコストはゼロユーロです。週末に OpenAI で 50 ユーロの請求書を受け取るプロトタイピングと、回数に制限なく反復できることの差です。

プライバシー
エージェントが読み込むファイル(契約書、独自の非公開コード、医療メモ)は、端末の外に出ません。署名すべきDPAはなく、EU域外へのデータ移転もありません。
限界費用ゼロ
モデルのダウンロードが完了すると、請求書が膨らむことなく、1日に数百回イテレーションを行うことができます。
再現性
モデルの正確なバージョンを固定します(qwen3.5:9b、granite4.2:8b など)。gpt-4o-2024-11-20 のように、1か月後に別のものになってしまうようなサイレントなドリフトを避けます。
予測可能な遅延
ネットワークの往復はありません。適切な GPU 上で、最初のトークンは 1 秒未満で出力されます。
i
これも万能というわけではありません
9Bのローカルモデルは、非常に複雑なタスクではGPT-5やClaude 4.7に及びません。実用的なエージェントの80%(ファイルを読む、内部APIを呼び出す、計算する、メールを分類するなど)には、十分な性能があります。それ以外についても、トークンに課金されるサービスを使う前の学習の場として最適です。

#前提条件

ローカルコパイロットキット

このガイドでモデルの導入まで、キットでエディタ内でコードを書くコパイロットの導入まで進められます。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 生涯アップデート
Python 3.10+
LangChainは、Python 3.9ではもうテストされていません。python --versionで確認してください。
Ollamaがインストール済みで起動していること
Ollama が http://localhost:11434 でリクエストを待ち受けている必要があります。まだインストールして起動していない場合は、Ollama のインストールガイド(Windows、macOS、Linux)を参照してください。
ツールを呼び出すことができるモデル
すべてのLLMがツールを呼び出せるわけではありません。Qwen 3.5、Granite 4.2、Gemma 4、Devstral、GLM 4.7 Flashは、ツール呼び出しをネイティブにサポートしています。すでに旧式となったモデル(Llama 2/3、Qwen 2.5、Mistral 7B)は避けてください。
ハードウェア
Qwen 3.5 9B Q4のVRAM使用量は約6.6 GBです。VRAMが8 GBのGPU(RTX 3060、4060)で足り、12 GBのGPU(4070)なら余裕があります。Macでは、余裕を持たせるために16 GBのユニファイドメモリを目安にしてください。
→
モデルの選択は極めて重要です
ツールを正しく呼び出せないモデルを使うと、エージェントは引数をでっち上げたり、ツール呼び出しを生成せずに自由形式のテキストで回答したりします。初めて取り組むなら、qwen3.5:9bを使ってください。2026年時点で、品質とVRAM使用量のバランスが最もよいモデルです。

#1. Pythonプロジェクトを初期化する

仮想環境、パッケージ三つ、それだけです。システムPythonにLangChainをインストールするのは避けてください。頻繁に変更され、環境を汚染する原因になります。

仮想環境(venv)を作成して有効化する
mkdir agent-local && cd agent-local
python -m venv .venv

# macOS / Linux
source .venv/bin/activate

# Windows PowerShell
# .venv\Scripts\Activate.ps1
依存関係のインストール
pip install --upgrade pip
pip install langchain langchain-ollama langgraph
langchain
中核:プロンプト、ツール、メッセージの抽象化。
langchain-ollama
Ollama の公式連携機能です。2024年から LangChain チームが保守しています。
langgraph
エージェントの処理ループ用。現在推奨されているエンジンで、従来のAgentExecutorより安定しています。
i
langgraphはなぜAgentExecutorよりも選ばれるのか?
古いLangChainのチュートリアルでは、AgentExecutorとcreate_react_agent(langchain.agentsからインポート)を使っています。このAPIはメンテナンスモードです。公式ドキュメントは現在、langgraph.prebuilt.create_react_agentを案内しており、ここでもこちらを使います。よりシンプルで、型付けも改善されており、ストリーミングも標準で利用できます。

#2. PythonからOllamaに接続する

エージェントを構築する前に、実際にモデルと話していることを確認します。モデルが既にダウンロードされていない場合はダウンロードし、最も簡単な呼び出しをテストしてください。

Qwen 3.5 9B をダウンロードする
ollama pull qwen3.5:9b

Q4_K_M(Ollamaのデフォルト量子化)でのダウンロードサイズは約6.6GBです。インストール後、最初のスクリプトを作成してください。

test_ollama.py
from langchain_ollama import ChatOllama

llm = ChatOllama(
    model="qwen3.5:9b",
    temperature=0,
    # base_url="http://localhost:11434",  # par défaut, à changer si Ollama est ailleurs
)

reponse = llm.invoke("En une phrase : qu'est-ce qu'un agent IA ?")
print(reponse.content)
テストを開始する
python test_ollama.py

意味の通る文が表示されれば、Python ↔ Ollamaの接続は機能しています。ConnectionErrorが発生した場合は、Ollamaが動作しているか確認してください(ollama psで稼働中のサービスが表示される必要があります)。

→
エージェントにはtemperature=0
モデルがツールを選択する際には、決定論的な動作が望まれます。temperatureの値が高いと、実行ごとにツール呼び出しが変わり、デバッグが非常に困難になります。創造的な回答が必要な場合は、後で値を0.7に上げてください。

#3. エージェントのツールを定義する

LangChainのツールは、@toolでデコレートしたPython関数にすぎません。ドキュメント文字列(docstring)がLLMに提示される説明となり、LLMはそれを使って関数をいつ呼び出すかを判断します。具体的に記述してください。曖昧なdocstringは、でたらめな呼び出しにつながります。

代表的なツールを 2 つ作成します。1 つは算術式エバリュエーター、もう 1 つはファイルリーダーです。

tools.py
from pathlib import Path
from langchain_core.tools import tool


@tool
def calculer(expression: str) -> str:
    """Évalue une expression arithmétique simple.

    Args:
        expression: une expression contenant uniquement des chiffres,
                    des espaces et les opérateurs + - * / ( ).

    Returns:
        Le résultat numérique sous forme de chaîne, ou un message d'erreur.
    """
    autorise = set("0123456789+-*/(). ")
    if not all(c in autorise for c in expression):
        return "Erreur : caractère non autorisé. Seuls 0-9 et + - * / ( ) sont permis."
    try:
        resultat = eval(expression, {"__builtins__": {}}, {})
        return str(resultat)
    except Exception as e:
        return f"Erreur de calcul : {e}"


@tool
def lire_fichier(chemin: str) -> str:
    """Lit le contenu d'un fichier texte du répertoire courant.

    Args:
        chemin: chemin relatif ou absolu vers un fichier texte (.txt, .md, .py, etc.).

    Returns:
        Le contenu du fichier, ou un message d'erreur si introuvable.
    """
    p = Path(chemin)
    if not p.exists():
        return f"Fichier introuvable : {chemin}"
    if not p.is_file():
        return f"Ce n'est pas un fichier : {chemin}"
    try:
        return p.read_text(encoding="utf-8")
    except UnicodeDecodeError:
        return "Fichier binaire ou encodage non UTF-8."
    except Exception as e:
        return f"Erreur de lecture : {e}"
!
eval() はプロダクション環境では危険です
eval()の使用は、__builtins__を空にしても、本物のサンドボックスとは言えません。自分のデスクトップ上で動作し、自分自身が制御できるアグエントの場合には問題ありません。第三者ユーザーに公開される場合、ast.parseを用い、演算子の白リストを設定するか、simpleevalライブラリを使用してください。

モデルが正しくツールを使用するための3つのルール:

役割が明確な名前
processよりもcalculer、getよりもlire_fichier。LLMはまず名前をもとに選びます。
詳細なdocstring
ツールが何を行い、どのような入力を必要とし、何を返すのかを説明してください。Pythonの型アノテーションはLangChainによって読み取られ、モデルに提示されます。
文字列を返す
常にそうしてください。関数がdictやオブジェクトを返す場合、LangChainがそれをシリアル化しますが、モデルにとって読み取りにくくなります。

#4. エージェントの構築

LLMとツールがあります。langgraphのcreate_react_agentがこれらを接続し、ループを管理します。モデルがツールを呼び出したい場合、処理を継続します。モデルがテキストで応答した場合、処理は終了します。

agent.py
from langchain_ollama import ChatOllama
from langgraph.prebuilt import create_react_agent
from tools import calculer, lire_fichier

llm = ChatOllama(model="qwen3.5:9b", temperature=0)

SYSTEM_PROMPT = (
    "Tu es un assistant en français. Tu disposes d'outils pour calculer "
    "et lire des fichiers. Utilise-les dès que c'est pertinent, sans jamais "
    "inventer un résultat. Réponds toujours en français."
)

agent = create_react_agent(
    model=llm,
    tools=[calculer, lire_fichier],
    prompt=SYSTEM_PROMPT,
)

if __name__ == "__main__":
    question = (
        "Combien fait 1234 * 5678 ? "
        "Ensuite, lis le fichier notes.txt et résume-le en deux phrases."
    )
    reponse = agent.invoke({"messages": [("user", question)]})

    # Le dernier message est la réponse finale du modèle
    print(reponse["messages"][-1].content)

テスト用に、同じ場所に小さなファイルnotes.txtを作成してください:

テストファイル
echo "Réunion projet Hermes : on garde Ollama comme runtime principal, on évalue vLLM pour la prod, RAG sur ChromaDB. Décision : POC en 2 semaines." > notes.txt

#5. 実行してループの動作を観察する

エージェントを起動
python agent.py

計算結果(7,006,652)とファイルの要約の両方を含む応答が表示されるはずです。ただし、実行中に何が起きているかを見るほうが、より理解が深まります。ループを一段階ずつ追えるように、次の詳細出力モードを追加してください:

詳細なストリーミングモード
for evenement in agent.stream(
    {"messages": [("user", question)]},
    stream_mode="values",
):
    dernier = evenement["messages"][-1]
    dernier.pretty_print()
    print("---")

エージェントの典型的な動作の流れを確認できます。モデルがcalculerへの呼び出しを生成し、結果を受け取り、lire_fichierへの呼び出しを生成し、内容を受け取ってから、最終的な回答を生成します。ユーザーの質問1つに対して3回の反復です。

i
モデルがツールを呼び出さない場合
よくある原因は2つあります。(1) Ollama側でモデルのツール呼び出しが有効になっていない場合です。最新バージョンを取得するため、ollama pull qwen3.5:9b を再実行してください。(2) システムプロンプトが曖昧すぎる場合です。モデルが意図を察してくれることを期待するのではなく、「計算にはツールを使ってください」と明示してください。

#ヒントとトラブルシューティング

コンテキストが短すぎます
デフォルトでは、Ollamaはコンテキストを2048トークンで切り詰めます。エージェントが複数のツールを続けて使うと、すぐにこの上限を超えます。ChatOllama(model="...", num_ctx=8192)でnum_ctx=8192を指定してください。
存在しないツールをでっち上げるモデル
エージェントが関数名を捏造する場合は、温度を0に下げ、利用可能なツールを明示的に列挙する形でシステムプロンプトを書き直してください。
無限ループ
制限を設定してください:create_react_agent(..., recursion_limit=10)。それ以上になると、エージェントは適切に終了します。
遅延が大きすぎる
CPUでは、9Bモデルの速度は5〜10トークン/秒です。用途に対して品質が引き続き許容範囲内であれば、qwen3.5:4b(VRAM 3.4 GB、控えめな性能のGPUで30トークン/秒以上)に切り替えてください。
「context length exceeded」エラー
長いファイルの要約がnum_ctxを超えています。ファイルをチャンクに分割する中間ツールを追加するか、VRAMに余裕があればnum_ctxを32768まで増やしてください。
→
LangSmithでエージェントをトレースする
本格的にデバッグするなら、LangSmithで各呼び出し、各トークン、各ツールを追跡できます。開発時は無料です。環境変数としてLANGSMITH_TRACING=trueとLANGSMITH_API_KEYを設定すると、完全なタイムラインが得られます。キーを設定しなければ、データは一切送信されません。

#さらに詳しく

ローカルで計算し、読み取り、推論するエージェントが手元にあります。さらに掘り下げるなら、次の3つの方向が考えられます:

エージェントに自分のドキュメントへのアクセス権を与える
エージェントをベクトルデータベースと連携させ、内部コーパスに基づいて回答できるようにする。まさにこの内容をローカルRAG入門ガイドで扱っています。
コード作業をCLI中心で行う
Aiderは、ターミナルからファイルを直接編集する開発用エージェントです。同じOllamaに接続すれば、Qwen3-Coder 30BやDevstralを使って編集の支援を受けられます。
モデルの量子化を調整する
もし Qwen 3.5 9B Q4が遅すぎたり品質が不十分だと感じるのであれば、量子化ガイドではQ5_K_Mに移行するか、モデルサイズを小さくするタイミングについて説明しています。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。