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

GLM-5.3-FlashをNode.jsから使う:画像の集計・確率問題・HTML生成で分かったこと

0
Posted at

GLM-5.3-Flashは、ZhipuのGLMシリーズに属するモデルです。Z.aiの公式ドキュメントでは、FlashとFlashXを画像、コード、文書などを扱うマルチモーダルモデルとして紹介しています。

用途の説明だけでは、自分の作業のどこに使えるかは判断しにくいところです。そこで私は2026年10月30日、Crazyrouter経由でglm-5.3-flashに、画像内の登録データの集計、条件付き確率の計算、割り勘用HTMLの生成を依頼しました。画像と確率の回答は独立に用意した答えと一致し、HTMLは最初の出力が途切れ、再リクエストで完全なコードを取得できました。

この記事では、モデルの位置付けからAPIの呼び出し方まで紹介します。APIを初めて試す人でも追えるよう、Node.jsだけで実行する例を載せます。元の実測は簡体字中国語で行っており、日本語の応答品質を測った記事ではありません。

GLM-5.3-Flashが受け取るものと、返すもの

Flashの出力はテキストです。入力に画像などを含められることと、モデル単体でファイルを保存したりブラウザを操作したりできることは分けて考える必要があります。

BigModel公式ページに掲載された入力形式とテキスト出力の説明

BigModel公式ページの実際のスクリーンショットから、入力と出力の説明部分を切り出したものです。左側は動画・画像・テキスト・ファイル、右側はテキスト出力を示しています。中国語の原文を残しています。すべての入力形式を今回検証したわけではありません。

たとえば、回答にHTMLが含まれていても、保存して実行する工程は別にあります。画面操作なら、モデルが使えるブラウザや操作ツールも必要です。今回モデルに外部ツールは渡していません。回答に含まれたコードは、受け取った後で私が別途実行しました。

また、FlashとFlashXは区別します。今回のモデルIDはglm-5.3-flashで、FlashXは未検証です。GLM-5.3のドキュメントも別にあり、こちらは入力・出力がテキストとして記載されています。似た名前でも、別モデルの仕様や成績をそのまま当てはめることはできません。

画像の集計では、読み取りより先にルールを決める

最初の課題は、12行の架空のイベント登録表でした。同じIDの更新、キャンセル、一部入金、返金を混ぜています。PNGをBase64のData URLにして、image_urlブロックで送りました。

実測でモデルに送った架空のイベント登録表

実際に入力したテスト画像です。列は登録ID、区分、請求額、入金済み額、返金済み額、状態、更新時刻。データはすべて架空で、原文は簡体字中国語です。金額は元の課題の中国元のままで、日本円への換算ではありません。

依頼したのは、単なる文字起こしではありません。「IDごとに最新の行を採用する」「キャンセルを有効な登録数から除く」「入金と返金を分ける」という条件も付けました。正解の集計値はモデルに渡していません。

回答には最新の9件が残り、抽出した項目と、独立に計算した10項目の集計値が一致しました。有効な登録は7件で、請求額720、返金控除後の受取額580、未収額140。キャンセル分は別集計で、入金200、返金80でした。

この条件を省いて「合計して」と頼むと、何を合計した数字なのかが曖昧になります。画像を扱う場合でも、まず通常のデータ処理と同じように、重複の扱いと対象行の条件を定義するのが出発点です。

モデルは、キャンセル済みなのに返金記録がないA004と、一部入金のA006にも言及しました。ただし、画像に書かれていない返金規定やキャンセル理由は補っていません。記録上の不足を指摘することと、返金すべきかを決めることは別だからです。

手元の名簿や申込表で試すなら、合計だけでなく「採用した行」も返してもらうと、間違いの箇所を追いやすくなります。今回確認できたのは1枚の鮮明な架空表に限ります。ぼけた写真、結合セル、複数ページの帳票についての精度は測っていません。

確率問題では、説明と実行結果を別々に照合した

次は次の条件の問題です。

箱Aには赤4個・青2個、箱Bには赤2個・青4個の玉が入っています。Aを選ぶ確率は1/3、Bは2/3です。選んだ同じ箱から、戻さずに3個を順に取り出します。最初の2個のうち少なくとも1個が赤だったと分かっているとき、3個目が赤である確率と、選ばれた箱がAである事後確率を求めます。

