1. 从零开始:你的第一个Gemini API调用

如果你刚接触Gemini API,可能会觉得有点复杂,但别担心,我刚开始用的时候也这样。其实只要几步,你就能让这个强大的AI模型为你工作。我建议你先从最简单的文本生成开始,感受一下它的能力。

首先,你得有个API密钥。这个密钥就像是你进入Gemini世界的门票。你可以去Google AI Studio免费申请一个。拿到密钥后,我习惯把它设置成环境变量,这样代码里就不用硬编码,更安全。在终端里输入 export GEMINI_API_KEY='你的密钥'(Windows用 set GEMINI_API_KEY='你的密钥')就行。

接下来安装Python库。官方推荐用 google-generativeai 这个库,它封装得比较好,用起来顺手。直接 pip install google-generativeai 就能搞定。我实测下来,Python版本最好在3.9以上,不然可能会遇到一些兼容性问题。

安装好了,我们来写第一个程序。这个程序简单到只有几行,但能让你立刻看到效果:

import google.generativeai as genai
import os

# 配置API密钥,这里会从环境变量GEMINI_API_KEY读取
genai.configure(api_key=os.getenv('GEMINI_API_KEY'))

# 创建一个模型实例,这里用gemini-pro,这是最通用的文本模型
model = genai.GenerativeModel('gemini-pro')

# 发送一个简单的请求
response = model.generate_content("用一句话解释什么是机器学习?")
print(response.text)

运行这段代码,你应该能看到一句关于机器学习的简洁解释。我第一次跑的时候,感觉特别神奇,几行代码就能调用世界顶级的AI模型。这里有个小细节要注意,generate_content 方法返回的对象里,真正的文本在 response.text 属性里。如果你直接打印 response,会看到一堆元数据,反而找不到答案。

你可能想知道还有哪些模型可用。其实Gemini提供了好几个模型,针对不同场景优化。我常用 genai.list_models() 来查看所有可用模型:

for model in genai.list_models():
    if 'generateContent' in model.supported_generation_methods:
        print(f"模型: {model.name}")
        print(f"描述: {model.description}")
        print("-" * 30)

这会列出所有支持内容生成的模型,比如 gemini-pro 适合通用文本任务,gemini-pro-vision 能处理图片,还有各种尺寸的模型适应不同算力需求。刚开始我建议先用 gemini-pro,它平衡了能力和速度,免费额度也够用。

2. 流式输出:让AI的回答像真人一样“打字”

不知道你有没有用过那些一个字一个字往外蹦的AI聊天应用?那种体验特别自然,就像对面真有人在思考打字一样。这就是流式输出的魅力。我第一次实现这个功能时,感觉整个应用的交互体验提升了一个档次。

传统的API调用是“阻塞式”的——你发送请求,然后干等着,直到整个回答生成完毕才一次性返回。对于长回答,用户可能要等好几秒,看着空白的界面,心里会想“是不是卡住了?”。流式输出就解决了这个问题,模型生成一点,就返回一点,用户能立即看到反馈。

用Gemini API实现流式输出简单得惊人,只需要加一个参数:

def stream_response(prompt):
    genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
    model = genai.GenerativeModel('gemini-pro')
    
    # 关键就在这里:stream=True
    response = model.generate_content(prompt, stream=True)
    
    # 然后像遍历普通列表一样遍历response
    for chunk in response:
        print(chunk.text, end='', flush=True)
        # 这里可以加上延迟,模拟真人打字速度
        # time.sleep(0.05)
    
    print()  # 最后换行

if __name__ == '__main__':
    stream_response("给我讲一个关于程序员的笑话")

运行这段代码,你会看到笑话是一个词一个词出现的,而不是一下子全出来。我在实际项目中发现,这种体验对用户特别友好,尤其是生成长文本时,用户不会因为等待而焦虑。

但流式输出不只是为了好看,它还有实际的技术优势。想象一下你要生成一篇5000字的文章,如果一次性生成,内存里要保存整个响应,而流式处理可以边生成边处理,内存占用小得多。我做过一个项目,需要实时处理AI生成的代码并立即语法高亮,流式输出让这变得可能。

