Siz Claude Code-a tanımadığınız bir layihəni verdiniz və belə cavab aldınız: "Tarixçə brauzerdə saxlanılır, son 100 qeydi qoruyur və səhifə yenidən yüklənəndən sonra bərpa olunur". Bu, həmin cümləni README-yə köçürmək üçün kifayət qədər konkret səslənir. Amma əvvəlcə cavabın əsaslandığı mənbələrə baxmaq lazımdır.

Belə bir nəticəni araşdıraq: tələbi suallara çevirək, kodun qısa bir hissəsini oxuyaq və işə salanda hansı davranışı yoxlamaq lazım olduğunu müəyyənləşdirək. Sonda nəyin işlədiyini, nəyin isə hələ yoxlanmalı olduğunu göstərən qısa hesabatımız olacaq.

Bütün layihəyə baxış əvəzinə bir tələb

Haiku 50 açar sözlərə əsasən üçmisralı şeirlər yaradan kiçik tətbiqdir. İstifadəçi dili seçir, mətn alır və öz generasiyalarının tarixçəsini görür. Nümunəmiz üçün bir tələb kifayətdir: brauzerdə son 100 generasiya saxlanmalıdır və səhifə yenidən yüklənəndən sonra da əlçatan olmalıdır.

Haiku 50 üçün illüstrasiya. Aşağıda tətbiqin davranışını kod və ssenarilər əsasında araşdıracağıq.

Burada Haiku 50 təlim nümunəsi kimi verilib. Kod və agentin cavabları araşdırma üçün hazırlanıb; gözlənilən davranışı koddan çıxarırıq. Layihənin orijinal arxivini yoxlamırıq. Lazım olan hər şey məqalədə var: tətbiqi endirmək, API açarı almaq və generasiyanı işə salmaq lazım olmayacaq.

"Burada hər şeyin necə işlədiyini izah et" demək əvəzinə üç sual verək. Yeni generasiya yaddaşa yazılırmı? Tətbiq növbəti açılışda saxlanmış məlumatı oxuyurmu? Qeydlərin sayı yüzü keçəndə nə baş verir?

Claude Code-a ilk sorğu belə ola bilər:

Yalnız generasiya tarixçəsini araşdır. Hələlik kodu dəyişmə.
Yeni şeirin alınmasından onun saxlanmasına qədər olan yolu tap,
sonra səhifənin açılmasından tarixçənin göstərilməsinə qədər olan yolu izlə.
Saxlanmış qeydlərin sayının harada məhdudlaşdırıldığını yoxla.
Hər nəticə üçün faylı, sətirləri və qısa fraqmenti göstər.
Ayrıca, işə salmaqla yoxlanmalı olanları sadala.

Belə sorğu axtarış sahəsini aydınlaşdırır. Agent tarixçənin başqa faylla əlaqəli olduğunu tapsa, onu niyə oxumaq lazım gəldiyini izah edə bilər. Bütün tətbiqin uzun təsvirindənsə bir neçə vacib yeri yoxlamaq sizin üçün daha asan olacaq.

Fayla keçid onu oxumağı əvəz etmir

Təlim üçün history.js faylını təsəvvür edin. Generasiya uğurla başa çatdıqdan sonra interfeys addToHistory(item) funksiyasını çağırır, renderHistory isə yalnız ötürülmüş siyahını göstərir. Bu nümunədə tarixçəni idarə edən başqa funksiya yoxdur.

const STORAGE_KEY = "haiku-history";
let history = [];

function addToHistory(item) {
  history.unshift(item);
  localStorage.setItem(STORAGE_KEY, JSON.stringify(history));
  renderHistory(history.slice(0, 100));
}

function startHistory() {
  renderHistory(history);
}
startHistory();

Bu hissəni anlamaq üçün məlumatın saxlandığı iki yeri fərqləndirmək kifayətdir. history massivi açıq səhifənin operativ yaddaşında qalır. localStorage saytın məlumatlarını brauzerdə, səhifəni yenidən açanda da saxlayır; tətbiq məlumatı ora ayrıca yazır və geri oxuyur. localStorage yaddaşı protokola, host-a və porta bağlıdır, ona görə yoxlama zamanı eyni ünvan və brauzer profilindən istifadə etmək lazımdır. Bu davranış localStorage sənədlərində təsvir olunur.

Tutaq ki, agent belə cavab verdi:

Tarixçə son 100 generasiyanı saxlayır və səhifə yenidən
yüklənəndən sonra bərpa olunur. Əsas: history.js:4-13,
localStorage və slice(0, 100) istifadə olunur.

