Databricks Certified Generative AI Engineer Associate 教科書
第3章 アプリケーション開発(Application Development, 30%)
🎯 この節の学習目標
3-1〜3-7 で構築してきたチェーン(RAGパイプラインやガードレール付きの処理列)は、このままではノートブック上のPythonコードにすぎません。これを本番にデプロイし、バージョン管理し、チームに配布するためには、標準化されたパッケージ形式に変換する必要があります。それが MLflowモデルとしてのログ(logging)です。
MLflowモデルとしてログすると、次が手に入ります。
predict() という共通の呼び出し方になるつまりこの節は、「開発したチェーン」を「デプロイ可能な資産」に変える、第3章と第4章をつなぐ結節点です。なお、現行の MLflow 3 は GenAI 向けに Tracing・評価(mlflow.genai.evaluate)・プロンプトレジストリを統合した世代で、チェーン/エージェントのログから評価・運用までを一貫して支える基盤になっています。
チェーン/エージェントをMLflowモデルにするときの実装インターフェースは、主に2つから選びます。
| 観点 | mlflow.pyfunc.PythonModel(汎用) | mlflow.pyfunc.ResponsesAgent(エージェント推奨) |
|---|---|---|
| 位置付け | 任意のPythonロジックをラップできる万能の入れ物 | エージェント/チェーン向けにMLflowが用意した推奨インターフェース |
| 入出力形式 | 自由(DataFrame・dict など自分で設計) | OpenAI Responses API 互換のリクエスト/レスポンス形式に統一 |
| ストリーミング | 自前で設計・実装する | predict_stream として標準サポート |
| ツール呼び出し・マルチエージェント | 自前で形式を設計する | 形式として標準対応 |
| 向いている場合 | 非対話型の変換処理や、独自の入出力形式が必要な場合 | チャット/エージェント系の新規開発の第一候補 |
従来の PythonModel ラップや ChatAgent インターフェースで作られたモデルも引き続き動作しますが、新規のエージェント/チェーン開発では ResponsesAgent が第一候補です。入出力が業界標準の形式に揃うため、クライアント・評価ツール・トレーシングとの相互運用性が高くなります。
試験では「mlflow.pyfunc.PythonModel を継承して predict() を実装し、log_model でログする」という従来型のラップ方法が問われる可能性があります。「pyfunc は任意のPythonロジックをモデル化できる汎用フレーバー」という理解は現在も有効で、そのまま得点につながります。
現行の MLflow 3 では、エージェント/チェーンの実装インターフェースとして ResponsesAgent(mlflow.pyfunc.ResponsesAgent)が推奨です。OpenAI Responses API 互換の入出力で、ストリーミング・ツール呼び出し・マルチエージェントに標準対応します。ロギングは models from code(コードベースロギング)が推奨方式です。
最も汎用的な方法が、mlflow.pyfunc.PythonModel を継承したクラスを作り、predict() メソッドにチェーンの呼び出しを実装する方法です。pyfunc(Python function)フレーバーは「Pythonで書けるものなら何でもモデルにできる」万能の入れ物で、独自のガードレールや複数ステージを含む複雑なチェーンもラップできます。
💡 コード例:RAGチェーンのpyfuncラップ
import mlflow
import mlflow.pyfunc
class RAGChainModel(mlflow.pyfunc.PythonModel):
def load_context(self, context):
# エンドポイント名などの初期化(サービング起動時に1回実行される)
from databricks_langchain import ChatDatabricks
self.llm = ChatDatabricks(
endpoint="databricks-meta-llama-3-3-70b-instruct"
)
def predict(self, context, model_input):
# model_input から質問を取り出してチェーンを実行
question = model_input["question"][0]
docs = self.retrieve(question) # 検索ステージ
answer = self.generate(question, docs) # 生成ステージ
return [answer]
with mlflow.start_run():
mlflow.pyfunc.log_model(
name="rag_chain",
python_model=RAGChainModel(),
pip_requirements=["mlflow", "databricks-langchain"],
input_example={"question": ["RAGとは何ですか?"]},
)
load_context() には重い初期化(クライアント生成など)を、predict() にはリクエストごとの処理を書く、という役割分担が基本です。
対話型のエージェント/チェーンを作るなら、ResponsesAgent を継承します。predict() が受け取るリクエストと返すレスポンスが OpenAI Responses API 互換の形式に統一されている点が特徴です。
💡 コード例:ResponsesAgent の最小実装
from mlflow.pyfunc import ResponsesAgent
from mlflow.types.responses import (
ResponsesAgentRequest,
ResponsesAgentResponse,
)
class SimpleRAGAgent(ResponsesAgent):
def predict(self, request: ResponsesAgentRequest) -> ResponsesAgentResponse:
# Responses API 互換のリクエストから最新のユーザー入力を取り出す
question = request.input[-1].content
docs = self.retrieve(question) # 検索ステージ
answer = self.generate(question, docs) # 生成ステージ
return ResponsesAgentResponse(
output=[self.create_text_output_item(text=answer, id="msg-1")]
)
入出力が標準形式に揃っているため、クライアント側は一般的な LLM API と同じ感覚で呼び出せます。ストリーミング応答が必要な場合は predict_stream() を実装します。ツール呼び出し(3-9)やマルチエージェント構成の途中経過も、この形式の中で表現できます。
インターフェースの選択とは別に、「どうやってログするか」にも選択肢があります。
| 方法 | 内容 | 向いている場合 |
|---|---|---|
pyfunc(mlflow.pyfunc.log_model) | PythonModel / ResponsesAgent を実装してログする | 独自ロジック・複数フレームワーク混在・ガードレール込みの複雑なチェーンやエージェント |
LangChainフレーバー(mlflow.langchain.log_model) | LangChain のチェーンオブジェクトを直接ログする専用フレーバー | チェーンが LangChain(LCEL)で完結している場合 |
| models from code(コードベースロギング) | チェーンを定義したPythonファイルそのものをモデルとしてログする方式 | MLflow 3 の推奨ロギング方式。直列化(pickle)が難しいチェーンでも壊れず、コードがそのまま保存されるためレビューしやすい |
models from code(コードベースロギング)は、チェーンオブジェクトをシリアライズする代わりに「チェーンを定義するコードファイル」を保存し、ロード時にそのコードを実行してチェーンを再構築します。複雑なGenAIチェーンはオブジェクトの直列化が壊れやすいため、MLflow 3 ではこれが推奨ロギング方式です。ResponsesAgent もこの方式でログするのが基本で、エージェントを定義したファイル内で mlflow.models.set_model(SimpleRAGAgent()) のようにモデルを指定し、log_model にはオブジェクトではなくそのファイルのパスを渡します。
モデルシグネチャ(model signature)は、モデルの入力・出力のスキーマ(名前と型)を定義するメタデータです。GenAIのチェーンでは特に重要で、次の役割を持ちます。
シグネチャは input_example(入力例)を渡すと自動推論されます。input_example はドキュメントとしても機能し、ロードしたモデルの動作確認にも使えるため、GenAIモデルでは必ず指定する習慣をつけましょう。なお、ResponsesAgent は入出力形式が標準化されているため、シグネチャが自動的に設定されるのも実務上の利点です。
📝 試験のポイント
「Model Serving にデプロイしたモデルが入力の形式エラーを返す。何を確認・定義すべきか?」という問題ではモデルシグネチャが答えの軸になります。「シグネチャは入出力スキーマを定義し、サービング時のリクエスト検証に使われる」という一文を覚えてください。
モデルをログする際には、実行に必要なライブラリを pip_requirements(または conda 環境)として記録します。サービング環境はノートブックの環境をそのまま引き継がないため、依存関係の記録漏れはデプロイ後のロードエラーの代表的な原因です。databricks-langchain のようなチェーンが使うライブラリは漏れなく列挙します。
ログしたチェーンのその後の流れは次のとおりです(第4章の予告)。
catalog.schema.model_name の3レベル名で登録し、バージョン・権限・リネージを管理また、MLflow 3 には MLflow Tracing が統合されており、チェーン実行の各ステップ(検索・LLM呼び出し・パース)の入出力とレイテンシをトレースとして自動記録できます。mlflow.genai.evaluate による評価やプロンプトレジストリと合わせて、デバッグ・品質分析の基盤になるもので、詳しくは 5-6 で扱います。
✅ この節のまとめ
問1. LangChain と独自のガードレール処理を組み合わせた複雑なRAGチェーンを、任意のPythonロジックを含む形でMLflowモデルとしてログしたい。最も適切な方法はどれか。
正解:A
pyfunc は任意のPythonロジックを predict() インターフェースでラップできる汎用フレーバーで、独自処理を含むチェーンに最適です。Bの log_artifact は単なるファイル保存であり、ロード・サービング可能な「モデル」にはなりません。Cのsklearnフレーバーはscikit-learnモデル専用です。DのGit管理はコードのバージョン管理としては有効ですが、デプロイ可能なモデルアーティファクトの作成にはなりません。なお、対話型エージェントとして開発する場合は、pyfunc の一種である ResponsesAgent を使うのが現行の推奨です。
問2. モデルシグネチャの説明として最も適切なのはどれか。
正解:B
モデルシグネチャは入出力の名前と型を定義するメタデータで、input_example から自動推論できます。サービングエンドポイントはこのスキーマに基づいてリクエストを検証します。A・C・Dはいずれも「署名」という語感からの引っかけで、セキュリティやライセンスとは無関係です。
問3. ノートブックでは正常に動作するチェーンを Model Serving にデプロイしたところ、エンドポイント起動時にライブラリの ImportError が発生した。最も可能性の高い原因はどれか。
正解:B
サービング環境はノートブックのライブラリ環境を引き継がず、モデルと一緒に記録された依存関係定義から環境を構築します。記録漏れがあると起動時に ImportError になります。Aは出力のランダム性の話で起動エラーとは無関係、Cなら実行時のKeyError等になりImportErrorにはなりません、Dなら検索結果が古くなる・取得に失敗するという症状であり、ライブラリのImportErrorは起きません。
問4. チェーンオブジェクトの直列化(シリアライズ)がうまくいかない複雑なGenAIエージェントをMLflowでログしたい。この課題に対応するMLflowの方式はどれか。
正解:A
models from code はオブジェクトの pickle 化の代わりに定義コードを保存し、ロード時にコードを実行してチェーンを再構築するため、直列化の問題を回避できます。MLflow 3 ではこれが推奨ロギング方式です。Bは推論パラメータであり直列化とは無関係です。Cは要件を損なう回避策で解決になっていません。Dのシグネチャ省略は直列化の問題を何も解決せず、サービング時の検証も失われるため悪手です。
問5. ツール呼び出しとストリーミング応答に対応した対話型エージェントを新規に開発し、MLflowでログして Model Serving にデプロイしたい。2026年時点で第一候補となる実装インターフェースはどれか。
正解:A
現行のMLflowでは、エージェント/チェーンの実装インターフェースとして ResponsesAgent が推奨です。OpenAI Responses API 互換の標準形式により、ストリーミング・ツール呼び出し・マルチエージェントに対応し、シグネチャも自動設定されます。Bのsklearnフレーバーはscikit-learn専用です。Cは再現性・バージョン管理・ガバナンスをすべて失います。Dは事実と逆で、従来の PythonModel や ChatAgent も動作はするものの、新規開発の第一候補は ResponsesAgent です。