不过流式输出也有些坑需要注意。最大的问题是“断句”——模型返回的chunk不一定在完整的句子或单词边界处切断。你可能收到半个词,或者标点符号和前文分开了。我的经验是,在前端展示时要做一些缓冲处理,比如积累几个chunk再一起渲染,或者智能地判断断句位置。

另一个实际问题是错误处理。在非流式调用中,如果有错误,整个请求会失败,你收到一个异常。但在流式调用中,错误可能发生在中间某个chunk。我建议这样处理:

try:
    response = model.generate_content(prompt, stream=True)
    for chunk in response:
        if chunk.parts and chunk.parts[0].text:
            print(chunk.text, end='', flush=True)
        elif chunk.prompt_feedback:
            # 处理安全过滤或其他反馈
            print(f"\n注意: {chunk.prompt_feedback}")
except Exception as e:
    print(f"流式请求出错: {e}")

我还发现一个有趣的现象:不同内容的流式输出速度不一样。简单的事实性问题,chunk来得又快又大段;复杂的推理问题,chunk来得慢但更“深思熟虑”。你可以利用这个特性给用户提示——如果chunk间隔长,显示“正在思考...”的动画。

3. 多模态实战:让AI“看懂”图片

Gemini真正厉害的地方在于多模态能力——它不仅能处理文字,还能理解图片。我第一次让AI描述我上传的猫咪照片时,那种感觉就像魔法。它不仅能认出是猫,还能说出品种、姿势、甚至情绪。

要用这个功能,你需要 gemini-pro-vision 模型。安装依赖很简单:pip install pillow。Pillow是Python里处理图片的标准库。

来看一个完整的例子:

import google.generativeai as genai
import PIL.Image
import os

def analyze_image(image_path, prompt="描述这张图片"):
    genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
    model = genai.GenerativeModel('gemini-pro-vision')
    
    # 加载图片
    img = PIL.Image.open(image_path)
    
    # 同时发送文本提示和图片
    response = model.generate_content([prompt, img])
    
    print(response.text)

if __name__ == '__main__':
    # 你可以换成自己的图片路径
    analyze_image("cat.jpg", "这只猫在做什么?它的情绪看起来怎么样?")

我测试过各种图片,从简单的图表到复杂的风景照,Gemini的表现都令人印象深刻。有一次我上传了一张满是文字的截图,问它“这里面讲了什么”,它居然准确地总结了内容,还提取了关键信息。

但多模态功能不只是“看图说话”那么简单。在实际项目中,我常用它来做这些事:

信息提取:上传一张收据,让AI提取金额、商家、日期。以前要用OCR加规则引擎,现在几行代码搞定:

receipt_img = PIL.Image.open("receipt.jpg")
response = model.generate_content([
    "提取这张收据上的以下信息,以JSON格式返回:",
    "1. 商家名称 2. 总金额 3. 日期 4. 商品列表",
    receipt_img
])

内容审核:自动检查用户上传的图片是否合适。这比传统的图像识别模型灵活多了,因为你可以用自然语言描述审核规则:

response = model.generate_content([
    "这张图片是否包含不适合公开的内容?",
    "只回答'是'或'否',然后简要说明原因。",
    user_image
])

创意辅助:我有个做设计的朋友,经常上传草图让AI给建议:

response = model.generate_content([
    "这是一张网站首页的草图,",
    "请从UI/UX角度给出3条改进建议,",
    "并指出色彩搭配是否协调。",
    design_sketch
])

多模态调用有个成本问题需要留意。图片会占用大量token,特别是高分辨率图片。Gemini API会根据图片尺寸和复杂度计算token消耗。我的经验是,如果不需要分析细节,可以先压缩图片。但要注意,压缩太厉害可能丢失关键信息。

还有一个实用技巧:你可以同时上传多张图片让AI分析关系。比如上传产品的前后左右视图,问它“这些是同一个产品的不同角度吗?”或者上传“之前”和“之后”的对比图,让AI描述变化。