Faylın yolu və sətirlər göstərilib. İndi onların bütün iddianı təsdiqləyib-təsdiqləmədiyini yoxlayaq. Təlim faylında ilk sətir const STORAGE_KEY ilə başlayır; boş sətirlər də nömrələnir.

  • 5-ci sətirdəki history.unshift(item) yeni qeydi massivin əvvəlinə əlavə edir;
  • 6-cı sətirdə localStorage.setItem çağırışı bütün massivi yaddaşa yazır. JSON-a çevirmə onu sətir kimi saxlamaq üçün lazımdır;
  • 7-ci sətirdəki renderHistory(history.slice(0, 100)) ekrana ilk 100 elementi ötürür. slice yeni massiv yaradır, ilkin massivi qısaltmır; bunu metodun sənədləri də izah edir;
  • başlanğıcda 2-ci sətirdəki let history = [] boş massiv yaradır, startHistory funksiyası və 10-13-cü sətirlərdəki çağırışı isə onu ekrana ötürür. Burada yaddaşdan oxuma yoxdur.

Kodu oxuyandan sonra nəticə dəyişir: tarixçəni yazmaq nəzərdə tutulub və ekranda göstərilən qeydlərin sayı yüzlə məhdudlaşır. Bu versiyada başlanğıcda bərpa yoxdur, saxlanan qeydlərin sayına məhdudiyyət də tapılmadı.

Real layihədə bu hissə yetərli olmaya bilər: məlumatların yüklənməsi başqa modula çıxarıla bilər. Ona görə agentdən bunu dəqiqləşdirmək faydalıdır: "Bu açarın oxunduğu və yazıldığı bütün yerləri, eləcə də bu funksiyaları kimin çağırdığını göstər". Təlim nümunəmizdə əhatə dairəsi bəllidir, davam edə bilərik.

Səhifə yenidən yüklənəndən sonrakı davranışı yoxlayaq

Kodu oxumaq uyğunsuzluğu harada axtarmaq lazım olduğunu göstərdi. İndi müşahidə şərtlərini müəyyənləşdirək. Səhifə brauzerin adi profilində eyni ünvanda açılıb, yaddaşa yazmağa icazə var, tarixçə isə başlanğıcda boşdur. Təlim ssenarisinə asan tanınan A işarəli bir uğurlu generasiya daxil olur; addımlar arasında kod dəyişmir.

Aşağıda koddan çıxarılan gözlənilən ssenari var. Daha bir addım əlavə edək: səhifə yenidən yüklənəndən sonra B adlı yeni qeyd alaq.

AddımEkranda gözlənilənhaiku-history açarı üzrə yaddaşda gözlənilən
Boş tarixçəsi olan səhifəni açdıqBoş siyahıQeyd yoxdur
A generasiyasını əlavə etdikBir A qeydiA qeydi olan massiv
Eyni səhifəni yenidən yüklədikBoş siyahıA qeydi olan massiv qaldı
Yenidən yükləyəndən sonra B generasiyasını əlavə etdikYalnız B qeydiYalnız B olan massiv; A qeydi əvəzləndi

Real müşahidə üçün yaddaşın məzmununa brauzerin developer tools-da, sayt məlumatlarının saxlandığı bölmədə baxmaq olar. Konkret açarın dəyərini açıb qeydi indicə əlavə etdiyiniz məlumatla müqayisə edin. Ekrandakı boş siyahı təkbaşına kifayət etmir.

"Yenidən yükləyəndən sonra hər şey silindi" demək dəqiq olmazdı. Məlumat yaddaşda qalıb, amma tətbiq onu oxumayıb. Bu reallaşdırmada zəncir saxlanmış sətirlə ekrana ötürülən massiv arasında qırılır.

Növbəti əlavə bu xətanın nəticəsini göstərir. Səhifə yenidən yüklənəndən sonra operativ yaddaşdakı massiv boşdur, ona görə yalnız B ora düşəcək və localStorage.setItem saxlanmış tarixçəni bir qeyddən ibarət massivlə əvəz edəcək. Tələbə görə B və A qalmalı idi, kodda isə yalnız B qalacaq. Problem həm tarixçənin göstərilməsinə, həm də onun saxlanmasına aiddir.

Kod üzrə nəticəni belə yaza bilərsiniz: "startHistory-də saxlanmış tarixçənin oxunması yoxdur; növbəti əlavə əvvəlki qeydləri əvəz edəcək". İşə salanda davranışı təsdiqləmək üçün dörd addımın hamısını keçin və hər addımdan sonra ekrandakı siyahını yaddaşın məzmunu ilə müqayisə edin.

