Azhary Arliansyah

Articles / Bisakah AI Benar-Benar Menulis Kode? Cara Mengukur Kemampuan AI Model dalam Pemrograman

Bisakah AI Benar-Benar Menulis Kode? Cara Mengukur Kemampuan AI Model dalam Pemrograman

nlp code-synthesis evaluation-metric
Bisakah AI Benar-Benar Menulis Kode? Cara Mengukur Kemampuan AI Model dalam Pemrograman

Metrik evaluasi memainkan peran penting dalam pertumbuhan suatu bidang karena menentukan standar untuk membedakan antara model yang baik dan buruk. Dalam bidang sintesis kode pemrograman, metrik evaluasi yang umum digunakan adalah BLEU atau akurasi sempurna (perfect accuracy), tetapi keduanya tidak cukup cocok untuk mengevaluasi kode. BLEU awalnya dirancang untuk mengevaluasi bahasa alami, mengabaikan fitur sintaksis dan semantik penting dari kode, dan akurasi sempurna terlalu ketat, sehingga meremehkan output yang berbeda dengan logika semantik yang sama.

Untuk mengatasi hal ini, Ren et al. [1] memperkenalkan metrik evaluasi otomatis baru, yang dijuluki CodeBLEU. Metrik ini menyerap kekuatan BLEU dalam pencocokan n-gram, dan lebih lanjut memasukkan informasi sintaksis kode melalui Abstract Syntax Trees (AST) dan semantik kode melalui Data-Flows.

Mengapa Bukan BLEU?

Meskipun BLEU [2] telah menjadi golden standard untuk menerjemahkan bahasa manusia, ia gagal menangkap sifat unik dari kode pemrograman:

  1. Keyword Terbatas vs Jutaan Kata: Berbeda dengan bahasa alami dengan kosakata yang luas, kode menggunakan set keywords yang terbatas. Kata kunci ini lebih penting daripada token lainnya dan harus mendapatkan bobot yang lebih tinggi dalam evaluasi.
  2. Struktur Pohon vs Struktur Sekuensial: Bahasa alami biasanya diproses secara sekuensial (dari kiri ke kanan), tetapi kode secara mendasar bersifat hierarkis, yang direpresentasikan oleh AST.
  3. Instruksi Unik vs Semantik Ambigu: Bahasa alami bergantung pada konteks dan ambigu. Kode, bagaimanapun, dirancang untuk menjadi deterministik, di mana ketergantungan variabel (data-flow) menentukan logikanya.

Formula CodeBLEU

CodeBLEU didefinisikan sebagai weighted combination dari empat skor berbeda:

CodeBLEU=αBLEU+βBLEUweight+γMatchast+δMatchdfCodeBLEU = \alpha \cdot BLEU + \beta \cdot BLEU_{weight} + \gamma \cdot Match_{ast} + \delta \cdot Match_{df}

Di mana:

  • α,β,γ,δ\alpha, \beta, \gamma, \delta adalah hyperparameter yang jumlahnya sama dengan 1.
  • BLEUweightBLEU_{weight} adalah pencocokan n-gram tertimbang.
  • MatchastMatch_{ast} adalah pencocokan AST sintaksis.
  • MatchdfMatch_{df} adalah pencocokan data-flow semantik.

Contoh Kasus

Di seluruh artikel ini, kita akan menelusuri keempat komponen CodeBLEU menggunakan satu contoh yang konsisten. Perhatikan evaluasi fungsi square berikut:

Kode Referensi:

public static int square(int x) {
    int y = x * x;
    return y;
}

Kode Kandidat:

public static int square(int x) {
    int y = x * x;
    return x;
}

Satu-satunya perbedaan adalah pada return statement: kandidat mengembalikan input x alih-alih hasil perhitungan y. Ini adalah kesalahan semantik yang halus namun kritis, jenis kesalahan yang sulit dideteksi oleh BLEU standar.

Kita akan menghitung keempat skor langkah demi langkah:

  • BLEU (overlap n-gram standar)
  • BLEU_weight (n-gram dengan penguatan kata kunci)
  • Match_ast (pencocokan subtree AST)
  • Match_df (pencocokan grafik data-flow)

...dan kemudian menggabungkannya ke dalam skor CodeBLEU akhir.

1. Weighted N-Gram Match

