Gemini generateContent
MarkdownΗ εγγενής μορφή του Google Gemini: για Gemini CLI, Google GenAI SDK και πελάτες REST.
Πλήρης οδηγός
https://api.ailoot.ai/v1beta/models/{model}:generateContentcurl "https://api.ailoot.ai/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $AILOOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "Πρότεινε τρία ονόματα για μια καφετέρια."}]}
]
}' from google import genai
from google.genai import types
import os
client = genai.Client(
api_key=os.environ["AILOOT_API_KEY"],
http_options=types.HttpOptions(base_url="https://api.ailoot.ai"), # χωρίς /v1beta
)
resp = client.models.generate_content(
model="gemini-3.8-flash",
contents="Πρότεινε τρία ονόματα για μια καφετέρια.",
)
print(resp.text)import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({
apiKey: process.env.AILOOT_API_KEY,
httpOptions: { baseUrl: "https://api.ailoot.ai" }, // χωρίς /v1beta
});
const resp = await ai.models.generateContent({
model: "gemini-3.8-flash",
contents: "Πρότεινε τρία ονόματα για μια καφετέρια.",
});
console.log(resp.text);{
"candidates": [
{
"content": {
"role": "model",
"parts": [{ "text": "1. «Κόκκος και ατμός» 2. «Πρωινό άλεσμα» 3. «Η καφετέρια της γωνίας»" }]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"promptTokenCount": 9,
"candidatesTokenCount": 27,
"totalTokenCount": 36
},
"modelVersion": "gemini-3.8-flash"
}Έλεγχος ταυτότητας
- x-goog-api-keyheaderυποχρεωτικό
Κλειδί
sk-…. Γίνονται επίσης δεκτά ταAuthorization: Bearerήx-api-key. Για συμβατότητα με το Google γίνεται επίσης δεκτό το?key=στη διεύθυνση — με τη χαμηλότερη προτεραιότητα·?api_key=απορρίπτεται με 400. Συνιστούμε την κεφαλίδα, ώστε το κλειδί να μην καταγράφεται στα αρχεία καταγραφής.
Διαδρομή
- modelstringυποχρεωτικό
ID μοντέλου με μορφή Gemini, για παράδειγμα
gemini-3.8-flashήgemini-3.1-pro. Συνολικά 27.
https://api.ailoot.ai/v1beta/models/{model}:streamGenerateContent?alt=ssehttps://api.ailoot.ai/v1beta/modelsΣώμα αιτήματος
- contentsarrayυποχρεωτικό
Μηνύματα με
role(user/model) καιparts: text, inlineData/fileData, functionCall/functionResponse. Τα συνημμένα πρέπει να υποστηρίζονται ως είσοδος από το μοντέλο. - systemInstructionobjectπροαιρετικό
Οδηγία συστήματος σε κείμενο:
{"parts": [{"text": "…"}]}. - generationConfigobjectπροαιρετικό
generationConfigδέχεταιtemperature,topP,topK,maxOutputTokens,thinkingConfig,responseMimeType(text/plainήapplication/json),responseSchemaήresponseJsonSchema(αντικείμενο JSON),stopSequences(πίνακας συμβολοσειρών),candidateCount: 1, ακέραιοseed, αριθμητικές τιμέςpresencePenaltyκαιfrequencyPenalty. Τα επιτρεπόμενα εύρη και οι δυνατότητες εξαρτώνται από το συγκεκριμένο μοντέλο· για απάντηση JSON επιλέξτε μία υποστηριζόμενη μορφή σχήματος καιapplication/json. Στα μοντέλα κειμένου τοresponseModalities— μόνο["TEXT"]. - safetySettingsarrayπροαιρετικό
Αντικείμενα με υποχρεωτικά
categoryκαιthreshold, προαιρετικόmethod. Οι τιμές πρέπει να υποστηρίζονται από το συγκεκριμένο μοντέλο. - toolsarrayπροαιρετικό
Οι δηλώσεις πελάτη
functionDeclarationsεκτελούνται από την εφαρμογή σας. Τα μοντέλα κειμένου δέχονται επίσης{"googleSearch": {}}και{"urlContext": {}}: μεμονωμένα ή μαζί στον πίνακαtools. Ούτε το Google Search ούτε το URL context μπορούν να συνδυαστούν μεfunctionDeclarationsστο ίδιο αίτημα. Για εικόνες εξόδου διατίθενται μόνο συναρτήσεις πελάτη. Άλλα ενσωματωμένα εργαλεία και explicit cache δεν υποστηρίζονται. Τα Search/URL context μπορεί να απαιτούν δέσμευση βάσει ολόκληρου του ορίου εισόδου· τα πραγματικάtoolUsePromptTokenCountυπολογίζονται ως token εισόδου. - toolConfigobjectπροαιρετικό
functionCallingConfig: mode (AUTO/ANY/NONE/VALIDATED/MODE_UNSPECIFIED), allowedFunctionNames.
Αν το μοντέλο δεν υποστηρίζει ένα πεδίο, συνημμένο ή συνδυασμό εργαλείων, το αίτημα απορρίπτεται πριν από τη δέσμευση — δεν χρεώνεται τίποτα. Θα λάβετε HTTP 400 με status INVALID_ARGUMENT και κλάση invalid_request (στο ErrorInfo.reason — INVALID_REQUEST). Το μη έγκυρο JSON, τα σφάλματα παραμέτρων διαδρομής και άλλων ελέγχων επιστρέφουν επίσης 400· διαβάστε το μήνυμα σφάλματος και το Request ID. Οι δυνατότητες εξαρτώνται από το μοντέλο: ελέγξτε τις μορφές και τις εισόδους του στον κατάλογο.
PDF, ήχος, βίντεο και σύνδεσμοι
Στα μοντέλα Gemini που υποστηρίζουν την αντίστοιχη είσοδο, το parts[].inlineData περιέχει mimeType και μη κενά δεδομένα base64· το PDF πρέπει να είναι πραγματικό αρχείο PDF. fileData περιέχει δημόσια διεύθυνση httpsστο fileUri και τον τύπο MIME του αρχείου. Για το YouTube μπορείτε να παραλείψετε τον τύπο MIME. http, ιδιωτικές διευθύνσεις, gs:// και αντικείμενα Google Files API δεν υποστηρίζονται, ούτε η μεταφόρτωση μέσω Google Files API. Στο βίντεο μπορείτε να προσθέσετε videoMetadata: startOffset/endOffset ως συμβολοσειρά σε δευτερόλεπτα (για παράδειγμα, 1.5s) και fps μεγαλύτερο από 0 και έως 24. Το μέγεθος σώματος, το παράθυρο συμφραζομένων, η επιτρεπόμενη είσοδος και το όριο απάντησης ελέγχονται ανά μοντέλο και μορφή.
| Είσοδος | Υποστηριζόμενοι τύποι MIME |
|---|---|
| Ενσωματωμένες εικόνες | image/png, image/jpeg, image/webp |
| Έγγραφα | application/pdf; text/plain, text/html, text/css, text/csv, text/xml, text/rtf, text/markdown, text/javascript, application/x-javascript, text/x-python, application/x-python |
| Ήχος | audio/wav, audio/mp3, audio/mpeg, audio/aiff, audio/aac, audio/ogg, audio/flac |
| Βίντεο | video/mp4, video/mpeg, video/mov, video/quicktime, video/avi, video/x-flv, video/mpg, video/webm, video/wmv, video/3gpp |
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
import base64, pathlib, sys
# Δώστε ένα πραγματικό τοπικό αρχείο PDF, ήχου ή βίντεο και τον υποστηριζόμενο τύπο MIME του.
path, mime = pathlib.Path(sys.argv[1]), sys.argv[2]
payload = {"contents": [{"role": "user", "parts": [
{"text": "Περίγραψε σύντομα το περιεχόμενο του αρχείου."},
{"inlineData": {"mimeType": mime,
"data": base64.b64encode(path.read_bytes()).decode()}},
]}]}
print(generate("gemini-3.8-flash", payload))
# Εναλλακτικό συνημμένο: {"fileData": {"mimeType": mime, "fileUri": public_https_url}}
# Για πραγματική διεύθυνση URL του YouTube: {"fileData": {"fileUri": youtube_url}}Search και URL context
Οι δηλώσεις πελάτη functionDeclarations εκτελούνται από την εφαρμογή σας. Τα μοντέλα κειμένου δέχονται επίσης {"googleSearch": {}} και {"urlContext": {}}: μεμονωμένα ή μαζί στον πίνακα tools. Ούτε το Google Search ούτε το URL context μπορούν να συνδυαστούν με functionDeclarations στο ίδιο αίτημα. Για εικόνες εξόδου διατίθενται μόνο συναρτήσεις πελάτη. Άλλα ενσωματωμένα εργαλεία και explicit cache δεν υποστηρίζονται. Τα Search/URL context μπορεί να απαιτούν δέσμευση βάσει ολόκληρου του ορίου εισόδου· τα πραγματικά toolUsePromptTokenCount υπολογίζονται ως token εισόδου.
{"tools": [{"googleSearch": {}}, {"urlContext": {}}]}Εικόνες στην έξοδο
Εικόνες σε απάντηση μορφής Gemini παράγει μόνο το gemini-3.1-flash-image. Αυτή η δυνατότητα είναι ξεχωριστή από το /v1/images/generations: τα άλλα μοντέλα εικόνας δεν λειτουργούν εδώ. Το μοντέλο δέχεται έως 131072 token εισόδου και παράγει έως 32768 token απάντησης· το πλήρες κόστος της μεγαλύτερης δυνατής απάντησης δεσμεύεται εκ των προτέρων.
responseModalities — μη κενό σύνολο TEXT/IMAGE χωρίς επαναλήψεις. imageConfig.imageSize: 1K/2K/4K; aspectRatio: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9, 1:4, 4:1, 1:8, 8:1. Η είσοδος αυτού του μοντέλου περιλαμβάνει κείμενο και ενσωματωμένες εικόνες PNG/JPEG/WebP· PDF/audio/video/fileData και ενσωματωμένα Search/URL context δεν γίνονται δεκτά εδώ. Η διαθεσιμότητα και οι τιμές για το κλειδί σας εμφανίζονται στον κατάλογο και στο GET /v1/models.
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
import base64, pathlib
reply = generate("gemini-3.1-flash-image", {
"contents": [{"role": "user", "parts": [{"text": "Ακουαρέλα: φάρος την αυγή"}]}],
"generationConfig": {
"responseModalities": ["TEXT", "IMAGE"],
"imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"},
},
})
index = 0
for candidate in reply.get("candidates", []):
for part in candidate.get("content", {}).get("parts", []):
if "text" in part:
print(part["text"])
blob = part.get("inlineData", {})
if blob.get("mimeType", "").startswith("image/") and blob.get("data"):
index += 1
extension = {"image/png": "png", "image/jpeg": "jpg",
"image/webp": "webp"}.get(blob["mimeType"], "bin")
pathlib.Path(f"gemini-image-v{index}.{extension}").write_bytes(
base64.b64decode(blob["data"]))
print("All returned images:", index)Πλήρης κύκλος κλήσης συναρτήσεων
Ο πελάτης εκτελεί τις συναρτήσεις. Επιστρέψτε όλο το αρχικό content του μοντέλου με το thoughtSignature χωρίς αλλαγές, έπειτα το functionResponse με τα ίδια name και id, εφόσον το id υπήρχε στο functionCall.
import json, os, urllib.request
def generate(model, payload):
req = urllib.request.Request(
"https://api.ailoot.ai/v1beta/models/" + model + ":generateContent",
data=json.dumps(payload).encode(),
headers={"x-goog-api-key": os.environ["AILOOT_API_KEY"],
"Content-Type": "application/json"},
)
# Μία αποστολή. Αν λήξει το χρονικό όριο, ελέγξτε το Request ID στο ιστορικό χρήσης σας πριν δοκιμάσετε ξανά.
with urllib.request.urlopen(req, timeout=300) as response:
print("Request ID:", response.headers.get("X-Request-ID"))
return json.load(response)
tools = [{"functionDeclarations": [{
"name": "multiply", "description": "Πολλαπλασιασμός δύο αριθμών",
"parameters": {"type": "object", "properties": {
"a": {"type": "number"}, "b": {"type": "number"}},
"required": ["a", "b"]},
}]}]
contents = [{"role": "user", "parts": [{"text": "Πολλαπλασίασε το 7 με το 8 με τη βοήθεια της συνάρτησης"}]}]
for turn in range(4): # Περιορίστε τον κύκλο εκτέλεσης των εργαλείων· μην ξαναστέλνετε αίτημα του οποίου το αποτέλεσμα είναι ασαφές.
reply = generate("gemini-3.8-flash", {"contents": contents, "tools": tools})
content = reply["candidates"][0]["content"]
contents.append(content) # Διατηρήστε όλα (ALL) τα αρχικά τμήματα και το thoughtSignature αμετάβλητα.
results = []
for part in content.get("parts", []):
call = part.get("functionCall")
if not call:
continue
if call["name"] != "multiply":
raise ValueError("Unexpected function")
args = call["args"]
result = {"name": call["name"], "response": {"value": args["a"] * args["b"]}}
if "id" in call:
result["id"] = call["id"]
results.append({"functionResponse": result})
if not results:
print(content)
break
contents.append({"role": "user", "parts": results})
else:
raise RuntimeError("Tool loop limit reached")Απάντηση
- candidates[].content.partsarray
Η απάντηση του μοντέλου.
- usageMetadataobject
promptTokenCount,candidatesTokenCount,totalTokenCount.