100 qeyd həddini yoxlayaq

Bərpa məsələsini aydınlaşdırdıq. Tələbin digər hissəsi qalıb: son 100 generasiyanı saxlamaq. Bu həddi bir qeydlə yoxlamaq olmur.

Tarixçənin boş olduğu ayrıca ssenari götürək. Səhifəni yenidən yükləmədən, 1-dən 101-ə qədər işarələnmiş 101 hazır qeydi eyni əlavəetmə funksiyasına ardıcıl ötürək. Tarixçənin özünü yoxlamaq üçün generatordan 101 sorğu göndərməyə ehtiyac yoxdur: hazır qeyd alındıqdan sonrakı davranış maraqlıdır.

Yeni qeyd massivin əvvəlinə düşür. Buna görə sonuncu əlavəetmədən sonra ekranda 101-dən 2-yə qədər işarələr, cəmi 100 qeyd olacaq. Amma saxlama sətrinə tam massiv ötürülüb: yaddaşda 101-dən 1-ə qədər işarələr, cəmi 101 qeyd qalacaq. Həm qeydlərin sayını, həm də tərkibini yoxlayın. Yoxsa tətbiqin son qeydlər əvəzinə ən köhnələri saxladığını gözdən qaçıra bilərsiniz.

Agentin cavabı məhz burada həddən artıq ümumi oldu. Kodda 100 rəqəmi doğrudan da var, amma bu, göstərilən qeydlərə aiddir. Kod üzrə dəqiq nəticə belədir: "İnterfeys son 100 qeydi göstərir; nümayiş etdirilən ssenaridə yaddaşda 101 qeyd var, buna görə saxlanmış tarixçənin həcminə dair tələb yerinə yetirilmir".

Ssenari tətbiqin hansı hissəsini yoxlayır

Hazırlanmış qeydlərlə tarixçəni ayrıca yoxlamaq mümkündür. Onlar generasiya xidmətinin əlçatanlığı, şeirlərin keyfiyyəti və ya seçilmiş dilin ötürülməsi barədə heç nə demir. Bu tələblər üçün ayrıca ssenarilər lazımdır.

Qısa hesabat hazırlayaq

Araşdırmanın nəticəsini layihənin yanında saxlamaq rahatdır ki, sabah dialoqu yenidən oxumaq lazım gəlməsin. Nümunədə faylı HANDOFF_REVIEW.md adlandıraq. Adı şərtidir; əsas odur ki, qeyddən yoxlamanın gedişini bərpa etmək mümkün olsun.

Təlim kodunun oxunması üzrə hesabat belə görünür. Gözlənilən davranış sahəsi işə salanda nə axtarmaq lazım olduğunu göstərir:

Əhatə dairəsi: generasiya tarixçəsi, məqalədəki history.js təlim versiyası.
Araşdırma üsulu: təlim fraqmentinin oxunması.
Brauzerdə sınaq aparılmayıb.

Tələb: brauzerdə son 100 generasiyanı saxlamaq
və səhifə yenidən yüklənəndən sonra göstərmək.

Kod üzrə:
- history.js:6, localStorage.setItem bütün massivi yazır;
- history.js:7, renderHistory(history.slice(0, 100)),
  yalnız ekranda göstərilənləri məhdudlaşdırır;
- history.js:10-13, startHistory və onun çağırışı,
  saxlanmış məlumatı oxumadan göstərməni başladır.

Kod üzrə gözlənilən davranış:
- A qeydi əlavə ediləndən sonra ekranda və yaddaşda görünəcək;
- səhifə yenidən yüklənəndən sonra A yaddaşda qalacaq, siyahı boş olacaq;
- yenidən yükləyəndən sonra B əlavə etmək saxlanmış tarixçəni əvəz edəcək:
  B və A əvəzinə yalnız B qalacaq;
- boş vəziyyətdən 101 əlavəetmə olan ayrıca ssenaridə
  ekranda 100 qeyd (101..2), yaddaşda isə 101 (101..1) olacaq.

Kod üzrə uyğunsuzluqlar: başlanğıcda bərpa yoxdur,
buna görə növbəti əlavə əvvəlki tarixçəni əvəz edəcək;
saxlanmış tarixçə son 100 qeydlə məhdudlaşmır.

Yoxlanmayıb: generatorun işi, yaddaşa yazma xətaları,
bir neçə brauzer tabında eyni vaxtda işləmə.

Növbəti addım: hər iki ssenarini təkrarlamaq və müşahidələri qeyd etmək.
Sonra başlanğıcda oxumağı və saxlanan massivə qoyulan həddi düzəldib,
eyni ssenariləri yenidən yoxlamaq.

