AI SDK で JSON を返す
AIをプログラムの一部として使うとき、「JSONで返してほしいな〜」と思うこと、ありますよね。
VercelのAI SDKにあるgenerateObjectを使うと簡単にできます。
- Deno
- Amazon Bedrock (モデル: Nova Pro)
を使います(過去に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が返ってきました。

うれしいこと
エラーにならずデータが返ってくれば、それはZodの型定義に準拠していることが保証されるので、AIのレスポンスでも安心して使えます。
また、コーディング中に以下のように補完されるのが便利です。

本当に型通りに生成されるの?
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.
具体的なエラーメッセージは以下の通りです。これで安心ですね!

感想
ちょっと前までは、マークダウンの中にJSONを埋め込んで、自前でパースして…などしていたように思います。
そしてFunction Callingとか言って盛り上がっている時期もありましたが、今ではツール呼び出しも当たり前になってしまいましたね。
とはいえ今でも、ちょっとした場面でJSON返してほしいこともあると思うので、そんなときにこの記事が参考になれば良いなと思います。