1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Deep Agents(LangChain) × Databricks: 長時間タスク向けエージェントハーネスを動かす

1
Posted at

Deep Agentsとは何か

Deep AgentsはLangChain/LangGraphベースの「エージェントハーネス」です。ハーネスとは「制御用の外装」のことで、ソフトウェアでは本体の動作を安定させるために外側からかぶせる仕組みを指します。犬の散歩用ハーネスをイメージするとわかりやすいかもしれません。犬(LLM)が自由に動けるが、暴走しないように飼い主(開発者)がコントロールできる、という関係です。

通常のReActエージェント(create_react_agent等)と同じツール呼び出しループを持ちますが、長時間・多ステップのタスクでコンテキストウィンドウが破綻しないための仕組みがビルトインで入っています。

具体的には以下の3つです。

機能 何をするか なぜ必要か
write_todos タスクをTODOリストに分解し、進捗を管理する ステップが増えると「今何をやっているか」を見失うのを防ぐ
ファイルシステム(write_file/read_file) 中間結果をファイルに書き出してコンテキストから追い出し、必要なときだけ読み返す ツール結果の蓄積によるコンテキスト溢れを防ぐ
task(サブエージェント) 子エージェントに委任し、結果だけ受け取る 親のコンテキストを汚さずに深い調査ができる

write_fileの書き込み先はデフォルトではLangGraphのステート内(メモリ上)です。DBFSやローカルディスクに永続化されるわけではなく、エージェントの実行が終わればファイルも消えます。目的はディスクへの保存ではなく、ツール結果をコンテキストウィンドウから追い出して、必要なときだけread_fileで読み返すことです。

逆に言えば、数ステップで終わるタスクにはオーバースペックです。「テーブルの行数を取得して」程度ならcreate_react_agentで十分です。

Databricksで動かす

Deep Agentsはプロバイダー非依存なので、ChatDatabricksを渡すだけでDatabricks Model Serving上のモデルで動きます。

セットアップ

%pip install deepagents databricks-langchain unitycatalog-langchain[databricks] -q
dbutils.library.restartPython()
from databricks_langchain import ChatDatabricks

MODEL_ENDPOINT = "databricks-claude-sonnet-4-5"  # 環境に合わせて変更

llm = ChatDatabricks(
    endpoint=MODEL_ENDPOINT,
    temperature=0,
)

ツールの定義

エージェントに渡すSQLクエリ実行ツールを定義します。

エラー時にカラム型のヒントを返すことで、エージェントが自力でSQLを修正しやすくなります。エージェント向けツールではエラーメッセージの設計が重要です。

from langchain_core.tools import tool
from datetime import datetime


@tool
def execute_sql(query: str) -> str:
    """Databricks上でSQLクエリを実行し、結果を文字列で返します。SELECT文のみ許可。

    Args:
        query: 実行するSQLクエリ(SELECT文のみ)
    """
    if not query.strip().upper().startswith("SELECT"):
        return "エラー: SELECT文のみ実行可能です。"
    try:
        df = spark.sql(query)
        result = df.limit(30).toPandas().to_string(index=False)
        row_count = df.count()
        return f"件数: {row_count}\nクエリ結果(最大30行):\n{result}"
    except Exception as e:
        return (
            f"クエリ実行エラー: {str(e)}\n"
            f"実行したクエリ:\n{query}\n"
            f"ヒント: カラムの型を確認してください。"
            f"数値型カラムに文字列比較(!= '')を使うとCAST_INVALID_INPUTエラーになります。"
            f"NULLの除外にはIS NOT NULLを使ってください。"
        )


@tool
def get_current_timestamp() -> str:
    """現在の日時をISO形式で返します。"""
    return datetime.now().isoformat()

MLflowトレーシングの有効化

mlflow.langchain.autolog()を有効にすることで、Deep Agentsの各ステップ(write_todos、ファイル操作、ツール呼び出し)がMLflowトレースとして自動記録されます。

import mlflow

mlflow.langchain.autolog()

username = spark.sql("SELECT current_user()").first()[0]
experiment_path = f"/Users/{username}/deep_agents_profiling_demo"
mlflow.set_experiment(experiment_path)

Deep Agentの作成

system_promptでDeep Agentsの機能(write_todos、write_file)を使うよう誘導します。

from deepagents import create_deep_agent