Öz hesabatınızda "təlim versiyası" əvəzinə yoxladığınız layihə versiyasını göstərin, məsələn commit-i və commit edilməmiş dəyişikliklərin olub-olmadığını. İşə salandan sonra ayrıca "Faktiki müşahidələr" sahəsi əlavə edin və nəticələri, yaxud əl ilə etdiyiniz addımların qeydini qoşun. Onları gözlənilən davranışla müqayisə edin; işə salmaq mümkün olmayıbsa, sahəni uyğun qeydlə boş saxlayın. Burada bütün ilkin məlumatlar məqaləyə yerləşir; böyük layihədə yoxlamanı təkrarlamaq üçün sətirlərə keçidlər təkbaşına yetməz.

Belə hesabat agentə növbəti tapşırığı verməyə kömək edir. Artıq onun qarşısında "tarixçəni daha etibarlı et" xahişi yox, iki konkret uyğunsuzluq var. Hansı nəticələrə gəlmək üçün hələ tez olduğu da görünür.

Nəticəni özünüz yoxlayın

Eyni təlim nümunəsinə tarixçəni təmizləyən düymə əlavə edilib. Onun emalçısı belədir:

function clearHistory() {
  history = [];
  renderHistory(history);
}

Düyməni basmazdan əvvəl siyahıda və yaddaşda A qeydi var idi. Basandan sonra siyahı boşaldı. Agent belə yazdı: "Düymə saxlanmış tarixçəni tamamilə silir".

Hansı nəticə təsdiqlənir: tarixçə ekrandan itdimi, qeyd localStorage-dən silindimi, yoxsa hər ikisi? Bundan sonra nəyi yoxlamaq lazımdır? İzahı oxumazdan əvvəl cavab verməyə çalışın.

İzah

Siyahının ekrandan itməsi təsdiqlənib. Koddan operativ yaddaşdakı massivin sıfırlandığı da görünür. Ancaq emalçı localStorage-i dəyişmir, şərtə görə renderHistory yalnız siyahını çəkir, buna görə A yaddaşda qalır.

Növbəti yoxlama - düyməni basandan dərhal sonra haiku-history açarının dəyərini oxumaqdır. Tarixçənin bərpası reallaşdırılandan sonra silinmiş qeydlərin geri qayıtmadığına əmin olmaq üçün səhifəni yenidən yükləmək də faydalıdır. İlkin versiyada təkcə yenidən yükləmək kömək etməzdi: o, təmizləmə olmadan da başlanğıcda boş siyahı göstərir. Yoxlamaya belə gözə çarpmayan bir maneə.

Claude Code-a belə tapşırıqları necə vermək olar

İş layihəsində növbəti qərarınıza təsir edən bir iddiadan başlayın. Məsələn, tarixçədən istifadə etmək olarmı, yoxsa əvvəlcə onun bərpasını düzəltmək lazımdır? Agentdən mənbəni açıb nəticəni yoxlamağı asanlaşdıran formatda cavab istəyin:

Bu iddianı yoxla: [tətbiqin konkret davranışı].
Əvvəlcə bununla əlaqəli faylları tap və lazım olan yerləri oxu.
Hələlik kodu dəyişmə.

Bunları qaytar:
1. Kodla nə təsdiqlənir: fayl, sətirlər, qısa fraqment.
2. İşə salanda davranışı yoxlayan ssenari.
3. Faktiki olaraq nə icra olunub və nə müşahidə edilib.
4. Dəqiq nəticə və hələ bilinməyən məqamlar.

İşə salmaq mümkün deyilsə, bunu açıq yaz.
Təklif olunan ssenarini yerinə yetirilmiş yoxlama kimi göstərmə.

Cavabdan sonra əsas nəticənin mənbələrini açın, müşahidəni tələblə müqayisə edin və yalnız bundan sonra nəticəni qeydlərə və ya sənədlərə köçürün. Mənbələr kifayət etmirsə, növbəti sorğu aydındır: tarixçənin haradan oxunduğunu tapmaq, açarın dəyərini yoxlamaq, 101 qeydlə ssenarini təkrarlamaq. Beləcə araşdırma kiçik və yoxlanıla bilən addımlarla irəliləyir.

Funksiyanın adı barədə sadə sual üçün kod keçidi kifayətdir. Cavab məlumatların saxlanmasını, bərpasını və ya ölçü həddini əhatə edirsə, uyğun davranışı başdan sona izləmək faydalıdır. Yoxlamanın həcmi irəli sürmək istədiyiniz iddiadan asılıdır.