こんにちは。
開発本部のデータ&AIチームでデータサイエンティストをしている古濵です。
最近はAIプロダクト開発をメインで担当しています。 今回は、Databricks Asset Bundlesを活用して、AIプロダクト開発向けにCI/CDパイプラインを整備した内容をまとめます。
Databricks Asset Bundlesとは
Databricks Asset Bundlesは、データやAIプロジェクトでソフトウェア開発におけるソース管理、コードレビュー、テスト、CI/CDなどを導入しやすくするツールです。 簡単に言えば、Databricksの各種リソースをInfrastructure-as-Code(IaC)として管理できます。 ノートブックをはじめとするソースコードやDatabricks上で動かすJobなどのリソースを、ymlファイルで定義できます。

動機
社内の多くのDatabricks用途は、メダリオンアーキテクチャを踏襲したデータ基盤です。 例えば、ダッシュボードで参照するデータのETL、A/Bテスト結果の集計、バッチ推論ベースのMLモデルの学習・推論・デプロイなどがあります。
一方でAIプロダクト文脈では、モデルの学習はバッチ処理ですが、推論はリアルタイム処理、モデルのデプロイ(Model Servingの機能を利用)はソースコードを更新したタイミングなことが多いのではないでしょうか。 特にLLMの場合は、OpenAIなどのAPIを利用することが多いため、モデルの学習自体不要です。 つまり、推論とデプロイに重点を置いた開発がメインになります。 この開発・運用上のギャップを埋めたい思いがありました。
これらのギャップを、As-Is(現状)とTo-Be(理想)としてまとめると以下のようになりました。
No. | 項目 | As-Is | To-Be | 理由 |
---|---|---|---|---|
1 | ソースコード管理 | pythonノートブック | pythonファイル | コードの再現性・テストの導入のしやすさを目指し、モジュール単位でコード管理したいため |
2 | ワークスペース | Default workspace(ap-northeast-1)のみ | Default workspace(ap-northeast-1)とTest workspace(us-east-1) | 推論にLLMを利用することが多く、LLMに対する評価のフィードバックを得ながら開発・運用したいため(us-east-1の方がアップデートが早く、LLMを評価する機能が利用可能) |
3 | 処理タイミング | スケジューリングされたバッチ処理 | githubのpushをトリガーとした処理 | CI/CDパイプラインを用いて、テストの実行、モデルの保存と評価、Model Servingへのデプロイを自動化したいため |
全体像
図1を参考に、今回のsample-project用のCI/CDパイプラインを作成しました(図2)。 右上のDatabricks workspacesを一部変更しています。
ワークスペースは2つのregion(ap-northeast-1、us-east-1)を利用します。
- Default workspace(ap-northeast-1)
- Test workspace(us-east-1)

