Gemini 調用方式
對於 Gemini 系列,我們提供原生調用和 Openai 相容這 2 種調用方式。使用前請執行
pip install google-genai 或 pip install -U google-genai,安裝(更新)原生依賴。
1️⃣ 原生調用時,需在內部傳入 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 2.5 系列「推理」說明
- 2.5 系列皆為推理模型。
- 2.5 flash 為混合模型,類似 claude sonnet 3.7,可用
thinking_budget控制推理預算以達最佳效果。 - 2.5 pro 為純推理模型,無法關閉 thinking,也不顯式傳遞推理預算。
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。
多媒體文件
Aihubmix 目前只支持小於 20MB 的多媒體文件(圖片、音頻、視頻),用inline_data 上傳。大於 20M 的多媒體需要用 File API(尚未支持),待完善狀態跟踪,返回
upload_url。
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.0-flash",
contents=types.Content(
parts=[
types.Part(
inline_data=types.Blob(
data=file_bytes,
mime_type="image/jpeg"
)
),
types.Part(
text="Describe the image."
)
]
)
)
print(response.text)
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)
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:create(background: true) + get / cancel / delete)均已支援。
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));
}
}
非同步模式(Background Interactions)
傳入background: true 發起背景推理。請求立即返回 Interaction 物件,status 為 in_progress,id 為該任務的控制代碼,模型在背景繼續推理。用 interactions.get(id) 輪詢取得結果,建議間隔 3 到 5 秒。適用於耗時較長的推理,無需保持長連線。
任務結果尚未就緒時,
get() 會返回 400 或 403。這表示結果還沒生成完,應繼續輪詢,不要當作失敗終止。只有返回 200 時 status 才是終態(completed / failed / cancelled)。JavaScript
const task = await ai.interactions.create({
model: "gemini-3.5-flash",
input: "Explain the water cycle in three sentences.",
background: true,
});
console.log(task.id, task.status); // iact1_xxx in_progress
let result;
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 3000));
try {
const current = await ai.interactions.get(task.id);
if (["completed", "failed", "cancelled"].includes(current.status)) {
result = current;
break;
}
} catch (err) {
continue; // 結果未就緒,繼續輪詢
}
}
console.log(result.output_text);
await ai.interactions.delete(task.id); // 已取回終態結果,可安全刪除
id以iact1_開頭,請原樣保存,後續get/cancel/delete都用它,不要截斷或改寫。- 任務執行中時,模型推理廠商不受理
cancel請求,返回403;delete在任務到達終態前返回409,需先用get()取回終態結果再刪除。 background與stream不能同時使用;圖像模型(如gemini-3.1-flash-image)不支援非同步模式。
完整的 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
# 定義模型的 function 宣告
def 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"],
},
}
# 配置 client
client = OpenAI(
api_key="sk-***", # 換成你在 AiHubMix 生成的密鑰
base_url="https://aihubmix.com/v1",
)
# 用 OpenAI 相容格式發送帶有 function 宣告的請求
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 相容,更穩定的請求方式
)
# 檢查是否有 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)
# 在實際應用中,這裡可以調用你的 function:
# 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-08-14