agent = create_deep_agent(
    model=llm,
    tools=[execute_sql, get_current_timestamp],
    system_prompt="""あなたはDatabricks上で動作するデータプロファイリングエージェントです。

## 作業方針
1. まずwrite_todosで調査対象テーブルごとのTODOリストを作成してください。
2. 各テーブルの調査結果はwrite_fileでファイルに保存し、コンテキストを節約してください。
   (例: /tables/customer_profile.md)
3. 全テーブルの調査が終わったらファイルを読み返し、横断的なサマリーレポートを作成してください。

## プロファイリング項目(テーブルごと)
- 行数
- カラム一覧と型
- 各カラムのNULL件数
- 主要カラムのカーディナリティ(ユニーク数)
- 数値カラムの基本統計(MIN, MAX, AVG)

日本語で回答してください。
""",
)

シナリオ: 複数テーブルのデータプロファイリング

samples.tpchスキーマには8つのテーブル(customer, lineitem, nation, orders, part, partsupp, region, supplier)があります。これら全テーブルのデータプロファイリングを1つのレポートにまとめるタスクをエージェントに依頼します。

このタスクでは以下の流れが自然に発生します。

  1. write_todos: 8テーブル分の調査計画をTODOリストとして作成
  2. ファイルシステム: 各テーブルの調査結果をファイルに書き出し、コンテキストから追い出す
  3. 最終レポート: ファイルを読み返して横断的なサマリーを作成
with mlflow.start_run(run_name="tpch_data_profiling"):
    result = agent.invoke(
        {"messages": [{"role": "user", "content": """
samples.tpch スキーマの全テーブルをプロファイリングしてください。
最終的に全テーブルの横断サマリーレポートを作成してください。
"""}]}
    )

実行結果

samples.tpchスキーマの全テーブルをプロファイリングします。まず、スキーマ内のテーブル一覧を取得します。
8つのテーブルが見つかりました。各テーブルのプロファイリングを実施します。
lineitemテーブルは約3000万行と大規模なので、カラムを分割してクエリします。
全テーブルのプロファイリングが完了しました。各テーブルのファイルを読み込んで横断サマリーレポートを作成します。
samples.tpchスキーマの全テーブルのプロファイリングが完了しました!

## 📊 完了サマリー

### プロファイリング対象
8つのテーブル(総行数: **43,300,825行**)

### 作成されたレポート

**個別テーブルレポート**(`/tables/`ディレクトリ):
1. `nation_profile.md` - 25行
2. `region_profile.md` - 5行
3. `supplier_profile.md` - 50,000行
4. `customer_profile.md` - 750,000行
5. `orders_profile.md` - 7,500,000行
6. `part_profile.md` - 1,000,000行
7. `partsupp_profile.md` - 4,000,000行
8. `lineitem_profile.md` - 29,999,795行(最大)

**横断サマリーレポート**: `/tpch_summary_report.md`

### 主要な発見

✅ **データ品質**: 全テーブル・全カラムでNULL値は0件(完璧なデータ品質)

📈 **規模感**:
- 最大テーブル: lineitem(約3000万行)
- トランザクション系: lineitem, orders(合計3750万行)
- マスタ系: 小規模で高品質

🔗 **リレーションシップ**: 
- 地理階層: region → nation → customer/supplier
- トランザクション階層: customer → orders → lineitem
- 部品階層: part → partsupp → lineitem

💡 **推奨事項**:
- 大規模テーブル(lineitem, orders)は日付パーティショニング推奨
- 小規模ディメンション(nation, region)はブロードキャスト結合に最適
- TPC-Hベンチマーク標準データセットとして分析・BI用途に最適

詳細は `/tpch_summary_report.md` をご確認ください!

MLflowトレース

Screenshot 2026-03-18 at 14.09.44.png
Screenshot 2026-03-18 at 14.10.17.png

MLflow Experimentタブを開くと、write_todosによる計画作成、execute_sqlによる各テーブルの調査、write_file/read_fileによるファイル操作の一連の流れが可視化されます。

まとめ

Deep Agentsは「長いタスクで破綻しないための外装」です。write_todosによる計画、ファイルシステムによるコンテキスト管理、サブエージェントによるタスク委任が最初から組み込まれています。

DatabricksではChatDatabricksを渡すだけで動き、MLflowトレーシングやUnity Catalogツールとも組み合わせられます。多テーブル調査やコードベース分析など、ステップ数が多いタスクで検討する価値があります。

参考リンク

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?