Praktik pertama: setup proyek lengkap dengan API key dari .env, inisialisasi ChatOpenAI dan ChatAnthropic, lalu semua mode invocation — invoke, ainvoke, stream, astream, batch, abatch — beserta isi response object seperti content dan token usage.

Di episode 2, kalian mengenal peta arsitektur LangChain: primitif langchain-core, LCEL dengan operator pipa, dan struktur paket modular. Sekarang saatnya berhenti sekadar memahami konsep — kita akan benar-benar menjalankan model. Episode ini adalah pintu masuk praktik: menyiapkan proyek, menginisialisasi chat model, dan menguasai semua mode invocation.
Seluruh kode di episode ini dan seterusnya dijalankan di dalam environment virtual yang kalian buat di episode 0. Pastikan pip show langchain-openai tidak error sebelum melanjutkan.
Langkah pertama, lengkapi dependency yang akan kita pakai untuk memuat file .env:
pip install python-dotenv langchain langchain-openaiBuat file chat_basic.py di akar proyek, lalu muat kunci dari .env:
from dotenv import load_dotenv
load_dotenv()belajar-langchain/
├── .env
├── chat_basic.py
└── .venv/load_dotenv() membaca file .env dan memasukkan nilainya ke environment. Setelah dipanggil, variabel OPENAI_API_KEY otomatis tersedia untuk diambil LangChain. Cara kerja ini berlaku untuk semua provider — baik OpenAI, Anthropic, maupun yang lain.
Inisialisasi chat model berarti satu hal: membuat instance yang mewakili sebuah model dari penyedia tertentu. Karena LangChain menstandardisasi lewat BaseChatModel, dua provider berikut dipakai dengan pola yang sama:
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
gpt = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
claude = ChatAnthropic(model="claude-3-5-sonnet-latest", temperature=0.3)Dua parameter paling umum: model untuk memilih nama model, dan temperature untuk mengontrol determinisme. Nilai temperature=0 membuat output hampir selalu sama untuk input yang sama — cocok untuk tugas yang butuh konsistensi seperti ekstraksi data; nilai tinggi lebih kreatif untuk brainstorming.
Info
Jika kalian memakai provider yang belum terpasang paketnya, cukup tambahkan paket integrasinya — misalnya pip install langchain-anthropic — dan pola inisialisasinya mengikuti bentuk yang sama. Ini standardisasi yang kita bahas di episode 1.
Mode paling dasar adalah invoke — kirim satu input, terima hasil lengkap:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
jawaban = llm.invoke("Sebutkan tiga keunggulan LCEL.")
print(jawaban.content)Perhatikan bahwa invoke mengembalikan objek AIMessage (bukan string), sehingga isi teks diakses lewat atribut .content. Untuk aplikasi async — misalnya di dalam async handler web — gunakan ainvoke:
import asyncio
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
async def utama():
jawaban = await llm.ainvoke("Apa itu RAG?")
return jawaban.content
hasil = asyncio.run(utama())
print(hasil)Versi async penting ketika kalian membangun server yang harus melayani banyak request bersamaan — memblokir satu request sambil menunggu model merespons akan menyia-nyiakan resource. Di episode 5 dan 18 kita akan membahas pola ini lebih dalam.
Streaming mengubah pengalaman pengguna secara drastis: alih-alih menunggu seluruh jawaban, chunk demi chunk muncul segera setelah tersedia — inilah yang membuat aplikasi terasa hidup. Polanya sama sederhananya:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
for chunk in llm.stream("Ceritakan singkat sejarah LangChain."):
print(chunk.content, end="", flush=True)Setiap chunk adalah potongan jawaban parsial; kita menampilkannya tanpa baris baru agar tampak mengalir. Untuk asinkron, ganti dengan astream di dalam fungsi async:
async def streaming():
async for chunk in llm.astream("Ceritakan singkat sejarah LangChain."):
print(chunk.content, end="", flush=True)
asyncio.run(streaming())batch mengirim banyak input sekaligus dalam satu panggilan — berguna untuk memproses daftar pertanyaan atau dokumen secara efisien:
daftar_pertanyaan = [
"Apa itu token?",
"Apa itu temperature?",
"Apa itu prompt?",
]
jawaban = llm.batch(daftar_pertanyaan)
for item in jawaban:
print(item.content, "\n")Di belakang layar, batch mengeksekusi setiap input secara berurutan dengan .invoke (atau paralel jika diberi konfigurasi). Variasi async-nya adalah abatch.
Terakhir, perhatikan isi response object yang dikembalikan semua mode di atas — karena bukan sekadar string:
jawaban = llm.invoke("Hitung 2 + 2.")
print("Isi:", jawaban.content)
print("Tipe:", type(jawaban).__name__)
print("Token pemakaian:", jawaban.usage_metadata)Output usage_metadata berisi rincian input_tokens, output_tokens, dan total_tokens — data penting untuk melacak biaya di production, yang akan kita manfaatkan saat membahas optimasi biaya di episode 18.
Warning
Mengirim daftar besar ke batch tanpa mengatur concurrency bisa memicu rate limit penyedia model. Untuk aplikasi production, atur tingkat paralelisme secara eksplisit — kita akan lihat caranya di episode 5 dan 18.
Episode 3 adalah praktik pertama kalian: memuat API key dari .env dengan python-dotenv, menginisialisasi ChatOpenAI dan ChatAnthropic, menguasai invoke/ainvoke, streaming dengan stream/astream, batch dengan batch/abatch, serta mengenal response object yang membawa content dan usage_metadata.
Inti yang harus dibawa pulang:
load_dotenv() dan simpan kunci di .env yang tidak di-commit.ChatOpenAI/ChatAnthropic; temperature mengontrol determinisme.invoke untuk satu input, batch untuk banyak input, stream untuk output bertahap.ainvoke, abatch, astream wajib untuk aplikasi server bersamaan..content dan pemakaian token di .usage_metadata.Di episode 4 berikutnya kita akan memperdalam prompts & chat models lanjutan: PromptTemplate dan ChatPromptTemplate dengan message system/human, few-shot prompting, input variables, model profiles per provider, hingga streaming content-block v2/v3 dengan version="v3" pada stream_events. Sampai jumpa!