目 录CONTENT

文章目录

【LLM】Gemini Schema结构化响应

EulerBlind
2025-09-10 / 0 评论 / 13 点赞 / 452 阅读 / 0 字

1. 简介

Gemini API的结构化响应功能允许开发者定义期望的输出格式,确保AI模型返回符合特定Schema的JSON数据。这对于需要稳定数据格式的应用场景非常有用,比如数据提取、API集成、自动化处理等。

通过使用Pydantic模型定义Schema,我们可以:

  • 确保输出格式的一致性
  • 进行类型验证和转换
  • 支持动态Schema生成
  • 提高代码的可维护性

2. 官方示例

from google import genai

import enum
from pydantic import BaseModel

class Grade(enum.Enum):
    A_PLUS = "a+"
    A = "a"
    B = "b"
    C = "c"
    D = "d"
    F = "f"

class Recipe(BaseModel):
  recipe_name: str
  rating: Grade

client = genai.Client()
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents='List 10 home-baked cookie recipes and give them grades based on tastiness.',
    config={
        'response_mime_type': 'application/json',
        'response_schema': list[Recipe],
    },
)

print(response.text)

对应的响应

[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "rating": "a+"
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "rating": "a"
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "rating": "b"
  },
  ...
]

3. 动态Schema实现

在实际应用中,我们经常遇到需要动态生成Schema的场景,比如:

  • 根据用户输入动态调整枚举值
  • 根据业务需求变化字段结构
  • 支持多种不同的输出格式

核心问题

静态定义的Schema无法满足动态需求,我们需要在运行时根据配置生成相应的Pydantic模型。

解决方案

3.1 动态枚举生成

from typing import Type, Dict
from enum import Enum

def generate_enum(enum_name: str, enum_values: Dict[str, str]) -> Type[Enum]:
    """
    动态生成枚举类
    
    Args:
        enum_name: 枚举类名
        enum_values: 枚举值字典,格式为 {显示名: 实际值}
    
    Returns:
        动态生成的枚举类
    """
    return Enum(enum_name, enum_values)

3.2 动态Schema生成

from pydantic import BaseModel, create_model
from typing import Optional, Type, Dict, Any

def generate_schema(
    field_definitions: Dict[str, Dict[str, Any]], class_name: str = "ParsedResponse"
) -> Type[BaseModel]:
    """
    根据字典配置动态生成Pydantic类
    
    Args:
        field_definitions: 字段定义字典
        格式: {
            'field_name': {
                'type': 字段类型,
                'optional': True/False,
                'default': 默认值
            }
        }
        class_name: 生成的类名
    
    Returns:
        动态生成的Pydantic模型类
    """
    fields = {}
    
    for field_name, field_config in field_definitions.items():
        field_type = field_config.get('type', str)
        is_optional = field_config.get('optional', False)
        default_value = field_config.get('default', None)
        
        if is_optional:
            field_type = Optional[field_type]
        
        if default_value is not None or is_optional:
            fields[field_name] = (field_type, default_value)
        else:
            fields[field_name] = field_type
    
    return create_model(class_name, **fields)

3.3 完整使用示例

import asyncio
from google.genai import Client
from datetime import datetime


# 初始化客户端
client = Client(api_key='your-api-key')

# 动态状态选项
candidate_status = ["待处理", "进行中", "已完成", "已取消"]
status_options = {f"{idx+1}": status for idx, status in enumerate(candidate_status)}

# 生成动态枚举
SexType = generate_enum("SexType", {"男": "0", "女": "1"})
Status = generate_enum("Status", status_options)

# 生成动态Schema
schema = generate_schema(
    {
        "name": {"type": str, "optional": False},  # 必填字段
        "age": {"type": int, "optional": True, "default": 0},  # 可选字段
        "status": {"type": Status, "optional": True, "default": None},  # 枚举字段
        "sex": {"type": SexType, "optional": True, "default": None},  # 枚举字段
        "description": {"type": str, "optional": True, "default": ""},  # 可选字符串
    }
)
    
# 构建提示词
prompt = f"""
请根据以下信息生成用户数据:
用户信息:张三,25岁,男性,状态为进行中
请按照指定格式返回JSON数据。
"""
    
# 调用Gemini API
response = await client.aio.models.generate_content(
    model='gemini-2.5-flash',
    contents=prompt,
    config={
        'response_mime_type': 'application/json',
        'response_schema': schema,
    },
)
    
print("原始响应:", response.text)

# 解析响应
parsed_data = schema.model_validate_json(response.text)
print("解析后的数据:", parsed_data.model_dump())

4. 重要注意事项

4.1 枚举值类型限制

枚举的Schema值必须是字符串类型,否则会报错。

**❌ **错误写法:

SexType = generate_enum("SexType", {"男": 0, "女": 1})  # 数字类型会报错

**✅ **正确写法:

SexType = generate_enum("SexType", {"男": "0", "女": "1"})  # 字符串类型

提示: 对于数字、布尔类型,可以在后续使用Pydantic对象进行类型转换。

4.2 枚举值映射关系

模型输出的是枚举的value,不是name,因此需要将期望输出的值构造到value中。

**❌ **错误写法:

SexType = generate_enum("SexType", {"0": "男", "1": "女"})
# 这会输出 "男" 或 "女",而不是 "0" 或 "1"

**✅ **正确写法:

SexType = generate_enum("SexType", {"男": "0", "女": "1"})
# 这会输出 "0" 或 "1",符合预期

4.3 性能优化建议

  • 对于频繁使用的Schema,建议缓存生成的模型类
  • 避免在循环中重复生成相同的Schema
  • 考虑使用单例模式管理常用的枚举类型

4.4 错误处理

from pydantic import ValidationError

try:
    parsed_data = schema.model_validate_json(response.text)
except ValidationError as e:
    print(f"数据验证失败: {e}")
    # 处理验证错误

5. 总结

Gemini Schema结构化响应功能为AI应用开发提供了强大的数据格式控制能力。通过动态Schema生成,我们可以:

  • 灵活适配:根据业务需求动态调整输出格式
  • 类型安全:利用Pydantic进行数据验证和类型转换
  • 易于维护:通过配置化的方式管理Schema定义
  • 提高效率:减少手动数据解析和验证的工作量

在实际应用中,建议结合具体业务场景选择合适的Schema设计模式,并注意性能优化和错误处理,以确保系统的稳定性和可维护性。

13

评论区