🐦‍⬛

LangChain DeepAgents × Local LLM で使い放題のAIエージェント開発

に公開

はじめに

LangChain/LangGraph v1.0とDeepagents

2025年10月22日にLangChain/LangGraph v1.0がリリースされました。その調査をしていたところ、DeepAgentsという、LangGraphのAI Agentを簡単に構築できるライブラリを発見しました。

https://github.com/langchain-ai/deepagents

DeepAgents自体は2025年7月30日にリリースされていたそうですが、LangChain/LangGraph v1.0に対応しているとのことです。今回の記事ではこのDeepAgentsを使ってシンプルなAI Agentを構築してみました。

AI Agentのコスト・セキュリティとローカルLLM

2025年に入ってから、AI Agentが注目されています。ChatGPTやGeminiのDeepResearch機能に始まり、Devin/Manus/Gensparkなどの非同期エージェント、Claude CodeやCodexなどのコーディングエージェントが話題となっています。ただ単にステートレスに応答するだけでなく、Webやファイルシステムなどとインタラクションすることで、できることが大きく増えてきました。

しかし、AI AgentはLLMをヘビーに使用する使い方でコストがかかります。LLMプロバイダでも収益性度外視で提供しているとのうわさがあるほどです。そのため、よほど高付加価値でない場合や開発の段階では、ローカルLLMを使用したいところです。

また、ローカルLLMも性能が上がり、AI Agentで利用できるレベルになっています。GLM-4.6は、Claude Sonnet 4と同等と謳われています。具体的には、与えられたTool群をうまく使いこなすことができるToolUse性能が十分かどうかが、AI Agentに使えるモデルかどうかの判断基準になります。

一方、AI Agentはセキュリティも課題になります。例えば、Codexにはリポジトリ以外の書き込みを禁止するなどのサンドボックス機能がありますが、それでもAPIキーなどを読んでしまう可能性はあります。また、そもそも外部APIに入力不可能な情報もあります。この点でも、ローカルLLMが使えると嬉しい場面は多く考えられます。

今回やったこと

長い前置きでしたが(読んでいただきありがとうございます)、ここからが本題です。つまり、「ローカルLLMで先端のAI Agentを構築したい!UIも欲しい!」ということで以下の構成で実施しました。

  • gpt-oss:20bをOllamaで動かす
  • DeepAgentsを動かす
  • DeepAgents UIを動かす

gpt-oss:20bは、OpenAIがリリースしたオープンウェイトモデルで、ToolUse性能が十分高く、AI Agentとしてコスパのよいモデルと言えます。これをOllamaでOpenAI API互換形式でサーブし、DeepAgentsで作ったシンプルなAI Agentを動かします。

https://openai.com/index/introducing-gpt-oss/
https://ollama.com/library/gpt-oss:20b

ついでに調査中に発見したDeepAgents向けのUIを動かし、ブラウザでチャットができるようにします。

https://github.com/langchain-ai/deep-agents-ui

やりかた

gpt-oss:20bをOllamaで動かす

Ollamaの詳細は省きます。もっとも簡単な方法でとりあえず動かしました。リモートで動かす場合は、OLLAMA_HOSTOLLAMA_ORIGINSの設定も適宜行ってください。

 Terminal1: OpenAI互換APIをローカルで公開
$ export OLLAMA_HOST=127.0.0.1:11434
$ ollama serve

 Terminal2: モデルの取得
$ export OLLAMA_HOST=127.0.0.1:11434
$ ollama pull gpt-oss:20b

別ターミナルから curl http://127.0.0.1:11435/v1/models を叩けば、OpenAI互換のレスポンスが返るはずです。実際の出力例は以下のとおりです(11434の待受を別プロセスが使用していたので +1 したポートで確認しました)。

$ curl http://127.0.0.1:11435/v1/models
{"object":"list","data":[{"id":"gpt-oss:20b","object":"model","created":1762493511,"owned_by":"library"},{"id":"hf.co/lmstudio-community/gpt-oss-20b-GGUF:latest","object":"model","created":1762322897,"owned_by":"lmstudio-community"}]}

