Back to blog

Ponytail Ketemu Project Besar: Less Code, More Problem?

Ricko Caesar Aprilla Tiaka
Ricko Caesar Aprilla Tiaka
Updated August 8, 2026 at 01:37

Suka artikelnya? Traktir penulis kopi

Tags: #AI Coding #Analytics #coding environment #Core Web Vitals #Cyber Security #Data #developer productivity #Full Stack #NgomonginIT #Programmer Life #Programming #Technology #Trend #vibe coding
Ponytail Ketemu Project Besar: Less Code, More Problem?
Ponytail punya filosofi yang sebenarnya susah untuk dibantah.

Jangan nulis 50 baris kalau masalahnya bisa selesai dengan 5 baris. Jangan bikin abstraction kalau memang belum dibutuhkan. Jangan install dependency kalau native feature sudah cukup. Kalau ada code yang memang tidak kepakai, ya hapus.

Sounds good, right?

Untuk project kecil, saya rasa filosofi seperti ini memang powerful banget. Kita jadi tidak gampang overengineering, tidak membuat architecture ala enterprise untuk aplikasi yang sebenarnya cuma punya beberapa halaman, dan tidak membuat abstraction hanya karena "siapa tahu nanti dibutuhkan".

Masalahnya mulai muncul ketika prinsip tersebut dibawa masuk ke project yang sudah besar.

Less Code ≠ Less Complexity

Di project besar, sebuah code belum tentu ada karena developer sebelumnya tidak tahu cara membuatnya lebih pendek.

Kadang code tersebut ada karena memang sengaja dibuat seperti itu.

Bisa jadi itu abstraction yang digunakan oleh puluhan module. Bisa jadi itu boundary antara dua domain. Bisa jadi dia menjaga business logic tetap berada di satu tempat. Atau bisa saja code tersebut terlihat redundant, tetapi sebenarnya dibutuhkan untuk menjaga compatibility dengan fitur lain.

Dan ini yang menurut saya menjadi blind spot dari AI coding agent.

AI melihat code dari context yang sedang diberikan kepadanya.

Developer yang sudah hidup bersama project tersebut selama dua tahun melihat histori keputusan di balik code tersebut.

Dua hal ini jelas berbeda.

Contoh Sederhana

Misalnya di sebuah project kita sudah punya UserPermissionService.
javascript
class UserPermissionService {
  async canAccess(
    userId: string,
    resourceId: string
  ) {
    const user = await this.userRepository.findById(userId);

    if (!user) {
      return false;
    }

    const permission =
      await this.permissionRepository.findPermission(
        user.id,
        resourceId
      );

    return permission?.canRead === true;
  }
}
Kemudian kita minta AI membuat endpoint baru.

AI melihat logic-nya sederhana.

Lalu muncullah implementasi seperti ini.
javascript
const user = await db.user.findUnique({
  where: {
    id: userId
  }
});

const permission = await db.permission.findFirst({
  where: {
    userId: user?.id,
    resourceId
  }
});

return permission?.canRead === true;
Kalau cuma melihat function tersebut, saya bahkan tidak bisa bilang code ini jelek.

Lebih pendek.

Lebih direct.

Tidak perlu class.

Tidak perlu abstraction.

Bahkan mungkin kelihatan lebih efisien.

Tapi sekarang kita punya dua cara melakukan hal yang sama.

Sebagian fitur menggunakan UserPermissionService.

Sebagian lagi langsung query database.

Dan beberapa bulan kemudian developer baru masuk.

Pertanyaan pertama yang muncul:

"Permission checking di project ini sebenarnya harus lewat service atau langsung query?"

Nah.

Masalahnya bukan lagi jumlah baris code.

Masalahnya adalah consistency.

Project Besar Tidak Cuma Butuh Code yang Jalan

Meme Day 1 vs Day 30 of Vibe Coding
Meme Day 1 vs Day 30 of Vibe Coding
Ini bagian yang sering dilupakan ketika kita terlalu fokus dengan "AI bisa bikin code lebih sedikit".

Project besar tidak cuma membutuhkan code yang bekerja.

Dia membutuhkan codebase yang predictable.

