3
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?

Databricks Free EditionでGLM-5.2のコーディング能力を試す

3
Posted at

GLMとは

GLMは、中国のAI企業Zhipu AI (智譜AI、現在はZ.aiとしてグローバル展開) が開発する大規模言語モデルのシリーズです。清華大学の研究チームを母体とする同社は、2026年1月に香港証券取引所に上場し、中国のAIラボとして初の上場企業となりました。

GLMシリーズはオープンウェイトで公開されることが多く、DeepSeekやQwenと並ぶ「中国発オープンソースLLM」の代表格です。特にコーディングとエージェントタスクに強いことで知られており、Claude Codeなどのコーディングエージェントから使える低価格プラン「GLM Coding Plan」を提供するなど、コーディング用途に注力しています。

本記事で使うGLM-5.2は2026年6月にリリースされた最新モデルで、主なスペックは以下の通りです。

  • 744BパラメータのMoE (Mixture-of-Experts) アーキテクチャ
  • 100万トークンのコンテキストウィンドウ
  • MITライセンスで完全オープンソース (Hugging Faceで公開)
  • 長時間のコーディング・エージェントタスク向けの設計で、Artificial AnalysisのIntelligence IndexではDeepSeek V4 ProやKimi K2.6を上回るスコア

詳しくはHugging Faceのブログ記事などをご覧ください。

Databricks Free EditionでGLM-5.2を試す

こちらのポストで、無料のDatabricks Free EditionでGLM-5.2のエンドポイントdatabricks-glm-5-2が使えることを知りました。実際に試したら動いたので、本記事はその記録です。

エンドポイントを呼ぶだけなので、インフラの準備は一切不要です。なお、執筆時点 (2026年7月11日) ではFoundation Model APIのサポートモデル一覧にGLMの記載はないため、利用可否や仕様は今後変わる可能性があります。

本記事では「GLMならでは」のコーディング能力を、以下の4つのデモで確認します。

  1. 自然言語からのPySparkコード生成と実行
  2. 自然言語からのSQL生成と実行
  3. 既存コードのレビューとリファクタリング
  4. ワンショットでのミニダッシュボード (HTML) 生成

セットアップ

Databricks SDK経由でOpenAI互換クライアントを取得します。トークンやURLの設定は不要です。

%pip install -U openai databricks-sdk
dbutils.library.restartPython()
from databricks.sdk import WorkspaceClient

ENDPOINT = "databricks-glm-5-2"

w = WorkspaceClient()
client = w.serving_endpoints.get_open_ai_client()

なお、実行するとget_open_ai_client()が非推奨である旨の警告が出ます。今後はdatabricks-openaiパッケージのDatabricksOpenAIを使うのが推奨のようですが、本記事ではこのまま進めます。

問い合わせとコードブロック抽出のヘルパー関数を定義しておきます。

import re


def ask_glm(prompt: str, system: str = "あなたは優秀なデータエンジニアです。", temperature: float = 0.0, max_tokens: int = 4000) -> str:
    """GLM-5.2に問い合わせて応答テキストを返す"""
    response = client.chat.completions.create(
        model=ENDPOINT,
        messages=[
            {"role": "system", "content": system},
            {"role": "user", "content": prompt},
        ],
        temperature=temperature,
        max_tokens=max_tokens,
    )
    return response.choices[0].message.content


def extract_code(text: str, lang: str = "python") -> str:
    """応答からコードブロックを抽出する"""
    pattern = rf"```{lang}\s*\n(.*?)```"
    matches = re.findall(pattern, text, re.DOTALL)
    if matches:
        return matches[0].strip()
    # 言語指定なしのコードブロックにフォールバック
    matches = re.findall(r"```\s*\n(.*?)```", text, re.DOTALL)
    return matches[0].strip() if matches else text.strip()

動作確認します。

print(ask_glm("こんにちは!あなたはどんなモデルですか?1文で答えてください。"))
私は優秀なデータエンジニアとして、データパイプラインの設計やデータ基盤の構築を支援するAIモデルです。

システムプロンプトに忠実に「データエンジニア」を名乗ってきました。ちゃんと動いています。

サンプルデータの準備

デモで使う架空の売上データを作成します。

data = [
    ("2026-01-05", "Laptop", "Electronics", 3, 120000),
    ("2026-01-12", "Coffee Beans", "Grocery", 20, 1500),
    ("2026-01-20", "Monitor", "Electronics", 5, 45000),
    ("2026-02-03", "Desk Chair", "Furniture", 2, 30000),
    ("2026-02-14", "Laptop", "Electronics", 4, 120000),
    ("2026-02-21", "Green Tea", "Grocery", 15, 800),
    ("2026-03-02", "Standing Desk", "Furniture", 3, 60000),
    ("2026-03-10", "Keyboard", "Electronics", 10, 8000),
    ("2026-03-18", "Coffee Beans", "Grocery", 25, 1500),
    ("2026-03-25", "Monitor", "Electronics", 7, 45000),
]

