如何使用 Google Gemini API 和 Python 从航行情报通告 (NOTAM) 中提取结构化空域信息

首先给大家准备一些gemini的api-key 方便大家实战gemini。
AIzaSyDFKzqbwbM78iflpIlgj81cSAaEOWjbzJs
AIzaSyBq_qvVZqp8InnNrkuAPCpJBC7EWiAnAVc
AIzaSyAxc7owaBrs9QbK9fzGplV6enyUt6T2aOg
AIzaSyCy4kznxmWi1OkLkaffZ6mL-RpVaUoeXEs
AIzaSyCj_dvlvKdf87b2zdyycFhcdHRuOigzSZQ
AIzaSyDhguhSVoZ_5EIbN2p63hDWKxNFFZBL_2s
AIzaSyBPHGM30gG4YHrTYI4yUEXYCJkTRjgYT80
AIzaSyDAJ8zQAl8nwA_JjDEf7WmAkqP8k9f5r-c

接下来,这是一个关于如何使用 Google Gemini API 和 Python 从航行情报通告 (NOTAM) 中提取结构化空域信息的教程。本教程将基于我们之前的讨论,包括定义数据结构、构建提示、进行 API 调用以及处理可能出现的 schema 问题。

教程:使用 Gemini API 和 Python 从 NOTAM 提取结构化空域信息

目标:

  • 学习如何设置和使用 Google Generative AI Python SDK。
  • 使用 Pydantic 定义期望的输出数据结构。
  • 构建有效的提示 (prompt) 以指导 Gemini API 进行信息提取。
  • 调用 Gemini API 并获取结构化的 JSON 响应。
  • 处理 API 响应,包括使用 response_schema (如果支持复杂类型) 和手动 JSON 解析作为备选方案。

前提条件:

  1. Python 环境: 确保您已安装 Python (建议 3.9 或更高版本)。
  2. Google AI API 密钥:
    • 您需要一个 Google Cloud 项目并启用 Vertex AI API,或者通过 Google AI Studio 获取 API 密钥。
    • 获取 API 密钥后,请妥善保管。
  3. 安装必要的库:
    pip install google-generativeai pydantic
    

步骤 1:设置项目和导入库

首先,创建一个 Python 文件 (例如 notam_parser.py) 并导入所需的库。

import google.generativeai as genai
from pydantic import BaseModel, TypeAdapter
import json
import os # 用于安全处理 API 密钥 (推荐)

# 用于清晰的类型提示 (Python 3.9+ 可以直接使用 list, dict)
# from typing import List, Dict

步骤 2:配置 API 密钥

安全地配置您的 API 密钥。建议使用环境变量。

# 推荐方式:从环境变量读取 API 密钥
# 在您的终端设置:export GOOGLE_API_KEY="YOUR_API_KEY"
# 或者,如果您在类似 Jupyter Notebook 的环境中,可以直接设置,但不推荐用于生产代码
# API_KEY = "YOUR_API_KEY" # 直接替换 YOUR_API_KEY,注意安全风险

try:
    # 尝试从环境变量获取 API 密钥
    API_KEY = os.environ["GOOGLE_API_KEY"]
except KeyError:
    print("错误:GOOGLE_API_KEY 环境变量未设置。")
    print("请设置该变量或在代码中直接提供 API_KEY (注意安全)。")
    # 为防止代码完全中断,您可以临时在这里设置,但强烈建议使用环境变量
    API_KEY = "YOUR_API_KEY_PLACEHOLDER" # <--- 临时的,请务必替换或通过环境变量设置
    if API_KEY == "YOUR_API_KEY_PLACEHOLDER":
        raise ValueError("请将 YOUR_API_KEY_PLACEHOLDER 替换为您的有效 API 密钥或设置 GOOGLE_API_KEY 环境变量。")


genai.configure(api_key=API_KEY)

请务必将 "YOUR_API_KEY_PLACEHOLDER" 替换为您的真实 API 密钥,或通过设置 GOOGLE_API_KEY 环境变量来提供。


步骤 3:定义输出数据结构 (Pydantic 模型)

我们将定义一个 Pydantic 模型来描述从 NOTAM 中提取的每个字段的结构。我们期望的最终输出是一个包含多个“区域”信息的列表,每个“区域”信息又包含多个提取字段。

class ExtractedField(BaseModel):
    start: int
    end: int
    label: str  # 例如: "通告号", "机场名称" 等中文标签
    text: str

# 期望的整体输出结构是: list[list[ExtractedField]]
# 即一个列表,其中每个元素是代表一个空域区域信息的字段列表

步骤 4:准备输入数据 (NOTAM 文本和指令)

这是我们要处理的 NOTAM 文本和给模型的指令。

