HyperAI超神経
Back to Headlines

LangGraphを使ってメモリ機能を持つReActエージェントを構築する方法

11日前

LangGraphを使ってメモリ機能付きReActエージェントを構築 AIエージェントがなぜ特定の行動を取るのか、どのように意思決定を行い、どのような方法でツールを使い分けるのかといった疑問について深掘りするためには、ReActエージェントを理解することが重要です。ReActエージェントとは、ロジックとアクションを組み合わせた強力なワークフローを指します。この記事では、LangGraphというオープンソースライブラリを使って、グラフベースのLLM(大規模言語モデル)ワークフローを構築する方法を見ていきます。 ReActエージェントとは? ReActエージェントは「思考(Reasoning)」と「行動(Action)」を組み合わせたAIワークフローで、モデルが以下のようなタスクを遂行できます: - 思考を発声化し、問題を論理的に考虑する - ツールを使用し、具体的な行動を取る - 目的を達成するまで繰り返す 例えば、OpenAIのChatGPTエージェントは、旅の旅程計画やコードのデバッグなど、20ステップ以上の推理とツール使用を连锁させることができます。 LangGraphの基本概念 LangGraphは、各ノードが能力(思考または行動)を表し、各エッジが遷移のロジックを定義する状態マシンまたはグラフとして、ReActエージェントのワークフローを作成しやすくします。主要概念は以下の通りです: - Messages: 宛先とメッセージのペア - State: 現在の状態 - Nodes: グラフの各部分を表すノード - Edges: ノード間の遷移を定義するエッジ - ToolExecutor: ツールを使用するためのExecutor - Memory Loop: メモリを維持するためのループ セットアップ まずは、言語モデルをセットアップします。ここでは、コスト効果かつ高速な deepseek-r1-distill-llama-70b を使用します。 ```python from dotenv import load_dotenv from langchain_groq import ChatGroq APIキーの読み込み load_dotenv() os.environ['GROQ_API_KEY'] = os.getenv("GROQ_API_KEY") モデルの初期化 model = ChatGroq(model="deepseek-r1-distill-llama-70b") ``` ワークフローの基礎 最初の简单的なワークフローを構築します。この段階では、ツールの使用なしにモデルを呼び出すだけです。 ```python from langgraph.graph import StateGraph, MessagesState from langchain_core.messages import AIMessage モデルを呼び出すシンプルな関数 def call_model(state: MessagesState): response = model.invoke(state["messages"]) return {"messages": [response]} グラフの作成とノードの追加 workflow = StateGraph(MessagesState) workflow.add_node("mybot", call_model) workflow.set_entry_point("mybot") workflow.set_finish_point("mybot") グラフのコンパイルとテスト app = workflow.compile() response = app.invoke({"messages": ["hi hello how are you?"]}) print(response["messages"][-1].content) ``` ツールの追加 次に、実際の使い方を想定したカスタム天気ツールを追加します。 ```python from langchain_core.tools import tool 天気情報を取得するカスタムツール @tool def weather_tool(query: str): if "delhi" in query.lower(): return "the temp is 45 degree and sunny" return "the temp is 25 degree and cloudy" ``` ReActエージェントノードの構築 カスタムツールをLLMに組み込み、LangGraphノードとして使用します。 ```python from langgraph.graph import StateGraph, MessagesState ツールの登録とLLMとのバインド tools = [weather_tool] llm_with_tool = model.bind_tools(tools) LangGraph互換ノードの定義 def weather_tool_with_llm(state: MessagesState): question = state["messages"] response = llm_with_tool.invoke(question) return {"messages": [response]} ``` ReActグラフの作成 次に、エージェントとツール間のフローを結びつけます。 ```python from langgraph.graph import END, START from langgraph.prebuilt import ToolNode ルーター関数の定義 def router_function(state: MessagesState): messages = state["messages"][-1] if messages.tool_calls: return "tools" return END ReActグラフの作成 workflow = StateGraph(MessagesState) tool_node = ToolNode(tools) workflow.add_node("LLM_with_Tool", weather_tool_with_llm) workflow.add_node("tools", tool_node) workflow.set_entry_point("LLM_with_Tool") workflow.add_conditional_edges("LLM_with_Tool", router_function, {"tools": "tools", END: END}) コンパイルとテスト app2 = workflow.compile() response = app2.invoke({"messages": ["what is a weather in bengaluru?"]}) print(response["messages"][-1].content) ``` フィードバックループの追加 フィードバックループを追加することで、エージェントがツールからの出力を反映してより自然な応答を行うことが可能になります。 ```python フィードバックループの追加 workflow.add_edge("tools", "LLM_with_Tool") app2 = workflow.compile() テスト events = app2.stream({"messages": ["what is a weather in new delhi?"]}) for event in events: event["messages"][-1].pretty_print() ``` メモリ機能の追加 最後に、ワークフローにメモリ機能を追加します。これにより、エージェントは以前のメッセージの履歴を記憶し、持続的な文脈を持つ会話を可能にします。 ```python from langgraph.checkpoint.memory import MemorySaver メモリチェックポイントの初期化 memory = MemorySaver() メモリ機能付きワークフローの作成 workflow = StateGraph(MessagesState) workflow.add_node("llmwithtool", weather_tool_with_llm) workflow.add_node("mytools", tool_node) workflow.add_edge(START, "llmwithtool") workflow.add_conditional_edges("llmwithtool", router_function, {"tools": "mytools", END: END}) workflow.add_edge("mytools", "llmwithtool") メモリサポート付きでコンパイル app3 = workflow.compile(checkpointer=memory) テスト config = {"configurable": {"thread_id": 1}} events = app3.stream({"messages": ["what is a weather in new delhi?"]}, config=config, stream_mode="values") for event in events: event["messages"][-1].pretty_print() 別の質問でテスト events = app3.stream({"messages": ["what is a weather in indore?"]}, config=config, stream_mode="values") for event in events: event["messages"][-1].pretty_print() メモリに基づいて回答 events = app3.stream({"messages": ["in which city the temp was 25 degree?"]}, config=config, stream_mode="values") for event in events: event["messages"][-1].pretty_print() ``` 業界の反応と今後の展望 LangGraphのこの新機能により、開発者はより柔軟でモジュール化されたAIエージェントを簡単に構築できるようになりました。実際、多くのAIエンジニアが、このライブラリを通じて、動的なツール連鎖や持続的な対話が可能なエージェントの開発を進めています。 LangGraphについて LangGraphは、AI開発者向けのオープンソースライブラリで、グラフベースのLLMワークフローを簡単に構築できるように設計されています。このライブラリを使うことで、高度な意思決定プロセスや複雑なタスクの実行が可能になり、将来的にはさらに多くの実用的なアプリケーションが期待されています。 まとめ 本記事では、LangGraphを使うことで、思考と行動を組み合わせたReActスタイルのAIエージェントを構築する方法を学びました。次のステップとして、リアルなAPIとの統合、複数のツールの追加、そしてシステムプロンプトのカスタマイズなどが挙げられます。これらの改善により、エージェントの応答はより inteligent で自然なものになるでしょう。 もし本記事が役立ったと感じたら、ぜひ共有していただけると嬉しいです。これを利用することで、AIエージェントの可能性を広げる第一歩を踏み出すことができます。

Related Links