4. 代码执行:让AI不仅说,还能做

这是Gemini最新也是最强大的功能之一——代码执行。简单说,就是AI不仅能回答问题,还能写代码并执行它,然后把结果告诉你。我第一次用这个功能时,感觉就像有个程序员同事在旁边,你说需求,他现场写代码跑给你看。

想象一下这个场景:你上传一张数据图表图片,问“这组数据的平均值是多少?”传统AI只能猜,但有了代码执行能力,AI可以写Python代码读取图片中的数据点,计算平均值,然后告诉你准确结果。

要启用代码执行,需要在请求配置中指定工具。最新版的Gemini 3 Flash模型对这个功能支持最好:

from google import genai
from google.genai import types
import requests
from PIL import Image
import io

def analyze_with_code_execution(image_url, question):
    client = genai.Client()
    
    # 下载图片
    image_bytes = requests.get(image_url).content
    
    response = client.models.generate_content(
        model="gemini-3-flash-preview",
        contents=[
            types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"),
            question
        ],
        config=types.GenerateContentConfig(
            tools=[types.Tool(code_execution=types.ToolCodeExecution())]
        ),
    )
    
    # 处理响应,可能包含文本、代码和执行结果
    for part in response.candidates[0].content.parts:
        if part.text is not None:
            print("AI说:", part.text)
        if part.executable_code is not None:
            print(f"\n生成的代码 ({part.executable_code.language}):")
            print(part.executable_code.code)
        if part.code_execution_result is not None:
            print("\n代码执行结果:")
            print(part.code_execution_result.output)

# 示例:分析图片中的仪表盘
analyze_with_code_execution(
    "https://example.com/gauge.jpg",
    "放大看这个仪表盘的读数区域,告诉我指针指向多少?"
)

这个功能特别适合需要精确计算或数据提取的场景。我举几个实际用过的例子:

数学计算:以前让AI算数学题,它可能瞎猜。现在它可以正经写代码算了:

response = client.models.generate_content(
    model="gemini-3-flash-preview",
    contents="计算前100个质数的和,写出代码并执行验证",
    config=types.GenerateContentConfig(
        tools=[types.Tool(code_execution=types.ToolCodeExecution())]
    ),
)

图像处理:让AI分析图片并标注:

response = client.models.generate_content(
    model="gemini-3-flash-preview",
    contents=[
        types.Part.from_bytes(data=family_photo, mime_type="image/jpeg"),
        "用箭头标出图片中所有人的脸,并统计人数"
    ],
    config=types.GenerateContentConfig(
        tools=[types.Tool(code_execution=types.ToolCodeExecution())]
    ),
)

数据转换:上传混乱的数据表格图片,让AI整理成结构化数据。AI可以写代码识别表格、解析数据、转换成CSV。

但代码执行功能也有安全考虑。Gemini在沙箱环境中运行生成的代码,有严格限制,不能访问网络、文件系统或进行危险操作。不过在实际应用中,我还是建议:

  1. 仔细审查AI生成的代码再执行(虽然API自动执行,但你可以先看看)
  2. 不要用这个功能处理敏感数据
  3. 对执行时间设限,避免无限循环

我发现在聊天场景中结合代码执行特别有用。你可以先和AI讨论问题,然后让它“写段代码验证一下”。比如讨论算法时,AI可以直接给出实现并运行测试。

5. 聊天模式与上下文管理

单次问答虽然有用,但真正的对话需要记忆上下文。Gemini的聊天模式让这变得简单。我第一次实现多轮对话时,发现用户体验完全不一样——AI能记住之前说过的话,对话变得连贯自然。

最基本的聊天会话这样创建:

import google.generativeai as genai
import os

def simple_chat():
    genai.configure(api_key=os.getenv('GEMINI_API_KEY'))
    model = genai.GenerativeModel('gemini-pro')
    
    # 开始一个新聊天
    chat = model.start_chat(history=[])
    
    # 发送消息
    response = chat.send_message("你好,我是小明")
    print(f"AI: {response.text}")
    
    # 继续对话,AI会记住上下文
    response = chat.send_message("我刚才说我叫什么名字?")
    print(f"AI: {response.text}")  # 它会记得你是小明