DeepAgentsを動かす

シンプルな構成のAI Agentを構築します。DeepAgentsのデフォルトツール以外は、DuckDuckGoツールのみを渡します。

https://duckduckgo.com/

今回はdeepagents==0.2.3 を使っています。

$ uv pip install \
    "langchain==1.0.3" \
    "langchain-community>=0.4.1" \
    "deepagents==0.2.3" \
    "langgraph==1.0.2" \
    "langgraph-cli[inmem]==0.4.4"

下記が最もシンプルな構成です。 workspace/は、AI Agentが操作するファイルシステムです。

root/
├── agent.py
├── langgraph.json
├── .env
└── workspace/
    ├── reports/
    └── scratch/

DeepAgentsのコードです。シンプルにしたかったのですが、DeepAgents UIに合わせるために LangGraphFilesystemBackend というカスタムバックエンドを導入しています。

agent.py
from __future__ import annotations

from pathlib import Path
from typing import Any, Dict

from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
from deepagents.backends.protocol import EditResult, WriteResult
from langchain.chat_models import init_chat_model
from langchain_community.tools import DuckDuckGoSearchRun

SYSTEM_PROMPT = (
    "あなたは業務支援エージェントです。依頼を整理し、必要に応じてDuckDuckGoで公開情報を検索しながら、"
    "1) write_todosツールでTODOを管理し、2) /reports/ にMarkdownレポートを作成し、3) /scratch/ に補助メモを残してください。\n"
    "レポートには以下の章を必ず含めます:\n"
    "- 概要\n- 重要なポイント\n- 推奨アクション (箇条書き)\n- 次のステップ\n- Web検索メモ (検索した場合のみ。`- タイトル — 要約 (URL)` の形式で3件以内)\n"
    "検索は新しい事実や最新情報が必要なときだけ実行し、取得した内容がレポートとTODOに正確に反映されるようまとめます。"
)

MODEL_PARAMS: Dict[str, Any] = {
    "model": "gpt-oss:20b",
    "model_provider": "openai",
    "base_url": "http://127.0.0.1:11434/v1",
    "api_key": "ollama",
    "temperature": 0.3,
}

class LangGraphFilesystemBackend(FilesystemBackend):
    """files_updateを付与してLangGraph UIに内容を表示させるバックエンド。"""

    @staticmethod
    def _create_files_update(path: str, content: str) -> Dict[str, str]:
        return {path: content}

    def write(self, file_path: str, content: str) -> WriteResult:
        result = super().write(file_path=file_path, content=content)
        if result.error:
            return result
        return WriteResult(path=result.path, files_update=self._create_files_update(file_path, content))

    def edit(
        self,
        file_path: str,
        old_string: str,
        new_string: str,
        replace_all: bool = False,
    ) -> EditResult:
        result = super().edit(
            file_path=file_path,
            old_string=old_string,
            new_string=new_string,
            replace_all=replace_all,
        )
        if result.error:
            return result

        resolved_path = self._resolve_path(file_path)
        try:
            with open(resolved_path, "r", encoding="utf-8") as f:
                updated_content = f.read()
        except OSError as exc:
            return EditResult(error=f"Error reading updated file '{file_path}': {exc}")

        return EditResult(
            path=result.path,
            files_update=self._create_files_update(file_path, updated_content),
            occurrences=result.occurrences,
        )


workspace_root = (Path(__file__).resolve().parent / "../workspace").resolve()
workspace_root.mkdir(parents=True, exist_ok=True)

deepagent = create_deep_agent(
    model=init_chat_model(**MODEL_PARAMS),
    tools=[
        DuckDuckGoSearchRun(
            name="duckduckgo_search",
            description=(
                "DuckDuckGoを使って最新の公開情報を検索します。クエリは日本語または英語で指定してください。"
            ),
        )
    ],
    system_prompt=SYSTEM_PROMPT,
    backend=LangGraphFilesystemBackend(root_dir=str(workspace_root), virtual_mode=True),
)

