DatabricksでLangGraphのクイックスタートを動かしてみる(その6)

こちらの続きです。このシリーズは一旦これで終了です。

https://qiita.com/taka_yayoi/items/58f2434defe5257dd8da

こちらのPart 6: Time Travelを動かします。

https://langchain-ai.github.io/langgraph/tutorials/introduction/#part-6-time-travel

# パート6: タイムトラベル

典型的なチャットボットのワークフローでは、ユーザーはタスクを達成するために1回以上ボットと対話します。前のセクションでは、メモリと人間を介在させてグラフの状態をチェックポイントし、将来の応答を制御する方法を見てきました。

しかし、以前の応答から「分岐」して別の結果を探求したい場合はどうでしょうか？または、ユーザーがアシスタントの作業を「巻き戻して」ミスを修正したり、別の戦略を試したりできるようにしたい場合はどうでしょうか(自律ソフトウェアエンジニアのようなアプリケーションで一般的です)？

LangGraphの組み込み「タイムトラベル」機能を使用して、これらの体験やそれ以上のことを実現できます。

このセクションでは、グラフの`get_state_history`メソッドを使用してチェックポイントを取得し、グラフを「巻き戻し」ます。その後、この以前の時点で実行を再開できます

## セットアップ

まず、必要なパッケージをインストールし、環境を設定します：

```py
%%capture --no-stderr
%pip install -U langgraph langsmith langchain_openai openai tavily-python langchain_community
%restart_python
```

```py
import os
os.environ["OPENAI_API_KEY"] = dbutils.secrets.get(scope="demo-token-takaaki.yayoi", key="openai_api_key")

# TavilyのAPIキー
os.environ["TAVILY_API_KEY"] = "TavilyのAPIキー"
```

