Program
Meminta satu model untuk meneliti topik, menulis draf artikel, meninjau, dan memoles versi final dalam satu kali jalan biasanya menghasilkan sesuatu yang biasa-biasa saja di keempatnya. Model tidak memiliki peran yang jelas di momen mana pun, sehingga ia menangani semua pekerjaan sekaligus dan jarang melakukan salah satunya dengan baik. Membagi pekerjaan itu ke agen-agen spesialis cenderung menghasilkan kualitas yang lebih kuat, karena setiap agen dapat fokus menuntaskan bagiannya dengan benar.
Dalam panduan ini, kita akan membangun sebuah agent swarm yang melakukan hal tersebut. Kita akan menggunakan CrewAI untuk mengoordinasikan para agen dan Gemini 3.5 Flash untuk mendukung penalaran dan penulisan mereka. Swarm ini memiliki empat anggota: Researcher untuk mengumpulkan informasi terkini, Writer untuk menghasilkan draf pertama, Reviewer untuk meningkatkan kejelasan dan akurasi, serta Manager untuk mengoordinasikan alur kerja.
Kita juga akan memberikan akses web langsung kepada Researcher melalui Olostep, sehingga ia dapat menarik sumber-sumber terbaru alih-alih hanya mengandalkan pengetahuan internal model. Pada akhirnya, Anda akan memiliki swarm hierarkis yang berfungsi, yang menerima sebuah topik dan mengembalikan artikel siap terbit — serta pemahaman yang jelas kapan pendekatan ini sepadan dengan biayanya dan kapan tidak.
Apa Itu Agent Swarm?
Agent swarm adalah sekelompok agen AI yang bekerja bersama untuk menyelesaikan sebuah tugas. Alih-alih meminta satu model untuk meneliti, menulis, meninjau, dan menyelesaikan semuanya sendiri, agent swarm membagi pekerjaan ke beberapa agen spesialis. Setiap agen memiliki peran yang jelas, dan sistem mengoordinasikannya untuk menghasilkan hasil akhir yang lebih kuat.
Keunggulannya adalah spesialisasi. Agen yang fokus riset dapat berkonsentrasi mencari dan memverifikasi sumber, agen yang fokus menulis dapat menitikberatkan pada struktur dan kejelasan, dan seorang reviewer dapat memeriksa draf terhadap riset asli tanpa terganggu oleh tulisan yang baru saja dihasilkannya.
Agen koordinator merangkai langkah-langkah tersebut dan memutuskan apa yang terjadi berikutnya. Dalam swarm yang kita bangun, peran-peran itu secara langsung dipetakan ke Researcher, Writer, Reviewer, dan Manager.

