AutoGen: Framework Multi-Agent Conversation dari Microsoft
AutoGen adalah framework open-source dari Microsoft Research yang memungkinkan pengembangan aplikasi berbasis Large Language Model (LLM) menggunakan arsitektur multi-agent conversation. Dengan AutoGen, Anda dapat membuat beberapa agen AI yang saling berkomunikasi, berkolaborasi, dan menyelesaikan tugas kompleks secara otomatis.
Dalam tutorial ini, kita akan mempelajari cara menggunakan AutoGen mulai dari instalasi, membuat berbagai jenis agen, membangun percakapan multi-agen, hingga membangun tim pengembangan software virtual yang terdiri dari planner, coder, dan tester.
Mengapa AutoGen?
Sebelum kita mulai, mari pahami mengapa AutoGen menjadi pilihan populer untuk membangun sistem multi-agent:
- Multi-Agent Conversation: Agen dapat berkomunikasi satu sama lain secara natural
- Customizable: Setiap agen dapat dikonfigurasi dengan perilaku, tools, dan LLM yang berbeda
- Human-in-the-Loop: Mendukung intervensi manusia dalam alur percakapan
- Code Execution: Agen dapat menulis dan mengeksekusi kode secara otomatis
- Teachable Agents: Agen dapat belajar dari interaksi sebelumnya
- Nested Chats: Mendukung percakapan bertingkat untuk alur kerja kompleks
Instalasi
Prasyarat
Pastikan Anda memiliki Python 3.8 atau lebih baru terinstal di sistem Anda.
Instalasi Dasar
pip install pyautogen
Instalasi dengan Fitur Tambahan
# Dengan dukungan Docker untuk code execution
pip install pyautogen[docker]
Dengan dukungan teachable agents
pip install pyautogen[teachable]
Instalasi lengkap
pip install pyautogen[docker,teachable]
Konfigurasi LLM
AutoGen membutuhkan akses ke LLM. Buat file konfigurasi OAICONFIGLIST:
[
{
"model": "gpt-4",
"apikey": "sk-your-openai-api-key"
},
{
"model": "gpt-3.5-turbo",
"apikey": "sk-your-openai-api-key"
}
]
Atau gunakan environment variable:
import os
os.environ["OPENAIAPIKEY"] = "sk-your-openai-api-key"
Konsep Dasar Agen
ConversableAgent
ConversableAgent adalah kelas dasar untuk semua agen di AutoGen. Setiap agen yang dapat berkomunikasi mewarisi kelas ini.
import autogen
configlist = autogen.configlistfromjson("OAICONFIGLIST")
llmconfig = {
"configlist": configlist,
"temperature": 0,
}
Membuat ConversableAgent dasar
agent = autogen.ConversableAgent(
name="basicagent",
llmconfig=llmconfig,
systemmessage="Kamu adalah asisten yang membantu.",
humaninputmode="NEVER",
)
Parameter penting humaninputmode:
"ALWAYS": Selalu meminta input manusia sebelum merespons"NEVER": Tidak pernah meminta input manusia"TERMINATE": Meminta input hanya saat percakapan akan berakhir
AssistantAgent
AssistantAgent adalah agen yang dirancang untuk menjadi asisten AI. Secara default, ia menggunakan LLM untuk menghasilkan respons.
assistant = autogen.AssistantAgent(
name="assistant",
llmconfig=llmconfig,
systemmessage="""Kamu adalah asisten AI yang membantu menyelesaikan tugas.
Berikan solusi yang jelas dan terstruktur.
Balas dengan 'TERMINATE' ketika tugas selesai."""
)
UserProxyAgent
UserProxyAgent bertindak sebagai proxy untuk pengguna manusia. Ia dapat mengeksekusi kode dan meneruskan input dari manusia.
userproxy = autogen.UserProxyAgent(
name="user
proxy",
humaninputmode="TERMINATE",
maxconsecutiveautoreply=10,
isterminationmsg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
codeexecutionconfig={
"workdir": "coding",
"usedocker": False, # Set True untuk keamanan
},
)
Percakapan Dua Agen
Percakapan paling sederhana melibatkan dua agen yang berkomunikasi satu sama lain.
import autogen
configlist = autogen.configlistfromjson("OAICONFIGLIST")
assistant = autogen.AssistantAgent(
name="assistant",
llmconfig={"configlist": configlist},
systemmessage="Kamu adalah programmer Python yang ahli. Tulis kode yang bersih dan terdokumentasi."
)
userproxy = autogen.UserProxyAgent(
name="userproxy",
humaninputmode="NEVER",
maxconsecutiveautoreply=5,
isterminationmsg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
codeexecutionconfig={"workdir": "coding", "usedocker": False},
)
Memulai percakapan
userproxy.initiatechat(
assistant,
message="Buatkan fungsi Python yang menghitung deret Fibonacci secara rekursif dan iteratif, lalu bandingkan performanya."
)
Group Chat: Percakapan Multi-Agen
Group Chat memungkinkan lebih dari dua agen berkomunikasi dalam satu sesi.
Membuat GroupChat
import autogen
configlist = autogen.configlistfromjson("OAICONFIGLIST")
llmconfig = {"configlist": configlist, "temperature": 0}
Agen Perencana
planner = autogen.AssistantAgent(
name="planner",
llmconfig=llmconfig,
systemmessage="""Kamu adalah project planner. Tugasmu:
- Menganalisis kebutuhan proyek
- Membuat rencana implementasi langkah demi langkah
- Memastikan semua aspek tercakup
Jangan menulis kode, fokus pada perencanaan."""
)
Agen Pengkritik
critic = autogen.AssistantAgent(
name="critic",
llmconfig=llmconfig,
systemmessage="""Kamu adalah code reviewer. Tugasmu:
- Mereview kode yang ditulis
- Memberikan saran perbaikan
- Memastikan best practices diikuti
Berikan feedback yang konstruktif."""
)
Agen Programmer
coder = autogen.AssistantAgent(
name="coder",
llmconfig=llmconfig,
systemmessage="""Kamu adalah senior programmer. Tugasmu:
- Menulis kode berdasarkan rencana
- Mengimplementasikan fitur sesuai spesifikasi
- Memperbaiki kode berdasarkan review"""
)
User Proxy
userproxy = autogen.UserProxyAgent(
name="admin",
humaninputmode="NEVER",
maxconsecutiveautoreply=10,
codeexecutionconfig={"workdir": "groupcoding", "usedocker": False},
)
GroupChatManager
GroupChatManager mengelola alur percakapan dalam group chat.
# Membuat GroupChat
groupchat = autogen.GroupChat(
agents=[userproxy, planner, coder, critic],
messages=[],
maxround=20,
speakerselectionmethod="auto", # LLM memilih speaker berikutnya
)
Membuat Manager
manager = autogen.GroupChatManager(
groupchat=groupchat,
llmconfig=llmconfig,
)
Memulai group chat
userproxy.initiatechat(
manager,
message="Buatkan REST API sederhana menggunakan FastAPI untuk manajemen buku (CRUD operations)."
)
Metode Pemilihan Speaker
# Round-robin: bergiliran
groupchatrr = autogen.GroupChat(
agents=[userproxy, planner, coder, critic],
messages=[],
maxround=20,
speakerselectionmethod="roundrobin",
)
Manual: pengguna memilih
groupchatmanual = autogen.GroupChat(
agents=[userproxy, planner, coder, critic],
messages=[],
maxround=20,
speakerselectionmethod="manual",
)
Custom function
def customspeakerselection(lastspeaker, groupchat):
if lastspeaker is userproxy:
return planner
elif lastspeaker is planner:
return coder
elif lastspeaker is coder:
return critic
else:
return userproxy
groupchatcustom = autogen.GroupChat(
agents=[userproxy, planner, coder, critic],
messages=[],
maxround=20,
speakerselectionmethod=customspeakerselection,
)
Code Execution
AutoGen mendukung eksekusi kode secara otomatis, baik menggunakan Docker maupun secara lokal.
Eksekusi Lokal
userproxy = autogen.UserProxyAgent(
name="executor",
codeexecutionconfig={
"workdir": "workspace",
"usedocker": False,
"timeout": 60,
"lastnmessages": 3,
},
)
Eksekusi dengan Docker
userproxy = autogen.UserProxyAgent(
name="executor",
code
executionconfig={
"work
dir": "workspace",
"usedocker": "python:3.11-slim",
"timeout": 120,
},
)
Custom Code Executor
from autogen.coding import LocalCommandLineCodeExecutor
executor = LocalCommandLineCodeExecutor(
timeout=60,
workdir="myworkspace",
)
userproxy = autogen.UserProxyAgent(
name="executor",
codeexecutionconfig={"executor": executor},
)
Tool Use (Function Calling)
Agen dapat menggunakan tools/fungsi untuk menyelesaikan tugas.
Mendaftarkan Tools
from typing import Annotated
Definisikan fungsi
def getweather(
city: Annotated[str, "Nama kota untuk cek cuaca"]
) -> str:
"""Mendapatkan informasi cuaca untuk kota tertentu."""
# Simulasi API cuaca
weatherdata = {
"Jakarta": "Cerah, 32°C",
"Bandung": "Berawan, 24°C",
"Surabaya": "Hujan ringan, 30°C",
}
return weatherdata.get(city, f"Data cuaca untuk {city} tidak tersedia")
def calculatebmi(
weight: Annotated[float, "Berat badan dalam kg"],
height: Annotated[float, "Tinggi badan dalam meter"]
) -> str:
"""Menghitung Body Mass Index (BMI)."""
bmi = weight / (height 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 25:
category = "Normal"
elif bmi < 30:
category = "Overweight"
else:
category = "Obese"
return f"BMI: {bmi:.1f} - Kategori: {category}"
Daftarkan ke agen
assistant = autogen.AssistantAgent(
name="assistant",
llmconfig=llmconfig,
)
userproxy = autogen.UserProxyAgent(
name="userproxy",
humaninputmode="NEVER",
codeexecutionconfig=False, # Nonaktifkan code execution
)
Register tools
autogen.registerfunction(
getweather,
caller=assistant,
executor=userproxy,
name="getweather",
description="Mendapatkan informasi cuaca untuk kota tertentu"
)
autogen.registerfunction(
calculatebmi,
caller=assistant,
executor=userproxy,
name="calculatebmi",
description="Menghitung Body Mass Index"
)
Gunakan tools
userproxy.initiatechat(
assistant,
message="Bagaimana cuaca di Jakarta hari ini? Dan tolong hitung BMI saya: berat 70kg, tinggi 1.75m"
)
Human-in-the-Loop
Kontrol intervensi manusia dalam percakapan agen.
Mode Input Manusia
# Selalu meminta persetujuan manusia
agentalways = autogen.UserProxyAgent(
name="humanalways",
humaninputmode="ALWAYS",
codeexecutionconfig={"workdir": "coding"},
)
Meminta input saat terminasi
agentterminate = autogen.UserProxyAgent(
name="humanterminate",
humaninputmode="TERMINATE",
maxconsecutiveautoreply=5,
isterminationmsg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
)
Tanpa intervensi manusia
agentnever = autogen.UserProxyAgent(
name="humannever",
humaninputmode="NEVER",
maxconsecutiveautoreply=10,
)
Custom Termination
def istaskcomplete(msg):
content = msg.get("content", "")
if content:
return "TASK
COMPLETE" in content or "TERMINATE" in content
return False
userproxy = autogen.UserProxyAgent(
name="user",
humaninputmode="TERMINATE",
isterminationmsg=istaskcomplete,
maxconsecutiveautoreply=15,
)
Nested Chats
Nested chats memungkinkan agen untuk memulai sub-percakapan saat menyelesaikan tugas.
import autogen
configlist = autogen.configlistfromjson("OAICONFIGLIST")
llmconfig = {"configlist": configlist}
Agen utama
writer = autogen.AssistantAgent(
name="writer",
llmconfig=llmconfig,
systemmessage="Kamu adalah penulis teknis. Tulis konten berdasarkan outline yang diberikan."
)
Agen reviewer untuk nested chat
reviewer = autogen.AssistantAgent(
name="reviewer",
llmconfig=llmconfig,
systemmessage="""Kamu adalah editor. Review tulisan dan berikan feedback.
Format: [APPROVED] jika sudah bagus, atau [REVISION NEEDED] dengan detail perbaikan."""
)
Agen SEO untuk nested chat
seooptimizer = autogen.AssistantAgent(
name="seooptimizer",
llmconfig=llmconfig,
systemmessage="Kamu adalah SEO specialist. Optimasi konten untuk search engine."
)
userproxy = autogen.UserProxyAgent(
name="user",
humaninputmode="NEVER",
maxconsecutiveautoreply=3,
codeexecutionconfig=False,
)
Konfigurasi nested chat
nestedchatconfig = [
{
"recipient": reviewer,
"message": "Review tulisan berikut dan berikan feedback:\n\n",
"summarymethod": "lastmsg",
"maxturns": 2,
},
{
"recipient": seooptimizer,
"message": "Optimasi konten berikut untuk SEO:\n\n",
"summarymethod": "lastmsg",
"maxturns": 2,
},
]
Register nested chats
userproxy.registernestedchats(
nestedchatconfig,
trigger=writer,
)
Mulai percakapan
userproxy.initiatechat(
writer,
message="Tulis artikel pendek tentang manfaat menggunakan Python untuk data science."
)
Teachable Agents
Teachable agents dapat mengingat informasi dari percakapan sebelumnya.
from autogen.agentchat.contrib.capabilities.teachability import Teachability
from autogen import ConversableAgent
configlist = autogen.configlistfromjson("OAICONFIGLIST")
llmconfig = {"configlist": configlist}
Membuat agen yang bisa diajar
teachableagent = ConversableAgent(
name="teachableassistant",
llmconfig=llmconfig,
systemmessage="Kamu adalah asisten yang bisa belajar dari percakapan.",
)
Tambahkan kemampuan teachability
teachability = Teachability(
resetdb=False, # Set True untuk reset memori
pathtodbdir="./teachabledb",
verbosity=0,
recallthreshold=1.5,
)
teachability.addtoagent(teachableagent)
User proxy
user = autogen.UserProxyAgent(
name="user",
humaninputmode="ALWAYS",
codeexecutionconfig=False,
)
Percakapan pertama - mengajarkan informasi
user.initiatechat(
teachableagent,
message="Ingat bahwa API key untuk layanan internal kita menggunakan prefix 'INT-' diikuti 12 karakter alfanumerik."
)
Percakapan kedua - agen mengingat informasi
user.initiatechat(
teachableagent,
message="Apa format API key untuk layanan internal kita?"
)
Contoh Praktis: Tim Pengembangan Software
Mari kita bangun tim pengembangan software virtual yang terdiri dari planner, coder, dan tester yang berkolaborasi membangun sebuah fitur.
Definisi Tim
import autogen
configlist = autogen.configlistfromjson("OAICONFIGLIST")
llmconfig = {"configlist": configlist, "temperature": 0}
1. Project Planner
planner = autogen.AssistantAgent(
name="planner",
llmconfig=llmconfig,
systemmessage="""Kamu adalah Senior Project Planner. Tugasmu:
Analisis kebutuhan fitur dari user
Pecah menjadi task-task yang terstruktur
Buat spesifikasi teknis untuk setiap task
Tentukan urutan implementasi
Format output:
## Analisis Kebutuhan
[deskripsi]
## Task Breakdown
- Task 1: [deskripsi]
- Task 2: [deskripsi]
## Spesifikasi Teknis
[detail teknis]
Setelah rencana disetujui, serahkan ke coder untuk implementasi.
Jangan menulis kode apapun."""
)
2. Senior Developer
coder = autogen.AssistantAgent(
name="coder",
llmconfig=llmconfig,
systemmessage="""Kamu adalah Senior Python Developer. Tugasmu:
Implementasikan kode berdasarkan rencana dari planner
Tulis kode yang bersih, terdokumentasi, dan mengikuti best practices
Gunakan type hints dan docstrings
Perbaiki kode berdasarkan feedback dari tester
Selalu tulis kode dalam blok Python yang lengkap dan siap dijalankan.
Sertakan semua import yang diperlukan."""
)
3. QA Tester
tester = autogen.AssistantAgent(
name="tester",
llmconfig=llmconfig,
systemmessage="""Kamu adalah Senior QA Engineer. Tugasmu:
Review kode yang ditulis oleh coder
Tulis unit tests menggunakan pytest
Identifikasi bug, edge cases, dan potensi masalah
Pastikan kode memenuhi spesifikasi dari planner
Format feedback:
## Code Review
[temuan review]
## Unit Tests
[kode test]
## Issues Found
[daftar masalah]
Jika semua test lulus dan tidak ada masalah kritis, balas dengan 'APPROVED - TERMINATE'"""
)
4. User Proxy (eksekutor kode)
executor = autogen.UserProxyAgent(
name="executor",
humaninputmode="NEVER",
maxconsecutiveautoreply=15,
isterminationmsg=lambda x: "TERMINATE" in (x.get("content", "") or ""),
codeexecutionconfig={
"workdir": "devproject",
"usedocker": False,
"timeout": 120,
},
)
Konfigurasi Group Chat
# Definisikan urutan percakapan
def devteamspeakerselection(lastspeaker, groupchat):
messages = groupchat.messages
if lastspeaker is executor:
# Setelah user memberikan tugas, planner yang merencanakan
if len(messages) <= 2:
return planner
# Setelah eksekusi kode, tester yang review
return tester
elif lastspeaker is planner:
# Setelah planning, coder yang implementasi
return coder
elif lastspeaker is coder:
# Setelah coding, executor menjalankan kode
return executor
elif lastspeaker is tester:
# Jika ada masalah, kembali ke coder
lastmsg = messages[-1].get("content", "")
if "APPROVED" in lastmsg:
return executor # Selesai
return coder # Perbaiki
return planner
Buat group chat
devgroupchat = autogen.GroupChat(
agents=[executor, planner, coder, tester],
messages=[],
maxround=25,
speakerselectionmethod=devteamspeakerselection,
)
devmanager = autogen.GroupChatManager(
groupchat=devgroupchat,
llmconfig=llmconfig,
)
Menjalankan Tim
# Berikan tugas ke tim
task = """
Bangun modul Task Manager dengan fitur berikut:
Class TaskManager yang bisa menambah, menghapus, dan menampilkan task
Setiap task memiliki: id, title, description, priority (low/medium/high), status (todo/inprogress/done), createdat
Bisa filter task berdasarkan priority dan status
Bisa mengurutkan task berdasarkan priority atau createdat
Export task ke format JSON
Validasi input (title tidak boleh kosong, priority harus valid, dll)
"""
executor.initiatechat(
devmanager,
message=task,
)
Output yang Diharapkan
Tim akan bekerja secara kolaboratif:
Contoh Hasil Implementasi
Berikut contoh kode yang mungkin dihasilkan oleh tim:
import json
from datetime import datetime
from typing import Optional
from enum import Enum
from dataclasses import dataclass, field, asdict
class Priority(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
class Status(Enum):
TODO = "todo"
INPROGRESS = "inprogress"
DONE = "done"
@dataclass
class Task:
id: int
title: str
description: str
priority: Priority
status: Status = Status.TODO
createdat: datetime = field(defaultfactory=datetime.now)
def todict(self):
return {
"id": self.id,
"title": self.title,
"description": self.description,
"priority": self.priority.value,
"status": self.status.value,
"createdat": self.createdat.isoformat(),
}
class TaskManager:
def init(self):
self.tasks: dict[int, Task] = {}
self.nextid: int = 1
def addtask(
self,
title: str,
description: str = "",
priority: str = "medium"
) -> Task:
if not title or not title.strip():
raise ValueError("Title tidak boleh kosong")
try:
pri = Priority(priority.lower())
except ValueError:
raise ValueError(
f"Priority tidak valid: {priority}. "
f"Gunakan: {[p.value for p in Priority]}"
)
task = Task(
id=self.nextid,
title=title.strip(),
description=description.strip(),
priority=pri,
)
self.tasks[self.nextid] = task
self.nextid += 1
return task
def removetask(self, taskid: int) -> bool:
if taskid not in self.tasks:
raise KeyError(f"Task dengan ID {taskid} tidak ditemukan")
del self.tasks[taskid]
return True
def gettask(self, taskid: int) -> Task:
if taskid not in self.tasks:
raise KeyError(f"Task dengan ID {taskid} tidak ditemukan")
return self.tasks[taskid]
def updatestatus(self, taskid: int, status: str) -> Task:
task = self.gettask(taskid)
try:
task.status = Status(status.lower())
except ValueError:
raise ValueError(
f"Status tidak valid: {status}. "
f"Gunakan: {[s.value for s in Status]}"
)
return task
def listtasks(
self,
priority: Optional[str] = None,
status: Optional[str] = None,
) -> list[Task]:
tasks = list(self.tasks.values())
if priority:
try:
pri = Priority(priority.lower())
tasks = [t for t in tasks if t.priority == pri]
except ValueError:
raise ValueError(f"Priority tidak valid: {priority}")
if status:
try:
st = Status(status.lower())
tasks = [t for t in tasks if t.status == st]
except ValueError:
raise ValueError(f"Status tidak valid: {status}")
return tasks
def sorttasks(
self,
by: str = "createdat",
reverse: bool = False
) -> list[Task]:
tasks = list(self.tasks.values())
priorityorder = {Priority.HIGH: 3, Priority.MEDIUM: 2, Priority.LOW: 1}
if by == "priority":
tasks.sort(key=lambda t: priorityorder[t.priority], reverse=reverse)
elif by == "createdat":
tasks.sort(key=lambda t: t.createdat, reverse=reverse)
else:
raise ValueError(f"Sort by '{by}' tidak didukung. Gunakan: priority, createdat")
return tasks
def exportjson(self, filepath: Optional[str] = None) -> str:
data = [task.todict() for task in self.tasks.values()]
jsonstr = json.dumps(data, indent=2, ensureascii=False)
if filepath:
with open(filepath, "w", encoding="utf-8") as f:
f.write(jsonstr)
return jsonstr
Contoh penggunaan
if name == "main":
tm = TaskManager()
# Tambah tasks
tm.addtask("Setup database", "Konfigurasi PostgreSQL", "high")
tm.addtask("Buat API endpoint", "REST API untuk user management", "medium")
tm.addtask("Tulis dokumentasi", "API documentation", "low")
# Filter dan sort
highpriority = tm.listtasks(priority="high")
sortedtasks = tm.sorttasks(by="priority", reverse=True)
# Export
print(tm.exportjson())
Tips dan Best Practices
1. System Message yang Jelas
Tulis system message yang spesifik dan terstruktur untuk setiap agen. Semakin jelas instruksi, semakin baik hasilnya.
2. Batasi Auto-Reply
Selalu set maxconsecutiveautoreply untuk mencegah loop tak terbatas.
userproxy = autogen.UserProxyAgent(
name="user",
maxconsecutiveautoreply=10, # Batasi 10 iterasi
)
3. Gunakan Docker untuk Code Execution
Untuk lingkungan produksi, selalu gunakan Docker untuk keamanan:
codeexecutionconfig={
"use
docker": "python:3.11-slim",
"timeout": 120,
}
4. Logging untuk Debugging
import autogen
Aktifkan logging
autogen.runtimelogging.start(loggertype="file", config={"filename": "autogen.log"})
Jalankan percakapan
...
Hentikan logging
autogen.runtimelogging.stop()
5. Cache untuk Efisiensi
# Menggunakan cache untuk menghindari panggilan API berulang
with autogen.Cache.disk(cacheseed=42) as cache:
userproxy.initiatechat(
assistant,
message="Tulis kode hello world",
cache=cache,
)
Kesimpulan
AutoGen dari Microsoft menyediakan framework yang powerful untuk membangun sistem multi-agent conversation. Dengan fitur-fitur seperti group chat, code execution, tool use, dan teachable agents, Anda dapat membangun aplikasi AI yang kompleks dan kolaboratif.
Kunci sukses menggunakan AutoGen:
- Definisikan peran agen dengan jelas melalui system message
- Pilih metode pemilihan speaker yang tepat
- Manfaatkan code execution untuk verifikasi otomatis
- Gunakan human-in-the-loop untuk kontrol kualitas
- Implementasikan nested chats untuk alur kerja bertingkat
Dengan memahami konsep-konsep ini, Anda siap membangun sistem multi-agent yang dapat menyelesaikan tugas-tugas kompleks secara kolaboratif, mulai dari pengembangan software hingga analisis data dan automasi bisnis.