Lewati ke konten utama

Tutorial Praktik Agen LangGraph

Kuasai dasar-dasar LangGraph — state, node, edge, memori — dan bangun agen AI yang dapat diskalakan dengan pola ReAct, tool kustom, dan manajemen state persisten.

Jelajahi bersama AI

LangGraph adalah kerangka kerja berbasis graf untuk membangun agen AI yang dapat menalar, merencanakan, dan bertindak melalui langkah-langkah yang saling terhubung. Keunggulan utamanya adalah memudahkan pembuatan alur kerja siklik dan bercabang, di mana setiap node dapat menjalankan LLM, tool, atau fungsi — sambil mengelola state secara otomatis.

Hal ini menjadikan LangGraph ideal untuk membangun sistem multi-agen yang kompleks dan tangguh, yang membutuhkan memori, penanganan error, serta pengambilan keputusan waktu nyata.

Dalam tutorial ini, saya akan memandu Anda memahami fundamental dan fitur lanjutan LangGraph, mulai dari komponen intinya hingga membangun agen AI yang stateful dan diperkaya dengan tool. Jika Anda tertarik membangun sistem multi-agen dengan LangGraph, pastikan untuk melihat kursus praktik kami. Anda juga dapat menonton video tutorial kami tentang membangun agen LangGraph di bawah ini.

Fundamental LangGraph

Mari mulai dengan membahas blok bangunan fundamental LangGraph. Elemen-elemen ini memungkinkan kita membangun alur kerja yang terstruktur, stateful, dan dapat diskalakan untuk membangun agen AI tingkat lanjut.

State

State adalah objek memori bersama yang mengalir melalui graf. Ia menyimpan semua informasi relevan seperti pesan, variabel, hasil perantara, dan riwayat keputusan. LangGraph mengelola state secara otomatis, sehingga pengembangan menjadi lebih efisien.

Untuk melengkapi State, ada fitur pendukung yang lebih lanjut seperti checkpointing, thread-local memory, dan persistensi lintas sesi. Sepanjang eksekusi, state diperbarui secara berkelanjutan, seperti terlihat pada diagram di bawah:Diagram siklus yang menunjukkan manajemen state di LangGraph

Siklus manajemen state di LangGraph yang menunjukkan pembaruan berkelanjutan antar node

Node

Node adalah unit fungsional tunggal dalam alur kerja. Ia dapat melakukan berbagai aksi, seperti:

  • Memanggil large language model (LLM)
  • Memanggil tool atau API
  • Menjalankan fungsi Python kustom
  • Logika perutean atau keputusan bercabang

Setiap node menerima state saat ini dan mengembalikan state yang diperbarui.

Edge dan conditional edge

Edge mendefinisikan transisi antar node. Edge menentukan alur kontrol graf dan dapat mendukung:

  • Koneksi statis (untuk progresi linear)
  • Jalur siklik (untuk perilaku iteratif)
  • Percabangan dinamis (berdasarkan kondisi state — dibuat melalui Conditional Edge)

Diagram yang menunjukkan bagaimana edge menghubungkan node untuk mendefinisikan alur di LangGraph

Berbagai jenis Edge mendefinisikan alur antar node dan mengontrol informasi melalui graf.

Edge sangat penting untuk mengorkestrasi perilaku agen yang kompleks.

Graph dan stategraph

Graf di LangGraph mendefinisikan struktur alur kerja agentic, dan terdiri dari node-node yang dihubungkan oleh edge.

Diagram struktur LangGraph yang menunjukkan node dan edge membentuk alur kerja

Struktur Graph adalah kombinasi Node dan Edge.

StateGraph adalah graf khusus yang mempertahankan dan memperbarui state bersama sepanjang eksekusi. Ini memungkinkan pengambilan keputusan yang peka konteks serta memori persisten di setiap langkah. Kita dapat menganggapnya sebagai perpaduan antara State dan Graph.

Tool dan toolnode

Tool adalah fungsi eksternal atau internal yang dapat dipanggil agen, seperti penelusuran web, kalkulator, atau utilitas kustom. Ada dua jenis Tool:

  • Tool bawaan: Tool yang sudah dibuat dan siap digunakan oleh LangChain, dan dapat diakses di Dokumentasi.
  • Tool kustom: Tool yang dapat kita buat sendiri dan gunakan dalam aplikasi (melalui penetapan decorator dan DocString — akan ditunjukkan di kode nanti).