Technical debt sendiri tidak selalu muncul karena code yang buruk. Inconsistency, duplicated logic, dan keputusan desain yang terus berubah juga dapat meningkatkan biaya maintenance sebuah sistem [1].

Kalau ada 40 tempat yang menggunakan pattern tertentu, lalu satu fitur baru tiba-tiba menggunakan pattern berbeda karena AI merasa implementasinya lebih efficient, kita baru saja menambah satu keputusan baru ke dalam kepala developer berikutnya.

Dan keputusan kecil seperti ini kalau dikumpulkan selama berbulan-bulan bisa berubah menjadi technical debt.

Bukan karena code-nya jelek.

Tapi karena codebase-nya mulai tidak konsisten.

Masalah yang Lebih Serius: AI Mulai Menghapus Code yang Sudah Jadi

Menurut saya, bagian paling berbahaya bukan ketika Ponytail membuat code baru.

Tapi ketika dia mulai melihat existing code dan berpikir:

"Ini sebenarnya tidak perlu."

Nah.

Kalimat tersebut sangat tricky.

Unused code?

Silakan hapus.

Dead code?

Hapus.

Duplicate code yang memang bisa diverifikasi?

Boleh.

Tapi "code ini kelihatannya unnecessary"?

Itu sudah masuk wilayah architectural decision.

Karena AI belum tentu tahu kenapa code tersebut dibuat.

Contoh 2 — Pricing Service

Misalnya kita punya PricingService.

Service ini sengaja dibuat supaya semua kalkulasi harga berada di satu tempat.
javascript
class OrderService {
  constructor(
    private readonly repository: OrderRepository,
    private readonly pricing: PricingService,
    private readonly eventBus: EventBus
  ) {}

  async createOrder(input: CreateOrderInput) {
    const price = await this.pricing.calculate(
      input.items
    );

    const order = await this.repository.create({
      ...input,
      total: price.total
    });

    await this.eventBus.publish(
      new OrderCreatedEvent(order.id)
    );

    return order;
  }
}
Sekarang developer meminta AI membuat fitur draft order.

AI melihat PricingService cuma digunakan sekali.

Kemudian dibuatlah versi yang lebih "simple".
javascript
async function createDraftOrder(
  input: CreateOrderInput
) {
  const total = input.items.reduce(
    (sum, item) =>
      sum + item.price * item.quantity,
    0
  );

  return db.order.create({
    data: {
      ...input,
      total,
      status: "DRAFT"
    }
  });
}
Sekilas?

Bagus.

Lebih pendek.

Lebih sedikit dependency.

Tidak perlu inject PricingService.

Tapi coba bayangkan tiga bulan kemudian bisnis menambahkan member discount, voucher, tax, currency conversion, dan dynamic pricing.

OrderService mendapatkan logic tersebut karena semuanya masuk melalui PricingService.

Tapi createDraftOrder()?

Masih menghitung harga sendiri.

Sekarang kita punya dua sumber kebenaran.

Dan bug seperti ini jauh lebih ngeselin daripada code yang kepanjangan.

AI Cenderung Bagus di Optimasi Lokal

Ada penelitian yang menganalisis lebih dari 15 ribu refactoring dari ribuan pull request open-source untuk melihat bagaimana AI coding agent melakukan refactoring [2].

Hasilnya menarik.

Banyak perubahan yang dilakukan agent berfokus pada perubahan lokal, seperti rename variable, rename parameter, dan perubahan struktur kecil.

Ini sebenarnya masuk akal.

AI sangat bagus ketika masalahnya jelas dan local.

"Rename ini."

"Extract function ini."

"Fix bug ini."

"Remove duplicate code ini."

Tapi architectural decision berbeda.

Pertanyaannya bukan lagi:

"Bagaimana cara memperbaiki code ini?"

Melainkan:

"Kenapa code ini dibuat seperti ini?"

Dan pertanyaan kedua membutuhkan context yang jauh lebih besar.

Velocity Naik, Complexity Bisa Ikut Naik

Ini juga yang menurut saya menarik dari perkembangan AI coding agent.

Kita sekarang bisa menghasilkan code jauh lebih cepat.

Tapi kemampuan menghasilkan code dan kemampuan menjaga codebase tetap sehat adalah dua hal berbeda.

