掌握 Gemini 1.5 的受控生成功能:面向开发者的架构遵循原则

九月 03, 2024
Lewis Liu Group Product Manager Gemini
Terry Koo Research Scientist Google Deepmind

目前,围绕生成式 AI 的大部分兴奋点都集中在“可能是什么”上,即可能与基础模型相关的实验和突破。但在 Google,我们一直致力于提供全面的 AI 生态系统,不仅可以帮助您尝试一流的模型,还可以帮助您在实际应用中予以采用。

作为这一旅程的一部分,我们在今年早些时候的 Google I/O 大会上推出了用于 Gemini 1.5 Pro 受控生成功能,同时我们也对功能的快速采用和收到的积极反馈感到非常兴奋。今天,我们又向前迈进了一步,为 Gemini 1.5 Flash 引入了受控生成,并添加了“枚举”支持。利用这个强大的工具,开发者可以可靠地生成遵循定义架构的响应。此外,当您在 Gemini 1.5 上使用函数调用时,受控生成也会在任何模式下自动启用。


什么是受控生成?为什么重要?

您可以将受控生成视为可为模型的输出提供蓝图的功能。通过定义响应架构,您可以决定 AI 响应的精确格式和结构。无论是以 JSON 格式提取实体以实现无缝下游处理,还是用您自己的分类法对新闻文章进行分类,受控生成都有助于确保一致性,并减少对耗时后期处理的需求。

要将 AI 完全集成到软件开发中,需要完成两件事:从数据科学和机器学习团队到应用开发者的无缝交接,以及在现有系统中无缝集成模型的输出。通过受控生成,您可以:

  • 使 AI 能够生成易于使用、机器可读的数据,从而减少对繁琐的后期处理和解析的需求。

  • 以 JSON 等格式生成输出,使您的 AI 成为 API 经济中的一等公民。它可以无缝插入现有的工作流。

  • 为 AI 输出注入一定的可预测性,以可靠地预测 AI 模型产生的数据的格式和结构。

用雅诗兰黛公司的首席机器学习工程师 Chris Curro(我们最早的测试人员之一)的话说:“我们正在 Gemini 1.5 的基础之上设计复杂的推理工作流,以打造否则不可能实现的消费者和员工体验。受控生成在本质上是对开发者友好的,使我们的团队能够快速创造并提升业务价值。”

该功能建立在我们 Google 团队最近开发的“受控解码”的基础之上。您可以在本文中详细了解我们的基础技术。

在 Gemini API 和 Vertex AI API 中,我们引入了“响应架构”的概念。响应架构充当模板,指示 AI 输出的元素、数据类型和整体结构。该架构基于 OpenAPI 3.0 架构定义构建而来,因此您始终知道自己正在按照开放且兼容的标准构建内容。通过在提示中包含响应架构,您可以指示模型遵守您定义的规则,从而产生可预测的结构化结果。


Google 秘密武器

  • Gemini 的受控生成为您现有的 API 调用增加了最低延迟,即使是在第一次 API 调用时

  • Gemini 支持以枚举作为类型,未来还会推出更多功能

  • Gemini 可强制执行架构,无需存储您的任何数据


如何上手

受控生成功能已同时面向 Gemini 1.5 Pro 和 Gemini 1.5 Flash 推出,请访问 Google AI StudioVertex AI


示例:使用 JSON 架构构建膳食计划应用

想象一下,您需要构建一个应用,为不同的场景提供食谱建议。食谱必须以结构化的格式生成,以便应用轻松提取,并直观地呈现给用户。以下示例说明了如何使用受控生成功能为多道菜肴生成一套食谱。

from vertexai.generative_models import GenerationConfig, GenerativeModel
vertexai.init(project=project_id, location="us-central1")
 
response_schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "course": {
                "type": "string",
                "enum": [
                    "appetizer",
                    "salad",
                    "soup",
                    "main",
                    "dessert",
                ],
            },
            "name": {
                "type": "string",
            },
            "ingredients": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "unit": {
                            "type": "string",
                            "enum": [
                                "count",
                                "cup",
                                "tablespoon",
                                "teaspoon",
                                "pound",
                                "ounce",
                            ],
                        },
                        "amount": {
                            "type": "number",
                        },
                        "name": {
                            "type": "string",
                        },
                    },
                    "required": ["name"],
                },
            },
            "steps": {
                "type": "array",
                "items": {
                    "type": "string",
                },
            },
        },
        "required": ["course", "name"],
    },
}
 
prompt = (
    有几个朋友到城里来了我想请他们吃晚饭。”
    您能为我安排三道菜吗?”
    我不是一位有经验的厨师我需要简单的食谱。”
)
 