instruction_text = "检测到空域相关关键词。请参照参考案例的结构和字段标签,从航行情报通告中提取所有相关的空域信息。"
notam_to_process = """ZCZC BUI2865 251937 

GG ZBAAUIXX

251937 ZBAAOIXX

UUUU

(K1372/25 NOTAMN

Q)UUWV/QRTCA/IV/BO/W/000/030/5549N03844E003

A)UUWV B)2501290900 C)2502031600 

D)JAN 29-31 FEB 01 03 0900-1600

E) AIRSPACE CLSD WI AREA:

554930N0384015E-554916N0383931E-

554903N0384027E-554902N0384104E-

554905N0384411E-554909N0384845E-

554940N0384840E-554930N0384512E-

554925N0384106E-554930N0384015E

F)SFC G)640M AMSL)


NNNN"""

步骤 5:构建提示 (Prompt)

一个好的提示对于引导模型输出正确的结构化数据至关重要。

# 详细的提示,指导模型进行提取并遵循特定的JSON结构
# 注意:这里的 {notam_to_process} 将会被实际的NOTAM文本替换
prompt_template = f"""指令: {
     
     instruction_text}

待处理的航行情报通告 (NOTAM) 文本:
---
{
     
     notam_to_process}
---

请从上述 NOTAM 文本中提取所有相关的空域信息。
您的输出必须是一个严格的 JSON 格式字符串。
此 JSON 字符串应代表一个JSON数组,该数组的每个元素本身也是一个JSON对象列表 (即 `list[list[object]]` 结构)。
每个JSON对象代表一个提取出的字段,并且必须包含以下键值对:
- "start": (整数) 提取文本在原始 NOTAM 字符串中的起始字符索引 (0-based)。
- "end": (整数) 提取文本在原始 NOTAM 字符串中的结束字符索引 (不包含结束字符本身)。
- "label": (字符串) 字段的中文标签 (例如:"通告号", "机场名称", "多边形坐标序列" 等,请参考通用NOTAM字段定义和标签)。
- "text": (字符串) 为该字段提取的实际文本。

例如,期望的 JSON 结构是:`[[{
    
    {"start": 0, "end": 5, "label": "示例标签", "text": "示例文本"}}]]`
如果NOTAM中包含多个空域区域的描述,请为每个区域生成一个内部列表。对于给定的NOTAM,它描述了一个主要区域。
"""

步骤 6:进行 API 调用和处理响应

我们将尝试两种方法:

  • 方法 A (推荐,如果SDK支持您的schema): 使用 response_schema 来让 SDK 自动解析和验证。
  • 方法 B (备选方案): 如果方法 A 对于 list[list[ExtractedField]] 这样的复杂嵌套 schema 失败 (出现 Unsupported schema type 错误),我们将移除 response_schema 并手动解析 JSON。
# 初始化 Gemini 模型客户端
# 您最初使用的是 client.models.generate_content,这里我们使用更通用的方式获取模型实例
# 但会保持与您原始代码相似的参数传递方式 (使用 'config' 而非 'generation_config')

# 使用您在原始代码中指定的模型
model_name = "models/gemini-2.5-flash-preview-04-17"
# 您也可以尝试其他模型,例如 "gemini-1.5-flash-latest"
# model_name = "gemini-1.5-flash-latest"

model = genai.GenerativeModel(model_name)


print(f"--- 方法 A: 尝试使用 response_schema ---")
try:
    # 注意:client.models.generate_content() 是您之前用的方式。
    # 如果直接使用 model.generate_content(),参数名可能是 generation_config。
    # 为了与您之前的代码和错误保持一致,我们先模拟 client.models.generate_content() 的参数风格
    # 但实际上 genai.GenerativeModel(model_name).generate_content() 是更推荐的用法。
    # 为简单起见,这里直接用 model.generate_content 并使用正确的 generation_config。
    # 如果您坚持使用 client.models.generate_content 且它存在并使用 'config',请相应调整。

    # 经过之前的讨论,我们知道 client.models.generate_content(config=...) 这种方式
    # 对于 list[list[ExtractedField]] 可能会报 "Unsupported schema type"
    # 因此,方法A的演示将直接跳到结论,并引导至方法B。
    # 或者,我们可以先尝试,如果您的SDK版本支持,它就能工作。

    print("尝试使用 config 和 response_schema...")
    # 这里我们用 model.generate_content,它使用 generation_config
    # 如果您想严格模拟 client.models.generate_content,您需要确保该方法存在且可用。
    # genai.Client 本身没有 .models.generate_content()。
    # 正确的方式是 client.get_generative_model(model_name).generate_content()
    # 或者 genai.GenerativeModel(model_name).generate_content()

    # 我们将使用 genai.GenerativeModel().generate_content(),它使用 'generation_config'
    # 并且,如果 'response_schema': list[list[ExtractedField]] 仍然不受支持,
    # 我们将看到同样的错误,然后转到方法B。

    response_attempt_A = model.generate_content(
        prompt_template, # 使用上面定义的完整 prompt
        generation_config=genai.types.GenerationConfig( 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值