if __name__ == '__main__':
    simple_chat()

但实际项目中的聊天要复杂得多。我做过一个客服机器人,需要处理这些情况:

历史记录管理:聊天会话默认会保存历史,但有时候你需要手动管理。比如用户开始新话题时,你可能想清空历史,或者只保留最近几轮对话。我发现保留10-15轮对话效果最好,再多可能让AI混乱。

系统指令:你可以给AI一个固定的身份或行为准则。这在 start_chat 时通过 system_instruction 参数设置:

chat = model.start_chat(
    history=[],
    system_instruction="你是一个专业的编程助手,回答要简洁准确。如果用户问与编程无关的问题,礼貌地拒绝。"
)

流式聊天:聊天也可以流式输出,体验更好:

chat = model.start_chat(history=[])
response = chat.send_message("讲一个长篇故事", stream=True)

for chunk in response:
    print(chunk.text, end='', flush=True)

我在实际项目中踩过几个坑,分享给你避免:

上下文长度限制:每个模型都有token限制,gemini-pro 约32768个token。如果对话太长,最旧的消息会被丢弃。你需要监控对话长度,或者在达到限制时主动总结历史、重新开始。

历史消息格式:手动设置历史消息时,格式必须正确。必须是 usermodel 交替的列表:

history = [
    {'role':'user', 'parts': ["你好"]},
    {'role':'model', 'parts': ["你好!有什么可以帮助你的?"]},
    {'role':'user', 'parts': ["我想学Python"]},
    {'role':'model', 'parts': ["Python是个很好的选择..."]}
]

我见过有人把role写错,或者parts不是列表,导致AI无法理解上下文。

多模态聊天:聊天中也可以混合图片和文字:

chat = model.start_chat(history=[])
img = PIL.Image.open("product.jpg")

# 第一次发送图片
response = chat.send_message([
    "看看这个产品",
    img
])

# 后续可以基于图片提问
response = chat.send_message("这个产品是什么颜色的?")

处理中断和恢复:在实际应用中,用户可能中途离开,稍后回来继续对话。你需要能保存和恢复聊天状态。我的做法是把历史消息序列化存储(比如用JSON),恢复时重新创建聊天:

import json

# 保存聊天
def save_chat(chat, filename):
    history = chat.history
    with open(filename, 'w') as f:
        json.dump([{'role': msg.role, 'parts': msg.parts} for msg in history], f)

# 恢复聊天
def load_chat(model, filename):
    with open(filename, 'r') as f:
        history_data = json.load(f)
    
    # 需要把parts从文本转回Part对象
    history = []
    for msg in history_data:
        history.append({
            'role': msg['role'],
            'parts': msg['parts']
        })
    
    return model.start_chat(history=history)

聊天模式中最有用的功能之一是 函数调用(Function Calling)。虽然原始文章没提,但这是构建智能应用的关键。你可以定义一些函数,AI在对话中判断需要时,会请求调用这些函数。比如定义“查询天气”函数,用户问“明天天气如何”时,AI会返回函数调用请求,你执行函数后把结果给AI,AI再组织成自然语言回答。

6. 高级配置与性能调优

当你熟悉了基础用法后,肯定会想优化性能和控制成本。Gemini API提供了丰富的配置选项,我花了不少时间测试各种组合,这里分享一些实用经验。

生成配置:这是最常用的配置,控制AI如何生成内容:

from google.generativeai.types import GenerationConfig

response = model.generate_content(
    "写一首关于春天的诗",
    generation_config=GenerationConfig(
        temperature=0.7,      # 创造性,0-1,越高越随机
        top_p=0.9,           # 核采样,控制多样性
        top_k=40,            # 候选词数量
        max_output_tokens=500, # 最大输出长度
        stop_sequences=["###"], # 停止序列
        candidate_count=1,    # 生成几个候选回答
    )
)

