Gemini API与JSON模式:精细化控制AI输出格式的实战指南

105

Gemini API与JSON模式:精细化控制AI输出格式的实践指南

在人工智能快速发展的今天,如何有效地控制AI模型的输出格式,使其更好地服务于我们的应用场景,成为了开发者们关注的焦点。Gemini API作为一款强大的AI工具,为我们提供了灵活的输出控制方式。本文将深入探讨如何利用JSON模式与Gemini API相结合,实现对AI响应格式的精确控制,并分享Python和Node.js的实战案例。

背景:驯服AI的“野生”输出

正如我在之前的报告“驯服野生输出:有效控制Gemini API响应格式与response_mime_type”中所述,控制AI的输出格式至关重要。AI模型在生成内容时,往往会产生结构不一致、格式混乱的“野生”输出,这给后续的数据处理和应用带来了诸多不便。为了解决这一问题,我们需要一种机制,能够引导AI按照我们预定的格式生成内容,从而提高AI应用的效率和可靠性。而JSON模式正是一种强大的工具,它可以帮助我们定义AI输出的数据结构,确保AI生成的响应符合我们的预期。

方法:JSON模式与response_mime_type的完美结合

本文介绍的方法核心在于利用JSON模式定义期望的输出格式,并通过response_mime_type参数告知Gemini API以JSON格式返回结果。具体步骤如下:

  1. 定义JSON模式:根据应用需求,设计清晰、完整的JSON模式。JSON模式描述了期望的JSON对象的结构、属性和数据类型。例如,如果我们需要获取日本几个主要城市的人口数据,可以定义一个包含城市名称和人口数量的JSON模式。
  2. 配置Gemini API:在使用Gemini API时,设置response_mime_typeapplication/json,表明我们期望API返回JSON格式的响应。
  3. 构建Prompt:在Prompt中明确告知AI模型遵循JSON模式。可以将JSON模式嵌入到Prompt中,例如:遵循JSON模式。<JSONSchema>{json.dumps(jsonSchema)}</JSONSchema>
  4. 调用API并解析结果:调用Gemini API,并解析返回的JSON格式结果。根据JSON模式,我们可以轻松地提取所需的数据,并将其应用于我们的应用场景。

方法示意图

通过这种方式,我们可以有效地控制Gemini API的输出格式,使其返回符合我们需求的复杂JSON对象。下面,我们将通过Python和Node.js的示例脚本,详细演示这一方法的具体实现。

Python示例脚本

示例1:获取日本主要城市人口数据

以下Python脚本演示了如何使用JSON模式获取日本京都、大阪、爱知、福冈和东京的当前人口数据。

import google.generativeai as genai
import google.ai.generativelanguage as glm
import json

apiKey = "YOUR_API_KEY"  # 请设置您的API密钥。

jsonSchema = {
    "title": "日本京都、大阪、爱知、福冈和东京的当前人口",
    "description": "返回日本京都、大阪、爱知、福冈和东京的当前人口",
    "type": "object",
    "properties": {
        "propertyNames": {"description": "都道府县名称"},
        "patternProperties": {"": {"type": "number", "description": "人口"}},
    },
}
prompt = f"遵循JSON模式。<JSONSchema>{json.dumps(jsonSchema)}</JSONSchema>"
genai.configure(api_key=apiKey)
model = genai.GenerativeModel(
    model_name="gemini-1.5-pro-latest",
    generation_config=glm.GenerationConfig(response_mime_type="application/json"),
)
response = model.generate_content(prompt)
print(response.text)

代码解析:

  • 首先,我们定义了一个JSON模式,描述了期望返回的JSON对象的结构。该JSON对象包含五个属性,分别对应日本的五个城市,每个属性的值为该城市的人口数量。
  • 然后,我们构建了一个Prompt,告知AI模型遵循该JSON模式。
  • 接着,我们配置Gemini API,设置response_mime_typeapplication/json
  • 最后,我们调用Gemini API,并打印返回的JSON格式结果。

运行结果:

{
  "Kyoto": 2539740,
  "Osaka": 8837681,
  "Aichi": 7552873,
  "Fukuoka": 5138026,
  "Tokyo": 14064563
}

示例2:生成受欢迎的曲奇食谱

以下Python脚本演示了如何使用JSON模式生成包含多个曲奇食谱的JSON数组。每个食谱包含食谱名称和所需材料等信息。

import google.generativeai as genai
import google.ai.generativelanguage as glm
import json

apiKey = "YOUR_API_KEY"  # 请设置您的API密钥。

