
Ini adalah bagian 3 dari seri postingan teknis tunaFlow. Di bagian 2, kami membahas pipeline alur kerja (Plan → Dev → Review), dan agar pipeline itu berfungsi, kami memerlukan "struktur yang membagi percakapan". Itulah Implementation(saat ini Dev) Branch dan Review Branch. Bagian ini membahas desain dan penggunaan Branch itu sendiri.
Mengapa percakapan harus dibagi
Saat berbicara dengan agen, situasi seperti ini sering terjadi.
Saya: "Bagaimana jika kami mengganti autentikasi dengan OAuth2?"
Claude: "Baik. Caranya begini..." (penjelasan panjang)
Saya: "Ah... tapi bisakah kami juga melihat cara mempertahankan JWT?"
Claude: (sudah dalam konteks OAuth2 selama ini)
Jika kami mencoba arah yang berbeda dalam percakapan utama, konteksnya menjadi tercampur. Untuk kembali mengatakan "cara OAuth2 itu lebih baik", kami harus mereferensikan pesan sebelumnya satu per satu.
Tetapi ini lebih serius dalam pekerjaan kode. Jika kami membuat agen memodifikasi kode dalam percakapan utama, hasilnya langsung tercermin di direktori kerja. Jika kami melakukan modifikasi eksperimental dalam percakapan utama, sulit untuk membatalkannya.
Sama seperti membuat branch di git untuk bereksperimen, lalu merge jika sudah bagus, kami memerlukan struktur yang sama untuk percakapan.
Struktur dasar Branch
Di tunaFlow, Branch adalah percakapan independen yang bercabang dari titik tertentu dalam percakapan utama.
Percakapan utama:
msg1 → msg2 → msg3 → msg4 → msg5 → ...
↓
Branch A (bercabang dari msg3)
→ branchMsg1 → branchMsg2 → ...
Shadow Conversation
Pesan Branch disimpan di conversation terpisah. Kami menyebutnya shadow conversation!
conversations table:
id: "conv_main" ← Percakapan utama
id: "branch:{branchId}" ← Shadow conversation dari Branch
Saat membuka Branch, kami memuat pesan dari shadow conversation. Karena sepenuhnya terpisah dari percakapan utama, apapun yang kami lakukan dalam Branch tidak mempengaruhi percakapan utama. Kami juga dapat membuat branch dari Branch — kami melacak struktur pohon dengan parent_branch_id. Dalam penggunaan praktis, jarang melampaui 2 tingkat, tetapi secara struktural tidak ada batasan kedalaman.
Checkpoint dan Pewarisan Konteks
Pesan pada titik di mana Branch bercabang disebut checkpoint.
pub struct Branch {
pub id: String,
pub conversation_id: String, // Percakapan induk
pub checkpoint_id: Option, // Pesan titik percabangan
pub parent_branch_id: Option,
pub mode: String, // "chat" atau "roundtable"
pub git_branch: Option,
// ...
}
Yang penting adalah bagaimana Branch mewarisi konteks dari percakapan induk. Ini berbeda tergantung mode eksekusi.
Mode PTY (default): Berbagi sesi PTY percakapan induk secara langsung. Claude CLI mempertahankan riwayat percakapan dalam sesi itu sendiri, jadi saat pesan pertama Branch dikirim, agen sudah merespons dalam keadaan yang sudah mengetahui seluruh konteks percakapan induk. Tidak perlu transmisi konteks terpisah.
// threadSlice.ts — Branch berbagi sesi PTY induk
const ptySession = usePtyStore.getState().getSession(engineKey);
await sendMessageViaPty(set, get, prompt, ptySession, convId, engineKey, {
forceNewJsonl: isFirstMessage, // Hanya pesan pertama path JSONL baru
});
Mode fallback CLI (-p): Ketika PTY tidak dapat digunakan, bagian thread inheritance disertakan dalam ContextPack. Kami memasukkan Thread Anchor (pesan titik percabangan) dan 4 giliran terbaru dari percakapan induk untuk memberikan konteks kepada agen.
// context_loading.rs
let thread_inheritance = if is_branch {
build_thread_inheritance_section(conn, conversation_id)
} else { None };
Mode RT: Peserta Roundtable selalu berjalan dalam mode -p. Karena setiap peserta adalah subproses independen, berbagi sesi tidak mungkin, dan sebaliknya RtContextCache merakit konteks minimal (~1-2k token) dan transcript per putaran untuk mengirimkannya. RT akan dibahas secara terperinci di bagian 4.
Tiga Jenis Branch
Di tunaFlow, Branch terbagi menjadi tiga berdasarkan penggunaan. Dalam kode, semuanya ada di tabel branches yang sama, dan digunakan berbeda tergantung penggunaannya.
1. Branch Umum — Eksperimen Bebas
Branch yang dibuat pengguna secara manual selama percakapan. Kami menggunakannya ketika ingin mencoba "arah ini sekali".
Klik kanan pesan → "Cabang Branch" → Buat Branch baru → Buka di drawer
2. Implementation(Dev) Branch — Pembuatan Otomatis Alur Kerja
Seperti dibahas di bagian 2, dibuat secara otomatis saat Plan disetujui.
Plan disetujui → Implementation Branch dibuat otomatis
→ Kirim prompt ke Developer
→ Implementasi selesai → Deteksi penanda impl-complete
3. Review Branch — Pembuatan Otomatis untuk Tinjauan
Setelah implementasi selesai, Branch untuk Review dibuat secara otomatis.
Deteksi impl-complete → Review Branch dibuat otomatis
→ Jalankan agen Reviewer → Output verdict
Ketiga jenis menggunakan struktur Branch yang sama. Branch alur kerja (2, 3) terhubung dengan implementation_branch_id dan review_branch_id Plan, sehingga status dapat dilacak di tab Workflow.
Struktur menempatkan alur kerja di atas Branch. Branch itu sendiri adalah percabangan percakapan serbaguna, dan alur kerja meletakkan Phase (implementation/review/rework) dan konversi otomatis di atasnya. Jadi Branch dapat digunakan dengan bebas tanpa alur kerja, dan Branch alur kerja dan Branch pengguna dikelola dengan struktur yang sama.
Drawer UX
Saat membuka Branch, branch dibuka di **drawer di sebelah kanan (slider)**. Bukan penggantian seluruh layar.
┌──────────┬──────────────────┬──────────────────┐
│ Sidebar │ CenterPanel │ Branch drawer │
│ │ (Chat utama) │ (Chat Branch) │
│ │ │ │
│ │ msg1 │ branchMsg1 │
│ │ msg2 │ branchMsg2 │
│ │ msg3 ← checkpoint│ │
│ │ msg4 │ │
└──────────┴──────────────────┴──────────────────┘
Dapat melihat percakapan utama dan berdampingan adalah kuncinya. Branch sering digunakan sambil merujuk diskusi desain dalam percakapan utama. Jika seluruh layar, kami harus bolak-balik, tetapi dengan drawer, terasa seperti "mereferensikan di samping". Biaya peralihan konteks rendah.
Mengklik tombol 📌 (pin) di drawer beralih ke mode panel tetap di mana dibagi 50:50 dengan CenterPanel bukannya overlay. Berguna ketika ingin terus menyimpan Branch implementasi di samping saat meninjau.
Adopt: Menggabungkan Hasil ke Percakapan Utama
Saat hasil bagus keluar dari Branch, **masukkan ringkasan ke percakapan utama**. Ini disebut adopt.
Branch mencapai kesimpulan "Cara PKCE OAuth2 cocok. Alasannya adalah..."
→ Klik Adopt
→ Masukkan pesan ringkasan ke percakapan utama
→ Status Branch: active → adopted → Pindah ke Archive
adopt ≠ merge
Tidak seperti git merge, adopt hanya memasukkan ringkasan. Tidak semua pesan Branch disalin ke percakapan utama.
Jika memasukkan semua pesan Branch, percakapan utama akan sangat panjang
Dengan ringkasan saja, "kesimpulan seperti ini telah tercapai" tetap ada dalam percakapan utama
Jika memerlukan asli, dapat membuka Branch terkait dari Archive
Metode Ekstraksi Ringkasan
Ekstraksi ringkasan untuk Branch RT dan Branch umum berbeda.
RT: Ekstrak bagian Key Positions dari brief (dokumen ringkasan diskusi). Karena RT memiliki struktur diskusi terstandar, ringkasan yang relatif bersih keluar.
Branch Umum: Potong 300 karakter dari pesan assistant terakhir dan masukkan. Jujur, ini kasar. Ini agak konyol. Dan ada cara untuk menghasilkan ringkasan dengan LLM, tetapi belum diterapkan secara otomatis. Pola penggunaan praktis saat ini adalah meminta kepada agen "tolong ringkas kesimpulan sejauh ini" sebelum adopt, lalu adopt.
Integrasi Git Branch
Dapat menghubungkan git branch nyata ke tunaFlow Branch.
Branch "impl-auth" → git branch "feature/oauth-migration"
Saat terhubung, nama git branch ditampilkan di sidebar, dan saat Developer bekerja di Branch itu, konteks git disediakan.
// branches.rs — create_branch
let git_branch: Option = if let Some(ref parent_id) = input.parent_branch_id {
// Warisi git_branch dari Branch induk
conn.query_row(
"SELECT git_branch FROM branches WHERE id = ?1",
[parent_id], |row| row.get(0),
).ok().flatten()
} else {
// Tanpa induk, deteksi otomatis git branch saat ini
detect_current_git_branch(project_path)
};
Warisi git branch dari Branch induk, dan jika tidak ada, deteksi otomatis git branch proyek saat ini. Saat agen memodifikasi kode dalam Implementation Branch, direfleksikan ke git branch terhubung, sehingga dapat bereksperimen tanpa mencemari branch utama.
Manajemen Branch di Sidebar
Sidebar menampilkan Branch di tiga tempat.
Sidebar:
▸ Branches (3) ← Branch umum aktif
🔀 impl-auth
🔀 review-auth
🔀 experiment-jwt
▸ Roundtables (1) ← RT aktif (RT = mode perpanjangan Branch)
👥 auth-discussion
▸ Archive ← Branch adopted/archived
📦 oauth-analysis
Dibedakan dengan bidang mode dan status. RT adalah "mode" Branch akan dibahas secara terperinci di bagian 4.
Batasan Saat Ini
1. Ringkasan adopt kasar
Pada RT, ekstraksi Key Positions berfungsi dengan relatif baik, tetapi pada Branch umum, hanya potongan 300 karakter respons terakhir. Dalam penggunaan praktis, kami meminta agen "ringkas kesimpulan sejauh ini" sebelum adopt sebagai jalan keluar.
Arah Perbaikan: Alami untuk membuat agen menghasilkan ringkasan seluruh percakapan Branch saat adopt. Karena jumlah pesan Branch biasanya di bawah 10, biaya token tidak besar, dan infrastruktur untuk menghasilkan ringkasan LLM sudah ada di pipeline memory terkompresi untuk digunakan kembali. Kami menambahkan penanda ke ringkasan adopt, jadi rendering dengan kartu khusus (BranchAdoptCard) di masa depan sudah siap.
2. Keseimbangan antara isolasi dan berbagi
Branch dan percakapan utama terisolasi dalam hal UI percakapan, tetapi bukan isolasi lengkap. Pipeline retrieval ContextPack menangkap semua percakapan dalam proyek (termasuk Branch) sebagai target pencarian FTS5 + vector, jadi konten yang didiskusikan dalam Branch dapat ditarik sebagai chunk terkait dalam ContextPack percakapan utama. Modifikasi kode juga berbagi direktori kerja yang sama, jadi langsung terlihat di level git.
Namun ini adalah transmisi tidak langsung berbasis pencarian, jadi informasi eksplisit "OAuth2 PKCE adalah kesimpulan di Branch" tidak ditransmisikan ke utama. Itu masih peran adopt.
Arah Perbaikan: Koneksi otomatis antara percakapan dengan tabel session_links sudah diimplementasikan, dan bagian cross-session disertakan dalam ContextPack. Jika membuat session link otomatis saat adopt Branch, agen dalam percakapan utama dapat mereferensikan konten Branch melalui cross-session setelah adopt. Sebelum adopt, juga sedang dipertimbangkan memasukkan hint kesimpulan utama Branch ke dalam utama, tetapi kami menghampiri dengan hati-hati agar tidak menghilangkan keuntungan isolasi.
Ringkasan Keputusan Inti
Keputusan | Alasan |
|---|
Isolasi dengan shadow conversation | Cegah pencemaran percakapan utama. Pembersihan pesan rapi saat penghapusan Branch |
Berbagi sesi PTY (Branch umum) | Warisi konteks percakapan induk secara alami. Tidak perlu transmisi konteks terpisah |
Drawer UX (bukan seluruh layar) | Lihat berdampingan dengan utama + biaya peralihan konteks rendah |
adopt = masukkan ringkasan saja | Cegah pembengkakan percakapan utama. Akses asli dari Archive |
Struktur alur kerja meminjam Branch | Branch serbaguna, alur kerja adalah layer di atasnya |
Warisan git branch | Warisi konteks git Branch induk secara otomatis |
Pratinjau Bagian Berikutnya
Bagian 4: "Membuat Agen Berdiskusi" — Desain dan Batasan Roundtable
RT adalah mode perpanjangan Branch. Jika branches.mode = "roundtable", beberapa agen mendiskusikan secara berurutan atau paralel. Kami membahas mengapa Review RT adalah 2-agen, perbedaan antara Sequential dan Deliberative, dan kasus saat RT tidak bekerja baik.
Daftar Seri
Berikan Proses kepada Agen — Apa yang Kami Pelajari Membuat AOC
Plan → Dev → Review — Catatan Implementasi Pipeline Alur Kerja
Bagi Percakapan — Desain dan Penggunaan Branch (artikel ini)
Membuat Agen Berdiskusi — Desain dan Batasan Roundtable
Saat Percakapan Panjang — Implementasi Memori Jangka Panjang Agen
Jalankan Alur Kerja dengan Claude $20 — Arsitektur Mesin
Katakan Struktur Kode kepada Agen — rawq + code-review-graph
Dari 246 Keterampilan Pilih yang Diperlukan — Implementasi Penerapan Keterampilan Otomatis
Jika Agen Mengulangi Kesalahan yang Sama — Desain Jaminan Kualitas
Putar Siklus Penuh dengan tunaFlow — Refleksi Tes Alur Kerja Praktis
Referensi