AizuDemy

Tutorial LangGraph & Ollama: Build Stateful Multi-Agent AI Lokal

Tutorial LangGraph & Ollama: Build Stateful Multi-Agent AI Lokal
๐ŸŽง
Dengarkan Artikel Ini
Suara AI Otomatis โ€ข 5 mnt baca baca
โšก TL;DR

Poin Kunci Artikel Ini:

  • Python 3.10 atau versi lebih baru
  • Ollama terpasang lokal
  • RAM minimum 16GB (runtime model 8B quantized)
๐Ÿ“‹ Daftar Isi Materi Tutup โ–ด

1. Keterbatasan Single Prompt & Arsitektur Graph Agent

Single prompt LLM gagal selesaikan alur kerja kompleks. Masalah: context window meluap, halusinasi instruksi bertumpuk, determinisme eksekusi nol. LLM jadi perencana, eksekutor, penguji bersamaan buat tingkat gagal melonjak. Solusi: Graph-based Multi-Agent System. LangGraph ubah rantai linier jadi State Machine terarah (Directed Cyclic Graph). Sistem pecah tugas kompleks jadi node terisolasi. Node tukar data lewat Shared State terstruktur.

Komponen Utama Arsitektur Graph Agent

  • State: Data skema terpusat. Simpan histori pesan, hasil eksekusi alat, metadata sistem.
  • Nodes: Fungsi Python atau agen mandiri. Terima State saat ini, komputasi/panggil LLM, kembalikan pembaruan (patch) ke State.
  • Edges: Logika penentu arah eksekusi berikutnya. Deterministik (pindah langsung) atau kondisional (keputusan LLM/evaluasi logika).
  • Checkpointer: Simpan snapshot State ke RAM/Database tiap siklus node selesai. Izinkan fitur fault tolerance, time-travel, human-in-the-loop.

2. Setup LangGraph, Memory Checkpoint & Integration Ollama Llama3

Arsitektur lokal butuh Ollama sebagai inference engine dan LangGraph sebagai orchestrator. Bebas biaya API eksternal. Data tetap dalam infrastruktur lokal.

Prasyarat Sistem

  • Python 3.10 atau versi lebih baru
  • Ollama terpasang lokal
  • Model Llama3 terunduh (eksekusi: ollama pull llama3:8b)
  • RAM minimum 16GB (runtime model 8B quantized)

Langkah 1: Instalasi Dependensi

Pasang library utama via pip:

pip install langgraph langchain-ollama langchain-core sqlite3

Langkah 2: Definisi Skema State

Buat berkas state.py. Gunakan TypedDict dan operator add_messages untuk append-only message history.

from typing import Annotated, TypedDict
from langgraph.graph.message import add_messages

class AgentState(TypedDict):
    messages: Annotated[list, add_messages]
    research_data: str
    draft_content: str
    review_status: str
    revision_count: int

Langkah 3: Inisialisasi LLM Ollama & Agen Nodes

Buat berkas nodes.py. Hubungkan ke instance Ollama lokal.

from langchain_ollama import ChatOllama
from langchain_core.messages import HumanMessage, SystemMessage
from state import AgentState

llm = ChatOllama(model="llama3:8b", temperature=0)

def researcher_node(state: AgentState) -> dict:
    messages = state["messages"]
    system_prompt = SystemMessage(content="Anda peneliti teknis. Cari informasi inti dari topik yang diberikan.")
    response = llm.invoke([system_prompt] + messages)
    return {"research_data": response.content, "messages": [response]}

def writer_node(state: AgentState) -> dict:
    research = state["research_data"]
    rev_count = state.get("revision_count", 0)
    system_prompt = SystemMessage(content=f"Anda penulis teknis. Tulis draf berdasarkan data penelitian ini: {research}. Revisi ke-{rev_count}.")
    response = llm.invoke([system_prompt])
    return {"draft_content": response.content, "messages": [response], "revision_count": rev_count + 1}