BLEU orisinal membandingkan n-gram antara kandidat dan referensi serta menghitung rasio n-gram yang cocok. Namun, ia memperlakukan semua token secara setara. Dalam bahasa pemrograman, token tertentu (seperti kata kunci) lebih kritis untuk logika program daripada yang lain (seperti nama variabel).

CodeBLEU memperkenalkan Weighted N-Gram Match untuk menetapkan bobot yang berbeda pada token yang berbeda. Dalam makalah aslinya, kata kunci diberikan bobot 5 kali lebih tinggi daripada token lainnya.

Weighted n-gram precision pnp_n dihitung sebagai:

pn=CCandidatesi=1lnwniCountclip(C(i,i+n))CCandidatesi=1lnwniCount(C(i,i+n))p_n = \frac{\sum_{C \in Candidates} \sum_{i=1}^{l_n} w_n^i \cdot Count_{clip}(C(i, i+n))}{\sum_{C' \in Candidates} \sum_{i=1}^{l_n} w_n^i \cdot Count(C'(i, i+n))}

Di mana wniw_n^i menunjukkan bobot yang diberikan pada n-gram tersebut. Saat ini, hal ini diterapkan pada unigram (N=1N=1).

Contoh: Proses Pembobotan

Pertimbangkan contoh fungsi square kita. Kita membandingkan kandidat yang salah mengembalikan input xx alih-alih yy yang dihitung.

REFERENCE TOKENS public weight: 5.0 static weight: 5.0 int weight: 5.0 square weight: 1.0 ( weight: 1.0 int x weight: 1.0 ) weight: 1.0 Keyword (5.0×) Identifier (1.0×) Punctuation (1.0×)

*Gambar 1: Pembobotan ulang token dalam CodeBLEU. Kata kunci seperti public diperkuat untuk menangkap kepentingan strukturalnya.*

Distribusi bobot yang dihasilkan memastikan bahwa ketidakcocokan kata kunci (misalnya, menukar int dengan float) menghukum skor lebih berat daripada ketidakcocokan pengenal (identifier).

Perhitungan: Weighted vs Standard N-Grams

Mari kita hitung skor untuk contoh kasus square kita.
Pertama, kita melakukan tokenisasi pada kode referensi dan kandidat. Keduanya berisi tepat 20 token.

1. Standard BLEU (Unigram overlap):

  • Kandidat memiliki x tambahan dan kehilangan y.
  • 19 dari 20 token cocok (dengan clipping diterapkan).
  • Skor BLEU = 19/20×100=95.019 / 20 \times 100 = 95.0

2. Weighted BLEU (BLEUweightBLEU_{weight}):

  • Keywords (Weight 5.0): Ada 6 kata kunci (public, static, int, int, int, return). 6×5.0=30.06 \times 5.0 = 30.0.
  • Token Lainnya (Weight 1.0): Ada 14 token lainnya. 14×1.0=14.014 \times 1.0 = 14.0.
  • Total Bobot Referensi: 30.0+14.0=44.030.0 + 14.0 = 44.0.
  • Bobot yang Cocok: Semua 6 kata kunci cocok dengan sempurna (+30.0). Dari 14 token lainnya, 13 cocok (+13.0). Total bobot yang cocok = 43.0.
  • Skor BLEUweightBLEU_{weight} = 43.0/44.0×100=97.743.0 / 44.0 \times 100 = 97.7

Perhatikan bahwa BLEUweightBLEU_{weight} sebenarnya lebih tinggi daripada BLEU standar di sini! Karena kesalahan tersebut melibatkan penukaran identifier (x untuk y), kata kunci dengan bobot tinggi berhasil cocok, sehingga mendorong skor tata bahasa naik. Ini membuktikan dengan sempurna mengapa kita juga harus memeriksa logika struktural dan semantik.

2. Syntactic AST Match

Bahasa pemrograman memiliki struktur pohon alami yang disebut Abstract Syntax Tree (AST). CodeBLEU menggunakan ini dengan mencocokkan subtree antara kandidat dan referensi.

Setiap node dalam AST mewakili sebuah construct (misalnya, MethodDeclaration, BinaryExpression). Daun (leaves), nama variabel dan fungsi, dihapus karena struktur sintaksis adalah yang paling penting di sini.

Skor pencocokan AST adalah:

Matchast=Countclip(Tcand)Count(Tref)Match_{ast} = \frac{Count_{clip}(T_{cand})}{Count(T_{ref})}