ToolNode adalah tipe node khusus untuk mengeksekusi tool di dalam graf. Ini memungkinkan kita sebagai pengembang untuk mengintegrasikan tool tanpa menulis logika pembungkus tambahan. Kita dapat menganggapnya sebagai perpaduan antara Tool dan Node.

Jenis pesan

Pesan adalah elemen data terstruktur (seperti masukan pengguna, keluaran sistem, respons perantara, dll.) yang bergerak melalui graf dan disimpan dalam state. Pesan memungkinkan pelacakan, memori, dan konteks bagi keputusan agen, yang membantu dalam pengambilan keputusan yang lebih tepat.

Ada beberapa MessageType di LangGraph:

  • HumanMessage: Mewakili masukan dari pengguna. Ini adalah tipe pesan paling umum untuk memulai atau melanjutkan percakapan dalam graf dengan agen.
  • AIMessage: Mewakili respons yang dihasilkan oleh model bahasa. Disimpan untuk mempertahankan memori percakapan dan menginformasikan tindakan selanjutnya.
  • SystemMessage: Memberikan konteks atau instruksi penyiapan perilaku ke LLM (misalnya, “Anda adalah asisten pribadi saya.”). Pesan ini memengaruhi cara model merespons.
  • ToolMessage: Membungkus keluaran dari sebuah tool. Ini krusial ketika agen Anda bergantung pada operasi eksternal (seperti perhitungan atau penelusuran) untuk menentukan langkah berikutnya.
  • RemoveMessage: Digunakan untuk menghapus atau membatalkan pesan yang sebelumnya ditambahkan ke state secara terprogram. Berguna untuk koreksi error atau memangkas konteks yang tidak relevan.
  • BaseMessage: Induk utama untuk semua jenis pesan di LangChain dan LangGraph. Setiap tipe pesan spesifik — seperti HumanMessage, AIMessage, atau SystemMessage — mewarisi dari BaseMessage.

Agen LangGraph

Sekarang kita akan mengodekan Agen ini di LangGraph, berfokus pada pemahaman berbagai metode dan langkah yang terlibat saat mengode sekaligus memvisualisasikan agen tersebut. 

Alur kerja agen tunggal

Mari mulai dengan membuat satu agen tanpa tool atau memori. Kita mulai dari impor berikut:

from typing import TypedDict, List
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, START, END
from dotenv import load_dotenv

Baris pertama menyebutkan TypedDict, yaitu anotasi tipe yang didefinisikan seperti ini di Python:

from typing import TypedDict
class Student(TypedDict):
name: str
grade: float
s1: Student = {"name": "Sam", "grade": 92.5}

Intinya, TypedDict adalah kamus yang memiliki langkah pengamanan tipe yang kuat, krusial untuk pengembangan Agen AI.

HumanMessage seharusnya kini familiar bagi Anda, karena telah kita bahas sebelumnya.

ChatOpenAI, bagaimanapun, baru. Mari sedikit menyinggung hal ini. 

Melalui LangChain, kita dapat menggunakan keluarga Chat, yang pada dasarnya memungkinkan kita menggunakan model dari banyak penyedia LLM, seperti OpenAI, Anthropic, Ollama, dll. melalui pustaka masing-masing seperti ChatOpenAI, ChatAnthropic, ChatOllama, dan lain-lain.

Secara fundamental, parameter dan penggunaannya serupa, sehingga memberikan modularitas pada kode kita. Langkah-langkah yang lebih detail dapat ditemukan di Dokumentasi LangChain.

Terakhir, StateGraph sudah kita bahas sebelumnya, dan Start serta End adalah titik mulai dan akhir graf kita.

Mari lanjutkan:

load_dotenv() # Obtaining over secret keys
# Creation of the state using a Typed Dictionary
class AgentState(TypedDict):
messages: List[HumanMessage] # We are going to be storing Human Messages (the user input) as a list of messages
llm = ChatOpenAI(model="gpt-4o") # Our model choice
# This is an action - the underlying function of our node
def process(state: AgentState) -> AgentState:
response = llm.invoke(state["messages"])
    print(f"\nAI: {response.content}")
    return state