LangGraphFilesystemBackendfiles_update に「パス → 文字列」の辞書を設定します。これにより、Deep Agents UIの既定実装がそのままファイルをプレビューできます。

LangGraphから読み込む設定を langgraph.json に書いておきます。DeepAgents UIの既定名が deepagent なので、そこに合わせています。

langgraph.json
{
  "dependencies": ["."],
  "graphs": {
    "deepagent": "./agent.py:deepagent"
  },
  "env": ".env"
}

.env には以下の1行書いておけばOKです。

.env
LANGGRAPH_DEFAULT_GRAPH=deepagent

実際にエージェントを起動するときは、LangGraph devサーバーを以下のコマンドで起動できます。

$ uv run langgraph dev --config langgraph.json

https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024を開くとAI Agentの構造や動作確認ができます。

LangSmith Studio
LangSmith Studio 初期画面

DeepAgents UIを動かす

UIは公式リポジトリを任意の場所にクローンして使います。

https://github.com/langchain-ai/deep-agents-ui

$ git clone https://github.com/langchain-ai/deep-agents-ui.git
$ cd deep-agents-ui
$ pnpm install
$ pnpm dev

デフォルトでは http://localhost:3000 でUIが立ち上がります。


DeepAgents UI 初期画面

実際に動かしてみる

では実際に動かしてみます。


処理開始

チャット画面から「最新のVLM情報をまとめて」と指示しました。


処理中

DuckDuckGoによるWeb検索、ファイルの読み書きなどを行っています。結構速いです。


終了

レポートの作成が完了したようです!Tasksの更新は忘れていますね。これはプロンプトの調整が必要そうです。


レポートプレビュー

Filesタブでレポートを確認できました!以下が実際に作成されたレポートです。一回の検索にしてはいい感じのレポートになっていますね。URLがhttps://example.com/になっているのは、DuckDuckGoの出力にURLが含まれないためです。ここも調整が必要ですね。

レポート全文
 最新Vision‑Language Model (VLM) 情報レポート

# 概要
2024‑2025年に入ってから、Vision‑Language Model(VLM)の開発は加速しています。大規模言語モデル(LLM)と高性能ビジョンエンコーダを組み合わせることで、画像・テキストの両方を同時に理解し、推論・生成を行うモデルが次々と登場しています。本レポートでは、主要な商用・オープンソースVLMのリリースと特徴、業界トレンドをまとめます。

# 重要なポイント
| モデル名 | 発表年 | 主な特徴 | 主要用途 | 備考 |
|---|---|---|---|---|
| **LFM2‑VL** | 2025‑08 | 低レイテンシ・デバイス向けファウンデーションモデル | エッジデバイス、リアルタイム推論 | 低消費電力設計 |
| **Qwen 2.5 VL** | 2025‑06 | 大規模(72B)・多言語・OCR対応 | 画像検索、マルチモーダル検索 | Alibaba Qwenチーム開発 |
| **LLaMA 3.2 Vision** | 2025‑06 | LLaMA 3.2ベース、Visionエンコーダ統合 | 研究・ファインチューニング | Meta社オープンソース |
| **DeepSeek‑VL** | 2025‑06 | 高精度推論、OCR・テキスト抽出 | 産業用画像解析 | DeepSeek社開発 |
| **Moondream** | 2025‑02 | 小規模(1B)・高速推論 | エッジ・モバイル | 低リソース環境向け |
| **SmolVLM** | 2025‑02 | 小規模・ファインチューニング容易 | 研究・教育 | 低コスト実装 |
| **Kimi‑VL‑A3B‑Thinking** | 2025‑01 | Moonshot AIチーム開発、思考型推論 | クリエイティブ生成 | 先進的推論アルゴリズム |
| **PaliGemma 2** | 2024‑05 | Gemini‑ベースのVLM、マルチモーダル対話 | チャットボット・対話 | Google社開発 |
| **Gemma 2** | 2024‑05 | Gemini‑ベース、オープンソース | 研究・ファインチューニング | 2024年I/O発表 |
| **CLIP** | 2021 | 画像とテキストの共通埋め込み | 画像検索・分類 | 代表的オープンソース |
| **GPT‑4V** | 2023 | 大規模マルチモーダル推論 | 画像+テキスト生成 | 商用・高精度 |
| **Claude** | 2023 | マルチモーダル対話 | 生成・対話 | Anthropic社 |

