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设计模式,并注意性能优化和错误处理,以确保系统的稳定性和可维护性。
评论区