跳到主內容

結構和輸出

瞭解如何使用結構化輸入和輸出模式,從大語言模型(LLM)中獲取可靠、可解析的 JSON 資料。

在編寫針對 LLM 的程式時,你希望提供明確的輸入並獲得明確的輸出。

結構化輸入

#

作為輸入,LLM 幾乎可以接受任何你可以渲染為文字的內容。這包括自由格式文字、像 Markdown 這樣的半結構化文字,也包括像 CSV、JSON 和 XML 這樣的結構化格式。如果你擁有具有結構的資料,請使用該結構來格式化資料,這樣 LLM 將為你提供更好的結果。

除了結構化文字輸入外,你還可以傳遞二進位制資料,例如影像或 PDF。在示例中,應用程式將填字遊戲截圖傳遞給 Gemini,以便它推斷出網格資料。

dart
final imageParts = <Part>[];
for (final image in images) {
  final imageBytes = await image.readAsBytes();
  final mimeType = lookupMimeType(image.path, headerBytes: imageBytes)!;
  imageParts.add(InlineDataPart(mimeType, imageBytes));
}

final content = [
  Content.multi([
    TextPart(_crosswordPrompt),
    ...imageParts,
  ]),
];

final response = await _crosswordModel.generateContent(content);
...

此程式碼將提示詞和影像作為同一請求的一部分傳遞給 Gemini。

結構化輸出

#

與結構化輸入相比,LLM 處理結構化輸出的難度更大。當要求模型輸出 JSON 時,你需要清晰且全面,以確保獲得可以在應用程式中可靠解析的內容。

首先使用你預期的輸出格式初始化模型例項。

dart
// the schema for the clue solver output
static final _crosswordSchema = Schema(
  SchemaType.object,
  properties: {
    'width': Schema(SchemaType.integer),
    'height': Schema(SchemaType.integer),
    'grid': Schema(
      SchemaType.array,
      items: Schema(
        SchemaType.array,
        items: Schema(
          SchemaType.object,
          properties: {
            'color': Schema(SchemaType.string),
            'clueNumber': Schema(SchemaType.integer, nullable: true),
          },
        ),
      ),
    ),
    'clues': Schema(
      SchemaType.object,
      properties: {
        'across': Schema(
          SchemaType.array,
          items: Schema(
            SchemaType.object,
            properties: {
              'number': Schema(SchemaType.integer),
              'text': Schema(SchemaType.string),
            },
          ),
        ),
        'down': Schema(
          SchemaType.array,
          items: Schema(
            SchemaType.object,
            properties: {
              'number': Schema(SchemaType.integer),
              'text': Schema(SchemaType.string),
            },
          ),
        ),
      },
    ),
  },
);

// The model for inferring crossword data from images.
_crosswordModel = FirebaseAI.googleAI().generativeModel(
  model: 'gemini-2.5-pro',
  generationConfig: GenerationConfig(
    responseMimeType: 'application/json',
    responseSchema: _crosswordSchema,
  ),
);

雖然這樣可能就足夠了,但當你還在系統指令中指定輸出模式時,會獲得最可靠的結果。

dart
final _crosswordPrompt =
'''
Analyze the following crossword puzzle images and return a JSON object
representing the grid size, contents, and clues. The images may contain
different parts of the same puzzle (e.g., the grid the across clues, the down
clues). Combine them to form a complete puzzle.

The JSON schema is as follows: ${jsonEncode(_crosswordSchema.toJson())}
'''

現在,你可以將模型的文字響應解析為 JSON。

dart
final response = await _crosswordModel.generateContent(content);

final json = jsonDecode(response.text!);
final width = json['width'] as int;
final height = json['height'] as int;
final gridData = json['grid'] as List;
final cluesData = json['clues'] as Map<String, dynamic>;
...

來自模型的可靠 JSON 輸出是將其整合到應用程式中的關鍵。資料內容可能正確也可能不正確,但它一定會以你的應用程式可以處理的格式呈現。