graph = StateGraph(AgentState) # Initialization of a Graph
graph.add_node("process_node", process) # Adding nodes
graph.add_edge(START, "process_node") # Adding edges
graph.add_edge("process_node", END)
agent = graph.compile() # Compiling the graph

Mari bahas metode .add_node() dan .add_edge() lebih jauh.

  • add.node(): Ada dua parameter utama yang perlu diperhatikan; nama node dan aksi yang mendasarinya. Aksi yang mendasari, dalam kasus kita — process() — adalah logika utama di balik node, yaitu apa yang dilakukan saat kita sampai di tahap ini. Nama node bisa apa saja, bahkan sama dengan nama fungsi, meski itu bisa membingungkan saat debugging!
  • add_edge.(): Sekali lagi ada dua parameter utama yang perlu diperhatikan, yaitu node awal dan akhir dari Edge. Perlu dicatat bahwa yang dimasukkan adalah nama node, bukan aksi yang mendasarinya.

Mari lihat contoh praktis: 

user_input = input("Enter: ")
while user_input != "exit":
agent.invoke({"messages": [HumanMessage(content=user_input)]})
user_input = input("Enter: ")

Potongan kode di atas memungkinkan kita memanggil Agen berkali-kali. Secara visual, Agen AI yang kita bangun terlihat seperti ini:

Diagram yang menggambarkan Agen Sekuensial mengeksekusi tugas dalam urutan tetap

Agen sekuensial menyelesaikan tugas langkah demi langkah sesuai urutan yang telah ditentukan, tanpa percabangan atau penalaran.

Untuk mendapatkan visualisasi seperti itu, kita dapat menggunakan kode berikut (Catatan: kita menggunakan graf yang sudah dikompilasi):

from IPython.display import Image, display
display(Image(agent.get_graph().draw_mermaid_png()))

Agen ReAct

Agen ReAct, agen Reasoning and Acting, sangat umum di industri karena mudah dibuat namun tangguh. Karena begitu umum, LangGraph memiliki metode bawaan yang dapat kita manfaatkan untuk membuat Agen seperti ini.

Untungnya, kita hanya membutuhkan dua impor tambahan:

from langgraph.prebuilt import create_react_agent
from langchain_google_community import GmailToolkit

Metode create_react_agent inilah yang akan membuat agen ReAct untuk kita.

tools = [GmailToolkit()] # We are using the Inbuilt Gmail tool
llm = ChatOllama(model="qwen2.5:latest") # Leveraging Ollama Models
agent = create_react_agent(
    model = llm, # Choice of the LLM
    tools = tools, # Tools we want our LLM to have
    name = "email_agent", # Name of our agent
    prompt = "You are my AI assistant that has access to certain tools. Use the tools to help me with my tasks.", # System Prompt
)

Bagian terbaiknya adalah kita dapat membuat banyak agen dan membangun arsitektur yang lebih kompleks.

Kita juga dapat membuat tool kustom sendiri.

@tool
def send_email(email_address: str, email_content: str) -> str:
    """
Sends an email to a specified recipient with the given content.
Args:
email_address (str): The recipient's email address (e.g., '[email protected]')
email_content (str): The body of the email message to be sent
Returns:
str: A confirmation message indicating success or failure
Example:
        >>> send_email('[email protected]', 'Hello John, just checking in!')
'Email successfully sent to [email protected]'
"""
    # Tool Logic goes here
    return "Done!"

Seperti disebutkan di atas, ada dua hal utama yang penting saat membuat tool kustom:

  • Decorator: Ini memberi tahu LangGraph bahwa fungsi tertentu ini adalah fungsi khusus — sebuah tool.
  • Docstring: Ini diperlukan untuk memberikan konteks tentang apa yang dilakukan tool kepada LLM. Berguna untuk memberikan contoh dan deskripsi setiap parameter karena membuat pemanggilan tool lebih tangguh.

Agen ReAct terlihat seperti ini:

Diagram yang menunjukkan cara kerja Agen ReAct dengan menggabungkan langkah penalaran dan aksi

