Ini adalah bagian 4 dari seri artikel teknis tunaFlow. Di bagian 3, kami membahas struktur Branch, dan Roundtable (RT) adalah mode perluasan dari Branch. Ketika branches.mode = "roundtable", beberapa agen berdiskusi tentang satu topik.
Mengapa membuat agen berdiskusi satu sama lain
Ketika menyuruh agen melakukan review kode, sebagian besar akan berkata "bagus". Jika Anda mempercayakan desain kepada satu agen, secara struktural sulit baginya untuk mengkritik arah yang dia usulkan sendiri.
Alasan code review bekerja dalam tim manusia adalah karena reviewer adalah orang yang berbeda dari penulis. Perspektif berbeda, hal yang terlewatkan juga berbeda. Kami dapat menerapkan struktur yang sama pada agen — ketika beberapa agen dengan mesin yang berbeda, peran yang berbeda, dan prompt yang berbeda melihat topik yang sama, agen lain akan menangkap apa yang dilewatkan satu agen.
RT adalah implementasi dari ide ini.
RT = Mode Perluasan Branch
RT bukan sistem terpisah, melainkan mode dari Branch.
// tabel branches
pub struct Branch {
pub mode: String, // "chat" atau "roundtable"
// ... sisanya sama dengan Branch biasa
}
Ketika membuat RT, Branch dengan mode = "roundtable" dibuat, dan pesan peserta menumpuk dalam shadow conversation. Di sidebar, ditampilkan di bagian Roundtables, dibuka di drawer, dan adopt berfungsi sama. Kami menggunakan infrastruktur Branch dari bagian 3 apa adanya.
Perbedaannya adalah pesan tidak dikirim oleh pengguna tetapi dikirim oleh peserta secara berurutan (atau bersamaan).
Dua mode diskusi
Sequential — Diskusi Berurutan
Peserta berbicara satu per satu secara berurutan. Peserta berikutnya dapat melihat apa yang dikatakan peserta sebelumnya.
Ronde 1:
Architect (claude) → Proposal desain: "Mari pisahkan menjadi 3 modul"
Reviewer (codex) → Melihat respons Architect: "Batas modul samar-samar"
Verifier (gemini) → Melihat keduanya: "Setuju dengan opini Reviewer, modul 2 masalah"
// sequential.rs — loop inti
for p in participants {
let prompt = if p.blind {
// peserta blind: tidak melihat respons peserta lain
build_round_prompt_with_identity(topic, &[], &[], Some(&identity))
} else {
// termasuk respons peserta sebelumnya
build_round_prompt_with_identity(topic, transcript, &round_responses, Some(&identity))
};
let result = stream_participant(p, prompt, ...).await;
round_responses.push((p.name.clone(), result.content.clone()));
}
Keuntungan mode berurutan adalah percakapan terakumulasi secara alami. Peserta berikutnya dapat membantah atau melengkapi poin yang dibuat sebelumnya.
Deliberative — Diskusi Paralel
Peserta berbicara secara bersamaan. Mereka tidak dapat melihat respons satu sama lain.
Ronde 1:
Architect (claude) → (independen) "Pisahkan 3 modul"
Reviewer (codex) → (independen) "Perlu abstraksi antarmuka"
Verifier (gemini) → (independen) "Cakupan tes tidak cukup"
// deliberative.rs — eksekusi paralel dengan tokio::spawn
for p in participants {
let prompt = build_round_prompt_with_identity(topic, transcript, &[], Some(&identity));
// ^^^ tidak ada respons ronde saat ini
tokio::spawn(async move {
let result = stream_participant(p, prompt, ...).await;
tx.send((msg_id, result)).await;
});
}
// kumpulkan hasil sesuai urutan penyelesaian
while let Some((id, result)) = rx.recv().await { ... }
Keuntungan mode paralel adalah perspektif independen. Karena tidak dipengaruhi oleh peserta sebelumnya, perspektif yang benar-benar berbeda muncul. Kerugiannya adalah poin dapat tersebar.
Mode mana yang digunakan kapan
Situasi | Mode yang Direkomendasikan | Alasan |
|---|
Review kode | Sequential | Reviewer harus melihat dan mengevaluasi hasil Developer |
Brainstorming desain | Deliberative | Ide independen diperlukan |
Audit keamanan | Deliberative + blind | Evaluasi independen tanpa prasangka |
Mencapai konsensus | Sequential 2 ronde | Ronde 1: opini independen, Ronde 2: reaksi saling |
Model Eksekusi Peserta
Setiap peserta dijalankan sebagai subproses independen. Bukan berbagi sesi PTY, melainkan panggilan mode -p terpisah untuk setiap peserta.
Eksekusi RT:
Participant A (claude) → claude -p "..." → subprocess 1
Participant B (codex) → codex exec "..." → subprocess 2
Participant C (gemini) → gemini -p "..." → subprocess 3
Alasan desain ini: peserta RT dapat berupa mesin yang berbeda. Nilai inti RT adalah mencampur Claude, Codex, Gemini untuk diskusi. Sesi PTY adalah satu per mesin, jadi berbagi secara struktural tidak mungkin.
Handler eksekusi per mesin:
Mesin | Cara Eksekusi | Streaming |
|---|
Claude | claude::stream_run()
| chunk real-time |
Codex | codex::stream_run()
| chunk real-time |
Gemini | gemini::stream_run()
| chunk real-time |
Ollama | openai_compat::stream_run()
| async native |
OpenCode | opencode::run()
| non-streaming |
Selama eksekusi, event roundtable:chunk di-stream ke depan, dan respons setiap peserta ditampilkan real-time di drawer.
Manajemen Konteks: Strategi Konteks Minimal
Mengirim seluruh ContextPack (~5-7k token) kepada peserta RT adalah pemborosan token. Jika 3 peserta, 3 kali lipat, jika 2 ronde, 6 kali lipat. Jadi RT menggunakan strategi konteks minimal.
RtContextCache — Hanya Tier 0+1
// context.rs
pub struct RtContextCache {
pub context: Option, // ~100-200 token
}
Dari 12 bagian ContextPack, kami hanya menyertakan path proyek + ringkasan Plan aktif. Skills, retrieval, compressed memory, cross-session semuanya dikecualikan. Cukup memberi tahu peserta RT "proyek apa yang sedang dikerjakan dan tugas apa sekarang".
Kompres ronde sebelumnya dengan pencarian vektor
Di ronde 2 atau lebih, mengirim seluruh transcript ronde sebelumnya menyebabkan token meledak. Jika 3 peserta dengan respons masing-masing 4.000 karakter, itu 12.000 karakter (~3.000 token).
RtVectorIndex menyematkan respons ronde sebelumnya dan hanya mengekstrak 5 chunk teratas yang relevan dengan topik saat ini.
// context.rs
pub fn search(&self, topic: &str, limit: usize) -> Vec<(String, String)> {
// pencarian berbasis kesamaan kosinus, hanya ≥0.2
// masing-masing chunk truncate ke 800 karakter
}
Hasil: 12.000 karakter → 2.400 karakter. Hemat ~80% token. Jika daemon rawq mati, fallback ke seluruh transcript.
Sistem Peran
Ketika peserta diberi peran, panduan spesifik peran disuntikkan ke dalam prompt, dan token output dibatasi.
4 Peran
fn role_guidance(role: &str) -> &'static str {
match role {
"proposer" => "Presentasikan kesimpulan terlebih dahulu dan berikan alasan...",
"reviewer" | "critic" => "Evaluasi dalam 4 dimensi (plan_coverage, code_quality, test_coverage, convention)...",
"verifier" | "judge" => "Jangan bergantung pada evaluasi peserta lain, nilai secara independen...",
"synthesizer" | "lead" => "Ringkas dalam 3 bagian: consensus/contested/dissent...",
_ => "",
}
}
Batasan output per peran
Peran | Batasan Token Default | Alasan |
|---|
proposer | 1.200 | Hanya proposal inti |
reviewer/critic | 900 | Fokus pada evaluasi |
verifier/judge | 800 | Keputusan harus singkat |
synthesizer/lead | 2.000 | Sintesis bisa lebih panjang |
Batasan token disuntikkan di awal prompt sebagai [Output limit: Keep your response under approximately N tokens.]. Bukan paksaan tetapi instruksi, namun sebagian besar model mengikutinya dengan baik.
Peserta Blind
Jika diatur blind: true, peserta tersebut hanya menerima topik dan peran mereka sendiri, dan tidak melihat respons peserta lain sama sekali.
if p.blind {
build_round_prompt_with_identity(topic, &[], &[], Some(&identity))
// ^^ ^^ transcript dan ronde saat ini keduanya array kosong
}
Berguna untuk audit keamanan atau verifikasi independen. Secara struktural mencegah bias "reviewer lain pass, jadi saya juga pass".
Review RT: Penggunaan dalam Alur Kerja
Di pipeline alur kerja yang dibahas di bagian 2, tahap Review menggunakan RT.
Deteksi impl-complete
→ Buat Review Branch (mode: "roundtable")
→ Jalankan Reviewer + Verifier 2 orang
→ Hasilkan verdict (pass/fail/conditional)
Alasan Review RT 2 orang: peran jelas berbeda. Reviewer mengevaluasi kualitas kode/tes/konvensi secara numerik, Verifier secara independen memverifikasi evaluasi Reviewer sendiri. 3 orang atau lebih hanya meningkatkan biaya token tanpa menambah perspektif signifikan. Berbeda dengan diskusi desain, review memiliki kriteria yang jelas jadi akurasi lebih penting daripada keragaman perspektif.
Brief: Ringkasan Hasil Diskusi
Setelah RT selesai, ringkasan berbasis aturan (brief) dibuat secara otomatis. Tidak ada panggilan LLM tambahan.
// persist.rs — save_shared_brief
for name in &unique_names {
if let Some((_, content)) = transcript.iter().rev().find(|(n, _)| n == name) {
let summary = first_sentences(content, 2); // 2 kalimat pertama, batasan 300 karakter
position_lines.push(format!("- **{}**: {}", name, summary));
}
}
Ekstrak 2 kalimat pertama dari respons terakhir setiap peserta dan ringkas sebagai Key Positions. Brief disimpan di tabel memos dengan type = 'roundtable_brief', dan saat adopt, Key Positions ini disisipkan ke percakapan utama.
Alasan tidak menggunakan ringkasan LLM: RT sendiri sudah banyak mengonsumsi token (basis 3 orang 1 ronde ~10k-20k token), menambah panggilan untuk ringkasan meningkatkan biaya lebih lanjut. Ekstraksi 2 kalimat pertama agak kasar, tetapi karena peserta RT mengikuti panduan peran "katakan kesimpulan terlebih dahulu", 2 kalimat pertama sebenarnya adalah inti posisi mereka.
Pola Penggunaan Aktual
Operasi Ronde
Pola umum dalam diskusi 3 orang adalah minimum 5 ronde. Bukan hanya agen yang berdiskusi tetapi pengguna campur tangan di tengah untuk menjernihkan arah. Campur tangan pengguna juga termasuk dalam hitungan ronde.
Ronde 1: 3 agen masing-masing tampilkan opini
Ronde 2: Pengguna — "Arah A tampak unggul, tapi pertimbangkan juga kekhawatiran B, tinjau ulang"
Ronde 3: 3 agen — Tinjau opini satu sama lain + perbaiki/lengkapi opini sendiri
Ronde 4: Pengguna — "Bagian ini terlihat sudah sepakat, fokus pada sisa isu"
Ronde 5: 3 agen — Opini akhir + synthesizer ringkas
Jika pengguna campur tangan 2 kali, diskusi agen aktual adalah 3 ronde. Ini cukup untuk sebagian besar konvergen. Peserta setuju dengan opini lain, memodifikasi proposal mereka, atau saling melengkapi. Kasus "mempertahankan opini saya" berulang-ulang lebih jarang dari yang diperkirakan.
Dalam diskusi desain kompleks dengan pengguna menjernihkan arah berkali-kali, bisa mencapai 8-10 ronde. Synthesizer melayani untuk meringkas bagian apa yang sudah disepakati dan tidak di akhir, dan jika ada isu yang tidak tercapai konsensus, pengguna menentukan arah.
Konten sederhana atau yang arah sudah jelas tidak perlu sampai RT, cukup percakapan 1:1 dengan Architect.
Kasus Nyata
Ada contoh di mana RT efektif dalam pengembangan tunaFlow. Saat merancang implementasi LLM Wiki untuk tunapi (proyek API) dan seCall (proyek analisis panggilan), diskusi 3 orang mendiskusikan struktur data, strategi indeksing, dan algoritma pencarian. Agen masing-masing mengusulkan pendekatan berbeda, dan melalui ronde, saling meninjau dan melengkapi proposal, hasilnya langsung direfleksikan dalam implementasi aktual. Jika hanya berbicara 1:1 dengan Architect, mungkin hanya satu arah yang dieksplorasi mendalam dan kemungkinan lain terlewatkan, tetapi diskusi membandingkan dan meninjau melalui berbagai kemungkinan tersebut.
Peran Pengguna
Dalam RT, pengguna adalah moderator. Bukan mengharapkan agen mencapai kesepakatan sendiri, tetapi dengan memberikan arah di antara ronde dan menjernihkan isu, kualitas diskusi meningkat. Satu baris seperti "fokus ke arah ini", "ambil proposal A dan kekhawatiran B, keluarkan proposal yang integrasikan keduanya" sangat mengubah kualitas ronde berikutnya.
Keterbatasan Saat Ini
1. Biaya token sebanding dengan ronde
N peserta × R ronde menghasilkan N×R panggilan LLM. 3 orang 3 ronde berarti 9 panggilan. Termasuk transcript ronde sebelumnya, token input juga meningkat seiring ronde. Pencarian vektor mengurangi ~80% konteks ronde sebelumnya, namun secara fundamental biaya proporsional dengan N dan R.
Meski biaya diskusi tinggi, dibanding biaya perbaikan desain yang salah di kemudian hari, biaya token 3 ronde RT cukup masuk akal. Masalahnya adalah sulit memprediksi biaya sebelumnya. Apakah akan selesai 3 ronde atau 8 ronde tergantung kompleksitas topik.
2. Keterbatasan Visual Mode Sequential
Dalam diskusi Sequential, saat melihat respons peserta B, jelas dia melihat dan merespons opini peserta A. Dia mengutip, membantah, atau melengkapi pernyataan sebelumnya. Tetapi di UI, terlihat sebagai "respons berurutan" saja, jadi tidak terlihat jelas bahwa peserta benar-benar berinteraksi.
Respons B dari peserta menerima seluruh respons A dalam prompt, dicerna B sebelum mulai respons sendiri, tetapi "pencernaan" ini terjadi di dalam LLM. Hasilnya menunjukkan referensi silang bagus, tetapi realtime terlihat seperti respons independen.
Ringkasan Keputusan Inti
Keputusan | Alasan |
|---|
RT = mode Branch | Sistem terpisah tidak perlu. Pakai ulang infrastruktur Branch (shadow conv, drawer, adopt) |
Subproses independen per peserta | Bisa campur mesin berbeda. Berbagi sesi PTY struktur tidak mungkin |
Konteks minimal (RtContextCache) | Biaya konteks naik × jumlah peserta × ronde. Hanya Tier 0+1 |
Kompres transcript dengan pencarian vektor | Kirim seluruh ronde sebelumnya → token meledak. Hemat ~80% |
Batasan output per peran | Cegah respons panjang. proposer 1200, reviewer 900, synthesizer 2000 |
Brief berbasis aturan (tanpa LLM) | RT sudah banyak token. Hindari biaya panggilan tambahan |
Review RT 2 orang | Review lebih penting akurasi daripada keragaman perspektif. Reviewer + Verifier independen |
Pratinjau Bagian Selanjutnya
Bagian 5: "Jika percakapan panjang" — Implementasi Memori Jangka Panjang Agen
Percakapan lama dengan agen melebihi jendela konteks. tunaFlow mengimplementasikan memori jangka panjang dengan compressed memory, pencarian vektor, dan tautan cross-session. Kami bahas timing kompresi, kualitas pencarian, dan keputusan desain "sampai mana agen perlu mengingat masa lalu".
Daftar Seri
[Berikan Proses ke Agen] - Pelajaran dari Membuat AOC
[Plan → Dev → Review] — Implementasi Pipeline Alur Kerja
Cabangkan Percakapan — Desain dan Penggunaan Branch
Buat Agen Berdiskusi — Desain dan Keterbatasan Roundtable (Artikel Ini)
Jika Percakapan Panjang — Implementasi Memori Jangka Panjang Agen
Jalankan Alur Kerja dengan Claude $20 — Arsitektur Mesin
Beri Tahu Agen Struktur Kode — rawq + code-review-graph
Dari 246 Keterampilan Pilih yang Perlu — Implementasi Penerapan Keterampilan Otomatis
Jika Agen Ulangi Kesalahan Sama — Desain Jaminan Kualitas
Jalankan Siklus Lengkap dengan tunaFlow — Tinjauan Uji Coba Alur Kerja
Referensi