使用 Gemini 4 Carbon API in CometAPI 透過原生 Gemini 的 GenerateContent 介面,為你的應用加入推理與文件分析能力。先從短文字請求開始,確認生成已完成並儲存答案,再逐步加入 PDF 輸入、圖片、串流或結構化 JSON。本指南為每一步提供設定與回應處理的程式碼。
關鍵重點
模型 ID:gemini-4-carbon。無免費層 — 需付費 Gemini API / Cloud Billing。
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["COMETAPI_KEY"],
http_options={
"api_version": "v1beta",
"base_url": "https://api.cometapi.com",
},
)
model = os.getenv("COMETAPI_MODEL", "gemini-4-carbon")
def completed_text(response):
if not response.candidates:
raise RuntimeError("No candidate returned; inspect prompt feedback.")
candidate = response.candidates[0]
reason = getattr(candidate.finish_reason, "value", candidate.finish_reason)
if reason != "STOP":
raise RuntimeError(f"Generation did not finish normally: {reason}")
parts = candidate.content.parts if candidate.content else []
text = "".join(
part.text or "" for part in (parts or []) if not part.thought
)
if not text.strip():
raise RuntimeError("The completed candidate contains no answer text.")
return text
from pathlib import Path
from carbon_client import client, model, types, completed_text
response = client.models.generate_content(
model=model,
contents="Give me a five-point checklist for reviewing a Python API client.",
config=types.GenerateContentConfig(
max_output_tokens=4096,
thinking_config=types.ThinkingConfig(thinking_level="MEDIUM"),
),
)
answer = completed_text(response)
Path("answer.txt").write_text(answer, encoding="utf-8")
print(answer)
print("Saved answer.txt")
if response.usage_metadata:
print(response.usage_metadata.model_dump(exclude_none=True))
python first_request.py
## Gemini 4 Carbon API 如何分析檔案?
從與 carbon_client.py 相同的目錄執行這些示例。它們將本機檔案載入為內嵌內容片段,讓初始流程不依賴獨立的檔案上傳服務。
PDF 理解包含視覺內容:Gemini 能同時解讀文字、表格、圖表與圖片。[Google 的文件處理指南](https://ai.google.dev/gemini-api/docs/document-processing)說明支援最多 1,000 頁的 PDF,仍受檔案大小與上下文限制。頁數係上限,並不保證每個文件都能適配某個閘道的請求。
小型、暫時性 PDF 建議用內嵌輸入。對於較大的檔案或多輪提問,Google 建議使用 Files API 以避免重複傳送完整檔案。在經由 CometAPI 使用該流程前,請先確認其上傳端點與檔案引用支援;以下內嵌示例仍是實務上的起點。
### 摘要本機 PDF
Google 為 GenerateContent 記載了[內嵌 PDF 輸入](https://ai.google.dev/gemini-api/docs/document-processing)。將一份小型、非敏感的 report.pdf 放入專案目錄,儲存以下為 analyze_pdf.py,並執行 python analyze_pdf.py。
傳送本機 PDF 並儲存完成的摘要。
from pathlib import Path
from carbon_client import client, model, types, completed_text
response = client.models.generate_content(
model=model,
contents=[
types.Part.from_bytes(
data=Path("report.pdf").read_bytes(),
mime_type="application/pdf",
),
"Summarize this report in five bullets. Do not invent missing figures.",
],
config=types.GenerateContentConfig(max_output_tokens=4096),
)
from pathlib import Path
from carbon_client import client, model, types, completed_text
response = client.models.generate_content(
model=model,
contents=[
types.Part.from_bytes(
data=Path("screen.png").read_bytes(),
mime_type="image/png",
),
"Review this screenshot for unreadable text and overlapping elements. "
"Describe only visible issues and identify their locations.",
],
config=types.GenerateContentConfig(max_output_tokens=4096),
)
print(completed_text(response))
finish_reason = None
received_text = False
for chunk in client.models.generate_content_stream(
model=model,
contents="Write a concise checklist for investigating intermittent API timeouts.",
config=types.GenerateContentConfig(max_output_tokens=4096),
):
if not chunk.candidates:
continue
candidate = chunk.candidates[0]
if candidate.finish_reason is not None:
finish_reason = getattr(candidate.finish_reason, "value", candidate.finish_reason)
parts = candidate.content.parts if candidate.content else []
for part in parts or []:
if part.text and not part.thought:
received_text = True
print(part.text, end="", flush=True)
print()
if finish_reason != "STOP" or not received_text:
raise RuntimeError(f"Stream not accepted as complete: {finish_reason}")
import json
from carbon_client import client, model, types, completed_text
response = client.models.generate_content(
model=model,
contents=(
"Extract the service and impact from this incident note: "
"The checkout API returned errors for ten minutes during a database restart."
),
config=types.GenerateContentConfig(
max_output_tokens=4096,
response_mime_type="application/json",
response_schema={
"type": "OBJECT",
"properties": {
"service": {"type": "STRING"},
"impact": {"type": "STRING"},
},
"required": ["service", "impact"],
},
),
)
data = json.loads(completed_text(response))
if not isinstance(data, dict) or not all(
isinstance(data.get(field), str) for field in ("service", "impact")
):
raise ValueError("The response does not match the expected field types.")
print(json.dumps(data, indent=2))