GLM-5.3-Flashの答えは、それぞれ13/32と7/16でした。推論の流れも独立に用意した解答と一致しています。

条件をEと置くと、AでEが起きる確率は14/15、Bでは3/5です。箱を選ぶ確率で重み付けするとP(E)は32/45となり、P(AかつE)=14/45を割れば7/16が得られます。単に「赤が多いAの方が選ばれやすそう」と考えるのではなく、最初の選択確率も残して計算する必要があります。

数式とは別に、私は各玉を区別して、1箱あたり6×5×4=120通りの取り出し順を列挙する参照計算を用意しました。そのうえで、モデルの回答に含まれていたBigIntによるJavaScriptコードも実行し、同じ分数になることを確認しました。

学習に使うなら、ここで役立つのは答えの数字だけではありません。「同じ箱から戻さずに取るので、各回を独立として扱えない」「観測後は箱の選択確率も変わる」という部分を説明してもらえます。ただし、1問の正答を数学全般の信頼性に読み替えることはできません。

Crazyrouterを例に、Node.jsから1回呼び出す

公式のBigModel APIやZ.ai APIからも利用できます。ここでは、上記の実測で使ったCrazyrouterを接続例にします。APIキーと接続先URLは、同じサービスのものを組み合わせてください。

コード生成に使う候補を比較したい場合は、Crazyrouterのコーディング向けモデル一覧も参照できます。これはFlash専用の仕様ページではありません。以下のリクエストではglm-5.3-flashを直接指定します。

APIキーとファイルを準備する

Node.js 22以降を用意し、ターミナルでnode --versionを実行します。CrazyrouterのAPIトークン管理画面でキーを作成し、利用可能なモデルを制限する場合はglm-5.3-flashを含めます。

新しいフォルダに、キーだけを保存したapi-key.txtを作ります。このファイルを公開リポジトリに追加したり、スクリーンショットに写したりしないでください。同じフォルダに、以下をglm-flash-ja.cjsとして保存します。

**次のコードは同じ確率問題を日本語で送る使用例です。元の実測の入力は簡体字中国語で、この日本語版では新たなモデル呼び出しを行っていません。**リクエストの組み立てと応答処理はローカルで確認しています。

'use strict';
const fs = require('node:fs');
const path = require('node:path');

async function main() {
  const key = fs.readFileSync(path.join(__dirname, 'api-key.txt'), 'utf8').trim();
  if (!key || /\s/.test(key)) throw new Error('Invalid key file');
  const request = {
    model: 'glm-5.3-flash',
    messages: [
      {
        role: 'system',
        content: "問題の条件に基づいて回答してください。計算、仮定、不明な情報を区別し、実行していないコードを実行済みと説明しないでください。"
      },
      {
        role: 'user',
        content: "箱Aには赤い玉4個と青い玉2個、箱Bには赤い玉2個と青い玉4個が入っています。Aを選ぶ確率は1/3、Bを選ぶ確率は2/3です。箱を1つ選び、その同じ箱から玉を戻さずに3個、順に取り出します。最初の2個のうち少なくとも1個は赤だったと分かっています。3個目が赤である条件付き確率と、選んだ箱がAである事後確率を求めてください。正確な分数、解法の手順、間違えやすい点を示してください。各玉を区別して取り出し順を全列挙し、答えを検証するNode.jsコードも付けてください。乱数シミュレーションで代用せず、コードを実行済みと主張しないでください。"
      }
    ],
    max_tokens: 24000,
    stream: false
  };
  const response = await fetch('https://api.crazyrouter.com/v1/chat/completions', {
    method: 'POST',
    redirect: 'error',
    signal: AbortSignal.timeout(720000),
    headers: { Authorization: 'Bearer ' + key, 'Content-Type': 'application/json' },
    body: JSON.stringify(request)
  });
  if (!response.ok) {
    console.error('リクエストに失敗しました。HTTP: ' + response.status);
    process.exitCode = 1;
    return;
  }
  const data = await response.json();
  const choice = data.choices?.[0];
  const redact = value => String(value).split(key).join('[redacted]');
  console.log('終了理由: ' + redact(choice?.finish_reason || '記載なし'));
  const answer = choice?.message?.content;
  if (typeof answer !== 'string' || !answer.trim()) {
    console.error('回答が空です。出力上限と対応パラメータを確認してください。');
    process.exitCode = 1;
    return;
  }
  console.log(redact(answer));
}
main().catch(() => {
  console.error('処理を完了できませんでした。ローカルファイル、接続、設定を確認してください。機密情報を含むエラー詳細は表示しません。');
  process.exitCode = 1;
});