Di mana:

  • Count(Tref)Count(T_{ref}) adalah jumlah total subtree dalam referensi.
  • Countclip(Tcand)Count_{clip}(T_{cand}) adalah jumlah subtree kandidat yang cocok.

Visualisasi: Perbandingan Struktural

Dalam kandidat kita, pernyataan return mengembalikan x alih-alih y. Namun, karena pencocokan AST berfokus pada struktur tata bahasa dan menghapus leaves nama variabel, "mengembalikan variabel lokal" menghasilkan subtree yang persis sama.

REFERENCE AST (LEAF-REDUCED) MethodDecl ParamDecl Block VarDecl (y) Return (var) matched subtree ✓ CANDIDATE AST MethodDecl ParamDecl Block VarDecl (y) Return (var) AST match ✓ *Setiap node dan anak-anaknya membentuk subtree. Nama leaves (nama variabel) dihapus sebelum perbandingan.*

*Gambar 2: Karena nama node leaves dikecualikan, struktur AST untuk mengembalikan `x` atau `y` benar-benar identik. AST memastikan integritas struktural tetapi melewatkan aliran logis.*

Perhitungan: Skor AST Match

Untuk contoh kasus kita:

  • Menghasilkan AST tree-sitter dan menghapus variable name leaves menghasilkan tepat 12 subtree.
  • Karena logika struktural (Return Statement -> Identifier) identik antara kandidat dan referensi, ke-12 subtree tersebut terpetakan 1-ke-1 dengan sempurna.
  • Skor MatchastMatch_{ast} = 12/12×100=100.012 / 12 \times 100 = 100.0

Dengan BLEU pada 95.0 dan AST Match pada 100.0, kandidat terlihat hampir sempurna. Di sinilah semantic data-flow berperan untuk mendeteksi critical bug tersebut.

3. Semantic Data-flow Match

Meskipun AST menangkap struktur sintaksis, terkadang ia melewatkan logika semantik. CodeBLEU mengatasi hal ini dengan menggunakan Data-Flow Graphs untuk mengukur kesamaan semantik.

Dalam grafik data-flow, node mewakili variabel dan edge mewakili sumber nilai-nilainya. Misalnya, dalam fungsi square kita, variabel y bergantung pada x, dan nilai return harus bergantung pada y.

Langkah Perhitungan Data-Flow

  1. Ekstrak Grafik: Identifikasi node variabel dan hubungannya (dari mana setiap nilai berasal).
  2. Normalisasi: Abaikan nama variabel dan posisi. Semua variabel diganti namanya menjadi format yang seragam (var_0, var_1, dst).
  3. Perhitungan Akurasi:
    Matchdf=Countclip(DFcand)Count(DFref)Match_{df} = \frac{Count_{clip}(DF_{cand})}{Count(DF_{ref})}

Visualisasi: Kesenjangan Semantik

Kesalahan semantik kandidat terlihat jelas saat membandingkan grafik data-flow. Node return pada kandidat menunjuk kembali ke input x, melewati perhitungan dalam y.

REFERENCE DATA-FLOW input x computes y = x * x y returns output RET x → y → return(y) ✓ CANDIDATE DATA-FLOW input x y = x * x y output RET incorrect dependency! x → return(x) — skips y! ✗ Ketergantungan benar Ketergantungan salah Variabel tak terpakai

*Gambar 3: Tangkapan semantic data-flow. Tautan yang hilang antara perhitungan (y) dan penggunaan akhirnya (return) mengungkap kesalahan logis yang mendalam.*

Perhitungan: Pencocokan Penentu

Mari kita evaluasi pencocokan semantik untuk contoh kasus kita:

Data-Flow Referensi:

  1. Nilai y berasal dari x
  2. RET (pernyataan return) berasal dari y
    (Total sisi referensi = 2)

Data-Flow Kandidat:

  1. Nilai y berasal dari x
  2. RET berasal dari x

Membandingkan sisi-sisi yang dinormalisasi:

  • Sisi y <- x cocok.
  • Referensi mengharapkan RET <- y, tetapi kandidat memiliki RET <- x. Ini adalah ketidakcocokan!

Skor MatchdfMatch_{df} = 1/2×100=50.01 / 2 \times 100 = 50.0

Perhitungan CodeBLEU Akhir