def reviewer_node(state: AgentState) -> dict:
    draft = state["draft_content"]
    system_prompt = SystemMessage(content=f"Evaluasi draf ini. Jika layak, jawab 'APPROVED'. Jika kurang, berikan saran revisi: {draft}")
    response = llm.invoke([system_prompt])
    status = "APPROVED" if "APPROVED" in response.content.upper() else "NEEDS_REVISION"
    return {"review_status": status, "messages": [response]}

Langkah 4: Konstruksi Graph & Dynamic Routing

Rangkai node dan edge dalam berkas workflow.py.

from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver
from state import AgentState
from nodes import researcher_node, writer_node, reviewer_node

def route_review(state: AgentState) -> str:
    if state["review_status"] == "APPROVED":
        return END
    if state.get("revision_count", 0) >= 3:
        return END
    return "writer"

builder = StateGraph(AgentState)

builder.add_node("researcher", researcher_node)
builder.add_node("writer", writer_node)
builder.add_node("reviewer", reviewer_node)

builder.add_edge(START, "researcher")
builder.add_edge("researcher", "writer")
builder.add_edge("writer", "reviewer")

builder.add_conditional_edges(
    "reviewer",
    route_review,
    {
        END: END,
        "writer": "writer"
    }
)

memory = MemorySaver()
graph = builder.compile(checkpointer=memory)

3. Implementasi Persistent Checkpoint dengan SQLite

MemorySaver simpan state dalam RAM. Sesi hilang saat proses mati. Produksi butuh penyiapan persistent database. Gunakan SqliteSaver dari LangGraph.

Integrasi Database Persistent

import sqlite3
from langgraph.checkpoint.sqlite import SqliteSaver

conn = sqlite3.connect("state_db.sqlite", check_same_thread=False)
memory_sqlite = SqliteSaver(conn)

app = builder.compile(checkpointer=memory_sqlite)

Database simpan state per thread_id. Memungkinkan fitur Resume execution, Audit trail, Stateful multi-session chatbot.

4. Pengendalian Loop Tak Terbatas & Human-in-the-Loop

Multi-agent siklis rawan infinite loop. Reviewer terus tolak draf, LLM habiskan sumber daya CPU/GPU. Solusi: Guard condition dan Human Interruption.

Langkah Kontrol Infinite Loop

  1. Batasi akumulasi revisi pakai penghitung (contoh: revision_count >= 3).
  2. Tambahkan instruksi eksplisit pada system prompt agen untuk penyelesaian bertahap.
  3. Gunakan fitur interrupt_before untuk verifikasi manusia sebelum node kritis dieksekusi.

Konfigurasi Human-in-the-Loop

app_with_human = builder.compile(
    checkpointer=memory_sqlite,
    interrupt_before=["writer"]
)

Eksekusi berhenti otomatis sebelum node writer berjalan. Operator manusia periksa state, berikan input manual, lalu lanjutkan eksekusi via update state.

5. Eksekusi End-to-End & Monitoring State

Jalankan workflow lengkap melalui berkas main.py.

from langchain_core.messages import HumanMessage
from workflow import app

config = {"configurable": {"thread_id": "session-001"}}
initial_input = {
    "messages": [HumanMessage(content="Jelaskan konsep Rust Ownership untuk pemula.")],
    "revision_count": 0
}

for event in app.stream(initial_input, config):
    for node_name, state_update in event.items():
        print(f"--- NODE TEREKSEKUSI: {node_name} ---")
        if "messages" in state_update:
            print(f"Output: {state_update['messages'][-1].content[:150]}...")
        print("\n")

6. Evaluasi Performa & Ringkasan Arsitektur Agen Lokal

Kombinasi LangGraph dan Ollama Llama3 beri kontrol penuh atas eksekusi agen AI tanpa ketergantungan API pihak ketiga.

  • Biaya: Rp 0 untuk panggol API. Murni konsumsi listrik dan hardware lokal.
  • Privasi: Data tidak tinggalkan mesin server lokal. Aman untuk enklaf data internal.
  • Kecepatan: Tergantung akselerasi hardware (GPU VRAM). Penggunaan model 8B quantized efisien pada GPU konsumer 8GB-12GB VRAM.
  • Keandalan: Graph state machine hilangkan masalah halusinasi alur kerja. Logika percabangan terjamin deterministik.

๐Ÿ“– Artikel Terkait