LangGraph Essentials
> LangGraph adalah framework untuk membangun aplikasi AI sebagai graph yang eksplisit dan stateful, bukan sekadar prompt chain linear. Notebook ini membahas masalah apa yang diselesaikannya, building block utamanya, dan contoh singkat merangkai agent yang bisa looping, branching, dan pause.
Apa itu LangGraph?
LangGraph adalah library orchestration low-level (dibuat oleh tim LangChain) untuk membangun aplikasi di mana control flow LLM butuh lebih dari sekadar "prompt masuk, jawaban keluar." Alih-alih merangkai step secara linear, aplikasi dimodelkan sebagai graph: node adalah unit kerja, edge menentukan bagaimana kontrol berpindah antar node, dan sebuah state bersama mengalir di sepanjang proses eksekusi.
Ini penting karena agent di dunia nyata jarang berjalan lurus dari awal sampai akhir. Mereka memanggil tool, melihat hasilnya, memutuskan apakah perlu coba lagi, meminta approval dari manusia, atau hand off ke specialist lain. Control flow semacam ini pada dasarnya bersifat cyclic — sesuatu yang tidak bisa direpresentasikan oleh chain sederhana, tapi bisa oleh graph.
Karakteristik utama:
Kenapa Tidak Pakai Chain Biasa Saja?
Chain (prompt → LLM → parse → selesai) sudah cukup untuk task single-shot. Tapi mulai kurang memadai begitu dibutuhkan:
LangGraph dibuat khusus untuk kelas masalah ini — layer di atas "sekadar panggil LLM API," dipakai begitu control flow aplikasi berubah dari garis lurus menjadi graph.
Konsep Inti
TypedDict atau Pydantic model) yang merepresentasikan semua yang dibawa graph antar step: riwayat percakapan, hasil tool, counter, flag.Use Case Umum
Contoh Praktis: Agent Loop dengan Tool Calling
Sketsa ini menunjukkan bentuk minimal sebuah agent graph: node LLM yang bisa meminta tool, node eksekusi tool, dan conditional edge yang loop kembali sampai model selesai memanggil tool.
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages
from langchain_core.messages import AnyMessage
class AgentState(TypedDict):
messages: Annotated[list[AnyMessage], add_messages]
def call_model(state: AgentState) -> dict:
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response]}
def call_tools(state: AgentState) -> dict:
last_message = state["messages"][-1]
results = [run_tool(call) for call in last_message.tool_calls]
return {"messages": results}
def should_continue(state: AgentState) -> str:
last_message = state["messages"][-1]
return "tools" if last_message.tool_calls else END
graph = StateGraph(AgentState)
graph.add_node("agent", call_model)
graph.add_node("tools", call_tools)
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue, {"tools": "tools", END: END})
graph.add_edge("tools", "agent") # loop balik setelah tool dieksekusi
app = graph.compile(checkpointer=my_checkpointer)
result = app.invoke(
{"messages": [("user", "Cuaca di Jakarta gimana, terus convert ke Fahrenheit?")]},
config={"configurable": {"thread_id": "user-123"}},
)
thread_id di config inilah yang membuat proses ini resumable — checkpointer meng-index state berdasarkan thread, jadi memanggil invoke lagi dengan thread_id yang sama akan melanjutkan percakapan yang sama dari titik terakhir.
Best Practices
Kapan Pakai LangGraph (dan Kapan Tidak)
Cocok untuk:
Berlebihan untuk: