Google Gemini API
Google Gemini API là giao thức AI tạo sinh gốc của Google. Nếu client của bạn đã được phát triển theo thông số kỹ thuật SDK Google GenAI, chỉ cần chuyển Base URL và API Key sang RouteAPI để sử dụng trực tiếp mà không cần viết lại cấu trúc yêu cầu.
Tổng quan giao thức
Phần tiêu đề “Tổng quan giao thức”Gemini API sử dụng thiết kế độc đáo trong đó tên model được nhúng vào đường dẫn URL. Thân yêu cầu sử dụng mảng contents để biểu thị cuộc hội thoại, mỗi thông điệp có vai trò user hoặc model (lưu ý: không phải assistant). Cấu trúc phản hồi sử dụng bọc mảng candidates, hỗ trợ lọc an toàn và tạo nhiều ứng viên.
Trường hợp sử dụng:
| Tình huống | Mô tả |
|---|---|
| SDK Google GenAI | SDK Python / Node.js google-generativeai, chỉ cần đổi base_url |
| Client REST Gemini | Ứng dụng đã được phát triển cho REST API Gemini |
| Ứng dụng đa phương thức | Tình huống cần hỗ trợ gốc cho đầu vào hình ảnh, video, âm thanh |
| Xuất Google AI Studio | Mã được xuất từ AI Studio có thể di chuyển trực tiếp |
Nếu client của bạn chỉ hỗ trợ giao thức OpenAI, hãy sử dụng Chat Completions. RouteAPI sẽ thực hiện chuyển đổi định dạng cần thiết bên trong, nhưng ưu tiên giao thức được hỗ trợ gốc bởi client của bạn đảm bảo khả năng tương thích tốt nhất.
Định dạng endpoint
Phần tiêu đề “Định dạng endpoint”Thiết kế endpoint của Gemini API là đặc biệt: tên model được nhúng trực tiếp vào đường dẫn URL.
POST /v1beta/models/{model}:generateContentVí dụ địa chỉ đầy đủ:
https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:generateContentEndpoint streaming:
https://api.routeapi.ai/v1beta/models/gemini-1.5-pro:streamGenerateContentThay thế phần {model} bằng tên model thực tế, chẳng hạn như gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash-exp, v.v. Lưu ý rằng không có khoảng trắng giữa tên model trước dấu hai chấm và tên phương thức sau nó.
Header yêu cầu:
Authorization: Bearer sk-your-routeapi-tokenContent-Type: application/jsonTất cả các giao thức đều sử dụng cùng một loại token RouteAPI. Vui lòng lưu token ở phía máy chủ và không để lộ nó trong trình duyệt, thiết bị di động hoặc kho lưu trữ công khai.
Định dạng yêu cầu
Phần tiêu đề “Định dạng yêu cầu”| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
contents | array | Có | Danh sách nội dung cuộc hội thoại, ít nhất một mục |
generationConfig | object | Không | Tham số cấu hình tạo |
safetySettings | array | Không | Cài đặt lọc an toàn |
systemInstruction | object | Không | Hướng dẫn hệ thống, trường độc lập |
tools | array | Không | Định nghĩa công cụ gọi hàm |
toolConfig | object | Không | Cấu hình gọi công cụ |
Ví dụ yêu cầu cơ bản:
{ "contents": [ { "role": "user", "parts": [ { "text": "Vui lòng giới thiệu RouteAPI trong một câu" } ] } ], "generationConfig": { "temperature": 0.7, "maxOutputTokens": 1024 }}Cấu trúc độc đáo của contents
Phần tiêu đề “Cấu trúc độc đáo của contents”Gemini API sử dụng cấu trúc lồng nhau ba cấp:
- Mảng
contentschứa nhiều thông điệp - Mỗi thông điệp có các trường
rolevàparts - Mảng
partschứa các khối nội dung thực tế
Sự khác biệt chính:
rolechỉ có thể làuserhoặcmodel(không phảiassistant)- Nội dung phải được đặt trong mảng
parts, mỗi phần tử là một đối tượng part - Hỗ trợ parts đa phương thức: văn bản, hình ảnh, video, âm thanh có thể được trộn trong
partscủa cùng một thông điệp
{ "contents": [ { "role": "user", "parts": [ { "text": "Phân tích hình ảnh này" }, { "inlineData": { "mimeType": "image/jpeg", "data": "dữ liệu hình ảnh được mã hóa base64..." } } ] }, { "role": "model", "parts": [ { "text": "Đây là một hình ảnh hiển thị..." } ] } ]}Tham số generationConfig
Phần tiêu đề “Tham số generationConfig”| Tham số | Kiểu | Mô tả |
|---|---|---|
temperature | number | Nhiệt độ lấy mẫu, phạm vi từ 0 đến 2, mặc định 1.0 |
topP | number | Tham số nucleus sampling, mặc định 0.95 |
topK | integer | Chỉ lấy mẫu từ K token có xác suất cao nhất |
maxOutputTokens | integer | Số token đầu ra tối đa |
stopSequences | array | Chuỗi dừng tùy chỉnh, tối đa 5 |
candidateCount | integer | Số lượng ứng viên để tạo, mặc định 1 |
responseMimeType | string | Định dạng phản hồi, ví dụ "application/json" |
responseSchema | object | JSON Schema để ràng buộc cấu trúc đầu ra |
Ví dụ:
{ "generationConfig": { "temperature": 0.9, "topP": 0.95, "topK": 40, "maxOutputTokens": 2048, "stopSequences": ["END", "STOP"] }}systemInstruction
Phần tiêu đề “systemInstruction”Hướng dẫn hệ thống là một trường độc lập, không nằm trong contents:
{ "systemInstruction": { "parts": [ { "text": "Bạn là một trợ lý kỹ thuật nghiêm ngặt, giữ câu trả lời ngắn gọn." } ] }, "contents": [ { "role": "user", "parts": [{ "text": "Giải thích API gateway là gì" }] } ]}safetySettings
Phần tiêu đề “safetySettings”Kiểm soát mức độ lọc an toàn nội dung:
{ "safetySettings": [ { "category": "HARM_CATEGORY_HARASSMENT", "threshold": "BLOCK_MEDIUM_AND_ABOVE" }, { "category": "HARM_CATEGORY_HATE_SPEECH", "threshold": "BLOCK_MEDIUM_AND_ABOVE" } ]}Các danh mục phổ biến: HARM_CATEGORY_HARASSMENT, HARM_CATEGORY_HATE_SPEECH, HARM_CATEGORY_SEXUALLY_EXPLICIT, HARM_CATEGORY_DANGEROUS_CONTENT.
Tùy chọn ngưỡng: BLOCK_NONE, BLOCK_LOW_AND_ABOVE, BLOCK_MEDIUM_AND_ABOVE, BLOCK_ONLY_HIGH.
Nội dung đa phương thức
Phần tiêu đề “Nội dung đa phương thức”Gemini API hỗ trợ gốc đầu vào đa phương thức thông qua các loại khác nhau trong mảng parts.
Văn bản
Phần tiêu đề “Văn bản”{ "text": "Đây là nội dung văn bản" }Hình ảnh nội tuyến (base64)
Phần tiêu đề “Hình ảnh nội tuyến (base64)”{ "inlineData": { "mimeType": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQAAAQ..." }}Định dạng hình ảnh được hỗ trợ: image/jpeg, image/png, image/webp, image/heic, image/heif.
URL hình ảnh (fileData)
Phần tiêu đề “URL hình ảnh (fileData)”{ "fileData": { "mimeType": "image/jpeg", "fileUri": "https://example.com/image.jpg" }}Video và âm thanh
Phần tiêu đề “Video và âm thanh”{ "fileData": { "mimeType": "video/mp4", "fileUri": "gs://bucket-name/video.mp4" }}Hỗ trợ video: video/mp4, video/mpeg, video/mov, v.v.
Hỗ trợ âm thanh: audio/wav, audio/mp3, audio/aac, v.v.
Ví dụ đa phương thức hỗn hợp
Phần tiêu đề “Ví dụ đa phương thức hỗn hợp”{ "contents": [ { "role": "user", "parts": [ { "text": "Phân tích mối quan hệ giữa video này và hình ảnh này" }, { "fileData": { "mimeType": "video/mp4", "fileUri": "gs://my-bucket/video.mp4" } }, { "inlineData": { "mimeType": "image/jpeg", "data": "base64..." } } ] } ]}Định dạng phản hồi
Phần tiêu đề “Định dạng phản hồi”Phản hồi chuẩn
Phần tiêu đề “Phản hồi chuẩn”{ "candidates": [ { "content": { "parts": [ { "text": "RouteAPI là một API gateway thống nhất quản lý nhiều nhà cung cấp model AI." } ], "role": "model" }, "finishReason": "STOP", "safetyRatings": [ { "category": "HARM_CATEGORY_HARASSMENT", "probability": "NEGLIGIBLE" } ] } ], "usageMetadata": { "promptTokenCount": 12, "candidatesTokenCount": 18, "totalTokenCount": 30 }}Mô tả trường phản hồi
Phần tiêu đề “Mô tả trường phản hồi”| Trường | Mô tả |
|---|---|
candidates | Mảng phản hồi ứng viên, mặc định là một |
candidates[].content | Nội dung được tạo, cùng cấu trúc với phần tử contents trong yêu cầu |
candidates[].content.role | Luôn là "model" |
candidates[].finishReason | Lý do hoàn thành |
candidates[].safetyRatings | Chi tiết đánh giá an toàn |
usageMetadata | Thống kê sử dụng token |
Giá trị finishReason
Phần tiêu đề “Giá trị finishReason”| Giá trị | Ý nghĩa |
|---|---|
STOP | Model kết thúc tự nhiên |
MAX_TOKENS | Đạt giới hạn maxOutputTokens |
SAFETY | Bị chặn do kích hoạt bộ lọc an toàn |
RECITATION | Bị chặn do phát hiện nội dung lặp lại |
OTHER | Lý do khác |
Trường usageMetadata
Phần tiêu đề “Trường usageMetadata”| Trường | Mô tả |
|---|---|
promptTokenCount | Số token đầu vào |
candidatesTokenCount | Số token đầu ra (tổng của tất cả ứng viên) |
totalTokenCount | Tổng số token |
cachedContentTokenCount | Số token được lưu trong bộ nhớ cache (nếu sử dụng bộ nhớ cache ngữ cảnh) |
Đầu ra streaming
Phần tiêu đề “Đầu ra streaming”Sử dụng endpoint streamGenerateContent để thực hiện phản hồi streaming:
POST /v1beta/models/{model}:streamGenerateContentPhản hồi streaming sử dụng định dạng SSE (Server-Sent Events), mỗi sự kiện là một đối tượng JSON:
data: {"candidates":[{"content":{"parts":[{"text":"RouteAPI"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":1,"totalTokenCount":13}}
data: {"candidates":[{"content":{"parts":[{"text":" là một"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":3,"totalTokenCount":15}}
data: {"candidates":[{"content":{"parts":[{"text":" API gateway"}],"role":"model"},"finishReason":""}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":5,"totalTokenCount":17}}
data: {"candidates":[{"content":{"parts":[{"text":""}],"role":"model"},"finishReason":"STOP","safetyRatings":[{"category":"HARM_CATEGORY_HARASSMENT","probability":"NEGLIGIBLE"}]}],"usageMetadata":{"promptTokenCount":12,"candidatesTokenCount":18,"totalTokenCount":30}}Đặc điểm của streaming:
- Mỗi chunk là một đối tượng JSON hoàn chỉnh chứa cấu trúc
candidatesđầy đủ finishReasonlà chuỗi rỗng để tiếp tục, có giá trị để chỉ ra hoàn thành- Chunk cuối cùng chứa
safetyRatingsđầy đủ vàusageMetadatacuối cùng - Phản hồi streaming không có dấu hiệu
[DONE]rõ ràng, dựa vàofinishReasonđể xác định hoàn thành
Gọi hàm (Function Calling)
Phần tiêu đề “Gọi hàm (Function Calling)”Gemini API hỗ trợ gọi hàm để cho phép model gọi các công cụ bên ngoài.
Định nghĩa công cụ
Phần tiêu đề “Định nghĩa công cụ”{ "tools": [ { "functionDeclarations": [ { "name": "get_weather", "description": "Truy vấn thời tiết hiện tại cho một thành phố được chỉ định. Sử dụng tên đầy đủ của thành phố.", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "Tên thành phố, ví dụ Hà Nội" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["city"] } } ] } ]}Phản hồi gọi hàm
Phần tiêu đề “Phản hồi gọi hàm”Model trả về yêu cầu gọi hàm:
{ "candidates": [ { "content": { "parts": [ { "functionCall": { "name": "get_weather", "args": { "city": "Hà Nội", "unit": "celsius" } } } ], "role": "model" }, "finishReason": "STOP" } ]}Trả về kết quả hàm
Phần tiêu đề “Trả về kết quả hàm”Trả về kết quả thực thi hàm dưới dạng thông điệp user mới:
{ "contents": [ { "role": "user", "parts": [{ "text": "Thời tiết ở Hà Nội hiện tại như thế nào?" }] }, { "role": "model", "parts": [ { "functionCall": { "name": "get_weather", "args": { "city": "Hà Nội", "unit": "celsius" } } } ] }, { "role": "user", "parts": [ { "functionResponse": { "name": "get_weather", "response": { "content": "Hà Nội, nắng, nhiệt độ 23 độ C, độ ẩm 45%." } } } ] } ]}So sánh với định dạng OpenAI
Phần tiêu đề “So sánh với định dạng OpenAI”Bảng so sánh cấu trúc
Phần tiêu đề “Bảng so sánh cấu trúc”| Mục | Gemini API | OpenAI Chat Completions |
|---|---|---|
| Định dạng endpoint | /v1beta/models/{model}:generateContent | /v1/chat/completions |
| Chỉ định model | Trong đường dẫn URL | Trường model của thân yêu cầu |
| Trường mảng hội thoại | contents | messages |
| Cấu trúc thông điệp | role + mảng parts | role + chuỗi/mảng content |
| Tên vai trò | user / model | user / assistant / system |
| Hướng dẫn hệ thống | Đối tượng systemInstruction | role: "system" trong messages |
| Bọc phản hồi | Mảng candidates | Mảng choices |
| Vị trí nội dung phản hồi | candidates[0].content.parts[0].text | choices[0].message.content |
| Trường lý do hoàn thành | finishReason | finish_reason |
| Trường thống kê sử dụng | usageMetadata | usage |
Bảng ánh xạ tham số
Phần tiêu đề “Bảng ánh xạ tham số”| Gemini API | OpenAI Chat Completions | Ghi chú |
|---|---|---|
generationConfig.temperature | temperature | Gemini tối đa 2, OpenAI cũng 2 |
generationConfig.topP | top_p | Phong cách đặt tên khác nhau |
generationConfig.topK | Không có tương đương | OpenAI không hỗ trợ |
generationConfig.maxOutputTokens | max_tokens / max_completion_tokens | Tên trường khác nhau |
generationConfig.stopSequences | stop | Tên khác nhau |
generationConfig.candidateCount | n | Cùng ngữ nghĩa |
generationConfig.responseMimeType | response_format.type | Phương pháp kiểm soát khác nhau |
generationConfig.responseSchema | response_format.json_schema | Cấp bậc khác nhau |
safetySettings | Không có tương đương | OpenAI sử dụng API kiểm duyệt nội dung |
tools[].functionDeclarations | tools[].function | Mức độ bọc khác nhau |
toolConfig | tool_choice | Tên trường và cấu trúc khác nhau |
Lưu ý khi di chuyển
Phần tiêu đề “Lưu ý khi di chuyển”Khi di chuyển từ OpenAI sang Gemini API, kiểm tra theo thứ tự sau:
- Chuyển tên model vào đường dẫn URL:
/v1beta/models/gemini-1.5-pro:generateContent - Đổi tên
messagesthànhcontents, thay đổi cấu trúc của mỗi thông điệp thànhrole+ mảngparts - Thay đổi tất cả vai trò
assistantthànhmodel - Thay đổi trường
contentthành mảngparts, bọc nội dung văn bản thành{ "text": "..." } - Chuyển system prompt từ mảng
messagessang đối tượngsystemInstruction - Bọc tham số tạo vào đối tượng
generationConfigvà điều chỉnh tên trường (ví dụmaxOutputTokens,stopSequences) - Thay đổi phân tích phản hồi để trích xuất nội dung từ
candidates[0].content.parts[0].text - Thay đổi endpoint streaming thành
streamGenerateContent, mỗi chunk là JSON hoàn chỉnh - Thay đổi định nghĩa công cụ thành bọc
functionDeclarations, trường tham số thànhparameters
Ánh xạ tên vai trò
Phần tiêu đề “Ánh xạ tên vai trò”| Gemini | OpenAI | Claude |
|---|---|---|
user | user | user |
model | assistant | assistant |
| Không có vai trò độc lập | system | Không có vai trò độc lập |
| Không có vai trò độc lập | tool | Không có vai trò độc lập |
Cả Gemini và Claude đều nâng hướng dẫn hệ thống lên trường cấp cao nhất, không xử lý nó như một vai trò thông điệp.
Ví dụ đầy đủ
Phần tiêu đề “Ví dụ đầy đủ”Hội thoại cơ bản (Python SDK)
Phần tiêu đề “Hội thoại cơ bản (Python SDK)”Sử dụng Python SDK Google GenAI, chỉ thay đổi client_options:
import osimport google.generativeai as genaifrom google.api_core.client_options import ClientOptions
# Cấu hình endpoint RouteAPIgenai.configure( api_key=os.environ["ROUTEAPI_KEY"], transport="rest", client_options=ClientOptions( api_endpoint="https://api.routeapi.ai/v1beta" ))
model = genai.GenerativeModel("gemini-1.5-pro")
response = model.generate_content( "Vui lòng giới thiệu RouteAPI trong một câu", generation_config={ "temperature": 0.7, "max_output_tokens": 1024 })
print(response.text)print(f"Token đầu vào: {response.usage_metadata.prompt_token_count}")print(f"Token đầu ra: {response.usage_metadata.candidates_token_count}")Ví dụ đầu vào hình ảnh (Python SDK)
Phần tiêu đề “Ví dụ đầu vào hình ảnh (Python SDK)”import osimport google.generativeai as genaifrom google.api_core.client_options import ClientOptionsfrom PIL import Image
genai.configure( api_key=os.environ["ROUTEAPI_KEY"], transport="rest", client_options=ClientOptions( api_endpoint="https://api.routeapi.ai/v1beta" ))
model = genai.GenerativeModel("gemini-1.5-pro")
image = Image.open("screenshot.jpg")
response = model.generate_content( ["Những điều khiển giao diện người dùng nào có trong hình ảnh này?", image], generation_config={"max_output_tokens": 2048})
print(response.text)Ví dụ đầu ra streaming (Python SDK)
Phần tiêu đề “Ví dụ đầu ra streaming (Python SDK)”import osimport google.generativeai as genaifrom google.api_core.client_options import ClientOptions
genai.configure( api_key=os.environ["ROUTEAPI_KEY"], transport="rest", client_options=ClientOptions( api_endpoint="https://api.routeapi.ai/v1beta" ))
model = genai.GenerativeModel("gemini-1.5-pro")
response = model.generate_content( "Giải thích từng bước API gateway là gì", stream=True)
for chunk in response: print(chunk.text, end="", flush=True)
print()Lưu ý về tương thích
Phần tiêu đề “Lưu ý về tương thích”- Hỗ trợ tham số thực tế phụ thuộc vào model được chọn và khả năng dịch vụ upstream. Một số tính năng nâng cao (như bộ nhớ cache ngữ cảnh, thực thi mã) nên được xác minh trước trong môi trường thử nghiệm.
- Các tham số tùy chọn được truyền rõ ràng là
0hoặcfalseđược coi là giá trị do người dùng đặt, không phải giá trị mặc định cần loại bỏ. - Môi trường sản xuất nên cố định ID model và không dựa vào bí danh tạm thời hoặc tên hiển thị.
- Ghi lại ID model, mã trạng thái và sử dụng token cho mỗi yêu cầu để dễ dàng khắc phục sự cố về độ trễ và chi phí bất thường.
- Khi sử dụng
fileUrivới giao thứcgs://, đảm bảo tệp có thể truy cập được từ upstream, hoặc sử dụnginlineDatađể truyền trực tiếp. - Định dạng phản hồi lỗi có thể khác với OpenAI/Claude, xem Xử lý lỗi.