Namun ini bukan tanpa biaya. Lebih banyak agen berarti lebih banyak panggilan model, lebih banyak waktu, dan lebih banyak titik potensial untuk alur kerja gagal; sebuah pertukaran yang akan kita bahas di akhir, setelah Anda melihat biaya aktual untuk menjalankannya.
Apa Itu CrewAI?
CrewAI adalah kerangka kerja open-source untuk membangun sistem multi-agen. Ini memberi cara yang rapi untuk mendefinisikan agen, menetapkan tugas, dan memilih bagaimana mereka berkoordinasi, sehingga Anda bisa fokus pada peran dan alur kerja alih-alih seluk-beluk koneksinya.
Tiga konsep melakukan sebagian besar pekerjaan.
- Agents adalah pekerja individual, masing-masing didefinisikan oleh peran, tujuan, dan latar belakang yang membentuk perilakunya.
- Tasks menggambarkan pekerjaan yang harus dilakukan dan keluaran yang diharapkan dari masing-masingnya.
- Sebuah crew menyatukan agen dan tugas, lalu menjalankannya di bawah proses yang dipilih
Proses ini bisa sequential, di mana tugas berjalan dalam urutan tetap, atau hierarchical, di mana agen manajer mendelegasikan pekerjaan ke yang lain dan memvalidasi keluarannya. Di sini kita akan menggunakan proses hierarchical, dengan Manager menangani pendelegasian.
CrewAI juga menangani akses model melalui LiteLLM, pustaka open-source yang menyediakan satu antarmuka terpadu untuk banyak penyedia. Inilah yang memungkinkan kita mendefinisikan satu model Gemini 3.5 Flash dan menggunakannya kembali di keempat agen, yang akan kita siapkan pada langkah-langkah di bawah.
Membangun Agent Swarm dengan CrewAI dan Gemini 3.5 Flash
Mari mulai dengan penyiapan.
1. Prasyarat
Sebelum memulai, pastikan Anda memiliki:
- Python 3.11 atau yang lebih baru terpasang
- Jupyter Notebook atau JupyterLab terpasang
- Pemahaman dasar tentang Python dan notebook
- Akun Google AI Studio
- Penagihan diaktifkan, atau kredit telah ditambahkan ke akun Google Anda untuk penggunaan Gemini
- Akun Olostep gratis
2. Instal dependensi
Luncurkan Jupyter Notebook atau JupyterLab dan buka notebook dengan kernel Python terbaru yang tersedia di lingkungan Anda. Lalu jalankan sel berikut untuk memasang paket yang diperlukan.
%pip install --quiet -U \
crewai \
crewai-tools \
google-genai \
litellm \
olostep \
nest-asyncio
Setelah instalasi selesai, jalankan sel berikutnya untuk memeriksa versi paket yang terpasang. Ini membantu memastikan semuanya terpasang dengan benar.
import importlib.metadata as md
for pkg in [
"crewai",
"crewai-tools",
"google-genai",
"litellm",
"olostep",
"nest-asyncio",
]:
print(f"{pkg:>16} {md.version(pkg)}")
Anda akan melihat keluaran serupa ini:
crewai 1.14.6
crewai-tools 1.14.6
google-genai 2.8.0
litellm 1.87.1
olostep 1.1.0
nest-asyncio 1.6.0
3. Atur variabel lingkungan
Anda akan memerlukan dua kunci API untuk proyek ini.
Pertama, buat kunci API Gemini dari Google AI Studio. Buka Google AI Studio, masuk ke bagian API key, dan buat kunci baru untuk proyek Anda. Gemini menawarkan tingkat gratis, tetapi dengan batas penggunaan dan laju. Untuk memeriksa dan menjalankan Gemini dengan lebih andal, hubungkan akun penagihan Google Anda atau tambahkan kredit ke akun Google Anda sehingga penggunaan dapat ditagihkan ketika melampaui batas tingkat gratis.
Selanjutnya, buat kunci API Olostep. Daftar ke Olostep, buka dasbor Olostep, dan buat kunci API dari halaman API keys. Kita akan menggunakan kunci ini untuk memberikan akses web langsung kepada agen Researcher untuk pencarian dan scraping halaman.
Setelah kedua kunci siap, simpan sebagai variabel lingkungan. Gemini akan menjalankan agen-agen CrewAI, sementara Olostep memungkinkan agen Researcher mengumpulkan informasi terkini dari web.
Setelah membuat kedua kunci, simpan sebagai variabel lingkungan sebelum menjalankan notebook.
PowerShell:
$env:GEMINI_API_KEY="your-gemini-key"
$env:OLOSTEP_API_KEY="your-olostep-key"
macOS/Linux:
export GEMINI_API_KEY="your-gemini-key"
export OLOSTEP_API_KEY="your-olostep-key"
Sekarang jalankan sel berikut untuk memeriksa bahwa kunci API Gemini dimuat dengan benar.
import os
api_key = os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY")
if not api_key:
raise RuntimeError(
"Set GEMINI_API_KEY or GOOGLE_API_KEY in your environment, "
"then restart the notebook kernel."
)
print(f"Gemini API key loaded")
Anda akan melihat:
Gemini API key loaded
4. Konfigurasikan Gemini 3.5 Flash melalui LiteLLM
Dalam proyek ini, kita akan menggunakan Gemini 3.5 Flash sebagai LLM bersama untuk semua agen CrewAI. Gemini 3.5 Flash dirancang untuk beban kerja yang cepat, agentic, dan berfokus pada coding. Ini berguna untuk proyek ini karena agen-agen kita perlu bernalar lintas beberapa langkah, mengikuti instruksi, bekerja dengan alat, dan menghasilkan keluaran terstruktur.
Gemini 3.5 Flash juga mendukung jendela konteks besar, keluaran panjang, thinking, dan penggunaan alat, menjadikannya pilihan kuat untuk alur kerja agen. Karena agent swarm mungkin memanggil model beberapa kali di sepanjang agen Researcher, Writer, Reviewer, dan Manager, menggunakan model Flash membantu menjaga alur kerja tetap responsif sekaligus memberikan kualitas penalaran dan penulisan yang kuat.
Jika Anda ingin membandingkan model ini dengan LLM mutakhir lainnya, saya sarankan membaca panduan kami tentang Gemini 3.5 Flash vs GPT-5.5 dan Gemini 3.5 Flash vs Claude Opus 4.8.
Kita akan mengakses Gemini melalui LiteLLM. LiteLLM adalah pustaka open-source yang menyediakan satu antarmuka terpadu untuk memanggil banyak penyedia LLM, termasuk Gemini, OpenAI, Anthropic, Bedrock, Vertex AI, dan lainnya. Dalam penyiapan ini, CrewAI menggunakan LiteLLM di belakang layar sehingga kita dapat meneruskan nama model Gemini dalam format sederhana provider/model.
Sekarang kita akan membuat LLM CrewAI bersama dan menggunakannya kembali untuk semua agen. Ini membuat penyiapan sederhana karena Researcher, Writer, Reviewer, dan Manager semuanya menggunakan model Gemini yang sama.
from crewai import LLM
GEMINI_MODEL = "gemini/gemini-3.5-flash"
gemini_llm = LLM(
model=GEMINI_MODEL,
api_key=os.getenv("GEMINI_API_KEY") or os.getenv("GOOGLE_API_KEY"),
temperature=1.0,
)
print(f"LLM ready: {gemini_llm.model}")
print("Provider API: Google Gemini (via LiteLLM)")
Anda akan melihat keluaran serupa ini:
LLM ready: gemini-3.5-flash
Provider API: Google Gemini (via LiteLLM)
Ini menegaskan bahwa CrewAI kini dapat mengakses Gemini melalui LiteLLM. Pada langkah berikutnya, kita akan meneruskan objek gemini_llm bersama ini ke setiap agen.
5. Tambahkan akses web langsung
Agen Researcher membutuhkan akses ke informasi terkini. Untuk itu, kita akan membuat alat pencarian Olostep kustom dan memberikannya ke agen Researcher nanti.
Alat ini dapat bekerja dalam dua mode. Ia bisa mengembalikan ringkasan pencarian saja, yang lebih cepat, atau melakukan scraping halaman hasil dan mengembalikan konten halaman dalam markdown. Kita juga menambahkan anggaran pencarian kecil agar agen tidak terus-menerus memanggil alat web terlalu banyak.
from pydantic import Field, PrivateAttr
from crewai.tools import BaseTool
try:
from olostep import Olostep, Olostep_BaseError
except ImportError:
raise ImportError(
"The 'olostep' package is not installed. Run %pip install -U olostep."
)
Pertama, muat kunci API Olostep dari lingkungan.
olostep_api_key = os.getenv("OLOSTEP_API_KEY")
if not olostep_api_key or olostep_api_key == "your-olostep-api-key-here":
print(
"The Olostep tool will fail at call time unless OLOSTEP_API_KEY "
"is set in the environment."
)
else:
print("Olostep API key loaded.")
_olostep_client = Olostep(api_key=olostep_api_key) if olostep_api_key else None
Sekarang buat alat CrewAI kustom.
class OlostepSearchTool(BaseTool):
"""Search the web with a strict research-call budget."""
name: str = "olostep_web_search"
description: str = (
"Search the live web. Set scrape=false for fast discovery and "
"scrape=true for full-page evidence. You have at most 3 discovery "
"searches without scraping and 6 external search calls total. After "
"3 discovery searches, use scrape=true on the strongest query or "
"domain. Each call returns at most 3 results. Inputs: query, scrape, "
"limit, and optional include_domains."
)
default_limit: int = Field(default=3, ge=1, le=3)
max_chars_per_page: int = Field(default=4000, ge=500, le=12000)
_total_calls: int = PrivateAttr(default=0)
_discovery_calls: int = PrivateAttr(default=0)
_call_history: list[dict] = PrivateAttr(default_factory=list)
def _run(
self,
query: str,
scrape: bool = False,
limit: int | None = None,
include_domains: list[str] | None = None,
) -> str:
if _olostep_client is None:
return (
"OLOSTEP_API_KEY is not set. Set it in the environment "
"and restart the kernel."
)
if self._total_calls >= 6:
return (
"Research search budget exhausted: 6 external calls have "
"already been used. Stop searching and complete the task "
"with the collected sources."
)
if not scrape and self._discovery_calls >= 3:
return (
"Discovery-search limit reached. Do not run another "
"scrape=False search. Use scrape=True on the strongest query "
"or selected domains, or finish with the sources already found."
)
clean_query = query.strip()
if not clean_query:
return "Search query cannot be empty."
result_limit = max(1, min(limit or self.default_limit, 3))
kwargs = {"query": clean_query, "limit": result_limit}
if scrape:
kwargs["scrape_options"] = {
"formats": ["markdown"],
"timeout": 25,
}
if include_domains:
kwargs["include_domains"] = include_domains
self._total_calls += 1
if not scrape:
self._discovery_calls += 1
call_record = {
"number": self._total_calls,
"query": clean_query,
"scrape": scrape,
"limit": result_limit,
"domains": include_domains or [],
"status": "started",
"results": 0,
}
self._call_history.append(call_record)
try:
search = _olostep_client.searches.create(**kwargs)
except Olostep_BaseError as error:
call_record["status"] = "error"
call_record["error"] = f"{type(error).__name__}: {error}"
return (
f"Olostep search error: {type(error).__name__}: {error}\n"
f"Budget used: {self._total_calls}/6 total calls; "
f"{self._discovery_calls}/3 discovery calls."
)
if not search.links:
call_record["status"] = "no_results"
return (
f"No results found for query: {clean_query!r}\n"
f"Budget used: {self._total_calls}/6 total calls; "
f"{self._discovery_calls}/3 discovery calls."
)
call_record["status"] = "success"
call_record["results"] = len(search.links)
chunks = [
f"## Web results for: {clean_query!r}",
f"Page scraping: {'enabled' if scrape else 'disabled'}",
(
f"Budget used: {self._total_calls}/6 total calls; "
f"{self._discovery_calls}/3 discovery calls."
),
]
for index, link in enumerate(search.links, 1):
url = link.get("url", "")
title = link.get("title") or url or "Untitled result"
description = link.get("description") or "No description provided."
chunks.append(
f"### {index}. {title}\n"
f"URL: {url}\n"
f"Summary: {description}"
)
markdown = link.get("markdown_content")
if scrape and markdown:
body = markdown.strip()
if len(body) > self.max_chars_per_page:
body = body[: self.max_chars_per_page] + "\n...[truncated]"
chunks.append(f"Page content:\n{body}")
return "\n\n".join(chunks)
Terakhir, buat sebuah instance alatnya.
olostep_search_tool = OlostepSearchTool()
print(f"Tool ready: {olostep_search_tool.name}")
Anda akan melihat keluaran serupa ini:
Olostep API key loaded.
Tool ready: olostep_web_search
Ini menegaskan bahwa alat pencarian web Olostep siap. Nanti, kita akan menautkan alat ini ke agen Researcher agar dapat mengumpulkan informasi terkini dari web.
6. Buat para agen
Sekarang kita akan membuat agen-agen untuk swarm kita. Kita akan mendefinisikan tiga agen pekerja dan satu agen manajer. Agen pekerja melakukan tugas utama, sementara manajer mengoordinasikan alur kerja.
Agen Researcher akan menggunakan alat Olostep untuk menemukan informasi terkini. Agen Writer akan mengubah riset menjadi draf. Agen Reviewer akan menyempurnakan draf. Agen Manager akan memutuskan bagaimana mendelegasikan pekerjaan dalam crew hierarkis.
Buat agen pekerja
Mari mulai dengan tiga agen pekerja.
from crewai import Agent
researcher = Agent(
role="Senior Research Analyst",
goal=(
"Find accurate, current, and well-sourced information about {topic}. "
"Produce concrete, verifiable points for the writer."
),
backstory=(
"You are a meticulous research analyst. You decide whether each web "
"search needs page scraping. Use scrape=False when titles, URLs, and "
"summaries are enough. Use scrape=True when you need full-page evidence "
"to verify a claim or understand a source in detail. Cite source URLs."
),
llm=gemini_llm,
tools=[olostep_search_tool],
verbose=True,
allow_delegation=False,
)
Selanjutnya, buat agen Writer.
writer = Agent(
role="Blog Post Writer",
goal=(
"Turn the research into a complete, publication-ready educational "
"article on {topic}. Include a strong title, an unlabeled italic "
"summary, TL;DR, detailed body sections, conclusion, and FAQs. Add a "
"table only when it makes a comparison or decision easier to understand."
),
backstory=(
"You are a seasoned technology educator and writer. You create "
"practical, approachable articles similar in structure to high-quality "
"DataCamp content, without copying its wording or branding. You use "
"clear headings, short paragraphs, concrete examples, and sourced facts."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
)
Sekarang buat agen Reviewer.
reviewer = Agent(
role="Senior Editor",
goal=(
"Review the draft for factual accuracy, clarity, structure, and "
"completeness. Ensure it follows the required article order and return "
"a polished, publication-ready version."
),
backstory=(
"You are a detail-oriented senior editor for an educational technology "
"publication. You verify claims, improve flow, remove repetition, and "
"ensure the title is followed by an unlabeled italic summary and TL;DR. "
"You keep a table only when it adds real value, remove any Key Takeaways "
"section, and ensure Conclusion appears immediately before FAQs."
),
llm=gemini_llm,
verbose=True,
allow_delegation=False,
)
Buat agen manajer
Terakhir, buat agen Manager.
manager = Agent(
role="Content Coordinator",
goal=(
"Coordinate research, writing, and review for {topic}. Delegate each "
"task to the correct specialist and ensure the reviewed article is the "
"final result."
),
backstory=(
"You are an experienced editorial lead. You keep the workflow simple: "
"research first, writing second, and editorial review last."
),
llm=gemini_llm,
verbose=True,
allow_delegation=True,
)
Manajer dikonfigurasi secara terpisah saat kita membangun crew hierarkis. Itulah mengapa ia belum ditambahkan ke daftar agen pekerja.
7. Definisikan Tugas
Sekarang kita akan mendefinisikan tugas untuk agent swarm. Tugas-tugas ini tidak langsung ditetapkan ke agen pekerja. Sebaliknya, agen Manager akan memutuskan pekerja mana yang harus menangani setiap tugas.
Dalam alur kerja ini, tugas pertama adalah riset, tugas kedua adalah penulisan, dan tugas ketiga adalah tinjauan. Setiap tugas juga menyertakan keluaran yang diharapkan, sehingga para agen tahu persis apa yang harus mereka hasilkan.
from crewai import Task
research_task = Task(
description=(
"Delegate to the Senior Research Analyst. Research '{topic}' using at "
"most 6 web-tool calls. Use no more than 3 calls with scrape=False, "
"then use scrape=True only when detailed evidence is needed. Collect "
"5-7 useful findings, source URLs, and common reader questions."
),
expected_output=(
"Clear markdown research notes with 5-7 sourced findings and 3-5 "
"potential FAQ questions."
),
)
Selanjutnya, buat tugas penulisan. Tugas ini menggunakan tugas riset sebagai konteks, sehingga Writer dapat membangun artikel dari riset yang terkumpul.
write_task = Task(
description=(
"Delegate to the Blog Post Writer. Write one complete educational "
"markdown article on '{topic}', approximately 1,000-1,500 words. Start "
"with one H1 title and an unlabeled italic summary. Then include TL;DR, "
"an introduction, useful body sections, an optional table only when it "
"improves understanding, a Conclusion, and FAQs. Use source links."
),
expected_output=(
"One continuous publication-ready markdown article with title, italic "
"summary, TL;DR, body, Conclusion, and 3-5 FAQs."
),
context=[research_task],
)
Sekarang, buat tugas tinjauan. Tugas ini menggunakan tugas riset dan penulisan sebagai konteks, sehingga Reviewer dapat memeriksa artikel terhadap riset asli.
review_task = Task(
description=(
"Delegate to the Senior Editor. Review the article for accuracy, "
"clarity, structure, and source support. Return only the corrected full "
"article. Keep the same continuous article format and ensure FAQs are "
"the final section."
),
expected_output=(
"Only the final reviewed markdown article, beginning with its H1 title "
"and ending with the final FAQ answer."
),
context=[research_task, write_task],
)
Terakhir, tambahkan ketiga tugas ke dalam sebuah daftar.
tasks = [research_task, write_task, review_task]
print(f"Defined {len(tasks)} manager-delegated tasks.")
Anda akan melihat:
Defined 3 manager-delegated tasks.
8. Bangun alur kerja
Sekarang kita akan menyambungkan agen dan tugas menjadi satu alur kerja CrewAI. Kita akan menggunakan proses hierarkis di mana agen Manager mengoordinasikan agen pekerja.
Dalam penyiapan ini, Researcher, Writer, dan Reviewer ditambahkan sebagai agen pekerja. Manager diteruskan secara terpisah melalui manager_agent, karena ia bertanggung jawab atas pendelegasian dan koordinasi.
from crewai import Crew, Process
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=tasks,
manager_agent=manager,
process=Process.hierarchical,
verbose=True,
memory=False,
)
Sekarang cetak detail crew untuk menegaskan bahwa alur kerja telah dirakit dengan benar.
print("Hierarchical crew assembled.")
print(f" Workers : {[a.role for a in crew.agents]}")
print(f" Manager : {crew.manager_agent.role}")
print(f" Tasks : {len(crew.tasks)}")
print(f" Process : {crew.process}")
Anda akan melihat keluaran serupa ini:
Hierarchical crew assembled.
Workers : ['Senior Research Analyst', 'Blog Post Writer', 'Senior Editor']
Manager : Content Coordinator
Tasks : 3
Process : Process.hierarchical
Ini menegaskan bahwa agent swarm hierarkis siap. Pada langkah berikutnya, kita akan menjalankan crew pada sebuah topik dan menghasilkan respons final.
9. Jalankan agent swarm
Sekarang kita dapat menjalankan agent swarm. Kita akan memberikan sebuah topik dan memulai alur kerja dengan kickoff_async().
Jupyter sudah menjalankan event loop di latar belakang. Karena itu, kita terlebih dahulu menerapkan nest_asyncio, sehingga alur kerja asinkron CrewAI dapat berjalan di dalam notebook.
try:
import nest_asyncio
nest_asyncio.apply()
print("nest_asyncio applied: CrewAI can now run inside this kernel.")
except ModuleNotFoundError:
print("nest_asyncio not installed. Run: pip install nest-asyncio")
Anda akan melihat:
nest_asyncio applied: CrewAI can now run inside this kernel.
Selanjutnya, tentukan topik dan buat fungsi pembantu untuk menjalankan crew.
from datetime import datetime
topic = "Learning Adaptive Thresholds for LLM Tool Use: When to Rely on Memory and When to Call a Tool"
async def run_crew(topic: str):
"""Run the CrewAI crew asynchronously."""
print(f"Starting crew at {datetime.now().isoformat(timespec='seconds')}")
print(f"Topic: {topic!r}\n")
result = await crew.kickoff_async(inputs={"topic": topic})
print(f"\nFinished at {datetime.now().isoformat(timespec='seconds')}")
print(f"Result type: {type(result).__name__}")
return result
result = await run_crew(topic)
Saat alur kerja dimulai, CrewAI pertama-tama memberikan tugas kepada agen Manager. Manager kemudian mendelegasikan pekerjaan riset kepada Senior Research Analyst. Researcher menggunakan alat olostep_web_search untuk mencari informasi di web tentang adaptive thresholds, penggunaan alat LLM, memori, dan keputusan pemanggilan alat.