sales_df = spark.createDataFrame(
    data, ["order_date", "product", "category", "quantity", "unit_price"]
)
sales_df.createOrReplaceTempView("sales")
display(sales_df)

Screenshot 2026-07-11 at 21.08.23.JPG

デモ1: 自然言語からPySparkコードを生成して実行

日本語の要件だけを渡して、PySparkの変換コードを書かせます。生成されたコードをそのままexec()で実行してみます。

prompt_pyspark = """
`sales_df`という名前のPySpark DataFrameがあります。スキーマは以下の通りです。

- order_date (string, yyyy-MM-dd形式)
- product (string)
- category (string)
- quantity (long)
- unit_price (long)

以下の処理を行うPySparkコードを書いてください。

1. 売上金額 (quantity * unit_price) をrevenue列として追加
2. 月 (yyyy-MM) とcategoryごとにrevenueを集計し、total_revenue列とする
3. カテゴリごとに月次売上の前月比増減率をgrowth_rate列 (パーセント、小数点1桁) として追加
4. 結果を月、カテゴリの昇順でソートし、`result_df`という変数に格納

制約:
- `sales_df`と`spark`は定義済みとして使うこと
- import文を含む完全なコードにすること
- コードのみをpythonコードブロックで出力し、説明は不要
"""

answer = ask_glm(prompt_pyspark)
generated_code = extract_code(answer)
print(generated_code)

GLM-5.2が生成したコードがこちらです。

from pyspark.sql.functions import col, substring, sum as _sum, lag, round
from pyspark.sql.window import Window

# 1. 売上金額 (quantity * unit_price) をrevenue列として追加
df = sales_df.withColumn("revenue", col("quantity") * col("unit_price"))

# 2. 月 (yyyy-MM) とcategoryごとにrevenueを集計し、total_revenue列とする
df = df.withColumn("month", substring(col("order_date"), 1, 7))
monthly_df = df.groupBy("month", "category").agg(_sum("revenue").alias("total_revenue"))

# 3. カテゴリごとに月次売上の前月比増減率をgrowth_rate列 (パーセント、小数点1桁) として追加
window_spec = Window.partitionBy("category").orderBy("month")
result_df = monthly_df.withColumn("prev_revenue", lag("total_revenue").over(window_spec)) \
    .withColumn(
        "growth_rate",
        round((col("total_revenue") - col("prev_revenue")) / col("prev_revenue") * 100, 1)
    ) \
    .drop("prev_revenue")

# 4. 結果を月、カテゴリの昇順でソートし、result_dfという変数に格納
result_df = result_df.orderBy("month", "category")

sum_sumとしてimportして組み込み関数との衝突を避けたり、要件の番号をコメントとして残したりと、丁寧なコードです。そのまま実行します。

exec(generated_code)
display(result_df)

Screenshot 2026-07-11 at 21.09.08.JPG

ウィンドウ関数 (lag) を使った前月比計算まで、一発で動くコードが返ってきました。

デモ2: 自然言語からSQLを生成して実行

テーブル定義を渡してSQLを書かせ、spark.sql()で実行します。

prompt_sql = """
一時ビュー`sales`があります。列: order_date (string, yyyy-MM-dd), product, category, quantity, unit_price。

「カテゴリごとに、最も売上金額 (quantity * unit_price の合計) が大きい商品トップ1とその売上金額、カテゴリ内売上シェア (%) を求める」
Spark SQLを書いてください。SQLのみをsqlコードブロックで出力してください。
"""

answer = ask_glm(prompt_sql)
generated_sql = extract_code(answer, lang="sql")
print(generated_sql)

生成されたSQLがこちらです。

WITH product_sales AS (
    SELECT
        category,
        product,
        SUM(quantity * unit_price) AS total_sales
    FROM sales
    GROUP BY category, product
),
ranked_products AS (
    SELECT
        category,
        product,
        total_sales,
        SUM(total_sales) OVER (PARTITION BY category) AS category_total_sales,
        ROW_NUMBER() OVER (PARTITION BY category ORDER BY total_sales DESC) AS rn
    FROM product_sales
)
SELECT
    category,
    product,
    total_sales,
    (total_sales / category_total_sales) * 100 AS sales_share_pct
FROM ranked_products
WHERE rn = 1;

CTEとROW_NUMBER、パーティション単位のSUM() OVERを組み合わせた、教科書のようなSQLです。実行結果は以下の通りです。

display(spark.sql(generated_sql))

Screenshot 2026-07-11 at 21.09.43.JPG

デモ3: コードレビューとリファクタリング

悪い書き方をしたpandasコードを渡して、問題点の指摘とPySparkへの書き換えをさせます。コードの意図を読み取る力と、Sparkのベストプラクティスの知識が問われるタスクです。

messy_code = '''
import pandas as pd

def proc(df):
    df2 = df.copy()
    result = []
    for i in range(len(df2)):
        row = df2.iloc[i]
        rev = row["quantity"] * row["unit_price"]
        if row["category"] == "Electronics":
            rev = rev * 0.9  # 10%割引
        result.append(rev)
    df2["rev"] = result
    out = {}
    for i in range(len(df2)):
        c = df2.iloc[i]["category"]
        if c not in out:
            out[c] = 0
        out[c] += df2.iloc[i]["rev"]
    return out
'''

