⚡ 言語エージェントをグラフとして構築する ⚡
注記
JS バージョンをお探しですか?ここをクリックしてください (JS ドキュメント)。
LangGraph は、LLM を使用してステートフルなマルチアクター アプリケーションを構築するためのライブラリであり、エージェントおよびマルチエージェント ワークフローの作成に使用されます。他の LLM フレームワークと比較して、サイクル、制御性、永続性といった主要な利点を提供します。 LangGraph を使用すると、ほとんどのエージェント アーキテクチャに不可欠なサイクルを含むフローを定義でき、DAG ベースのソリューションと区別できます。非常に低レベルのフレームワークとして、信頼性の高いエージェントを作成するために重要な、アプリケーションのフローと状態の両方に対するきめ細かい制御を提供します。さらに、LangGraph には永続性が組み込まれており、高度な人間参加型機能とメモリ機能が可能になります。
LangGraph は Pregel と Apache Beam からインスピレーションを受けています。パブリック インターフェイスは NetworkX からインスピレーションを得ています。 LangGraph は、LangChain の作成者である LangChain Inc によって構築されていますが、LangChain がなくても使用できます。
LangGraph プラットフォームは、LangGraph エージェントを展開するためのインフラストラクチャです。これは、エージェント アプリケーションを運用環境に展開するための商用ソリューションであり、オープンソースの LangGraph フレームワークに基づいて構築されています。 LangGraph プラットフォームは、LangGraph アプリケーションの開発、展開、デバッグ、監視をサポートするために連携して動作するいくつかのコンポーネントで構成されています。LangGraph Server (API)、LangGraph SDK (API のクライアント)、LangGraph CLI (サーバーを構築するためのコマンド ライン ツール) )、LangGraph Studio (UI/デバッガー)、
LangGraph について詳しくは、ここから無料で利用できる最初の LangChain Academy コース「LangGraph の概要」をご覧ください。
LangGraph プラットフォームは、エージェント アプリケーションを運用環境に展開するための商用ソリューションであり、オープンソースの LangGraph フレームワークに基づいて構築されています。以下に、複雑なデプロイメントで発生する一般的な問題をいくつか示します。LangGraph プラットフォームはこれらの問題に対処します。
pip install -U langgraph
LangGraph の中心的な概念の 1 つは状態です。グラフを実行するたびに、実行時にグラフ内のノード間で渡される状態が作成され、各ノードは実行後の戻り値でこの内部状態を更新します。グラフが内部状態を更新する方法は、選択したグラフのタイプまたはカスタム関数によって定義されます。
検索ツールを使用できるエージェントの簡単な例を見てみましょう。
pip install langchain-anthropic
export ANTHROPIC_API_KEY=sk-...
オプションで、クラス最高の可観測性を実現するために LangSmith をセットアップできます。
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=lsv2_sk_...
from typing import Annotated , Literal , TypedDict
from langchain_core . messages import HumanMessage
from langchain_anthropic import ChatAnthropic
from langchain_core . tools import tool
from langgraph . checkpoint . memory import MemorySaver
from langgraph . graph import END , START , StateGraph , MessagesState
from langgraph . prebuilt import ToolNode
# Define the tools for the agent to use
@ tool
def search ( query : str ):
"""Call to surf the web."""
# This is a placeholder, but don't tell the LLM that...
if "sf" in query . lower () or "san francisco" in query . lower ():
return "It's 60 degrees and foggy."
return "It's 90 degrees and sunny."
tools = [ search ]
tool_node = ToolNode ( tools )
model = ChatAnthropic ( model = "claude-3-5-sonnet-20240620" , temperature = 0 ). bind_tools ( tools )
# Define the function that determines whether to continue or not
def should_continue ( state : MessagesState ) -> Literal [ "tools" , END ]:
messages = state [ 'messages' ]
last_message = messages [ - 1 ]
# If the LLM makes a tool call, then we route to the "tools" node
if last_message . tool_calls :
return "tools"
# Otherwise, we stop (reply to the user)
return END
# Define the function that calls the model
def call_model ( state : MessagesState ):
messages = state [ 'messages' ]
response = model . invoke ( messages )
# We return a list, because this will get added to the existing list
return { "messages" : [ response ]}
# Define a new graph
workflow = StateGraph ( MessagesState )
# Define the two nodes we will cycle between
workflow . add_node ( "agent" , call_model )
workflow . add_node ( "tools" , tool_node )
# Set the entrypoint as `agent`
# This means that this node is the first one called
workflow . add_edge ( START , "agent" )
# We now add a conditional edge
workflow . add_conditional_edges (
# First, we define the start node. We use `agent`.
# This means these are the edges taken after the `agent` node is called.
"agent" ,
# Next, we pass in the function that will determine which node is called next.
should_continue ,
)
# We now add a normal edge from `tools` to `agent`.
# This means that after `tools` is called, `agent` node is called next.
workflow . add_edge ( "tools" , 'agent' )
# Initialize memory to persist state between graph runs
checkpointer = MemorySaver ()
# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable.
# Note that we're (optionally) passing the memory when compiling the graph
app = workflow . compile ( checkpointer = checkpointer )
# Use the Runnable
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what is the weather in sf" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in San Francisco is:nnTemperature: 60 degrees FahrenheitnConditions: FoggynnSan Francisco is known for its microclimates and frequent fog, especially during the summer months. The temperature of 60°F (about 15.5°C) is quite typical for the city, which tends to have mild temperatures year-round. The fog, often referred to as "Karl the Fog" by locals, is a characteristic feature of San Francisco's weather, particularly in the mornings and evenings.nnIs there anything else you'd like to know about the weather in San Francisco or any other location?"
同じ"thread_id"
渡すと、保存された状態 (つまり、保存されたメッセージのリスト) を介して会話コンテキストが保持されるようになりました。
final_state = app . invoke (
{ "messages" : [ HumanMessage ( content = "what about ny" )]},
config = { "configurable" : { "thread_id" : 42 }}
)
final_state [ "messages" ][ - 1 ]. content
"Based on the search results, I can tell you that the current weather in New York City is:nnTemperature: 90 degrees Fahrenheit (approximately 32.2 degrees Celsius)nConditions: SunnynnThis weather is quite different from what we just saw in San Francisco. New York is experiencing much warmer temperatures right now. Here are a few points to note:nn1. The temperature of 90°F is quite hot, typical of summer weather in New York City.n2. The sunny conditions suggest clear skies, which is great for outdoor activities but also means it might feel even hotter due to direct sunlight.n3. This kind of weather in New York often comes with high humidity, which can make it feel even warmer than the actual temperature suggests.nnIt's interesting to see the stark contrast between San Francisco's mild, foggy weather and New York's hot, sunny conditions. This difference illustrates how varied weather can be across different parts of the United States, even on the same day.nnIs there anything else you'd like to know about the weather in New York or any other location?"
ChatAnthropic
使用します。注:呼び出すことができるこれらのツールがあることをモデルが認識していることを確認する必要があります。これを行うには、 .bind_tools()
メソッドを使用して LangChain ツールを OpenAI ツール呼び出しの形式に変換します。MessagesState
) を渡すことでグラフ ( StateGraph
) を初期化します。MessagesState
は、LangChain Message
オブジェクトのリストと、各ノードからの更新を状態にマージするロジックという 1 つの属性を持つ、事前に構築された状態スキーマです。必要な主なノードは 2 つあります。
agent
ノード: (ある場合) どのようなアクションを実行するかを決定します。tools
ノード: エージェントがアクションを実行することを決定した場合、このノードはそのアクションを実行します。まず、グラフ実行のエントリ ポイント、つまりagent
ノードを設定する必要があります。
次に、1 つの通常エッジと 1 つの条件付きエッジを定義します。条件付きエッジは、宛先がグラフの状態 ( MessageState
) の内容に依存することを意味します。私たちの場合、エージェント (LLM) が決定するまで宛先はわかりません。
.invoke()
、 .stream()
、および.batch()
を呼び出すことが自動的に有効になります。MemorySaver
を使用します。 LangGraph は入力メッセージを内部状態に追加し、その状態をエントリポイント ノード"agent"
に渡します。
"agent"
ノードが実行され、チャット モデルが呼び出されます。
チャット モデルはAIMessage
を返します。 LangGraph はこれを状態に追加します。
グラフは、 AIMessage
のtool_calls
がなくなるまで、次の手順を繰り返します。
AIMessage
にtool_calls
がある場合、 "tools"
ノードが実行されます"agent"
ノードが再度実行され、 AIMessage
が返されます。実行は特別なEND
値まで進み、最終状態を出力します。その結果、すべてのチャット メッセージのリストが出力として取得されます。
貢献方法の詳細については、こちらをご覧ください。