Gemini 调用方式
对于 Gemini 系列,我们提供原生调用和 Openai 兼容这 2 种调用方式。使用前运行
pip install google-genai 或 pip install -U google-genai,安装(更新)原生依赖。
1️⃣ 对于原生调用,我们的 Gemini 调用支持 AI Studio 和 VertexAI 自动路由。转发方法主要是在内部传入 AIHubMix 密钥和请求链接。需要注意的是,这个链接和常规的 base_url 写法不同,请参考示例:
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
v1 端点:
client = OpenAI(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
base_url="https://aihubmix.com/v1",
)
- 原生调用:传入
include_thoughts=True - OpenAI 兼容方式:传入
reasoning_effort
Gemini 3 Pro Image Preview 说明
Gemini 3 Pro Image Preview(Nano Banana Pro 预览版)专为专业素材资源制作和复杂指令而设计。该模型具有以下特点:- 使用Google 搜索实时获取世界知识
- 默认“思考”过程(在生成之前优化构图)
- 能够生成分辨率高达 4K 的图像
- 流式模式只返回推理过程,生成的图片不会在流式输出中出现。
- 如需获取图片数据,请使用非流式请求。
import os
from google import genai
from google.genai import types
API_KEY = "<YOUR AIHUBMIX API KEY>"
client = genai.Client(
api_key=API_KEY,
http_options={"base_url": "https://aihubmix.com/gemini"},
)
prompt = (
"Da Vinci style anatomical sketch of a dissected Monarch butterfly. "
"Detailed drawings of the head, wings, and legs on textured parchment with notes in English."
)
# 可选参数
aspect_ratio = "1:1" # 支持: "1:1","2:3","3:2","3:4","4:3","4:5","5:4","9:16","16:9","21:9"
resolution = "4K" # 默认1K,支持: "1K", "2K", "4K",注意:必须是大写“K”
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents=prompt,
config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE'],
image_config=types.ImageConfig(
aspect_ratio=aspect_ratio,
image_size=resolution,
),
),
)
# 保存图片 & 输出文本
for part in response.parts:
if part.text:
print(part.text)
elif image := part.as_image():
image.save("butterfly.png")
print("Image saved: butterfly.png")
from google import genai
from PIL import Image
API_KEY = "<YOUR AIHUBMIX API KEY>"
client = genai.Client(
api_key=API_KEY,
http_options={"base_url": "https://aihubmix.com/gemini"}
)
prompt = (
"Create a picture of my cat eating a nano-banana "
"in a fancy restaurant under the Gemini constellation."
)
image = Image.open("cat_image.jpg")
response = client.models.generate_content(
model="gemini-2.5-flash-image",
contents=[prompt, image],
)
# 保存图片 & 输出文本
for part in response.parts:
if part.text is not None:
print(part.text)
elif part.inline_data is not None:
image = part.as_image()
image.save("generated_image.png")
from google import genai
from google.genai import types
from PIL import Image
API_KEY = "<YOUR AIHUBMIX_API_KEY>"
prompt = "An office group photo of these people, they are making funny faces."
aspect_ratio = "5:4"
resolution = "2K"
client = genai.Client(
api_key=API_KEY,
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents=[
prompt,
Image.open('person1.png'),
Image.open('person2.png'),
Image.open('person3.png'),
Image.open('person4.png'),
Image.open('person5.png'),
],
config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE'],
image_config=types.ImageConfig(
aspect_ratio=aspect_ratio,
image_size=resolution,
),
)
)
# 保存图片 & 输出文本
for part in response.parts:
if part.text is not None:
print(part.text)
elif image := part.as_image():
image.save("office.png")
from google import genai
from google.genai import types
API_KEY = "<YOUR AIHUBMIX API KEY>"
prompt = (
"Visualize the current weather forecast for the next 5 days in Shanghai "
"as a clean, modern weather chart. Add a visual on what I should wear each day."
) # 将上海近五日天气以天气图表形式呈现出来
aspect_ratio = "16:9"
client = genai.Client(
api_key=API_KEY,
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-3-pro-image-preview",
contents=prompt,
config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE'],
image_config=types.ImageConfig(
aspect_ratio=aspect_ratio,
),
tools=[{"google_search": {}}]
)
)
# 保存图片 & 输出文本
for part in response.parts:
if part.text is not None:
print(part.text)
elif image := part.as_image():
image.save("weather.png")
Gemini 2.5 系列的「推理」说明
- 2.5 系列都是推理模型。
- 2.5 flash 是混合模型,类似 claude sonnet 3.7,可以通过用
thinking_budget控制推理预算来达到最佳效果。 - 2.5 pro 是纯粹的推理模型,因此不能关闭 thinking、也不显式传递推理预算。
- 温度值支持范围 0 <=
temprature<= 2
from google import genai
from google.genai import types
def generate():
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.0-flash"
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""For the average stock investor, if analyzing financial reports works, why is luck still needed?"""),
],
),
]
print(client.models.generate_content(
model=model,
contents=contents,
))
if __name__ == "__main__":
generate()
from google import genai
from google.genai import types
def generate():
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.0-flash"
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""For the average stock investor, if analyzing financial reports works, why is luck still needed?"""),
],
),
]
generate_content_config = types.GenerateContentConfig(
response_mime_type="text/plain",
)
for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
print(chunk.text, end="")
if __name__ == "__main__":
generate()
from google import genai
from google.genai import types
def generate():
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.5-flash-preview-04-17" #gemini-2.5-pro-preview-03-25、gemini-2.5-flash-preview-04-17
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""For the average stock investor, if analyzing financial reports works, why is luck still needed?"""),
],
),
]
generate_content_config = types.GenerateContentConfig(
thinking_config = types.ThinkingConfig(
thinking_budget=2048, #范围 0-16384。默认 1024,最佳边际效果 16000
),
response_mime_type="text/plain",
)
for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
print(chunk.text, end="")
if __name__ == "__main__":
generate()
from google import genai
from google.genai import types
def generate():
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.5-pro-preview-03-25"
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""How do I know I'm not just wasting my time?"""),
],
),
]
generate_content_config = types.GenerateContentConfig(
response_mime_type="text/plain",
)
for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
print(chunk.text, end="")
if __name__ == "__main__":
generate()
from google import genai
from google.genai import types
def generate():
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.5-pro-preview-05-06"
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""How is the Rule of 72 in finance derived?"""),
],
),
]
generate_content_config = types.GenerateContentConfig(
response_mime_type="text/plain",
thinking_config=types.ThinkingConfig(
include_thoughts=True # 🧠 启用思考过程输出
),
)
# 用于存储最后一个 chunk 的 usage_metadata
final_usage_metadata = None
for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
# 检查是否有内容部分
if chunk.candidates and len(chunk.candidates) > 0:
for part in chunk.candidates[0].content.parts:
if part.text:
if part.thought:
# 思考过程内容
print(part.text, end="")
else:
# 最终答案内容
print(part.text, end="")
# 保存最新的 usage_metadata,只有最后一个 chunk 会包含完整信息
if chunk.usage_metadata:
final_usage_metadata = chunk.usage_metadata
# 在所有 chunk 处理完后,打印完整的 token 使用情况
if final_usage_metadata:
print(f"\n\n📊 Token 使用情况:")
print(f"思考 tokens: {getattr(final_usage_metadata, 'thoughts_token_count', '不可用')}")
print(f"输出 tokens: {getattr(final_usage_metadata, 'candidates_token_count', '不可用')}")
print(f"总计: {final_usage_metadata}")
if __name__ == "__main__":
generate()
Gemini 2.5 Flash 支持
Openai 兼容方式调用参考如下:from openai import OpenAI
client = OpenAI(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
base_url="https://aihubmix.com/v1",
)
completion = client.chat.completions.create(
model="gemini-2.5-flash-preview-04-17-nothink",
messages=[
{
"role": "user",
"content": "Explain the Occam's Razor concept and provide everyday examples of it"
}
]
)
print(completion.choices[0].message.content)
from openai import OpenAI
client = OpenAI(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
base_url="https://aihubmix.com/v1",
)
completion = client.chat.completions.create(
model="gemini-2.5-flash-preview-04-17",
reasoning_effort="low", # 可选 "low", "medium" 和 "high", 分别对应 1024, 8192 和 16384 推理预算
messages=[
{
"role": "user",
"content": "Explain the Occam's Razor concept and provide everyday examples of it"
}
]
)
print(completion.choices[0].message.content)
curl -X POST https://aihubmix.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-***" \
-d '{
"model": "gemini-2.5-flash-preview-04-17-nothink",
"messages": [
{
"role": "user",
"content": "Explain the Occam'\''s Razor concept and provide an everyday example of it."
}
]
}'
curl https://aihubmix.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-***" \
-d '{
"model": "gemini-2.5-pro-preview-05-06",
"messages": [
{
"role": "user",
"content": "Explain the Occam'\''s Razor concept and provide an everyday example of it."
}
],
"reasoning_effort": "low"
}'
- 用于复杂任务时,只需要将模型 id 设置为默认开启思考的
gemini-2.5-flash-preview-04-17即可。 - Gemini 2.5 Flash 通过
budget(思考预算)来控制思考的深度,范围 0-16K,目前转发采用的是默认预算 1024,最佳边际效果为 16K。
多媒体文件
- 对于 20MB 以下的多媒体文件(图片、音频、视频),用
inline_data上传。 - 当多媒体文件大于 20M 时,需要用 Files API。
20M 以下文件
你可以增加
EDIARESOLUTION_MEDIUM 参数来约束图片的精度,从而大幅节省输入的费用以及减少大图报错的可能性。支持的媒体分辨率参数值:| 参数名 | 备注 |
|---|---|
| MEDIA_RESOLUTION_UNSPECIFIED | 媒体分辨率未指定 |
| MEDIA_RESOLUTION_LOW | 媒体分辨率设为 low (64 tokens). |
| MEDIA_RESOLUTION_MEDIUM | 媒体分辨率设为 medium (256 tokens). |
| MEDIA_RESOLUTION_HIGH | 媒体分辨率设为 high (zoomed reframing with 256 tokens). |
from google import genai
from google.genai import types
# 读取文件为二进制数据
file_path = "yourpath/file.jpeg"
with open(file_path, "rb") as f:
file_bytes = f.read()
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=types.Content(
parts=[
types.Part(
inline_data=types.Blob(
data=file_bytes,
mime_type="image/jpeg"
)
),
types.Part(
text="Describe the image."
)
]
),
config=types.GenerateContentConfig(
system_instruction="You are a helpful assistant that can describe images.",
max_output_tokens=768,
temperature=0.1,
thinking_config=types.ThinkingConfig(
thinking_budget=0, include_thoughts=False
),
media_resolution=types.MediaResolution.MEDIA_RESOLUTION_MEDIUM # 256 tokens
)
)
print(response.text)
print(response.usage_metadata) # 输出 token 花费细节
from google import genai
from google.genai import types
# 读取文件为二进制数据
file_path = "yourpath/file.m4a"
with open(file_path, "rb") as f:
file_bytes = f.read()
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=types.Content(
parts=[
types.Part(
inline_data=types.Blob(
data=file_bytes,
mime_type="audio/m4a"
)
),
types.Part(
text="Transcribe the audio to text."
)
]
)
)
print(response.text)
from google import genai
from google.genai import types
# 读取文件为二进制数据
file_path = "yourpath/file.mp4"
with open(file_path, "rb") as f:
file_bytes = f.read()
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=types.Content(
parts=[
types.Part(
inline_data=types.Blob(
data=file_bytes,
mime_type="video/mp4"
)
),
types.Part(
text="Summarize this video. Then create a quiz with an answer key based on the information in this video."
)
]
)
)
print(response.text)
from google import genai
from google.genai import types
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=types.Content(
parts=[
types.Part(
file_data=types.FileData(
file_uri="https://www.youtube.com/watch?v=OoU7PwNyYUw"
)
),
types.Part(
text="Please summarize the video in 3 sentences."
)
]
)
)
print(response.text)
Files API
Gemini 可以同时处理各种类型的输入数据,包括文本、图片和音频。当总请求大小(包括文件、文本提示、系统指令等)超过 20 MB 时,请务必使用 Files API。- 不支持列出已上传的文件
- 文件会在 48 小时后自动删除,也可以手动删除已上传的文件
from google import genai
client = genai.Client(
api_key="sk-****",
http_options={"base_url": "https://aihubmix.com/gemini"},
)
myfile = client.files.upload(file="path/to/sample.mp3")
response = client.models.generate_content(
model="gemini-2.5-flash", contents=["Describe this audio clip", myfile]
)
print(response.text)
from google import genai
client = genai.Client(
api_key="sk-****",
http_options={"base_url": "https://aihubmix.com/gemini"},
)
myfile = client.files.upload(file='path/to/sample.mp3')
file_name = myfile.name
myfile = client.files.get(name=file_name)
print(myfile)
from google import genai
client = genai.Client()
myfile = client.files.upload(file='path/to/sample.mp3')
client.files.delete(name=myfile.name)
Code Execution
自动代码解析器用例参考:Python
from google import genai
from google.genai import types
# 读取文件为二进制数据
file_path = "yourpath/file.csv"
with open(file_path, "rb") as f:
file_bytes = f.read()
client = genai.Client(
api_key="sk-***", # 🔑 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"}
)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=types.Content(
parts=[
types.Part(
inline_data=types.Blob(
data=file_bytes,
mime_type="text/csv"
)
),
types.Part(
text="Please analyze this CSV and summarize the key statistics. Use code execution if needed."
)
]
),
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(part.text)
if getattr(part, "executable_code", None) is not None:
print("Generated code:\n", part.executable_code.code)
if getattr(part, "code_execution_result", None) is not None:
print("Execution result:\n", part.code_execution_result.output)
Interactions API
Interactions 是 Gemini 新一代推理接口,返回结构化的Interaction 对象,支持文本生成、原生图像生成(Nano Banana)及多步推理。目前已支持同步模式(interactions.create());异步模式(Background Interactions)敬请期待。
SDK 版本要求:
@google/genai >= 2.0.0(JS/TS)或 google-genai >= 2.0.0(Python)。低版本 SDK 调用 Interactions 会被 Google 后端拒绝(legacy Interactions schema no longer supported)。文本生成
调用interactions.create() 发起推理,返回的 Interaction 对象提供 output_text 便捷属性。
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: "sk-***", // 替换为你在 AIHubMix 生成的 API Key
httpOptions: { baseUrl: "https://aihubmix.com/gemini" },
});
const interaction = await ai.interactions.create({
model: "gemini-3.5-flash",
input: "Explain quantum computing in one sentence",
});
console.log(interaction.output_text);
console.log(interaction.usage);
// { total_tokens, total_input_tokens, total_output_tokens, ... }
from google import genai
client = genai.Client(
api_key="sk-***", # 替换为你在 AIHubMix 生成的 API Key
http_options={"base_url": "https://aihubmix.com/gemini"},
)
interaction = client.interactions.create(
model="gemini-3.5-flash",
input="Explain quantum computing in one sentence",
)
print(interaction.output_text)
原生图像生成
通过response_format 配置输出模态为图像,返回的 Interaction 对象提供 output_image 便捷属性。
- 推荐模型
gemini-3.1-flash-image(Nano Banana 2,通用生图模型)。 response_modalities值必须为小写['text', 'image'];大写为generateContentAPI 的写法,在 Interactions API 中会返回400。- 勿传
delivery: 'inline'(400 Image delivery mode is not supported),结果默认即以 inline 方式返回。
import { GoogleGenAI } from "@google/genai";
import fs from "node:fs";
const ai = new GoogleGenAI({
apiKey: "sk-***", // 替换为你在 AIHubMix 生成的 API Key
httpOptions: { baseUrl: "https://aihubmix.com/gemini" },
});
const interaction = await ai.interactions.create({
model: "gemini-3.1-flash-image",
input: "A translucent banana-shaped glass lamp on a white desk, soft studio lighting.",
response_modalities: ["text", "image"],
response_format: { type: "image", aspect_ratio: "1:1", image_size: "1K" },
});
// output_image 便捷属性(取最后一张生成图像)
if (interaction.output_image?.data) {
fs.writeFileSync("output.png", Buffer.from(interaction.output_image.data, "base64"));
}
import base64
from google import genai
client = genai.Client(
api_key="sk-***", # 替换为你在 AIHubMix 生成的 API Key
http_options={"base_url": "https://aihubmix.com/gemini"},
)
interaction = client.interactions.create(
model="gemini-3.1-flash-image",
input="A translucent banana-shaped glass lamp on a white desk, soft studio lighting.",
response_format={
"type": "image",
"aspect_ratio": "1:1",
"image_size": "1K",
},
)
if interaction.output_image:
with open("output.png", "wb") as f:
f.write(base64.b64decode(interaction.output_image.data))
流式输出
传入stream: true 启用 SSE 流式传输。增量文本通过 event.delta.text 获取。
JavaScript
const stream = await ai.interactions.create({
model: "gemini-3.5-flash",
input: "Write a haiku about the moon",
stream: true,
});
for await (const event of stream) {
if (event.event_type === "step.delta" && event.delta?.type === "text") {
process.stdout.write(event.delta.text);
}
if (event.event_type === "interaction.completed") {
console.log("\nUsage:", JSON.stringify(event.interaction?.usage));
}
}
完整的 SDK 接入指南(含 Embeddings、显式缓存 CRUD、能力矩阵等)请参考 Gemini 原生 SDK 接入。
上下文缓存
Gemini 在原生 API 下默认启用了隐式上下文缓存,无需开发者手动操作。每一次generate_content 请求,系统会自动为输入内容建立缓存。当后续请求与此前内容完全一致时,将直接命中缓存,返回上一次的推理结果,大幅提升响应速度并有机会节省 token 消耗。
- 缓存自动生效,无需手动配置。
- 缓存仅在内容、模型、参数完全一致时生效;任何字段不同都会视为新请求,不命中缓存。
- 缓存有效期(TTL)由开发者设定,也可以不设置。如果未指定,默认为 1 小时。无最小或最大时长限制,费用取决于缓存 token 数与缓存时间。
- 虽然 Google 官方对 TTL 不设上下限,但由于我们作为转发平台,仅支持有限的 TTL 配置范围,不保证永久有效。
注意事项
- 无成本节省保证:缓存 token 的计费为输入原价的 25%,理论上输入部分可最多节省 75% 成本,但 Google 官方并未承诺必然节省,实际账单还需结合缓存命中率、token 类型与存储时长共同评估。
- 缓存命中条件:建议将重复的上下文放在请求前部,将易变内容(如用户输入)置于后部,以提高缓存命中率。
-
缓存命中反馈:如果响应结果命中缓存,在
response.usage_metadata中会包含cache_tokens_details字段,并有cached_content_token_count,开发者可以据此判断本次请求是否命中缓存。
示例响应字段(命中缓存时):cache_tokens_details=[ModalityTokenCount(modality=<MediaModality.TEXT: 'TEXT'>, token_count=2003)] cached_content_token_count=2003
from google import genai
client = genai.Client(
http_options={"base_url": "https://aihubmix.com/gemini"},
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
)
prompt = """
Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off—then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me. There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs—commerce surrounds it with her surf. Right and left, the streets take you waterward.
"""
def generate_content_sync():
response = client.models.generate_content(
model="gemini-2.5-flash-preview-05-20",
contents=prompt + "How many sentences are in this passage? ",
)
print(response.usage_metadata) # 命中缓存时会显示 cache_tokens_details 和 cached_content_token_count 字段
return response
generate_content_sync()
命中缓存时,核心结论:隐式缓存支持自动命中与命中反馈。开发者可以通过 usage_metadata 判断命中情况。成本节省非保证,实际效果因请求结构和使用场景而异。response.usage_metadata会包含如下结构:cache_tokens_details=[ModalityTokenCount(modality=<MediaModality.TEXT: 'TEXT'>, token_count=2003)] cached_content_token_count=2003
Function calling
使用 openai 兼容方式调用 Gemini 的 function calling 功能时,需要在请求体内部传入tool_choice="auto",否则会报错。
from openai import OpenAI
# Define the function declaration for the model
schedule_meeting_function = {
"name": "schedule_meeting",
"description": "Schedules a meeting with specified attendees at a given time and date.",
"parameters": {
"type": "object",
"properties": {
"attendees": {
"type": "array",
"items": {"type": "string"},
"description": "List of people attending the meeting.",
},
"date": {
"type": "string",
"description": "Date of the meeting (e.g., '2024-07-29')",
},
"time": {
"type": "string",
"description": "Time of the meeting (e.g., '15:00')",
},
"topic": {
"type": "string",
"description": "The subject or topic of the meeting.",
},
},
"required": ["attendees", "date", "time", "topic"],
},
}
# Configure the client
client = OpenAI(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
base_url="https://aihubmix.com/v1",
)
# Send request with function declarations using OpenAI compatible format
response = client.chat.completions.create(
model="gemini-2.0-flash",
messages=[
{"role": "user", "content": "Schedule a meeting with Bob and Alice for 03/14/2025 at 10:00 AM about the Q3 planning."}
],
tools=[{"type": "function", "function": schedule_meeting_function}],
tool_choice="auto" ## 📍 此处追加了 Aihubmix 兼容,更稳定的请求方式
)
# Check for a function call
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
function_call = tool_call.function
print(f"Function to call: {function_call.name}")
print(f"Arguments: {function_call.arguments}")
print(response.usage)
# In a real app, you would call your function here:
# result = schedule_meeting(**json.loads(function_call.arguments))
else:
print("No function call found in the response.")
print(response.choices[0].message.content)
Function to call: schedule_meeting
Arguments: {"attendees":["Bob","Alice"],"date":"2025-03-14","time":"10:00","topic":"Q3 planning"}
CompletionUsage(completion_tokens=28, prompt_tokens=111, total_tokens=139, completion_tokens_details=None, prompt_tokens_details=None)
Tokens 用量追踪
- Gemini 原生采用
usage_metadata来追踪使用的 token,其中的字段对应如下:
- prompt_token_count: 输入 token 数
- candidates_token_count: 输出 token 数
- thoughts_token_count: 推理使用的 token 数,性质上也是输出 token
- total_token_count: 总 token 使用量(输入+输出)
- 对于 OpenAI 兼容格式,则采用
.usage来追踪,字段对应如下:
- usage.completion_tokens: 输入 token 数
- usage.prompt_tokens: 输出 token 数(包含推理使用的 token 数)
- usage.total_tokens:总 token 使用量
from google import genai
from google.genai import types
import time
def generate():
client = genai.Client(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
http_options={"base_url": "https://aihubmix.com/gemini"},
)
model = "gemini-2.5-pro-preview-03-25"
contents = [
types.Content(
role="user",
parts=[
types.Part.from_text(text="""How is the Rule of 72 in finance derived?"""),
],
),
]
generate_content_config = types.GenerateContentConfig(
response_mime_type="text/plain",
)
final_usage_metadata = None
for chunk in client.models.generate_content_stream(
model=model,
contents=contents,
config=generate_content_config,
):
print(chunk.text, end="")
if chunk.usage_metadata:
final_usage_metadata = chunk.usage_metadata
# 在所有 chunk 处理完后,打印完整的 token 使用情况
if final_usage_metadata:
print(f"\nUsage: {final_usage_metadata}")
if __name__ == "__main__":
generate()
from openai import OpenAI
client = OpenAI(
api_key="sk-***", # 换成你在 AiHubMix 生成的密钥
base_url="https://aihubmix.com/v1",
)
completion = client.chat.completions.create(
model="gemini-2.5-flash-preview-04-17",
reasoning_effort="low", #"low", "medium", and "high", which behind the scenes we map to 1K, 8K, and 24K thinking token budgets. If you want to disable thinking, you can set the reasoning effort to "none".
messages=[
{
"role": "user",
"content": "How is the Rule of 72 in finance derived?"
}
],
stream=True
)
#print(completion.choices[0].message.content)
for chunk in completion:
print(chunk.choices[0].delta)
# 只在最后一个 chunk(包含完整 usage 数据)时打印 usage 信息
if chunk.usage and chunk.usage.completion_tokens > 0:
print(f"输出 tokens: {chunk.usage.completion_tokens}")
print(f"输入 tokens: {chunk.usage.prompt_tokens}")
print(f"总 tokens: {chunk.usage.total_tokens}")
更新时间:2026-07-07