このため、[Part 3](https://qiita.com/taka_yayoi/items/255b124aae94df2e04ec)のツールを持つシンプルなチャットbotを使いましょう:

```py
from typing import Annotated

from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.messages import BaseMessage
from typing_extensions import TypedDict

from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.prebuilt import ToolNode, tools_condition


class State(TypedDict):
    messages: Annotated[list, add_messages]


graph_builder = StateGraph(State)


tool = TavilySearchResults(max_results=2)
tools = [tool]
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools(tools)


def chatbot(state: State):
    return {"messages": [llm_with_tools.invoke(state["messages"])]}


graph_builder.add_node("chatbot", chatbot)

tool_node = ToolNode(tools=[tool])
graph_builder.add_node("tools", tool_node)

# 条件付きエッジを追加
graph_builder.add_conditional_edges(
    "chatbot",
    tools_condition,
)
# ツールが呼び出されるたびに、次のステップを決定するためにチャットボットに戻る
graph_builder.add_edge("tools", "chatbot")
graph_builder.add_edge(START, "chatbot")

memory = MemorySaver()
graph = graph_builder.compile(checkpointer=memory)
```

グラフにいくつかのステップを踏ませましょう。すべてのステップは状態履歴にチェックポイントされます:

```py
config = {"configurable": {"thread_id": "1"}}
events = graph.stream(
    {
        "messages": [
            {
                "role": "user",
                "content": (
                    "LangGraphを学んでいます。"
                    "調査してもらえますか？"
                ),
            },
        ],
    },
    config,
    stream_mode="values",
)
for event in events:
    if "messages" in event:
        event["messages"][-1].pretty_print()
```
```
================================== Ai Message ==================================

LangGraphは、複数のエージェントを用いたアプリケーションを構築するためのライブラリで、主に大規模言語モデル（LLM）を活用した状態を持つマルチアクターアプリケーションを作成するのに使用されます。このライブラリは、LangChainの作成者であるLangChain Incによって開発されており、LangChainなしでも使用可能です。

### 主要なポイント
- **目的**: LangGraphは、エージェントやマルチエージェントワークフローを作成するために使用されます。
- **インスピレーション**: PregelやApache Beamに触発されており、NetworkXのインターフェースからも影響を受けています。
- **機能**: 複雑なマルチエージェントLLMアプリケーションの開発を簡素化し、ノード、エッジ、状態管理を用いて、状態を持つ柔軟でスケーラブルなシステムを作成できるようにします。

### 参考リンク
- [LangGraphの公式サイト](https://langchain-ai.github.io/langgraph/) - ライブラリの概要とチュートリアルがあります。
- [DataCampのLangGraphチュートリアル](https://www.datacamp.com/tutorial/langgraph-tutorial) - LangGraphの使用方法を学ぶためのガイドです。

LangGraphについてさらに詳しく知りたい場合は、上記のリンクを訪れてみてください。
```

```py
events = graph.stream(
    {
        "messages": [
            {
                "role": "user",
                "content": (
                    "はい、それは役に立ちます。"
                    "それで自律エージェントを構築しようかな！情報をもらえますか。"
                ),
            },
        ],
    },
    config,
    stream_mode="values",
)
for event in events:
    if "messages" in event:
        event["messages"][-1].pretty_print()
```
```
2025/02/04 00:45:53 WARNING mlflow.utils.autologging_utils: Encountered unexpected error during autologging: Span for run_id 32b69066-7049-4085-ac13-a21f835c84de not found.
================================ Human Message =================================

はい、それは役に立ちます。それで自律エージェントを構築しようかな！情報をもらえますか。
2025/02/04 00:45:54 WARNING mlflow.utils.autologging_utils: Encountered unexpected error during autologging: Span for run_id a22a11ea-1b22-4142-a525-83b5a7bee37b not found.
================================== Ai Message ==================================
Tool Calls:
  tavily_search_results_json (call_SWfIcYtLuGof1Z2AWDGdWCK9)
 Call ID: call_SWfIcYtLuGof1Z2AWDGdWCK9
  Args:
    query: self-driving agents LangGraph
2025/02/04 00:45:57 WARNING mlflow.utils.autologging_utils: Encountered unexpected error during autologging: Span for run_id 62a6b915-f959-4f47-b8ac-00c2b1dd33c9 not found.
================================= Tool Message =================================
Name: tavily_search_results_json

[{"url": "https://prateekjoshi.hashnode.dev/developing-an-ai-blogging-agent-a-complete-journey-with-langchain-and-langgraph", "content": "Comprising three core components—a language model (serving as the decision-making engine), tools (enabling interaction with external systems via APIs, data stores, or custom functions), and an orchestration layer (managing iterative cycles of planning, execution, and adjustment)—these agents operate proactively, even without explicit instructions. 1. Managing Complex Workflows: Use AI agents (e.g., LangChain) to orchestrate multi-step processes requiring integration across systems or contextual awareness. | LangGraph | Stateful interactions, multi-agent coordination, graph-based representation | Interactive storytelling, strategic decision-making, game AI | Complex task management, scalability, enhanced traceability | Use Cases: LangChain is best suited for applications needing multiple LLM integrations and context-aware responses, whereas LangGraph is ideal for managing intricate, multi-actor workflows and large-scale AI deployments."}, {"url": "https://www.nomidl.com/generative-ai/slug-building-ai-agents-lang-graph/", "content": "Building an AI Agents with Lang Graph - Nomidl AI agents are self-governing entities capable of performing intricate, multi-step activities, maintaining state throughout interactions, and dynamically adapting to new information. Steps to Build AI Agents With LangGraph The first step in creating an AI agent using LangGraph is configuring your development environment. Preparing for development is an initial step in building an AI agent with LangGraph. You can now use your AI agent in an interactive loop, where it constantly accepts input from the user and produces an answer based on the established logic. By following this guide, you can develop AI agents that can interact with users, process information, and provide meaningful responses in a conversational manner."}]
================================== Ai Message ==================================

自律エージェントをLangGraphを使用して構築することは非常にエキサイティングなプロジェクトです。以下は、LangGraphを使ったAIエージェントの構築に関する重要な情報とステップです。

### 自律エージェントの構成要素
自律エージェントは通常、以下の三つのコアコンポーネントで構成されます:
1. **言語モデル**: 意思決定エンジンとして機能します。
2. **ツール**: APIやデータストア、カスタム関数を介して外部システムと相互作用できるようにします。
3. **オーケストレーション層**: 計画、実行、調整の反復サイクルを管理します。

### LangGraphの特徴
- **状態の管理**: 状態を持ちながらインタラクティブに動作します。
- **マルチエージェントの調整**: 複数のエージェントが協調して作業を行うことができます。
- **グラフベースの表現**: 複雑なタスクの管理がしやすく、トレーサビリティが向上します。

### 自律エージェントを構築するステップ
1. **開発環境の設定**: LangGraphを使用するための環境を構築します。
2. **エージェントの設計**: ユーザー入力を受け取り、その入力に基づいて応答を生成するロジックを設定します。
3. **インタラクティブループの実装**: エージェントがユーザーと常に対話し、情報を処理する方法を実装します。

これらのステップを通じて、LangGraphを使った自律エージェントを開発することができます。詳しいガイドラインやケーススタディについては、以下のリンクを参照してください。

- [AIブログエージェントの構築についての完全な旅](https://prateekjoshi.hashnode.dev/developing-an-ai-blogging-agent-a-complete-journey-with-langchain-and-langgraph)
- [LangGraphを使ってAIエージェントを構築する方法](https://www.nomidl.com/generative-ai/slug-building-ai-agents-lang-graph/)

これらのリソースが自律エージェントの設計と実装に役立つことを願っています！
```

エージェントがいくつかのステップを踏んだので、発生したすべてのことを確認するために、完全な状態履歴を`replay`できます。

```py
to_replay = None
for state in graph.get_state_history(config):
    print("Num Messages: ", len(state.values["messages"]), "Next: ", state.next)
    print("-" * 80)
    if len(state.values["messages"]) == 6:
        # チャットメッセージの数に基づいて特定の状態を任意に選択しています。
        to_replay = state
```
```
Num Messages:  8 Next:  ()
--------------------------------------------------------------------------------
Num Messages:  7 Next:  ('chatbot',)
--------------------------------------------------------------------------------
Num Messages:  6 Next:  ('tools',)
--------------------------------------------------------------------------------
Num Messages:  5 Next:  ('chatbot',)
--------------------------------------------------------------------------------
Num Messages:  4 Next:  ('__start__',)
--------------------------------------------------------------------------------
Num Messages:  4 Next:  ()
--------------------------------------------------------------------------------
Num Messages:  3 Next:  ('chatbot',)
--------------------------------------------------------------------------------
Num Messages:  2 Next:  ('tools',)
--------------------------------------------------------------------------------
Num Messages:  1 Next:  ('chatbot',)
--------------------------------------------------------------------------------
Num Messages:  0 Next:  ('__start__',)
--------------------------------------------------------------------------------
```

:::note info
**注意**
チェックポイントはグラフの各ステップごとに保存されることに注意してください。これは**呼び出し全体に渡るので**、フルスレッドの履歴全体を巻き戻すことができます。再開する状態として `to_replay` を選びました。これは、上記の2回目のグラフ呼び出しで`chatbot`ノードの後の状態です。
:::

このポイントから再開すると、次に**アクション**ノードが呼び出されるはずです。

```py
print(to_replay.next)
print(to_replay.config)
```
```
('tools',)
{'configurable': {'thread_id': '1', 'checkpoint_ns': '', 'checkpoint_id': '1efe2916-3cff-6f22-8006-1b8505ff496a'}}
```

:::note info
**注意**

チェックポイントの構成 (`to_replay.config`) の `checkpoint_id` に**タイムスタンプ**が含まれていることに注意してください。この `checkpoint_id` 値を指定すると、LangGraph のチェックポインタにその時点の状態を**ロード**するように指示します。以下で試してみましょう。
:::

```py
# `to_replay.config` の `checkpoint_id` は、チェックポインタに永続化した状態に対応しています。
for event in graph.stream(None, to_replay.config, stream_mode="values"):
    if "messages" in event:
        event["messages"][-1].pretty_print()
```
```
2025/02/04 00:47:43 WARNING mlflow.utils.autologging_utils: Encountered unexpected error during autologging: Span for run_id 07385eb9-b460-4266-8e6d-382d6e054c18 not found.
================================== Ai Message ==================================
Tool Calls:
  tavily_search_results_json (call_SWfIcYtLuGof1Z2AWDGdWCK9)
 Call ID: call_SWfIcYtLuGof1Z2AWDGdWCK9
  Args:
    query: self-driving agents LangGraph
2025/02/04 00:47:45 WARNING mlflow.utils.autologging_utils: Encountered unexpected error during autologging: Span for run_id c6dd36e2-b086-48e4-a815-e8ec9553d60b not found.
================================= Tool Message =================================
Name: tavily_search_results_json

[{"url": "https://prateekjoshi.hashnode.dev/developing-an-ai-blogging-agent-a-complete-journey-with-langchain-and-langgraph", "content": "Comprising three core components—a language model (serving as the decision-making engine), tools (enabling interaction with external systems via APIs, data stores, or custom functions), and an orchestration layer (managing iterative cycles of planning, execution, and adjustment)—these agents operate proactively, even without explicit instructions. 1. Managing Complex Workflows: Use AI agents (e.g., LangChain) to orchestrate multi-step processes requiring integration across systems or contextual awareness. | LangGraph | Stateful interactions, multi-agent coordination, graph-based representation | Interactive storytelling, strategic decision-making, game AI | Complex task management, scalability, enhanced traceability | Use Cases: LangChain is best suited for applications needing multiple LLM integrations and context-aware responses, whereas LangGraph is ideal for managing intricate, multi-actor workflows and large-scale AI deployments."}, {"url": "https://www.nomidl.com/generative-ai/slug-building-ai-agents-lang-graph/", "content": "Building an AI Agents with Lang Graph - Nomidl AI agents are self-governing entities capable of performing intricate, multi-step activities, maintaining state throughout interactions, and dynamically adapting to new information. Steps to Build AI Agents With LangGraph The first step in creating an AI agent using LangGraph is configuring your development environment. Preparing for development is an initial step in building an AI agent with LangGraph. You can now use your AI agent in an interactive loop, where it constantly accepts input from the user and produces an answer based on the established logic. By following this guide, you can develop AI agents that can interact with users, process information, and provide meaningful responses in a conversational manner."}]
================================== Ai Message ==================================

自律エージェントをLangGraphで構築するためのポイントをいくつか紹介します。

### 自律エージェントの構成要素
自律エージェントは通常、以下の3つのコアコンポーネントから成り立っています：
1. **言語モデル**: 意思決定のエンジンとして機能します。
2. **ツール**: API、データストア、またはカスタム関数を介して外部システムと対話を可能にします。
3. **オーケストレーションレイヤー**: 計画、実行、調整のiterativeなサイクルを管理します。

これらのエージェントは、明示的な指示なしでも積極的に動作します。

### LangGraphでの自律エージェント構築手順
1. **開発環境の設定**: LangGraphを使ったAIエージェントの構築には、最初に開発環境を適切に設定する必要があります。
2. **インタラクティブループの構成**: AIエージェントをインタラクティブループで使用し、ユーザーからの入力を常に受け取り、設定されたロジックに基づいて応答を生成します。
3. **状態管理**: エージェントは状態を維持しながらinteractionsを行うことができ、新しい情報に動的に適応します。

### 具体的な使用例
- **複雑なワークフロー管理**: AIエージェントを使って、システム間の統合や文脈認識を必要とするマルチステッププロセスをオーケストレートできます。
- **インタラクティブなストーリーテリング**: ユーザーとの対話を通じて、ストーリーを展開することも可能です。
- **戦略的意思決定**: ゲームAIやタスク管理、スケーラビリティを向上させるために利用できます。

### 参考リンク
- [AIエージェントの構築ガイド](https://www.nomidl.com/generative-ai/slug-building-ai-agents-lang-graph/)
- [AIブログエージェントの開発に関する完全な旅](https://prateekjoshi.hashnode.dev/developing-an-ai-blogging-agent-a-complete-journey-with-langchain-and-langgraph)

これらの情報を参考に、自律エージェントの構築に挑戦してみてください！
```

グラフが`**action**`ノードから実行を再開したことに注意してください。これは、上記の最初の値が検索エンジンツールからの応答であることからわかります。

**おめでとうございます！** これで、LangGraphでタイムトラベルチェックポイントトラバーサルを使用できるようになりました。巻き戻して代替パスを探索できることは、デバッグ、実験、およびインタラクティブなアプリケーションに無限の可能性をもたらします。

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)