我重点说几个关键参数:

  • temperature:我最常调整的。写创意内容时设0.8-0.9,需要确定性答案时设0.1-0.3。默认0.7适合大多数场景。
  • max_output_tokens:一定要设置!我有次忘了设,AI给我生成了上万字的废话,浪费token。根据场景合理设置,短回答100-200,长文章1000-2000。
  • stop_sequences:很有用。比如让AI生成JSON时,可以设 ["}"] 确保完整结束。

安全设置:控制AI回答的“安全等级”:

from google.generativeai.types import SafetySetting
import google.generativeai as genai

safety_settings = [
    {
        "category": "HARM_CATEGORY_HARASSMENT",
        "threshold": "BLOCK_MEDIUM_AND_ABOVE"
    },
    {
        "category": "HARM_CATEGORY_HATE_SPEECH", 
        "threshold": "BLOCK_ONLY_HIGH"
    },
    # 还有其他类别:SEXUALLY_EXPLICIT, DANGEROUS_CONTENT等
]

response = model.generate_content(
    prompt,
    safety_settings=safety_settings
)

安全等级从低到高有:BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE。我一般用 BLOCK_MEDIUM_AND_ABOVE,在安全和实用性间取得平衡。如果AI因安全原因拒绝回答,可以通过 response.prompt_feedback 查看原因。

Token使用统计:控制成本很重要,特别是大规模使用时:

response = model.generate_content(prompt)

# 查看用了多少token
if hasattr(response, 'usage_metadata'):
    print(f"输入token: {response.usage_metadata.prompt_token_count}")
    print(f"输出token: {response.usage_metadata.candidates_token_count}")
    print(f"总token: {response.usage_metadata.total_token_count}")

我建议记录每次调用的token使用,特别是处理图片时。一张1024x1024的图片可能消耗上千token。对于文本,英文大约1token=0.75单词,中文更复杂,1个汉字可能对应1-2个token。

超时和重试:生产环境必须有错误处理:

import time
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def generate_with_retry(prompt, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = model.generate_content(prompt, timeout=30)  # 30秒超时
            return response
        except Exception as e:
            if attempt == max_retries - 1:
                raise
            wait_time = 2 ** attempt  # 指数退避
            time.sleep(wait_time)
            print(f"请求失败,{wait_time}秒后重试...")

批量处理:如果需要处理大量请求,不要一个个发,用批量:

# 假设有多个prompt
prompts = ["总结1", "总结2", "总结3"]

responses = []
for prompt in prompts:
    response = model.generate_content(prompt)
    responses.append(response.text)
    
# 或者用线程池加速
from concurrent.futures import ThreadPoolExecutor

def process_one(prompt):
    return model.generate_content(prompt).text

with ThreadPoolExecutor(max_workers=5) as executor:
    results = list(executor.map(process_one, prompts))

但要注意API的速率限制。免费版每分钟约60次请求,付费版更高。如果超限,请求会失败,需要实现限流。

缓存策略:相同的问题没必要每次都问AI。我常用简单的缓存:

import hashlib
import pickle

cache = {}

def get_cached_response(prompt, model_name="gemini-pro"):
    # 用prompt和模型名生成缓存键
    key = hashlib.md5(f"{prompt}_{model_name}".encode()).hexdigest()
    
    if key in cache:
        return cache[key]
    
    response = model.generate_content(prompt)
    cache[key] = response.text
    return response.text

对于生产环境,可以用Redis或数据库做分布式缓存。

模型选择策略:不同任务用不同模型。我的经验是:

  • 简单问答:gemini-2.0-flash-lite(快且便宜)
  • 复杂推理:gemini-2.5-pro(能力强但慢)
  • 多模态:gemini-2.0-pro-vision 或最新的 gemini-3-flash-preview
  • 代码相关:gemini-3-flash-preview(代码执行功能好)

最后提醒一点:定期检查API使用情况和费用。Google AI Studio有使用统计,设置预算提醒,避免意外费用。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