Converse API
Converse menyatukan bentuk permintaan untuk semua model yang mendukung pesan. Ini API yang direkomendasikan AWS dan yang dipakai di sisa roadmap ini.
Intisari
- Kelebihan utamanya: bentuk permintaan sama untuk semua model — ganti
modelId, kode tetap. - Ada di client
bedrock-runtimesaja. Butuh izinbedrock:InvokeModel. - System prompt punya field sendiri (
system), terpisah darimessages. - Parameter khas model dikirim lewat
additionalModelRequestFields. - Tool use dan guardrail juga masuk lewat API yang sama —
toolConfigdanguardrailConfig.
Kenapa Converse, bukan InvokeModel
InvokeModel mengirim body mentah yang bentuknya berbeda per penyedia model. Pindah dari satu
model ke model lain berarti menulis ulang serialisasi permintaan dan parsing responsnya. Converse
menormalkan itu:
InvokeModel | Converse | |
|---|---|---|
| Bentuk permintaan | Beda per penyedia | Sama untuk semua |
| Ganti model | Ubah kode serialisasi | Ubah satu string |
| Tool use | Format khas model | toolConfig seragam |
| Parameter unik model | Tercampur di body | Terpisah di additionalModelRequestFields |
Permintaan lengkap
import boto3
runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
resp = runtime.converse(
modelId=MODEL_ID,
# System prompt: instruksi dan konteks, TERPISAH dari percakapan
system=[{"text": "Kamu asisten teknis. Jawab ringkas dan berbahasa Indonesia."}],
# Riwayat percakapan, bergantian user/assistant
messages=[
{"role": "user", "content": [{"text": "Apa itu vector store?"}]},
{"role": "assistant", "content": [{"text": "Basis data yang menyimpan embedding..."}]},
{"role": "user", "content": [{"text": "Kapan aku butuh itu?"}]},
],
# Parameter yang berlaku untuk semua model
inferenceConfig={"maxTokens": 512, "temperature": 0.2, "topP": 0.9},
# Parameter khas model tertentu
additionalModelRequestFields={"top_k": 50},
)
System prompt bukan sebuah message. Di beberapa SDK lain, instruksi sistem dikirim sebagai pesan
pertama dengan role system. Di Converse ia punya field sendiri. Menaruhnya sebagai
{"role": "system", …} di dalam messages menghasilkan
ValidationException.
Membaca respons
jawaban = resp["output"]["message"]["content"][0]["text"]
pakai = resp["usage"]
print(pakai["inputTokens"], pakai["outputTokens"], pakai["totalTokens"])
print(resp["stopReason"]) # end_turn | max_tokens | tool_use | stop_sequence
print(resp["metrics"]["latencyMs"])
| Field | Kenapa penting |
|---|---|
usage | Satu-satunya sumber kebenaran biaya per permintaan. Catat ke log sejak hari pertama. |
stopReason | max_tokens berarti jawaban terpotong — jangan diperlakukan sebagai jawaban utuh. |
metrics.latencyMs | Latensi menurut Bedrock, tanpa overhead jaringanmu. |
content berupa list | Bisa berisi lebih dari satu blok: teks, gambar, atau permintaan tool. |
Multi-modal
gambar = open("diagram.png", "rb").read()
resp = runtime.converse(
modelId=MODEL_ID,
messages=[{
"role": "user",
"content": [
{"image": {"format": "png", "source": {"bytes": gambar}}},
{"text": "Jelaskan arsitektur pada diagram ini."},
],
}],
)
Karena content adalah list blok, teks dan gambar hidup berdampingan dalam satu pesan.
Bentuk yang sama juga dipakai untuk dokumen — berguna sekali untuk pipeline pemrosesan dokumen di Fase 4.
Fungsi pembungkus yang layak dipakai
from botocore.config import Config
import boto3, logging
log = logging.getLogger(__name__)
runtime = boto3.client(
"bedrock-runtime",
config=Config(retries={"max_attempts": 5, "mode": "adaptive"}, read_timeout=300),
)
def tanya(pertanyaan: str, *, sistem: str, model_id: str, maks_token: int = 512) -> str:
resp = runtime.converse(
modelId=model_id,
system=[{"text": sistem}],
messages=[{"role": "user", "content": [{"text": pertanyaan}]}],
inferenceConfig={"maxTokens": maks_token, "temperature": 0.2},
)
log.info(
"bedrock",
extra={
"model": model_id,
"token_masuk": resp["usage"]["inputTokens"],
"token_keluar": resp["usage"]["outputTokens"],
"alasan_berhenti": resp["stopReason"],
},
)
if resp["stopReason"] == "max_tokens":
log.warning("jawaban terpotong — naikkan maxTokens atau perpendek konteks")
return resp["output"]["message"]["content"][0]["text"]
Latihan: tulis fungsi tanya() di atas, lalu jalankan pertanyaan yang sama ke dua model
berbeda hanya dengan mengganti model_id. Bandingkan usage dan
metrics.latencyMs keduanya, dan catat selisih biayanya — data ini yang dipakai untuk memilih model
di Fase 7.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.