
Integrasi API LLM jarang gagal karena satu baris kode. Biasanya gagal karena keputusan yang diambil di awal—endpoint mana yang dipakai, mode berpikir mana yang aktif, dan bagaimana request yang gagal diperlakukan—baru terasa mahal setelah trafik naik. Checklist ini disusun dari dokumentasi resmi DeepSeek supaya bisa dipakai di sprint planning atau code review, bukan setelah tagihan bulan pertama datang.
Kenapa Integrasi DeepSeek API Perlu Checklist
DeepSeek API memakai format yang kompatibel dengan OpenAI dan Anthropic [1][2]. Artinya kamu bisa memakai SDK yang sudah ada dan cukup mengganti konfigurasi. Kemudahan ini justru sumber masalah: karena terasa seperti drop-in replacement, banyak tim langsung menembak ke satu endpoint tanpa memeriksa default-nya.
Default-nya tidak netral. Di Chat Completions, thinking mode aktif secara default, dan max_tokens default-nya 8K saat non-thinking tapi 64K saat thinking [4]. Di Responses API, thinking juga aktif kalau kamu tidak menyetel apa pun [3]. Dua default ini berpasangan: mode berpikir menaikkan plafon output, dan plafon yang lebih tinggi berarti potensi biaya per request yang lebih tinggi juga. Trade-off-nya jelas—kualitas penalaran naik, latensi dan biaya ikut naik.
Langkah 1: Siapkan Akun, API Key, dan Base URL
Yang perlu ada sebelum kode pertama: API key, base URL, dan nama model yang benar. Base URL untuk format OpenAI adalah https://api.deepseek.com, sedangkan untuk format Anthropic https://api.deepseek.com/anthropic [1][2].
Nama model yang tersedia: deepseek-flash dan deepseek-v4-pro [1][2][3][4]. Satu catatan soal deepseek-flash: nama itu sekarang dilayani oleh DeepSeek-V4.1-Flash-1017, dan nama lama seperti deepseek-v4-flash atau deepseek-v4-flash-vision-exp masih diterima tapi model di baliknya sudah pensiun serta tetap ditagih dengan harga Flash [1][2]. Kalau kamu menemukan nama lama di kode atau config, ganti.
Untuk kunci: simpan di secret manager atau environment variable, jangan di repo. Ini bukan aturan spesifik DeepSeek, tapi konsekuensinya di sini konkret—satu key bocor berarti kuota dan tagihan seluruh tim.
Langkah 2: Pilih Endpoint yang Tepat
Chat Completions API untuk percakapan klasik
POST /chat/completions menerima array messages berisi role system, user, assistant, dan tool [4]. Formatnya yang paling banyak dikenal, jadi cocok kalau kamu memakai SDK OpenAI yang sudah jalan dan tidak ingin mengubah lapisan abstraksi. Streaming memakai SSE dan diakhiri data: [DONE] [4].
Responses API untuk kontrol lebih terstruktur
POST /responses memakai format OpenAI Responses API. Yang perlu dipahami sejak awal: API ini stateless—respons dan percakapan tidak disimpan di server, jadi untuk percakapan multi-turn klien harus mengirim seluruh riwayat percakapan di input pada tiap request [3]. Konsekuensinya ada dua: kamu harus mengelola state sendiri, dan token input naik seiring panjang percakapan.
Responses API juga lebih kaya soal item. input bisa berupa string biasa atau daftar item dengan tipe message, function_call, function_call_output, custom_tool_call, custom_tool_call_output, reasoning, dan web_search_call [3]. Untuk gambar, deepseek-flash mendukung input_image di message user atau developer, tapi gambar di message system atau assistant mengembalikan error 400, dan input file tidak didukung [3]. Streaming-nya pun beda: tidak ada [DONE], penanda akhirnya event response.completed, response.incomplete, atau response.failed [3].
Pilihan endpoint bukan soal mana yang lebih baru, tapi soal siapa yang memegang state percakapan dan berapa banyak riwayat yang kamu relakan dikirim ulang.
Langkah 3: Konfigurasi Model dan Mode Berpikir
Parameter thinking dan reasoning_effort
Di Chat Completions, thinking.type menerima enabled atau disabled dengan default enabled. reasoning_effort menerima none, low, high, dan max; none mematikan thinking, sedangkan low, high, dan max menyalakannya dengan default high. Nilai minimal dipetakan ke low, sementara medium dan xhigh dipetakan ke high untuk kompatibilitas [4].
Di Responses API, konfigurasinya ada di objek reasoning dengan field effort yang menerima nilai setara [3].
Praktisnya: klasifikasi atau ekstraksi field biasanya tidak butuh thinking, dan mematikannya adalah cara paling langsung menekan latensi. Sebaliknya, max masuk akal untuk penalaran bertingkat—tapi ingat bahwa di Chat Completions, reasoning_effort: max menaikkan plafon default max_tokens ke 128K [4].
Batas token, suhu, dan format output
max_tokens di Chat Completions harus di antara 1 dan 384K, dan kalau tidak diset default-nya 8K pada mode non-thinking atau 64K pada mode thinking [4]. Set eksplisit. Plafon yang berbeda antar mode adalah sumber kejutan biaya yang paling mudah dihindari.
Soal determinisme, ada jebakan yang sering lolos code review: temperature tidak berpengaruh saat thinking mode aktif [3][4], dan top_p hanya efektif di thinking mode dengan rentang efektif 0.95 sampai 1.0 [4]. Jadi menyetel temperature: 0 sambil membiarkan thinking menyala tidak memberi output sedeterministik yang mungkin kamu bayangkan.
Untuk format: Chat Completions mendukung response_format bertipe text atau json_object [4], sedangkan Responses API mendukung text, json_object, dan json_schema [3]. Kalau kamu memakai JSON Output di Chat Completions, kamu wajib menginstruksikan model lewat system atau user message untuk menghasilkan JSON; tanpa itu model bisa mengeluarkan whitespace terus-menerus sampai kena batas token, dan request terlihat menggantung [4]. Contoh bagus bahwa jaminan “JSON valid” di dokumentasi bukan berarti instruksinya boleh dilewatkan.
Langkah 4: Antisipasi Error, Rate Limit, dan Keamanan
Dokumentasi DeepSeek punya halaman Error Codes serta Rate Limit & Isolation [1][2], dan halaman Responses API merujuk ke sana untuk detail isolasi [3]. Yang tidak tersedia di sumber yang saya rujuk adalah angka batas rate limit spesifik dan pola retry yang direkomendasikan. Jadi jangan berasumsi angka tertentu—ukur sendiri dari respons API di lingkunganmu.
Yang bisa disiapkan sekarang: petakan tiap kelas error ke perilaku yang jelas (retry dengan backoff, fallback ke model lain, atau gagal cepat), dan tangani 400 secara terpisah karena itu biasanya bug request, bukan gangguan sementara. Contoh konkret dari dokumentasi: mengirim stream_options tanpa stream: true menghasilkan 400 [4], dan input_image tanpa image_url maupun file_id juga 400 [3]. Retry pada error seperti ini hanya membuang kuota.
Untuk isolasi, ada parameter user di Responses API: identifier end-user dengan karakter yang diizinkan [a-zA-Z0-9-_], maksimal 512 karakter, dipakai untuk membantu review keamanan konten, isolasi KVCache, dan isolasi scheduling [3]. Dokumentasi mengingatkan agar tidak memasukkan informasi pribadi ke situ [3]. Ini keputusan desain, bukan detail teknis: kalau kamu ingin isolasi per tenant, ID-nya harus stabil dan tidak mengikat data pribadi.
Checklist Ringkas Sebelum Go-Live
- Base URL benar sesuai SDK: OpenAI
https://api.deepseek.com, Anthropichttps://api.deepseek.com/anthropic[1][2]. - Nama model
deepseek-flashataudeepseek-v4-pro, tanpa nama legacy [1][2]. - Endpoint dipilih sadar: Chat Completions atau Responses, dengan pemilik state percakapan yang eksplisit [4][3].
thinkingdanreasoning_effortdiset per use case, bukan dibiarkan default [3][4].max_tokensataumax_output_tokensdiset sesuai anggaran, bukan mengandalkan default [4][3].- Format output dipilih sesuai kebutuhan, dan instruksi JSON ditambahkan kalau memakai
json_object[4]. - Streaming diuji sampai event penutupnya, karena
[DONE]danresponse.completedbukan hal yang sama [4][3]. - Error handling membedakan error request dari error sementara, dengan retry hanya untuk yang kedua [3][4].
- API key di secret manager; parameter
userdiisi ID non-pribadi kalau butuh isolasi [3]. - Observabilitas: catat token usage per request, karena rincian harga per token tidak tercantum di halaman dokumentasi yang saya rujuk.
Dalam gambaran lebih besar, biaya integrasi yang paling besar biasanya bukan di kode, tapi di keputusan yang dibiarkan default. Menyetel thinking, batas token, dan format output secara eksplisit memakan waktu satu sesi code review—dan itu jauh lebih murah daripada menemukan masalahnya setelah produksi jalan.