blog top

AI SDK で JSON を返す

AIをプログラムの一部として使うとき、「JSONで返してほしいな〜」と思うこと、ありますよね。

VercelのAI SDKにあるgenerateObjectを使うと簡単にできます。

を使います(過去にAI SDKからBedrockを呼び出すという記事も書いているのでそちらもどうぞ)。

今回のサンプルコードはGitHubのリポジトリで公開しています。

実際にやってみた

以下のように、欲しいJSONの形をZodで表現するだけで作成できてしまいます。

// main.ts (Deno)

import { generateObject } from "npm:ai@5.0.76";
import { createAmazonBedrock } from "npm:@ai-sdk/amazon-bedrock@3.0.45";
import { z } from "npm:zod@4.1.12";

const bedrock = createAmazonBedrock({
  region: "ap-northeast-1",
});

const userSchema = z.object({
  name: z.string(),
  age: z.number(),
  email: z.email(),
});

const model = bedrock("apac.amazon.nova-pro-v1:0");

const res = await generateObject({
  model,
  schema: userSchema,
  prompt: "日本人のダミーデータを作ってください",
});

console.log(res.object);

そしてdeno run --allow-env --allow-net main.tsで呼び出します。

すると以下のように、期待通りのJSONが返ってきました。

Denoを実行してJSONが生成した様子

うれしいこと

エラーにならずデータが返ってくれば、それはZodの型定義に準拠していることが保証されるので、AIのレスポンスでも安心して使えます。

また、コーディング中に以下のように補完されるのが便利です。

VSCodeで型の補完が効いている様子

本当に型通りに生成されるの?

AIにお願いして、Zodの型を破ってもらいましょう。emailを出力するのを忘れてもらいます。

// main.ts (Deno)

// ...(省略)

await generateObject({
  model,
  schema: userSchema,
  prompt: `日本人のダミーデータを作ってください。
ただし、JSONフォーマットが崩れていると正しくエラーになることを確かめたいので、
あえてemailプロパティを生成しないようにしてください。`,
});

すると、Zodは以下のようなエラーを返します。

error: Uncaught (in promise) AI_NoObjectGeneratedError: No object generated: response did not match schema.

具体的なエラーメッセージは以下の通りです。これで安心ですね!

emailプロパティundefinedになっているというエラー

感想

ちょっと前までは、マークダウンの中にJSONを埋め込んで、自前でパースして…などしていたように思います。

そしてFunction Callingとか言って盛り上がっている時期もありましたが、今ではツール呼び出しも当たり前になってしまいましたね。

とはいえ今でも、ちょっとした場面でJSON返してほしいこともあると思うので、そんなときにこの記事が参考になれば良いなと思います。