prompt_review = f"""
以下のpandasコードをレビューしてください。

```
{messy_code}
```

次の形式で回答してください。

1. 問題点の指摘 (パフォーマンス、可読性の観点で箇条書き)
2. 同じロジックをPySparkで実装したコード (関数`proc_spark(df)`として、集計結果のDataFrameを返す)

PySparkコードはpythonコードブロックで出力してください。
"""

answer = ask_glm(prompt_review, max_tokens=6000)
print(answer)

GLM-5.2のレビュー結果 (抜粋) です。

パフォーマンスの観点

  • for i in range(len(df2))df2.iloc[i] を用いた行ごとのループ処理は、pandasのベクトル化された演算を活用していないため、データサイズが大きくなるほど処理速度が著しく低下します (アンチパターン)。
  • カテゴリごとの集計処理も同様にループと辞書を用いた手動集計を行っており、groupby 演算子を使用しないことで不要なオーバーヘッドが発生しています。

可読性の観点

  • pandasのDataFrameに対して、あたかも標準のPythonリストのように行単位でのアクセスと更新を行っており、pandasのAPIの意図しない使い方になっています。
  • 中間変数 resultout を用いて手動で状態を管理しているため、コードが冗長になり、バグの混入リスクが高まっています。
  • df2.iloc[i]["category"] のようなチェーンインデックスは、意図しない SettingWithCopyWarning を引き起こす可能性があり、推奨されません。

行ループのアンチパターン、groupby不使用、チェーンインデックスまで的確に指摘してきました。リファクタリングされたPySpark版がこちらです。

from pyspark.sql import DataFrame
from pyspark.sql import functions as F

def proc_spark(df: DataFrame) -> DataFrame:
    # 売上の計算
    df_with_rev = df.withColumn(
        "rev",
        F.col("quantity") * F.col("unit_price")
    )

    # Electronicsカテゴリの場合は10%割引を適用
    df_with_rev = df_with_rev.withColumn(
        "rev",
        F.when(F.col("category") == "Electronics", F.col("rev") * 0.9)
         .otherwise(F.col("rev"))
    )

    # カテゴリごとの集計
    result_df = df_with_rev.groupBy("category").agg(
        F.sum("rev").alias("rev")
    )

    return result_df

「Electronicsは10%割引」というコメントからロジックの意図を読み取り、F.when()で正しく再現しています。実行します。

refactored_code = extract_code(answer)
exec(refactored_code)
display(proc_spark(sales_df))

Screenshot 2026-07-11 at 21.16.09.JPG

なお、元のpandasコードのproc()を同じデータで実行すると{'Electronics': 1314000.0, 'Grocery': 79500.0, 'Furniture': 240000.0}が返り、PySpark版と一致します。

デモ4: ワンショットでミニダッシュボードを生成

最後に、デモ1の集計結果を渡して、単一HTMLのダッシュボードをワンショットで生成させ、displayHTML()で表示します。フロントエンドコードの一発生成はGLM-5.2が得意とするところです。

summary_json = result_df.toPandas().to_json(orient="records", force_ascii=False)

prompt_dashboard = f"""
以下のJSONは月次・カテゴリ別の売上集計データです。

{summary_json}

このデータを可視化するダッシュボードを単一のHTMLファイルとして作成してください。

要件:
- Chart.js (CDN: https://cdn.jsdelivr.net/npm/chart.js) を使用
- 月別売上の積み上げ棒グラフ (カテゴリ別に色分け) と、カテゴリ別売上構成のドーナツチャートを横に並べる
- 上部に総売上、最大カテゴリなどのサマリーカードを表示
- ダークテーマのモダンなデザイン
- データはHTML内にハードコード
- HTMLのみをhtmlコードブロックで出力
"""

answer = ask_glm(prompt_dashboard, max_tokens=8000)
dashboard_html = extract_code(answer, lang="html")
displayHTML(dashboard_html)

Screenshot 2026-07-11 at 21.20.48.JPG

サマリーカード、積み上げ棒グラフ、ドーナツチャートを備えたダークテーマのダッシュボードが、一度の呼び出しで動く形で返ってきました。

まとめ

Databricks Free Editionのdatabricks-glm-5-2エンドポイントを使って、GLM-5.2のコーディング能力を確認しました。

  • 日本語の要件からウィンドウ関数を含むPySpark/SQLコードを一発生成し、そのまま実行できた
  • アンチパターンだらけのpandasコードの問題点を的確に指摘し、コメントの意図まで汲んでPySparkへ正しくリファクタリングできた
  • Chart.jsを使ったダッシュボードHTMLをワンショットで生成できた

準備はクライアントの取得だけ、Free Editionなら無料で試せます。「コーディングに強い」と言われるGLMの実力を手軽に体験できるので、ぜひ試してみてください。

参考リンク

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

3
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
3
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?