コードは以下のような構成で進めます。
sample-project ├── .github │ └── workflows │ ├── _deploy_databricks.yml │ └── sample_project_cd.yml ├── bundles │ ├── resources │ │ └── job_deploy_sample_project_model.yml │ └── targets │ ├── default_databricks.yml │ └── test_databricks.yml ├── src │ ├── sample_project │ │ ├── __init__.py │ │ ├── pipeline.py │ │ ├── rag.py │ │ └── model.py │ └── deploy_model.py ├── tests └── databricks.yml
実装してみる
1. pythonファイルによるソースコード管理
モジュール
メイン機能となるモジュール群はsrc/sample_project/*
に置きます。
rag.py
RAGの機能を有したモジュールを定義します。 今回は、シンプルなRAGクラスを定義し、OpenAIのAPIを利用して回答を生成するコードを記述しています。
from openai import OpenAI class RAG: def __init__(self): self.llm = OpenAI() def generate(self, query, contexts): context_str = "\n".join([f"- {context['content']}" for context in contexts]) messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": f"Context:\n{context_str}\n\nQuery: {query}"}, ] completion = self.llm.chat.completions.create( model="gpt-4o-mini", messages=messages, ) answer = completion.choices[0].message.content return answer def retrieve(self, query): query_embedding = self.llm.embeddings.create( input=query, model="text-embedding-3-large", ) contexts = self.retieve_databricks_vector_store(query_embedding) return contexts def retieve_databricks_vector_store(self, query_embedding): # query_embeddingをもとにベクトル検索したコンテキスト情報を返す # ここではダミーのコンテキスト情報を返す contexts = [ {"doc_uri": "doc1.txt", "content": "In 2013, Spark, a data analytics framework, was open sourced by UC Berkeley's AMPLab."}, {"doc_uri": "doc2.txt", "content": "To convert a Spark DataFrame to Pandas, you can use toPandas()"}, ] return contexts
pipeline.py
ユーザのクエリを受け取り、LLMの回答を返すパイプラインを定義します。
from sample_project.rag import RAG def generate_answer(query): rag = RAG() contexts = rag.retrieve(query) answer = rag.generate(query, contexts) return answer
model.py
pipelineを利用するmlflow.pyfunc.PythonModelを継承したクラスを定義します。 このクラスは、モデルの保存時に指定することで、python modelとしてMLflowのモデルとして保存され、Model Servingで利用できるようになります。
import mlflow from sample_project.pipeline import generate_answer class SampleAI(mlflow.pyfunc.PythonModel): def predict(self, context, model_input): query = model_input['query'][0] return generate_answer(query)
テスト
テストはtests/*
に置きます。
LLMによる生成が絡む処理のテストは難しいですが、前処理や後処理などのテスト可能なコードに対しては単体テスト書く想定です。
今回のサンプルコードでは前処理や後処理はないですが、要件が複雑化していくと必要になってくるかと思います。
今までの開発では、ノートブックかつDatabricksのコンソール上での開発だったため、モジュール単位の実装やテストコードが書きづらい問題がありました。 しかし、pythonファイルによるモジュール化ができたことで、モジュール単位に実装が容易になりました。 これにより、コーディングや単体テストはローカルで行い、Spark、Mlflow、Unity CatalogなどDatabricksのメイン機能を利用する開発はコンソール上で行う、といった開発フローができるようになりました。
モデルの保存と評価
モデルの保存と評価はdeploy_model.py
に記述します。
このコードは例外的にノートブックで管理します。
理由としては
- 将来的に自作のパッケージをinstallするとき、動的に
pip install
できることが便利なため - MLflow Tracingを利用したため
などがあります。
色々記述していますが、重要なのはmlflow.start_run()
で実行される、モデルの保存と評価コードです。
保存
mlflow.pyfunc.log_model
で、モデルの保存をしています。
このとき引数にcode_pathsを指定することで、モデルと一緒に該当のソースコードを保存することができます。
注意点として、MLflowのドキュメントにある通り、code_pathsは親ディレクトリを見ることができない仕様になっているようです。
そのため、以下のようなディレクトリ構成にし、code_paths=["sample_project"]
を指定しています。
├── sample_project └── deploy_model.py
この問題に関しては、MLflowのIssueでも言及されており、今後仕様が変わる可能性があります。
評価
mlflow.evaluate
で、モデルの評価をしています。
このとき、model_type="databricks-agent"
を指定することで、Mosaic AI Agent Evaluationに組み込まれているAI審査員機能(一般的にはLLM as a Judgeと呼ばれる審査員用のLLMがプロダクトのLLMを評価する機能)を利用することができます。
今回は以下のAI審査員を指定しています。
- correctness: エージェントの実際の応答がground truth(expected_response)と比較して誤っていないことを保証
- relevance_to_query: エージェントの応答が無関係なトピックに逸脱することなくユーザーの入力に直接対処することを保証
- safety: エージェントの応答に有害、攻撃的、または有毒な内容が含まれていないことを保証
%load_ext autoreload %autoreload 2 # COMMAND ---------- %pip install --upgrade mlflow cloudpickle databricks-vectorsearch databricks-agents openai tiktoken %restart_python # COMMAND ---------- dbutils.widgets.text("model_env", "dev") dbutils.widgets.text("workspace_url", "https://{sub-domain}.cloud.databricks.com") model_env = dbutils.widgets.get("model_env") workspace_url = dbutils.widgets.get("workspace_url") # COMMAND ---------- import os os.environ["OPENAI_API_KEY"] = dbutils.secrets.get(...) os.environ["DATABRICKS_VECTOR_SEARCH_HOST"] = "https://{sub-domain}.cloud.databricks.com" os.environ["DATABRICKS_VECTOR_SEARCH_TOKEN"] = dbutils.secrets.get(...) # COMMAND ---------- import mlflow from sample_project.model import SampleAI # DatabricksのUnity Catalogを利用するための設定 mlflow.set_registry_uri("databricks-uc") # COMMAND ---------- # Unity Catalogで登録するモデル名 model_name = ( "{catalog}.{schema}.sample_project_model" if model_env == "prd" else "{catalog_dev}.{schema}.sample_project_model" ) # 実験管理先を設定 mlflow_experiment_name = '/Shared/experiments/sample_project' mlflow.set_experiment(mlflow_experiment_name) # COMMAND ---------- from mlflow.models import ModelSignature from mlflow.types.schema import Schema, ColSpec input_schema = Schema([ColSpec("string", "query")]) output_schema = Schema([ColSpec("string", "answer")]) signature = ModelSignature(inputs=input_schema, outputs=output_schema) # COMMAND ---------- # https://docs.databricks.com/ja/generative-ai/agent-evaluation/index.html # 今回は評価データは直に書く import pandas as pd eval_df = pd.DataFrame({ "request": [ {"query": "What is Spark?"}, {"query": "How do I convert a Spark DataFrame to Pandas?"} ], "expected_response": [ "Spark is a data analytics framework.", "To convert a Spark DataFrame to Pandas, you can use the toPandas() method.", ] }) display(eval_df) # COMMAND ---------- # モデルの保存・評価 with mlflow.start_run(): model_info = mlflow.pyfunc.log_model( artifact_path="model", python_model=SampleAI(), signature=signature, registered_model_name=model_name, code_paths=["sample_project"], ) # test-databricks環境でのみ評価 if "test" in workspace_url: mlflow.evaluate( model=generate_answer, data=eval_df, model_type="databricks-agent", evaluator_config={ "databricks-agent": { "metrics": [ "correctness", "relevance_to_query", "safety", ] } } )
2. 複数のregionに分けてワークスペースを運用
図1をはじめ、Databricksのドキュメントでは、Development、Staging、Productionごとにワークスペースを分けた運用例が多いです。
しかし、弊社では、1つのワークスペースでdev/prdをwidgetsで切り替えて運用しているケースがほとんどです。
例えば、
dbutils.widgets.text("model_env", "dev")
と書くと、model_envという名前のwidgetsが作成され、
model_env = dbutils.widgets.get("model_env")
と書くと、model_envの値を取得できます。
以降、model_envの値によって参照するデータソースを変えるなど、処理の分岐をさせることができます。
Databricks Asset Bundlesは、上記のようなケースでも柔軟に対応することができました。
ここでは、冒頭の全体像で述べたようにDefault workspaceとTest workspaceの2つのワークスペースを利用します。
Default workspace: 主要なワークスペースで、regionはap-northeast-1を使用。 Model ServingやVector Storeなどを運用する。
Test workspace: テスト用のワークスペースで、regionはus-east-1を使用。 モデルの保存時に、AI審査員によるLLMの評価を行う。
ここではDevelopment、Staging、Productionを、それぞれdev
、stage
、prd
とし、以下のような意味を持つとします。
図2と合わせて参照ください。
dev
: 個人開発用。 ワークスペースのName(自分の名前)ディレクトリに反映される。 ローカルから、コードやJobの設定などのリソースをデプロイするときに使用する。stage
: 開発用。 ワークスペースのStagingディレクトリに反映される。 作業ブランチ→developブランチにpushした時に、CI/CDでコードやJobの設定などのリソースをデプロイするときに使用する。prd
: 本番用。 ワークスペースのProductionディレクトリに反映される。 developブランチ→masterブランチにpushした時に、CI/CDでコードやJobの設定などのリソースをデプロイするときに使用する。
.databrickscfg
~/.databrickscfg
にワークスペースの設定を記述します。
この例では、パーソナルアクセストークン(PAT)の認証方法を利用しています。
databricksの認証に関しての詳細はこちらを参照してください。
[DEFAULT] host = https://{default-databricks-subdomain}.cloud.databricks.com token = dapi11111111111111111111111111111111 [TEST] host = https://{test-databricks-subdomain}.cloud.databricks.com token = dapi22222222222222222222222222222222
databricks.yml
Databricks Asset Bundlesの各種設定をdatabricks.yml
に記述します。
ここでは、ymlファイルの見通しをよくするために、resourcesとtargetsを別のファイルに分離しています。
dev
、stage
、prd
のpathは、それぞれは使いまわしやすいようにvariablesに定義しています。
bundle: name: sample-project variables: dev_file_path: description: "The path to the development" default: /Repos/${workspace.current_user.userName}/${bundle.name} stage_file_path: description: "The path to the staging" default: /Repos/Staging/${bundle.name} prd_file_path: description: "The path to the production" default: /Repos/Production/${bundle.name} run_as: user_name: ${workspace.current_user.userName} include: - "bundle/resources/*.yml" - "bundle/targets/*.yml"
resources
JobなどのDatabricksのリソースを定義するファイルをresources/*.yml
に記述します。
他にも設定できるリソースに関してはこちらを参照してください。
resourcesの設定は全てのtargetsで共通のため、defaultではdev
の設定で記述します。
これらの設定は、targetsの設定で上書きすることができます。
ここでは、モデルの保存と評価を実行するdeploy_sample_project_model
というJobを定義しています。
このJobを実行することで、モデルの保存と評価をCI/CDのパイプラインに組み込むことができます。
resources: jobs: deploy_sample_project_model: name: deploy_sample_project_model tasks: - task_key: deploy_model notebook_task: notebook_path: ${var.dev_file_path}/src/deploy_model source: WORKSPACE base_parameters: model_env: dev workspace_url: "{{workspace.url}}" job_cluster_key: deploy_model_cluster job_clusters: - job_cluster_key: deploy_model_cluster new_cluster: spark_version: 15.4.x-cpu-ml-scala2.12 aws_attributes: first_on_demand: 0 availability: SPOT zone_id: auto instance_profile_arn: arn:aws:iam::123456789101:instance-profile/databricks_shared-instance-profile spot_bid_price_percent: 100 ebs_volume_count: 0 node_type_id: r7gd.large enable_elastic_disk: false data_security_mode: SINGLE_USER runtime_engine: STANDARD autoscale: min_workers: 1 max_workers: 2 permissions: - group_name: dai-engineer level: CAN_MANAGE queue: enabled: false
targets
各環境ごとの設定をtargets/*.yml
に記述します。
ここでは、Default workspace(default_databricks)と Test workspace(test_databricks)の設定を記述しています。
default_databricks.yml
dev
、stage
、prd
の3つの環境を定義しています。
dev
をdefaultに設定し、stage
とprd
の設定は必要な箇所を上書きしています。
run_as
- CI/CD用のサービスプリンシパルを指定
- 指定するサービスプリンシパルは
stage
とprd
で同様
resources
- jobの設定を上書き
stage
では、notebook_pathを開発用に上書きprd
では、notebook_pathとbase_parametersを本番用に上書き
targets: dev: mode: development default: true workspace: host: https://{default-databricks-subdomain}.cloud.databricks.com file_path: ${var.dev_file_path} stage: mode: production workspace: host: https://{default-databricks-subdomain}.cloud.databricks.com file_path: ${var.stage_file_path} run_as: service_principal_name: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" resources: jobs: deploy_sample_project_model: name: "[${bundle.target}] deploy_sample_project_model" # notebook_pathを開発用に上書き tasks: - task_key: deploy_model notebook_task: notebook_path: ${var.stage_file_path}/src/deploy_model source: WORKSPACE prd: mode: production workspace: host: https://{default-databricks-subdomain}.cloud.databricks.com file_path: ${var.prd_file_path} run_as: service_principal_name: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" resources: jobs: deploy_sample_project_model: name: deploy_sample_project_model # notebook_pathとbase_parametersを本番用に上書き tasks: - task_key: deploy_model notebook_task: notebook_path: ${var.prd_file_path}/src/deploy_model source: WORKSPACE base_parameters: model_env: prd workspace_url: "{{workspace.url}}"
test_databricks.yml
default_databricks.yml
とほとんど同じ設定です。
Test workspace固有の設定をする場合、こちらに記述します。
targets: test-dev: mode: development workspace: host: https://{test-databricks-subdomain}.cloud.databricks.com file_path: ${var.dev_file_path} test-stage: mode: production workspace: host: https://{test-databricks-subdomain}.cloud.databricks.com file_path: ${var.stage_file_path} run_as: service_principal_name: "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" resources: jobs: deploy_sample_project_model: # notebook_pathを開発用に上書き name: "[${bundle.target}] deploy_sample_project_model" tasks: - task_key: deploy_model notebook_task: notebook_path: ${var.stage_file_path}/src/deploy_model source: WORKSPACE test-prd: mode: production workspace: host: https://{test-databricks-subdomain}.cloud.databricks.com file_path: ${var.prd_file_path} run_as: service_principal_name: "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy" resources: jobs: deploy_sample_project_model: # notebook_pathとbase_parametersを本番用に上書き name: deploy_sample_project_model tasks: - task_key: deploy_model notebook_task: notebook_path: ${var.prd_file_path}/src/deploy_model source: WORKSPACE base_parameters: model_env: prd workspace_url: "{{workspace.url}}"
3. pushのタイミングで処理を実行
sample_project_cd.yml
CI/CDのパイプラインをGithub Actionsでsample_project_cd.yml
に記述します(テストなどはsample_projet_ci.yml
を追加想定)。
このパイプラインは、developブランチとmasterブランチに、それぞれpushされたタイミングで処理します。
dev
は個人開発用のため、CI/CDのパイプラインではstage
とprd
のみ記述します。
name: CD sample-project on: push: branches: - master - develop jobs: deploy_test_stage: if: ${{ github.ref_name == 'develop' }} uses: ./.github/workflows/_deploy_databricks.yml with: targets: test-stage deploy_model_name: deploy_sample_project_model secrets: DATABRICKS_CLIENT_ID: ${{ secrets.TEST_DATABRICKS_CLIENT_ID }} DATABRICKS_SECRET: ${{ secrets.TEST_DATABRICKS_SECRET }} deploy_stage: if: ${{ github.ref_name == 'develop' }} uses: ./.github/workflows/_deploy_databricks.yml with: targets: stage deploy_model_name: deploy_sample_project_model secrets: DATABRICKS_CLIENT_ID: ${{ secrets.DEFAULT_DATABRICKS_CLIENT_ID }} DATABRICKS_SECRET: ${{ secrets.DEFAULT_DATABRICKS_SECRET }} deploy_test_prd: if: ${{ github.ref_name == 'master' }} uses: ./.github/workflows/_deploy_databricks.yml with: targets: test-prd deploy_model_name: deploy_sample_project_model secrets: DATABRICKS_CLIENT_ID: ${{ secrets.TEST_DATABRICKS_CLIENT_ID }} DATABRICKS_SECRET: ${{ secrets.TEST_DATABRICKS_SECRET }} deploy_prd: if: ${{ github.ref_name == 'master' }} uses: ./.github/workflows/_deploy_databricks.yml with: targets: prd deploy_model_name: deploy_sample_project_model secrets: DATABRICKS_CLIENT_ID: ${{ secrets.DEFAULT_DATABRICKS_CLIENT_ID }} DATABRICKS_SECRET: ${{ secrets.DEFAULT_DATABRICKS_SECRET }}
_deploy_databricks.yml
sample_project_cd.yml
で利用するデプロイのパイプラインを_deploy_databricks.yml
に記述します。
このパイプラインは、databricks/setup-cli
を利用し、Databricks Asset Bundleを使ってリソースをデプロイします。
databricks bundle deploy
でリソースをデプロイし、databricks bundle run
でデプロイしたコードをJobとして実行します。
name: deploy databricks on: workflow_call: inputs: targets: required: true type: string deploy_model_name: required: true type: string secrets: DATABRICKS_CLIENT_ID: required: true # service_principal_nameと同じ DATABRICKS_SECRET: required: true jobs: deploy_resources: name: "Deploy resources" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: databricks/setup-cli@main - run: databricks bundle deploy -t ${{ inputs.targets }} working-directory: . env: DATABRICKS_CLIENT_ID: ${{ secrets.DATABRICKS_CLIENT_ID }} DATABRICKS_CLIENT_SECRET: ${{ secrets.DATABRICKS_SECRET }} deploy_model: name: "Deploy model" runs-on: ubuntu-latest needs: - deploy_code steps: - uses: actions/checkout@v4 - uses: databricks/setup-cli@main - run: databricks bundle run ${{ inputs.deploy_model_name }} -t ${{ inputs.targets }} working-directory: . env: DATABRICKS_CLIENT_ID: ${{ secrets.DATABRICKS_CLIENT_ID }} DATABRICKS_CLIENT_SECRET: ${{ secrets.DATABRICKS_SECRET }}
結果
Jobの実行結果
test_databricks.ymlの設定を利用する場合は、targetsにはtest-dev
、test-stage
、test-prd
などを指定します。
test-dev
はローカルから、test-stage
とtest-prd
はGithub Actionsから実行します。
そのため、Created byを見ると、test-dev
のみユーザ名であり、test-stage
とtest-prd
はCI/CDのサービスプリンシパル名であることが確認できます(図3)。

Jobの画面に進むと実行結果も確認できます(図4)。 resourcesに記述した各種設定内容もここで確認できます。 正直、Jobの設定をコード管理できるという時点で感無量です。

モデルの評価の結果
モデルの評価結果は、mlflow.evaluate
で指定したAI審査員によって判定されます。
今回評価データとして設定した、「What is Spark?」と「How do I convert a Spark DataFrame to Pandas?」は、contextに含まれるため、AI審査員をPassすることができました(図5)。

AI審査員の評価結果の詳細は以下のとおりです(図6)。 Responseに書かれているModel outputとExpected outputの文章は一致していなくても、回答の文脈として合っているかで評価されていることがわかります。
Correct
期待される回答は「Sparkはデータ分析フレームワークである」と述べている。 回答はSparkを「暗黙のデータ並列性とフォールトトレランスを備えたクラスタ全体をプログラミングするためのインタフェースを提供するオープンソースのデータ処理フレームワーク」と説明している。 回答では「データ分析フレームワーク」という用語は明確に使われていないが、SQLクエリ、機械学習、グラフ処理、ストリーム処理などのタスクを含むデータ処理のために設計されたフレームワークとしてSparkを説明している。 これらのタスクは一般的にデータ分析に関連している。したがって、期待される回答がサポートされている。
Relevant
質問は「Sparkとは何か?回答は、Sparkの目的、起源、特徴、サポートされているプログラミング言語など、Sparkとは何かについて詳しく説明している。 解答のすべての部分が、Sparkとは何かを理解するのに関連している。
Safe
回答に有害なコンテンツが検出されない

ここで、contextになく、gpt-4o-miniの学習データに含まれない、最新の情報を問う質問を評価データに加えてみることにします。 今回は、巷で話題の2025/02/02に発表されたOpenAIのDeep researchに関して質問してみます。 ground truthであるexpected_responseの文章は、発表時の文章をgpt-4oで要約させて作成しました。
eval_df = pd.DataFrame({ "request": [ {"query": "What is Spark?"}, {"query": "How do I convert a Spark DataFrame to Pandas?"}, {"query": "What is Deep research"}, ], "expected_response": [ "Spark is a data analytics framework.", "To convert a Spark DataFrame to Pandas, you can use the toPandas() method.", "Deep research is a ChatGPT feature that autonomously conducts multi-step web research, generating detailed, cited reports in minutes. It’s ideal for in-depth inquiries, leveraging OpenAI’s o3 model for advanced analysis and synthesis.", ] })
図7からわかるとおり「What Is Deep research」というクエリで、CorrectnessがFailとなりました。 「Deep research」を「深掘った調査」という意味合いとして回答してしまっています。

Deep researchに関して質問した場合のAI審査員の評価結果の詳細は以下のとおりです(図8)。 なぜFailとなったかを説明してくれています。
Incorrent
Deep researchはChatGPTの機能で、多段階のweb調査を自律的に行い、詳細な引用レポートを数分で作成する。 OpenAIのo3モデルを活用し、高度な分析と合成を行うため、詳細な調査に最適である。 この回答では、「Deep research」とは、広範なデータ収集と分析、批判的思考、情報の統合を含む、特定の分野における徹底的かつ集中的な調査または研究であると説明している。 これには、包括的な文献調査、方法論の厳密さ、革新的な問題解決、学際的アプローチ、縦断的研究、知識への貢献などが含まれる。 この回答には、ChatGPT、自律的なweb調査、数分でレポートを作成すること、OpenAIのo3モデルの活用については何も言及されていない。したがって、期待される回答は回答によってサポートされていない。
Relevant
設問は「Deep research」について尋ねており、回答は、包括的な文献レビュー、方法論の厳密さ、革新的な問題解決、学際的アプローチ、縦断的研究、知識への貢献といった側面を含む、深い研究とは何かを詳細に説明している。 これらの点はすべて、深い研究とは何かを理解するのに関連している。
Safe
回答に有害なコンテンツは検出されない

なお、RelevanceやSafetyをPassしているのは、expected_responseと比較して評価していないためです。 「Deep research」を「深掘った調査」と回答したとしても、質問の回答としては関連性がある答えのため、RelevanceをPassしているのだと考えられます。
おわりに
Databricks Asset Bundlesを使って、モデルの保存と評価をCI/CDパイプラインとして組み込むまでの一連の流れを紹介しました。
今回はモデルのデプロイの自動化に関しては取り組めませんでした。
ここも、Model Servingへのデプロイ処理をdeploy_model_serving.py
のように作成し、Jobに設定を追加するようにすれば、同様のパイプラインを組み込むことができると思います。
モデルの評価では、AI審査員について紹介しました。 個人的に、このLLMの評価を実運用に乗せるには、各AI審査員がどのような評価しているかの特性に対して理解が必要だと感じました。 他にもretrieval観点で評価するAI審査員もおり、LLMの評価には様々な観点を考える必要がありそうです。 LLMの評価に関しては、また別の機会にまとめたいと思います。
また、今回は日本語で評価しませんでしたが、日本語でも概ね精度は変わらない印象です。 ただ、AI審査員の回答は英語のため、Pass/Failとなった説明に日本語と英語が入り混じることになり、文章として読みづらい感は否めません。 ap-northeast-1のパブリックプレビューと同時に、日本語で回答するAI審査員の登場に期待です。