はじめに
LangChain 1.0が先日リリースされました。
詳細は公式Blogを確認いただくのがいいかと思います。
また、主な変化点は以下のドキュメントにも掲載されています。
ドキュメント含めて大きく変更されており、またαリリースの際よりも組み込みMiddlewareも増えてましたので、個人的に気になる内容をピックアップしてDatabricks Free Edition上で検証していきます。
最初は、Quickstartにある「リアルワールドエージェントのサンプル」です。
LangChain 1.0の目玉とも言うべきエージェント構築機能の代表格ですのでドキュメントのサンプルをDatabricks上で動作するように修正して実行します。
リアルワールドエージェントのサンプル作成
上記ドキュメントより、以下のようなエージェントを作成します。
次に、主要な制作コンセプトを示す実用的な天気予報エージェントを構築します。
- エージェントの行動を改善するための詳細なシステムプロンプト
- 外部データと統合するツールを作成する
- 一貫した応答のためのモデル構成
- 予測可能な結果を得るための構造化された出力
- チャットのようなやり取りのための会話記憶
- エージェントを作成して実行し、完全に機能するエージェントを作成します
まずはノートブックを作成して必要なパッケージをインストール。
TracingのためにMLflowもインストールします。
%pip install -U langchain>=1.0.0 langchain_openai>=1.0.0 mlflow
%restart_python
利用するモデルをセットアップします。
今回は(現時点でベータ版ですが)databricks-qwen3-next-80b-a3b-instructを利用することにしました。
from langchain.chat_models import init_chat_model
import mlflow
mlflow.langchain.autolog()
creds = mlflow.utils.databricks_utils.get_databricks_host_creds()
model = init_chat_model(
"openai:databricks-qwen3-next-80b-a3b-instruct",
api_key=creds.token,
base_url=creds.host + "/serving-endpoints",
)
次にエージェントが利用するシステムプロンプトとツールを用意します。
システムプロンプト内に記載のように、ツールはダミーの天気情報の取得とユーザロケーションを取得するものになります。
from dataclasses import dataclass
from langchain.tools import tool, ToolRuntime
SYSTEM_PROMPT = """あなたはダジャレを交えた話し方をする天気予報の専門家です。
あなたは2つのツールにアクセスできます:
- get_weather_for_location: 特定の場所の天気を取得するために使用します
- get_user_location: ユーザーの現在地を取得するために使用します
ユーザーが天気を尋ねてきた場合、必ず場所を把握してください。質問からユーザーの現在地を指していると判断できる場合は、get_user_locationツールを使って場所を特定してください。
"""
@tool
def get_weather_for_location(city: str) -> str:
"""指定した都市の天気を取得します。"""
return f"{city}はいつも晴れです!"
@dataclass
class Context:
"""カスタム実行時コンテキストスキーマ。"""
user_id: str
@tool
def get_user_location(runtime: ToolRuntime[Context]) -> str:
"""ユーザーIDに基づいてユーザー情報(場所)を取得します。"""
user_id = runtime.context.user_id
return "Florida" if user_id == "1" else "SF"
次に出力時のフォーマットを指定するためのデータクラスを用意します。
(@dataclassを利用していますが、Pydanticも対応しているようです)
from dataclasses import dataclass
# ここではdataclassを使用していますが、Pydanticモデルもサポートされています。
@dataclass
class ResponseFormat:
"""エージェントのレスポンススキーマ"""
# ダジャレを含むレスポンス(必須)
punny_response: str
# 天気に関する興味深い情報(あれば)
weather_conditions: str | None = None
そしてメモリ内に短期記憶を保持するためのCheckpointerを用意します。
from langgraph.checkpoint.memory import InMemorySaver
# 短期記憶をメモリ内に保持
checkpointer = InMemorySaver()
最後に、create_agentを使ってエージェントを作成します。
from langchain.agents import create_agent
from pprint import pprint
agent = create_agent(
model=model,
system_prompt=SYSTEM_PROMPT,
tools=[get_user_location, get_weather_for_location],
context_schema=Context,
response_format=ResponseFormat,
checkpointer=checkpointer
)
# `thread_id` は会話ごとの一意な識別子です。
config = {"configurable": {"thread_id": "1"}}
response = agent.invoke(
{"messages": [{"role": "user", "content": "外の天気はどうですか?"}]},
config=config,
context=Context(user_id="1")
)
print(response['structured_response'])
# 同じ `thread_id` を使って会話を続けることができます。
response = agent.invoke(
{"messages": [{"role": "user", "content": "ありがとう!"}]},
config=config,
context=Context(user_id="1")
)
print(response['structured_response'])
出力結果は以下のようになりました。
ResponseFormat(punny_response='Floridaは太陽に愛されているから、雨なんてサヨナラ!毎日がビーチパーティーの気分ですよ~☀️🏖️', weather_conditions='Floridaはいつも晴れです!')
ResponseFormat(punny_response='いえい!太陽と仲良しで、ご機嫌な一日をどうぞ~(でもサングラスは忘れずに!)😎', weather_conditions=None)
ずいぶん陽気な回答ですね。。。ダジャレとは言いづらいかな。
そしてMLflowのトレース結果はこちら。2種のツールを利用して最終の答えを導き出しています。
まとめ
LangChain 1.0の目玉であろうエージェント作成機能を使って、リアルワールドケースのサンプルエージェントを作成しました。
このサンプルぐらいであれば、LangGraphに慣れてると違和感なく使える印象です。
これをカスタムする際には、同じく1.0の新機能であるMiddlewareを使うことになります。(そして、かなりカスタム性が高い仕組になっています)
さらにMiddlewareでも賄えないような複雑なケースではLangGraphを直接使うことになると思いますが、大半のケースはLangChainのエージェントフレームワークで対応できる気がしました。
ドキュメントも刷新され、いろいろ気になる機能も増えているので触りながらキャッチアップしていければと思います。