## 業界トレンド
1. **オープンソース化の進展** – Qwen 2.5 VL、LLaMA 3.2 Visionなど、商用モデルのオープンソース化が進み、研究・実務での利用が拡大。
2. **低レイテンシ・デバイス向け設計** – LFM2‑VL、Moondreamはエッジデバイスでのリアルタイム推論を可能にする設計が特徴。
3. **多言語・OCR対応** – Qwen 2.5 VL、DeepSeek‑VLなどは多言語テキスト抽出とOCRを組み合わせ、グローバル展開をサポート。
4. **ファインチューニング容易化** – SmolVLM、Moondreamは小規模モデルでありながら、ファインチューニングが容易で実務導入が容易。
5. **思考型推論** – Kimi‑VL‑A3B‑Thinkingのように、推論過程を可視化・制御できるモデルが登場し、解釈性向上が期待される。

# 推奨アクション
- **社内評価**:LLaMA 3.2 VisionとQwen 2.5 VLを社内サーバーでベンチマークし、推論速度・精度を比較。
- **エッジ導入検討**:LFM2‑VLとMoondreamを組み合わせ、IoTデバイスでの画像認識・対話機能をプロトタイプ化。
- **ファインチューニング実験**:SmolVLMを使い、社内データで小規模ファインチューニングを行い、コスト削減効果を測定。
- **多言語対応**:DeepSeek‑VLを導入し、国際展開に向けたOCRと多言語テキスト抽出の統合を検討。
- **解釈性評価**:Kimi‑VL‑A3B‑Thinkingを使用し、推論過程の可視化と説明責任を強化。

# 次のステップ
1. 上記モデルのライセンスと利用条件を確認し、社内導入計画を策定。
2. ベンチマーク結果をまとめ、経営層への報告資料を作成。
3. エッジデバイス向けプロトタイプを開発し、ユーザーテストを実施。
4. ファインチューニング実験を実施し、コスト・性能を定量化。

# Web検索メモ
- **FastVLM** — Apple ML researchers introduced FastVLM at CVPR 2025, improving accuracy‑latency trade-offs. (https://example.com/fastvl)
- **Qwen 2.5 VL** — Leading open‑source VLM with 72 B parameters, achieving MMBench > 80 %. (https://example.com/qwen2.5)
- **Serial Compression Architecture** — New direction for efficient high‑resolution image processing. (https://example.com/serial-compression)
- **PaliGemma 2** — Googleが2024年5月に発表した高性能VLM。詳細はhttps://ai.googleblog.com/2024/04/paligemma-2.html
- **LLaVA‑NeXT** — 2024年1月にリリース。高解像度入力とマルチイメージ・動画対応。詳細はhttps://github.com/haotian-liu/LLaVA-NeXT
- **LLaVA‑Video‑178K** — 2024年8月に公開された動画指示調整データセット。詳細はhttps://github.com/haotian-liu/LLaVA-Video

まとめ

ローカルLLMとDeepAgentsを組み合わせ、電気代以外のランニングコストを気にせず「使い放題」のエージェント環境を構築できました。LangChainにはMCPアダプターなども提供されているので、MCPを通じた社内ナレッジ連携や、サブエージェント拡張を進めれば、Manusのようなエージェントを社内特化・完全ローカルで構築できるかもしれないですね。

参考文献

Discussion