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つのデモで確認します。
- 自然言語からのPySparkコード生成と実行
- 自然言語からのSQL生成と実行
- 既存コードのレビューとリファクタリング
- ワンショットでのミニダッシュボード (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)
デモ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)
ウィンドウ関数 (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))
デモ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の意図しない使い方になっています。
- 中間変数
resultやoutを用いて手動で状態を管理しているため、コードが冗長になり、バグの混入リスクが高まっています。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))
なお、元の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)
サマリーカード、積み上げ棒グラフ、ドーナツチャートを備えたダークテーマのダッシュボードが、一度の呼び出しで動く形で返ってきました。
まとめ
Databricks Free Editionのdatabricks-glm-5-2エンドポイントを使って、GLM-5.2のコーディング能力を確認しました。
- 日本語の要件からウィンドウ関数を含むPySpark/SQLコードを一発生成し、そのまま実行できた
- アンチパターンだらけのpandasコードの問題点を的確に指摘し、コメントの意図まで汲んでPySparkへ正しくリファクタリングできた
- Chart.jsを使ったダッシュボードHTMLをワンショットで生成できた
準備はクライアントの取得だけ、Free Editionなら無料で試せます。「コーディングに強い」と言われるGLMの実力を手軽に体験できるので、ぜひ試してみてください。
参考リンク
- Databricks Free Edition
- Databricks Foundation Model API
- Foundation Model APIでサポートされるモデル
- 基盤モデルへのクエリ
- GLM-5: China's First Public AI Company Ships a Frontier Model (Hugging Face Blog)




