LangChain はリアルタイムの更新を表示するストリーミングシステムを実装しています。
ストリーミングは LLM 上に構築されたアプリケーションの応答性を強化するために不可欠です。完全なレスポンスが準備される前でも出力を段階的に表示することで、特に LLM の遅延に対応する際、ストリーミングはユーザエクスペリエンス (UX) を大幅に向上させます。
LangChain 1.0 alpha : コアコンポーネント – ストリーミング
作成 : クラスキャット・セールスインフォメーション
作成日時 : 09/26/2026
バージョン : 1.0.0a9
* 本記事は docs.langchain.com の以下のページを独自に翻訳した上で、補足説明を加えてまとめ直しています。スニペットはできる限り日本語を使用しています :
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
LangChain 1.0 alpha : コアコンポーネント – ストリーミング
LangChain はリアルタイムの更新を表面化させる (surface) ストリーミングシステムを実装しています。
ストリーミングは LLM 上に構築されたアプリケーションの応答性を強化するために不可欠です。完全なレスポンスが準備される前でも出力を段階的に表示することで、特に LLM の遅延に対応する際、ストリーミングはユーザエクスペリエンス (UX) を大幅に向上させます。
エージェントからのストリーミング
LangChain のストリーミングシステムは、エージェント実行からアプリケーションへのリアルタイムなフィードバックを表面化させることができます。
LangChain ストリーミングで可能なことは :
- エージェントの進捗状況をストリーミング – 各エージェントステップ後に状態更新を取得します。
- LLM トークンのストリーミング – 言語モデルのトークンをそれらが生成されながらストリーミングします。
- カスタム更新のストリーミング – ユーザ定義済みシグナル (e.g., “10/100 レコードを取得しました”) を送信します。
- マルチモードのストリーミング – 更新 (エージェントの進捗)、メッセージ (LLM トークン + メタデータ)、カスタム (任意のユーザデータ) から選択します。
エージェントの進捗
エージェントの進捗をストリーミングするには、stream_mode=”updates” で stream() or astream() メソッドを使用します。これはすべてのエージェントステップの後にイベントを発行します。
例えば、ツールを一度呼び出すエージェントがある場合、以下の更新を確認できるはずです :
- LLM ノード : ツール呼び出しリクエストを含む AI メッセージ
- ツールノード : 実行結果を含むツールメッセージ
- LLM ノード : 最終的な AI レスポンス
Streaming agent progress
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"{city} では常に晴れています!"
agent = create_agent(
model="openai:gpt-5-nano",
tools=[get_weather],
)
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "東京の天気はどうでしょう?"}]},
stream_mode="updates",
):
for step, data in chunk.items():
print(f"\n### step: {step}")
print(f"# content: {data['messages'][-1]}")
#data['messages'][-1].pretty_print()
出力例
### step: agent # content: content='' additional_kwargs={'tool_calls': [{'id': 'call_eOEDB9stfkLxjqRRaUCCvMAg', 'function': {'arguments': '{"city":"東京"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None} response_metadata={'token_usage': {'completion_tokens': 215, 'prompt_tokens': 133, 'total_tokens': 348, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 192, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-5-nano-2025-08-07', 'system_fingerprint': None, 'id': 'chatcmpl-CJmNDcRqD1tUgtnxcybrEfKVhzbev', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None} id='run--985efb15-2ef6-4b20-a2c8-1b838e73a272-0' tool_calls=[{'name': 'get_weather', 'args': {'city': '東京'}, 'id': 'call_eOEDB9stfkLxjqRRaUCCvMAg', 'type': 'tool_call'}] usage_metadata={'input_tokens': 133, 'output_tokens': 215, 'total_tokens': 348, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 192}} ### step: tools # content: content='東京 では常に晴れています!' name='get_weather' id='72e19f40-ebe3-4516-82e6-b225c2f2c0e8' tool_call_id='call_eOEDB9stfkLxjqRRaUCCvMAg' ### step: agent # content: content='東京の天気は現在、晴れています。\n\nほかにも知りたい情報があれば教えてください(今後の予報や気温などもお伝えします)。別の都市の天気も知れます。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 1148, 'prompt_tokens': 170, 'total_tokens': 1318, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 1088, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-5-nano-2025-08-07', 'system_fingerprint': None, 'id': 'chatcmpl-CJmNHin2OFrc4oKXPi8vUjeWzzTLa', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None} id='run--4bb224a4-8f28-4705-8a18-6bb2063e03ab-0' usage_metadata={'input_tokens': 170, 'output_tokens': 1148, 'total_tokens': 1318, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 1088}}
### step: agent ================================== Ai Message ================================== Tool Calls: get_weather (call_OX5amScDlxP0lavWMrDX6Aob) Call ID: call_OX5amScDlxP0lavWMrDX6Aob Args: city: Tokyo ### step: tools ================================= Tool Message ================================= Name: get_weather Tokyo では常に晴れています! ### step: agent ================================== Ai Message ================================== 現在の東京の天気は、晴れているとの情報です(このデータはダミー情報です)。 実際の最新情報を知りたい場合は、最新の天気を取得しますか?温度・風速・風向・降水確率・日別の予報など、知りたい情報を教えてください。
LLM トークン
LLM により生成されているトークンをストリーミングするには、stream_mode=”messages” を使用します。以下で、エージェントストリーミングのツール呼び出しと最終レスポンスの出力を確認できます。
Streaming LLM tokens
from langchain.agents import create_agent
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"{city} は常に晴れています!"
agent = create_agent(
model="openai:gpt-5-nano",
tools=[get_weather],
)
for token, metadata in agent.stream(
{"messages": [{"role": "user", "content": "東京の天気はどうでしょう?"}]},
stream_mode="messages",
):
if token.content: # type:ignore
print(f"node: {metadata['langgraph_node']}") # type:ignore
print(f"content: {token.content}") # type:ignore
print("\n")
出力例
node: tools content: 東京 は常に晴れています! node: agent content: 東京 node: agent content: の node: agent content: 天 node: agent content: 気 node: agent content: について node: agent content: お node: agent content: 伝 node: agent content: え node: agent content: します node: agent content: 。 node: agent content: この node: agent content: ツ node: agent content: ール node: agent content: の node: agent content: 返信 node: agent content: では node: agent content: 、 node: agent content: 東京 node: agent content: は node: agent content: 「 node: agent content: 常 node: agent content: に node: agent content: 晴 node: agent content: れ node: agent content: ています node: agent content: !」 node: agent content: と node: agent content: 表示 node: agent content: されています node: agent content: 。ただ node: agent content: し node: agent content: 現 node: agent content: 実 node: agent content: の node: agent content: 天 node: agent content: 気 node: agent content: は node: agent content: 日 node: agent content: によ node: agent content: って node: agent content: 変 node: agent content: 化 node: agent content: します node: agent content: 。 node: agent content: 最新 node: agent content: の node: agent content: 正 node: agent content: 確 node: agent content: な node: agent content: 現在 node: agent content: の node: agent content: 天 node: agent content: 気 node: agent content: や node: agent content: 今 node: agent content: 後 node: agent content: の node: agent content: 予 node: agent content: 報 node: agent content: を node: agent content: 知 node: agent content: り node: agent content: たい node: agent content: 場合 node: agent content: は node: agent content: 、 node: agent content: リア node: agent content: ル node: agent content: タイ node: agent content: ム node: agent content: 情報 node: agent content: を node: agent content: 表示 node: agent content: します node: agent content: 。 node: agent content: 知 node: agent content: り node: agent content: たい node: agent content: です node: agent content: か node: agent content: ? node: agent content: ほ node: agent content: か node: agent content: の node: agent content: 都市 node: agent content: の node: agent content: 天 node: agent content: 気 node: agent content: も node: agent content: 知 node: agent content: り node: agent content: たい node: agent content: 場合 node: agent content: は node: agent content: 教 node: agent content: えて node: agent content: ください node: agent content: 。
カスタム更新
実行時にツールからの更新をストリーミングするには、get_stream_writer を使用できます。
Streaming custom updates
from langchain.agents import create_agent
from langgraph.config import get_stream_writer
def get_weather(city: str) -> str:
"""Get weather for a given city."""
writer = get_stream_writer()
# stream any arbitrary data
writer(f"都市: {city} のデータを検索しています")
writer(f"都市: {city} のデータを取得しました")
return f"{city} は常に晴れています!"
agent = create_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
)
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "東京の天気はどうですか?"}]},
stream_mode="custom"
):
print(chunk)
出力例
都市: 東京 のデータを検索しています 都市: 東京 のデータを取得しました
マルチモードのストリーミング
ストリーミングモードをリスト: stream_mode=[“updates”, “custom”] として渡すことで、複数のストリーミングモードを指定できます :
Streaming multiple modes
from langchain.agents import create_agent
from langgraph.config import get_stream_writer
def get_weather(city: str) -> str:
"""Get weather for a given city."""
writer = get_stream_writer()
writer(f"都市: {city} のデータを検索しています")
writer(f"都市: {city} のデータを取得しました")
return f"{city} は常に晴れています!"
agent = create_agent(
model="openai:gpt-5-nano",
tools=[get_weather],
)
for stream_mode, chunk in agent.stream(
{"messages": [{"role": "user", "content": "東京の天気はどうですか?"}]},
stream_mode=["updates", "custom"]
):
print(f"stream_mode: {stream_mode}")
print(f"content: {chunk}")
print("\n")
出力例
stream_mode: updates content: {'agent': {'messages': [AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_APbzKorDhgRuUKxfCaKRcKjX', 'function': {'arguments': '{"city":"東京"}', 'name': 'get_weather'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 151, 'prompt_tokens': 134, 'total_tokens': 285, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 128, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-5-nano-2025-08-07', 'system_fingerprint': None, 'id': 'chatcmpl-CJnFhX4iY5sB3R5KSTuqRiQp4sjCg', 'service_tier': 'default', 'finish_reason': 'tool_calls', 'logprobs': None}, id='run--cc0c459b-aed3-4a5a-9342-f092c478ddff-0', tool_calls=[{'name': 'get_weather', 'args': {'city': '東京'}, 'id': 'call_APbzKorDhgRuUKxfCaKRcKjX', 'type': 'tool_call'}], usage_metadata={'input_tokens': 134, 'output_tokens': 151, 'total_tokens': 285, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 128}})]}} stream_mode: custom content: 都市: 東京 のデータを検索しています stream_mode: custom content: 都市: 東京 のデータを取得しました stream_mode: updates content: {'tools': {'messages': [ToolMessage(content='東京 は常に晴れています!', name='get_weather', tool_call_id='call_APbzKorDhgRuUKxfCaKRcKjX')]}} stream_mode: updates content: {'agent': {'messages': [AIMessage(content='東京の天気について、今の情報では「東京は常に晴れています」と出ています。ただし現実には天気は変わりやすいので、最新の予報を知りたい場合は日付を教えてください。特定の日の天気を調べます。', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 714, 'prompt_tokens': 170, 'total_tokens': 884, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 640, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-5-nano-2025-08-07', 'system_fingerprint': None, 'id': 'chatcmpl-CJnFj8LFEbv5vaLe0j8v1nyAVwRrt', 'service_tier': 'default', 'finish_reason': 'stop', 'logprobs': None}, id='run--e1425f72-957f-49d9-b93a-e7cf8838e3f3-0', usage_metadata={'input_tokens': 170, 'output_tokens': 714, 'total_tokens': 884, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 640}})]}}
以上