jsonSchema = {
    "title": "5个受欢迎的曲奇食谱",
    "description": "通过包括以下属性列出5个受欢迎的曲奇食谱。",
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "recipe_name": {"description": "食谱名称。", "type": "string"},
            "materials": {
                "description": "运行食谱所需材料。",
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "material": {
                            "description": "运行食谱所需材料。",
                            "type": "string",
                        },
                        "amount": {
                            "description": "运行食谱所需材料的数量。单位是克。",
                            "type": "number",
                        },
                        "cost": {
                            "description": "运行食谱所需材料的成本。单位是美元。",
                            "type": "number",
                        },
                    },
                    "required": ["material", "material", "cost"],
                    "additionalProperties": False,
                },
            },
        },
        "additionalProperties": False,
    },
}

prompt = f"遵循JSON模式。<JSONSchema>{json.dumps(jsonSchema)}</JSONSchema>"
genai.configure(api_key=apiKey)
model = genai.GenerativeModel(
    model_name="gemini-1.5-pro-latest",
    generation_config=glm.GenerationConfig(response_mime_type="application/json"),
)
response = model.generate_content(prompt)
print(response.text)

代码解析:

  • 该JSON模式定义了一个包含五个食谱对象的JSON数组。每个食谱对象包含recipe_namematerials两个属性。materials属性是一个包含多个材料对象的JSON数组,每个材料对象包含materialamountcost三个属性。
  • 通过设置required属性,我们可以指定哪些属性是必需的。例如,我们指定materialamountcost属性是必需的。
  • 通过设置additionalPropertiesFalse,我们可以禁止返回额外的属性。

运行结果:

[
  {
    "食谱名称": "巧克力碎片饼干",
    "材料": [
      { "材料": "黄油", "数量": 226, "成本": 2.5 },
      { "材料": "糖", "数量": 200, "成本": 0.5 },
      { "材料": "面粉", "数量": 320, "成本": 0.8 }
    ]
  },
  {
    "食谱名称": "燕麦葡萄干饼干",
    "材料": [
      { "材料": "黄油", "数量": 113, "成本": 1.25 },
      { "材料": "糖", "数量": 150, "成本": 0.4 },
      { "材料": "面粉", "数量": 230, "成本": 0.58 }
    ]
  },
  {
    "食谱名称": "花生酱饼干",
    "材料": [
      { "材料": "黄油", "数量": 113, "成本": 1.25 },
      { "材料": "花生酱", "数量": 120, "成本": 1.2 },
      { "材料": "糖", "数量": 150, "成本": 0.4 }
    ]
  },
  {
    "食谱名称": "糖饼干",
    "材料": [
      { "材料": "黄油", "数量": 226, "成本": 2.5 },
      { "材料": "糖", "数量": 200, "成本": 0.5 },
      { "材料": "面粉", "数量": 320, "成本": 0.8 }
    ]
  },
  {
    "食谱名称": "酥饼",
    "材料": [
      { "材料": "黄油", "数量": 226, "成本": 2.5 },
      { "材料": "糖", "数量": 100, "成本": 0.25 },
      { "材料": "面粉", "数量": 320, "成本": 0.8 }
    ]
  }
]

Node.js示例脚本

示例1:获取日本主要城市人口数据

以下Node.js脚本演示了如何使用JSON模式获取日本京都、大阪、爱知、福冈和东京的当前人口数据。

const { GoogleGenerativeAI } = require("@google/generative-ai");

const apiKey = "YOUR_API_KEY"; // 请设置您的 API 密钥。

const genAI = new GoogleGenerativeAI(apiKey);

async function main() {
  const model = genAI.getGenerativeModel({
    model: "gemini-1.5-pro-latest",
    generationConfig: { response_mime_type: "application/json" },
  });
  const jsonSchema = {
    title: "日本京都、大阪、爱知、福冈、东京的当前人口",
    description:
      "返回日本京都、大阪、爱知、福冈、东京的当前人口",
    type: "object",
    properties: {
      propertyNames: { description: "府名" },
      patternProperties: { "": { type: "number", description: "人口" } },
    },
  };
  const prompt = `Follow JSON schema.<JSONSchema>${JSON.stringify(
    jsonSchema
  )}</JSONSchema>`;
  const result = await model.generateContent(prompt);
  const text = await result.response.text();
  console.log(text);
}

main();

代码解析:

  • 与Python示例类似,我们首先定义了一个JSON模式,描述了期望返回的JSON对象的结构。
  • 然后,我们构建了一个Prompt,告知AI模型遵循该JSON模式。
  • 接着,我们配置Gemini API,设置response_mime_typeapplication/json
  • 最后,我们调用Gemini API,并打印返回的JSON格式结果。