Dalam log, Researcher menggunakan panggilan hanya pencarian dan panggilan scraping. Anggaran pencarian digunakan sepenuhnya, mencapai 6 dari 6 total panggilan web dan 3 dari 3 panggilan discovery. Satu permintaan hanya pencarian tambahan diblokir karena batas discovery-search telah tercapai. Ini menunjukkan bahwa aturan anggaran di dalam alat Olostep kustom kita bekerja dengan benar.

Setelah fase riset, Manager melanjutkan alur kerja dengan mendelegasikan langkah penulisan dan tinjauan. Para agen menghasilkan catatan riset, menyusun draf artikel, lalu memoles respons final. Proses berjalan sukses dan mengembalikan objek CrewOutput.
Anda akan melihat keluaran serupa ini:
Starting crew at 2026-06-05T13:54:07
Topic: 'Learning Adaptive Thresholds for LLM Tool Use: When to Rely on Memory and When to Call a Tool'
Crew Execution Started
Task Started
Agent: Content Coordinator
Agent: Senior Research Analyst
Tool: olostep_web_search
Budget used: 6/6 total calls; 3/3 discovery calls
Finished at 2026-06-05T13:59:29
Result type: CrewOutput
Ini berarti seluruh swarm berjalan dengan sukses. Manager mengoordinasikan alur kerja, Researcher mengumpulkan informasi terkini, Writer membuat draf, dan Reviewer menyempurnakan keluaran akhir.
10. Lihat hasilnya
Setelah swarm selesai berjalan, kita dapat menampilkan artikel final yang dihasilkan oleh crew. Nilai result.raw berisi respons akhir dari alur kerja.
from IPython.display import Markdown, display
raw = result.raw
if "Blog Post" in raw:
raw = raw.split("Blog Post", 1)[1].strip()
display(Markdown(raw))
Ini akan merender keluaran akhir sebagai markdown terformat di dalam notebook.
Dalam banyak kasus, blog yang dihasilkan sudah terstruktur dengan baik, dengan beberapa heading, bagian-bagian yang jelas, diagram atau penjelasan visual bila sesuai, dan kesimpulan yang kuat.
Kombinasi riset, penulisan, dan tinjauan editorial membantu menghasilkan konten yang siap terbit. Setelah meninjau keluarannya, saya pribadi akan memberi lampu hijau untuk publikasi.