Sekarang kita menggabungkan semua komponen untuk mendapatkan skor akhir. Menggunakan bobot yang didistribusikan secara merata (α,β,γ,δ=0.25\alpha, \beta, \gamma, \delta = 0.25), kita jumlahkan:

CodeBLEU=0.25(BLEU)+0.25(BLEUweight)+0.25(Matchast)+0.25(Matchdf)CodeBLEU = 0.25 (BLEU) + 0.25 (BLEU_{weight}) + 0.25 (Match_{ast}) + 0.25 (Match_{df})

CodeBLEU=0.25(95.0)+0.25(97.7)+0.25(100.0)+0.25(50.0)=85.67CodeBLEU = 0.25 (95.0) + 0.25 (97.7) + 0.25 (100.0) + 0.25 (50.0) = \mathbf{85.67}

Kesimpulan: Skor BLEU berbasis teks murni melaporkan nilai 95.0 yang menipu. Dengan menangkap anomali data-flow, CodeBLEU sangat menghukum kesalahan logis tersebut, menurunkan skor evaluasi sebenarnya menjadi 85.67, yang secara sempurna mencerminkan penilaian manusia.

4. Hasil Eksperimen & Korelasi

Efektivitas CodeBLEU dievaluasi pada tiga tugas dunia nyata: Text-to-Code, Penerjemahan Kode, dan Penyempurnaan Kode. Para peneliti menghitung Koefisien Korelasi Pearson untuk memeriksa seberapa baik CodeBLEU cocok dengan penilaian manusia dibandingkan dengan metrik tradisional.

Peningkatan Kinerja Utama

CodeBLEU menunjukkan peningkatan signifikan dalam mencocokkan skor yang diberikan oleh programmer:

Tugas BLEU & Manusia CodeBLEU & Manusia Peningkatan
Text-to-code 0.967 0.977 +1.0%
Code translation 0.940 0.970 +3.0%
Code refinement 0.923 0.979 +5.6%

Optimal Hyperparameter

Melalui studi ablasi, para penulis menemukan bahwa meningkatkan bobot pencocokan Syntactic AST dan Semantic Data-Flow menghasilkan korelasi manusia yang lebih baik. Konfigurasi yang direkomendasikan untuk sintesis kode umum adalah:

α=0.1β=0.1γ=0.4δ=0.4\alpha = 0.1 \quad \beta = 0.1 \quad \gamma = 0.4 \quad \delta = 0.4

Ini memberikan total bobot 80% pada karakteristik struktural dan logis dari kode, alih-alih hanya tumpang tindih token n-gram.

Kesimpulan

CodeBLEU mewakili langkah maju yang besar dari pencocokan teks sederhana (BLEU) dan pemeriksaan logika kaku (Perfect Accuracy). Dengan menggabungkan weighted n-grams, pencocokan subtree AST, dan pemeriksaan ketergantungan data-flow, metrik ini memberikan penilaian yang lebih holistik dan selaras dengan manusia untuk mengevaluasi model sintesis kode.

Metrik ini dapat mempercepat pengembangan agen penghasil kode yang lebih andal dan logis secara matematis.

References

1. Shuo Ren and Daya Guo and Shuai Lu and Long Zhou and Shujie Liu and Duyu Tang and Neel Sundaresan and Ming Zhou and Ambrosio Blanco and Shuai Ma (2020). CodeBLEU: a Method for Automatic Evaluation of Code Synthesis. arXiv preprint arXiv:2009.10297.
2. Kishore Papineni and Salim Roukos and Todd Ward and Wei-Jing Zhu (2002). BLEU: a method for automatic evaluation of machine translation. Proceedings of the 40th annual meeting of the Association for Computational Linguistics.
3. Chen, Mark and Tworek, Jerry and Jun, Heewoo and Yuan, Qiming and Pinto, Henrique Ponde and Kaplan, Jared and Edwards, Harri and Burda, Yuri and Joseph, Nicholas and Brockman, Greg and others (2021). Evaluating Large Language Models Trained on Code. arXiv preprint arXiv:2107.03374.
4. Austin, Jacob and Odena, Augustus and Nye, Maxwell and Bosma, Maarten and Michalewski, Henryk and Miranda, David and Lau, Nathan and Peng, Charles and Sutton, Charles and Huybrechts, Sebastien (2021). Program Synthesis with Large Language Models. arXiv preprint arXiv:2108.07732.