运行结果:

{
  "Kyoto": 1446575,
  "Osaka": 8808183,
  "Aichi": 7552112,
  "Fukuoka": 5138809,
  "Tokyo": 14047594
}

示例2:生成受欢迎的曲奇食谱

以下Node.js脚本演示了如何使用JSON模式生成包含多个曲奇食谱的JSON数组。每个食谱包含食谱名称和所需材料等信息。

const { GoogleGenerativeAI } = require("@google/generative-ai");

const apiKey = "YOUR_API_KEY"; // 请设置您的 API 密钥。

const genAI = new GoogleGenerativeAI(apiKey);

async function main() {
  const model = genAI.getGenerativeModel({
    model: "gemini-1.5-pro-latest",
    generationConfig: { response_mime_type: "application/json" },
  });
  const jsonSchema = {
    title: "5 种受欢迎的饼干食谱",
    description:
      "列出 5 种受欢迎的饼干食谱,包括以下属性。",
    type: "array",
    items: {
      type: "object",
      properties: {
        recipe_name: { description: "食谱名称。", type: "string" },
        materials: {
          description: "制作食谱所需材料。",
          type: "array",
          items: {
            type: "object",
            properties: {
              material: {
                description: "制作食谱所需材料。",
                type: "string",
              },
              amount: {
                description:
                  "制作食谱所需材料的数量。单位是克。",
                type: "number",
              },
              cost: {
                description:
                  "制作食谱所需材料的费用。单位是美元。",
                type: "number",
              },
            },
            required: ["material", "material", "cost"],
            additionalProperties: false,
          },
        },
      },
      additionalProperties: false,
    },
  };
  const prompt = `Follow JSON schema.<JSONSchema>${JSON.stringify(
    jsonSchema
  )}</JSONSchema>`;
  const result = await model.generateContent(prompt);
  const text = await result.response.text();
  console.log(text);
}

main();

代码解析:

  • 该JSON模式定义了一个包含五个食谱对象的JSON数组。每个食谱对象包含recipe_namematerials两个属性。materials属性是一个包含多个材料对象的JSON数组,每个材料对象包含materialamountcost三个属性。
  • 通过设置required属性,我们可以指定哪些属性是必需的。例如,我们指定materialamountcost属性是必需的。
  • 通过设置additionalPropertiesFalse,我们可以禁止返回额外的属性。

运行结果:

[
  {
    "recipe_name": "巧克力饼干",
    "materials": [
      { "material": "黄油", "amount": 115, "cost": 2 },
      { "material": "糖", "amount": 100, "cost": 1 },
      { "material": "面粉", "amount": 150, "cost": 0.5 }
    ]
  },
  {
    "recipe_name": "花生酱饼干",
    "materials": [
      { "material": "花生酱", "amount": 120, "cost": 3 },
      { "material": "糖", "amount": 100, "cost": 1 },
      { "material": "面粉", "amount": 150, "cost": 0.5 }
    ]
  },
  {
    "recipe_name": "燕麦葡萄干饼干",
    "materials": [
      { "material": "燕麦", "amount": 100, "cost": 2 },
      { "material": "葡萄干", "amount": 80, "cost": 2.5 },
      { "material": "面粉", "amount": 150, "cost": 0.5 }
    ]
  },
  {
    "recipe_name": "糖饼干",
    "materials": [
      { "material": "黄油", "amount": 115, "cost": 2 },
      { "material": "糖", "amount": 150, "cost": 1.5 },
      { "material": "面粉", "amount": 150, "cost": 0.5 }
    ]
  },
  {
    "recipe_name": "黄油饼干",
    "materials": [
      { "material": "黄油", "amount": 120, "cost": 2 },
      { "material": "糖", "amount": 60, "cost": 0.5 },
      { "material": "面粉", "amount": 180, "cost": 0.7 }
    ]
  }
]

总结与展望

通过本文的介绍,我们可以看到,利用JSON模式与Gemini API的response_mime_type参数相结合,可以有效地控制AI模型的输出格式,使其生成结构化的JSON数据。这种方法不仅提高了AI应用的效率和可靠性,也为开发者们提供了更大的灵活性和控制力。未来,我们可以进一步探索JSON模式的更多高级特性,例如自定义校验规则、条件依赖等,以实现更加精细化的输出控制。

此外,随着AI技术的不断发展,我们可以期待更多的AI模型能够支持JSON模式,从而简化开发流程,降低开发成本,并最终推动AI应用的普及和发展。我们有理由相信,在不远的将来,AI将成为我们生活和工作中不可或缺的助手,为我们带来更多的便利和惊喜。