Agen ReAct bergantian antara penalaran (pikiran) dan aksi untuk menyelesaikan tugas langkah demi langkah.

Fungsi reducer untuk pertumbuhan state

Saat mendefinisikan State untuk sistem agentic yang lebih rumit dan tangguh, ada baiknya menggunakan Fungsi Reducer atau reducers. reducers adalah anotasi data yang memastikan setiap kali sebuah node mengembalikan pesan, pesan tersebut ditambahkan ke daftar yang sudah ada di state, bukannya menimpa nilai sebelumnya. Ini memungkinkan state kita membangun konteks.

# State dengan fungsi reducer
class AgentState(TypedDict):
messages: Annotated[list[BaseMessage], operator.add]

Kode ini mengintegrasikan fungsi reducer operator.add dengan state, memastikan semua pesan tetap terjaga.

Manajemen Memori di LangGraph

Di bagian ini kita akan berfokus pada komponen inti setiap agen — Memori. Memori sangat penting bagi agen karena menyediakan konteks yang dibutuhkan agar lebih tangguh dan andal. Mari telusuri berbagai cara kita dapat mengelola memori dalam agen.

Penyimpanan checkpoint eksternal

State adalah elemen terpenting di LangGraph, dan secara alami, ada banyak cara untuk menyimpan state secara eksternal. Beberapa penyimpanan eksternal populer adalah:

  • SQLite
  • PostgreSQL
  • Amazon S3
  • Azure Blob Storage
  • Google Cloud Storage
  • Mem0

Semua pustaka ini dapat ditemukan di dokumentasi.

Untuk saat ini, kita akan melihat SQLite:

from langgraph.checkpoint.sqlite import SqliteSaver
memory = SqliteSaver.from_conn_string(":memory:") # This is for connecting to the SQLite database
graph = graph_builder.compile(checkpointer=memory) # Compiling graph with checkpointer as SQLite backend

Menggunakan SQLite adalah cara mudah untuk menambahkan Persistensi pada Agen kita. Persistensi adalah kemampuan mempertahankan konteks di berbagai interaksi.

Semua ini untuk menyimpan dan memperbarui state. Sekarang mari lihat cara menggunakan dan mengelola state tersebut secara efektif, terutama daftar messages, yang menjadi cukup besar seiring berlanjutnya percakapan.

LangGraph menyediakan dukungan native untuk memori jangka pendek dan jangka panjang. Mari kita telusuri.

Memori jangka pendek

Memori jangka pendek memungkinkan agen kita mengingat riwayat pesan selama satu sesi, sehingga berguna untuk percakapan multi-giliran.

from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph

checkpointer = InMemorySaver()

builder = StateGraph(...)
graph = builder.compile(checkpointer=checkpointer)


# Invoking the Graph with our message
agent_graph.invoke(
    {"messages": [{"role": "user", "content": "What's the weather today?"}]},
    {"configurable": {"thread_id": "session_42"}},
)

Pada contoh di atas, thread_id digunakan untuk mengidentifikasi secara unik sebuah percakapan atau sesi.

Memori jangka panjang

Memori jangka panjang dipertahankan di banyak sesi dan cocok untuk mengingat hal-hal seperti nama, tujuan, atau pengaturan — hal penting yang dibutuhkan lintas sesi.

from langgraph.store.memory import InMemoryStore
from langgraph.graph import StateGraph

long_term_store = InMemoryStore()
builder = StateGraph(...)
agent = builder.compile(store=long_term_store)

Namun, karena percakapan kita bisa menjadi besar, kita butuh cara untuk membatasi riwayat pesan. Di sinilah trimming berperan.

Trimming

Pada contoh di bawah, kita menghapus token dari awal riwayat pesan (karena baris: strategy="first") sehingga setelah trimming, kita menyisakan maksimal 150 token.

from langchain_core.messages.utils import trim_messages, count_tokens_approximately

trimmed = trim_messages(
        messages=state["messages"],
        strategy="first",  # remove the messages from beginning
        token_counter=count_tokens_approximately,
        max_tokens=150
    )

Pemangkasan berbasis peringkasan

Cara lain untuk mengurangi riwayat pesan adalah dengan peringkasan. Ini memungkinkan pelestarian informasi penting di sepanjang riwayat pesan, alih-alih hanya memotong token dari sebagian percakapan.