Selanjutnya, kita dapat mencetak jejak eksekusi. Ini membantu kita memahami bagaimana swarm bekerja, agen mana yang berpartisipasi, berapa banyak panggilan web yang digunakan, dan bagaimana setiap tugas diproses.
from collections import Counter
def role_name(value):
"""Return a readable role/name for CrewAI agent values."""
if value is None:
return "Not reported"
if isinstance(value, str):
return value
return getattr(value, "role", None) or getattr(value, "name", None) or str(value)
print("=" * 70)
print("SWARM EXECUTION TRACE")
print("=" * 70)
# Hierarchical crew structure
print("\nCOORDINATION")
print(f"Process : {crew.process}")
print(f"Manager : {role_name(crew.manager_agent)}")
print(f"Workers : {', '.join(role_name(agent) for agent in crew.agents)}")
print(
"Flow : Manager receives each task, delegates specialist work, "
"validates the response, and passes approved context to the next task."
)
Now print the web-tool usage recorded by the custom Olostep tool.
history = list(getattr(olostep_search_tool, "_call_history", []))
discovery_calls = sum(not item["scrape"] for item in history)
scrape_calls = sum(item["scrape"] for item in history)
successful_calls = sum(item["status"] == "success" for item in history)
print("\nWEB TOOL USAGE")
print(f"Total external calls : {len(history)}/6")
print(f"Without scraping : {discovery_calls}/3")
print(f"With scraping : {scrape_calls}")
print(f"Successful calls : {successful_calls}")
if history:
for item in history:
mode = "scrape" if item["scrape"] else "search only"
domains = ", ".join(item["domains"]) if item["domains"] else "all domains"
print(
f" {item['number']}. {mode}; status={item['status']}; "
f"results={item['results']}; scope={domains}"
)
print(f" Query: {item['query']}")
else:
print(" No Olostep calls were recorded.")
Finally, print the task-by-task trace.
print("\nTASK-BY-TASK TRACE")
agent_activity = Counter()
for index, task_out in enumerate(result.tasks_output, start=1):
task = crew.tasks[index - 1] if index <= len(crew.tasks) else None
reported_agent = role_name(getattr(task_out, "agent", None))
processed_by = sorted(getattr(task, "processed_by_agents", set()) or [])
participants = processed_by or [reported_agent]
for participant in participants:
agent_activity[role_name(participant)] += 1
delegations = getattr(task, "delegations", 0) if task else 0
used_tools = getattr(task, "used_tools", 0) if task else 0
tool_errors = getattr(task, "tools_errors", 0) if task else 0
start_time = getattr(task, "start_time", None) if task else None
end_time = getattr(task, "end_time", None) if task else None
duration = end_time - start_time if start_time and end_time else None
print(f"\n--- Task {index} ---")
print(f"Reported owner : {reported_agent}")
print(f"Processed by : {', '.join(map(role_name, participants))}")
print(f"Delegations : {delegations}")
print(f"Tool uses : {used_tools}")
print(f"Tool errors : {tool_errors}")
if duration is not None:
print(f"Duration : {duration}")
preview = getattr(task_out, "raw", "").strip().replace("\n", " ")
print(f"Output preview : {preview[:300]}{'...' if len(preview) > 300 else ''}")
print("\nAGENT ACTIVITY")
for agent, count in agent_activity.most_common():
print(f"{agent}: participated in {count} task(s)")
if not agent_activity:
print("CrewAI did not expose per-agent processing metadata for this run.")
Anda akan melihat keluaran serupa ini:

Jejak ini menunjukkan bahwa swarm hierarkis bekerja seperti yang diharapkan. Manager mengoordinasikan ketiga tugas, Researcher menangani langkah riset, Writer membuat draf artikel, dan Reviewer menyempurnakan keluaran akhir.
Namun, ini juga menunjukkan keterbatasan penting: alur kerja multi-agen dapat menjadi mahal.
Dalam proses ini, alur kerja menggunakan 6 panggilan web eksternal dan beberapa panggilan LLM di seluruh Manager, Researcher, Writer, dan Reviewer. Satu kali jalan bisa berbiaya hingga sekitar $0,28, dan membuat panduan ini menelan biaya sekitar $2,78 selama pengujian. Itu tinggi untuk proyek tutorial sederhana.

Pemikiran Akhir
Agent swarm dan alur kerja multi-agen terlihat menjanjikan di atas kertas. Gagasan memiliki Researcher, Writer, Reviewer, dan Manager yang bekerja bersama terasa kuat, dan dalam panduan ini, keluaran akhirnya memang cukup baik untuk dipublikasikan dengan sedikit penyuntingan.
Namun dalam praktik, penyiapan ini dapat lebih mahal, memakan waktu lebih lama, dan menciptakan lebih banyak titik kegagalan. Dalam kasus saya, satu kali jalan berbiaya sekitar $0,28, dan membuat panduan ini berbiaya sekitar $2,78. Itu banyak untuk proyek tutorial sederhana.
Untuk aplikasi nyata, saya tidak selalu akan menggunakan swarm multi-agen penuh. Saya lebih memilih penyiapan yang lebih programatis di mana tugas sederhana ditangani oleh kode atau aturan, dan hanya tugas kompleks yang diserahkan ke agen. Kita juga dapat menurunkan biaya dengan membatasi panggilan alat, menggunakan lebih sedikit agen, memendekkan prompt, dan menggunakan alur kerja linear alih-alih hierarkis.
Tentu, setelah kita mengoptimalkan terlalu jauh, itu mungkin tidak lagi menjadi agent swarm sejati. Ia menjadi lebih seperti alur kerja AI berbasis aturan. Karena itu tujuannya adalah keseimbangan: gunakan agent swarm ketika benar-benar menambah nilai, tetapi tetap sederhana ketika tidak.

Sebagai data scientist tersertifikasi, saya bersemangat memanfaatkan teknologi mutakhir untuk menciptakan aplikasi machine learning yang inovatif. Dengan latar belakang kuat di pengenalan ucapan, analisis dan pelaporan data, MLOps, conversational AI, dan NLP, saya mengasah keterampilan dalam mengembangkan sistem cerdas yang berdampak nyata. Selain keahlian teknis, saya juga komunikator andal yang mampu menyederhanakan konsep kompleks menjadi bahasa yang jelas dan ringkas. Karena itu, saya menjadi blogger yang dicari di bidang data science, membagikan wawasan dan pengalaman kepada komunitas profesional data yang terus berkembang. Saat ini, saya berfokus pada pembuatan dan penyuntingan konten, bekerja dengan large language model untuk mengembangkan konten yang kuat dan menarik agar membantu bisnis dan individu memaksimalkan data mereka.