model = GenerativeModel("gemini-1.5-pro-001")
 
response = model.generate_content(
    prompt,
    generation_config=GenerationConfig(
        response_mime_type="application/json",
        response_schema=response_schema
    ),
)

此模型的输出确实确认了请求正文中指定的架构,并且可以由应用直接使用。

[
    {
        "course": "appetizer",
        "name": "Caprese Skewers",
        "ingredients": [
            {
                "name": "cherry tomatoes",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "fresh mozzarella balls",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "fresh basil leaves",
                "amount": 12,
                "unit": "count"
            },
            {
                "name": "olive oil",
                "amount": 2,
                "unit": "tablespoon"
            },
            {
                "name": "balsamic glaze",
                "amount": 2,
                "unit": "tablespoon"
            },
            {
                "name": "salt",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "black pepper",
                "amount": 1,
                "unit": "teaspoon"
            }
        ],
        "steps": [
            "Thread cherry tomatoes, mozzarella balls, and basil leaves onto skewers.",
            "Drizzle with olive oil and balsamic glaze.",
            "Season with salt and pepper to taste."
        ]
    },
    {
        "course": "main",
        "name": "One-Pan Lemon Herb Salmon",
        "ingredients": [
            {
                "name": "salmon fillets",
                "amount": 4,
                "unit": "count"
            },
            {
                "name": "asparagus",
                "amount": 1,
                "unit": "pound"
            },
            {
                "name": "cherry tomatoes",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "lemon",
                "amount": 1,
                "unit": "count"
            },
            {
                "name": "dried oregano",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "dried thyme",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "salt",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "black pepper",
                "amount": 1,
                "unit": "teaspoon"
            },
            {
                "name": "olive oil",
                "amount": 2,
                "unit": "tablespoon"
            }
        ],
        "steps": [
            "Preheat oven to 400 degrees F (200 degrees C).",
            "Line a baking sheet with parchment paper.",
            "Place salmon fillets on one side of the baking sheet and spread asparagus and cherry tomatoes on the other side.",
            "Squeeze lemon juice over the salmon and vegetables.",
            "Sprinkle with oregano, thyme, salt, and pepper.",
            "Drizzle with olive oil.",
            "Bake for 15-20 minutes, or until salmon is cooked through and vegetables are tender."
        ]
    },
    {
        "course": "dessert",
        "name": "Fruit Salad with Honey Yogurt",
        "ingredients": [
            {
                "name": "strawberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "blueberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "raspberries",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "greek yogurt",
                "amount": 1,
                "unit": "cup"
            },
            {
                "name": "honey",
                "amount": 2,
                "unit": "tablespoon"
            }
        ],
        "steps": [
            "In a large bowl, combine strawberries, blueberries, and raspberries.",
            "In a separate bowl, mix together greek yogurt and honey.",
            "Serve fruit salad with a dollop of honey yogurt."
        ]
    }
]

使用枚举架构对产品条件进行分类

要以一组预定义值限制模型输出,您可以使用“text/x.enum”。

import vertexai
from vertexai.generative_models import GenerationConfig, GenerativeModel
 
vertexai.init(project=project_id, location="us-central1")
model = GenerativeModel("gemini-1.5-flash-001")
 
response_schema = {
     "type": "STRING",
     "enum": ["new in package", "like new", "gently used", "used", "damaged", "soiled"]
}
 
prompt = [
     商品说明商品是一件超长款的冬季大衣接缝处有很多口子快要裂开了并且表面有很多可疑污渍。”
]
 
 
response = model.generate_content(
     prompt,
     generation_config=GenerationConfig(
         response_mime_type="text/x.enum", response_schema=response_schema
     ),
)
print(response.candidates[0])

模型输出包含产品为“已损坏”的简单分类。

content {
  role: "model"
  parts {
    text: "damaged"
  }
}

限制

  • 受控生成支持 OpenAPI3.0 架构的子集。

  • 输出内容仍然取决于模型的推理和提取能力。使用受控生成强制执行输出格式,但不是实际响应

  • 如果必填字段所需的提示信息不足,受控生成可能会根据训练所用的数据输出响应。在字段上将“是否可为 null”设置为“True”可以缓解此限制。


总结

通过受控生成,您现在拥有一个强大的工具来生成遵循定义架构的响应。您可以将其应用于许多现有工作流,使其更具可靠性和预测性。我们致力于为开发者提供易于使用的 API 功能,以更好地引导和控制模型行为。受控生成只是一个开始。

要开始使用此功能,您可以在 Google AI StudioVertex AI 文档页面中阅读更多内容。