Penelitian terhadap penggunaan autonomous coding agent juga menunjukkan bahwa peningkatan produktivitas tidak otomatis berarti kualitas codebase meningkat. Dalam studi longitudinal tersebut ditemukan indikasi peningkatan static-analysis warnings dan cognitive complexity setelah penggunaan coding agent [3].

Kalau developer biasanya menghasilkan 500 baris code dalam sehari, lalu dengan AI menjadi 2.000 baris, kita memang mendapatkan velocity.

Tapi kalau kemampuan kita melakukan review, testing, documentation, dan architectural reasoning tidak ikut naik empat kali lipat?

Kita hanya menghasilkan technical debt lebih cepat.

AI tidak selalu membuat project lebih berantakan.

Tapi AI membuat keputusan buruk menjadi jauh lebih murah untuk dilakukan.

Dan itu justru yang perlu kita waspadai.

Jadi Apakah Ponytail Jelek?

Menurut saya?

Enggak.

Justru prinsip Ponytail cukup bagus.

Jangan overengineering.

Jangan membuat abstraction yang belum dibutuhkan.

Reuse existing code.

Pilih solusi paling sederhana yang menyelesaikan masalah.

Saya setuju dengan semuanya.

Yang saya tidak setuju adalah ketika prinsip tersebut berubah menjadi:

"Kalau bisa dihapus, hapus."

Karena di project besar, "bisa dihapus" belum tentu berarti "seharusnya dihapus".

Ponytail Harus Tahu Batas

Kalau saya menggunakan Ponytail di project besar, saya justru akan kasih boundary yang jelas.

Untuk code baru:

Boleh minimal.

Boleh sederhana.

Boleh menghindari abstraction yang belum diperlukan.

Boleh reuse existing implementation.

Tapi untuk existing architecture?

Jangan sembarangan menyederhanakan.

Kalau mau menghapus abstraction yang sudah digunakan banyak module, harus ada alasan yang jelas.

Kalau mau mengganti pattern yang sudah digunakan seluruh project, harus ada architectural decision.

Kalau mau menghapus code karena dianggap redundant, pastikan memang redundant secara behavior, bukan cuma kelihatan redundant dari satu file.

Karena Senior Developer Bukan yang Menulis Code Paling Sedikit

Menurut saya ini bagian paling penting.

Senior developer bukan orang yang selalu menghasilkan code paling sedikit.

Senior developer adalah orang yang tahu kapan code tersebut memang tidak perlu ditulis.

Dan lebih penting lagi:

Tahu kapan code yang kelihatannya unnecessary sebenarnya sedang menjaga sistem tetap waras.

Ponytail ngajarin AI untuk menjadi lazy senior developer.

Menurut saya, problem-nya muncul ketika AI cuma belajar bagian "lazy"-nya, tapi belum benar-benar punya pengalaman bertahun-tahun melihat bagaimana satu keputusan kecil hari ini bisa menjadi masalah enam bulan kemudian.

Less code is good.

Less understanding is not.

Referensi

[1] Avgeriou, P., Kruchten, P., Ozkaya, I., & Seaman, C. (2016). Managing Technical Debt in Software Engineering. In Advances in Computers, Vol. 108. Elsevier.

[2] Ma, Y., et al. (2025). Agentic Refactoring: An Empirical Study of AI Coding Agents. arXiv preprint arXiv:2511.04824.

[3] AI IDEs or Autonomous Agents? Measuring the Impact of Coding Agents on Software Development. (2026). arXiv preprint arXiv:2601.13597.

[4] GitHub. (2026). Reducing Technical Debt with GitHub Copilot. GitHub Documentation.

[5] Ponytail. (2026). Ponytail: AI Coding Agent. Ponytail Documentation.

Share this article with your network.

Suka dengan artikel ini?

Setiap artikel yang kamu baca lahir dari riset mendalam, kerja keras, dan secangkir kopi yang tak pernah habis. Jika tulisan ini memberi wawasan baru, kamu bisa mendukung penulis lewat tombol di bawah — setiap dukunganmu, sekecil apa pun, sangat berarti untuk terus menghadirkan konten yang berkualitas.

Terima kasih telah membaca dan mendukung karya penulis 🙏

Komentar (0)

Belum ada komentar. Jadilah yang pertama!