実行して、終了理由と回答を読む

フォルダを開いた状態でターミナルを起動し、次を実行します。Windowsではエクスプローラーのアドレス欄にpowershellと入力してEnterを押す方法もあります。

node glm-flash-ja.cjs

追加パッケージは不要です。ファイル名がglm-flash-ja.cjs.txtになっていないことも確認してください。

このコマンドは実際のAPIリクエストを送ります。非ストリーミングなので、回答が返るまで途中の文章は表示しません。終了理由と回答を表示するだけで、モデルが返したコードを自動実行することはありません。

元の問題の照合値は13/32と7/16です。日本語版の回答が同じ値になっても、条件の取り違えがないか説明を読みます。finish_reasonがlengthなら、回答の末尾が途中で切れていないかを先に確認してください。

HTTP 401ならキーの有効性と発行元を確認します。キーを読み込めない場合はファイルの名前と場所を確認します。HTTP 200でも回答が空なら、完成した結果とは扱えません。原因を見ずに連続して再送するのではなく、出力上限や対応パラメータを調べます。

OpenAI互換クライアントのBase URL欄にはhttps://api.crazyrouter.com/v1を使います。上のコードのURLは、そこに/chat/completionsを加えた完全なエンドポイントです。他の入力形式はAPIドキュメントの索引から確認できます。この例はテキスト入力で、画像の送信にはimage_urlブロックが必要です。

HTML生成では、HTTP 200の後に作業が残った

最後に作らせたのは、1ファイルでオフライン動作する割り勘ページです。参加者の追加・改名・削除、支出ごとの対象者指定、支出の編集・削除、リセットを依頼しました。

金額は最小単位の整数で処理し、余りを表示順に割り当てる条件にしました。100.00を3人で分けるなら33.34、33.33、33.33、0.01なら0.01、0、0です。小数を個別に丸めて、合計が変わる実装は避けたいからです。

最初のリクエストはHTTP 200でしたが、コードは途中で切れ、finish_reasonはlengthでした。上限は32,000トークンで、usageにはその内訳として25,707の推論トークンが記録されています。32,000すべてが、画面に見えるHTML用の枠だったわけではありません。

そこで、プロンプトとシステムメッセージは変えずに、max_tokensだけ48,000へ増やして再送しました。2回目はstopで終了し、完全なHTMLを取得できました。取得後にコードを手で補完・修正してから検査したわけではありません。

スクリプト全体の構文検査を行い、計算・入力検証の関数を変更せずNode.jsで実行しました。40項目のチェックが通り、そのうち1項目では金額と人数の132通りの組合せを確認しています。合計の保存、余りの配分順、対象者の選択、不正な金額、ある支出の唯一の参加者を削除しようとする場合などを検査しました。

**実ブラウザでの表示と操作は未検証です。**ボタン、編集、削除、リセットが画面上で期待どおり動くかまでは確認していません。結果は「完全なコードを得て計算部分を確認できた」であり、「完成したツールを一通り操作して確認した」ではありません。また再送は新しい生成なので、上限を増やせば常に解決するという比較実験にもなっていません。

最初に任せるなら、正しい結果を確かめられる作業から

今回の実測は2026年10月30日の3課題・計4リクエストです。すべてhttps://api.crazyrouter.com/v1/chat/completionsへglm-5.3-flashを指定し、stream: falseで送りました。出力上限は画像16,000、確率24,000、HTML32,000と48,000。temperature、top_p、reasoning_effortは明示的には設定していません。

画像から最新の行を選ぶ、確率の条件を分解する、小さな計算機能を書く。こうした作業では、モデルの出力を元データや別計算と突き合わせる道筋を作れます。私なら、まずその道筋を用意できる1つの作業で試します。

一方、生成したHTMLを人に渡すなら、計算が合うだけでは足りません。実際に参加者を追加し、支出を変更し、リセットするところまで確認が必要です。モデルの紹介ページにある用途と、自分が確認できた範囲を分けておくと、次に何を試すべきかも具体的になります。

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