from langmem.short_term import SummarizationNode
from langchain_core.messages.utils import count_tokens_approximately

summary_node = SummarizationNode(
    model=summary_llm,                       # Our summarization LLM
    max_tokens=300,                          # Total token limit
    max_tokens_before_summary=150,           # when to start summarizing
    max_summary_tokens=150,                  # summary size
    token_counter=count_tokens_approximately
)

Penting untuk dicatat bahwa peringkasan dilakukan oleh LLM yang mendasarinya, dalam hal ini summary_llm, yang bisa berupa LLM apa pun.

Penghapusan selektif

Operasi utama terakhir dalam Manajemen Memori adalah Hapus. Untuk menghapus pesan terpilih, kita dapat menggunakan kode ini:

from langchain_core.messages import RemoveMessage

def clean_state(state):
    # Remove all tool-related messages
    to_remove = [RemoveMessage(id=msg.id) for msg in state["messages"] if msg.role == "tool"]
    return {"messages": to_remove}

Pada kode di atas, kita menghapus semua pesan terkait tool, yang bisa saja redundan (karena secara realistis, Tool-Message ditujukan bagi LLM untuk menyusun jawabannya setelah menggunakan tool).

Namun, jika kita ingin menghapus seluruh riwayat pesan, kita bisa melakukan ini:

from langgraph.graph.message import REMOVE_ALL_MESSAGES
from langchain_core.messages import RemoveMessage

def reset_history(state):
    # Remove entire conversation history
    return {"messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES)]}

Penutup

Secara keseluruhan, LangGraph adalah pustaka yang kuat yang menawarkan pendekatan terstruktur dan dapat diskalakan untuk membangun sistem agentic. Memodelkan logika sebagai graf node dan edge, dengan state bersama dan memori persisten, memungkinkan kita mengembangkan agen yang kokoh, dapat bernalar, berinteraksi, dan beradaptasi seiring waktu.

Seiring sistem bertambah kompleks, kerangka kerja ini menyediakan alat yang dibutuhkan untuk mengelola memori, mengoordinasikan penggunaan tool, dan mempertahankan konteks jangka panjang — sambil tetap modular dan dapat diperluas.

Dengan komponen inti yang kini sudah Anda kuasai, Anda siap merancang dan menerapkan agen AI yang tangguh dan mampu menangani alur kerja dunia nyata.

Untuk terus belajar, pastikan untuk melihat kursus kami, Building Multi-Agent Systems With LangGraph. Anda juga dapat melihat kursus Designing Agentic Systems with LangChain kami, serta tutorial tentang Agentic RAG.

FAQ Agen LangGraph

Apa sebenarnya LangGraph itu?

Kerangka kerja Python yang memodelkan logika agen AI sebagai graf node dan edge, sehingga memungkinkan penalaran, panggilan tool, dan memori.

Mengapa saya harus memilih LangGraph dibandingkan pustaka agen lainnya?

LangGraph menggunakan struktur Graf untuk mendefinisikan logika, faktor pembeda utama yang tidak digunakan oleh banyak kerangka agentic populer lainnya. LangGraph juga menawarkan dukungan native untuk loop, percabangan, memori, persistensi, dan alur kerja multi-agen — menjadikannya ideal untuk sistem agen yang skalabel di dunia nyata.

Bagaimana LangGraph mengelola dan mempertahankan memori?

Ia menggunakan state bersama yang dapat disimpan jangka pendek (in-memory) atau jangka panjang (SQLite, S3, dll.), sehingga agen dapat mengingat interaksi sebelumnya.

Bisakah saya menggunakan model lokal sebagai gantinya?

Tentu saja! LangGraph menawarkan dukungan native untuk Model Ollama, Model HuggingFace, LlamaCpp, dll.

Bagaimana cara mengurangi ukuran riwayat pesan yang panjang?

Gunakan trim_messages untuk membuang token lama atau SummarizationNode untuk memampatkan pesan masa lalu sambil mempertahankan konteks penting.

Vaibhav Mehra

Penulis

Vaibhav Mehra

Topik

Terkait

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

blogs

Tutorial Korelasi di R