ИТ развој

Beyond the Prompt: Architecting Software AI Truly Learns From

Надвор од поттикот: Архитектура на софтвер од кој ВИ навистина учи

Најважниот потсетник во инженерски работен тек со помош на ВИ често е оној што никој не го пишува. Тоа е акумулираниот потсетник отелотворен во складиштето: неговото именување, тестови, шеми, граници, датотеки за распоредување, ракување со грешки и историја на одлуки.

ВИ може да генерира уверлив код од кратко барање. Дали тој код ќе стане безбедна промена зависи од тоа што го учи околниот софтвер. Кодна база со слаби граници и двосмислени конвенции го претвора секое барање во нагаѓање. Кодна база што ја прави намерата видлива им дава многу подобра почетна точка и на луѓето и на ВИ.

Ова не е аргумент за секое складиште да се прави формално. Ова е аргумент важните вистини да бидат лесни за откривање и тешки за противречење.

Софтверот е материјал за обука под маска

Кога инженер отвора непозната PHP услуга, брзо бара обрасци: каде влегуваат барањата, како се врши валидацијата, како се прават промени во базата на податоци, каде живеат деловните правила и како се пријавуваат неуспесите. Алатките за ВИ прават многу слично. Тие извлекуваат конвенции од блиските примери, дури и кога тие примери се случајни или застарени.

Тоа ја прави недоследноста поскапа отколку што првично изгледа. Ако една крајна точка користи објекти за барања, друга чита директно од глобални променливи, а трета меша валидација со перзистирање, нема сигурен локален преседан. Генерираното решение може да работи, но помала е веројатноста дека ќе припаѓа таму.

Корисните складишта го изложуваат својот архитектонски речник. Развивачот треба да може да одговори на неколку основни прашања без обратен инженеринг на целата апликација:

  • Каде HTTP-влезот станува валидирани податоци за апликацијата?
  • Кој слој ги поседува деловните правила?
  • Како се дефинираат и повторуваат трансакциите во базата на податоци?
  • Кои грешки смеат да ја преминат границата на API?
  • Како се конфигурира услугата локално и при распоредување?

На овие одговори не им е потребен голем архитектонски документ. Треба доследно да бидат претставени во кодот, тестовите и мала количина фокусирана документација.

Направете ги границите очигледни

ВИ е особено ефикасна кога задачата има јасен спој. „Додај поле за статус“ е нејасно кога контролерите, пребарувањата, серијализацијата и авторизацијата се испреплетени. Станува изводливо кога системот ги одделува транспортните грижи од операциите на апликацијата и деталите за перзистирање.

Разгледајте операција за потврдување на нарачка. Контролерот треба да преведе HTTP-барање во повик до услуга на апликацијата. Услугата треба да го спроведе значајното правило: нарачката може да се потврди само од дозволена состојба. Складиште или слој за перзистирање треба да се занимава со складирањето. Секој дел ѝ дава на идната промена потесно, посигурно место каде да се вклопи.

final class ConfirmOrder
{
    public function __construct(
        private OrderRepository $orders,
    ) {
    }

    public function handle(OrderId $id): void
    {
        $order = $this->orders->get($id);

        $order->confirm();

        $this->orders->save($order);
    }
}

Примерот е намерно мал. Неговата вредност не е во бројот на класи; туку во видливото сопствеништво на правилото. Ако потврдувањето бара и настан за ревизија, проверка на плаќање или трансакција, операцијата има очигледен дом.

Не создавајте слоеви само за да задоволите дијаграм. Создавајте ги таму каде што промената на една грижа не треба да бара разбирање на секоја друга грижа. Најдобрата архитектура често е помалку за апстракција, а повеќе за намалување на бројот места што читателот мора да ги држи во глава.

Тестовите се извршлива намера

Тестовите се меѓу најсилните сигнали што системот може да ги даде. Тие му кажуваат на одржувачот што мора да остане вистинито кога се менуваат деталите на имплементацијата. За работа со помош на ВИ, тие исто така даваат примери за фикстури, именување, очекувани неуспеси и претпочитаното ниво на покриеност со тестови.

Тест што само потврдува успешен HTTP-статус е корисен, но нецелосен. Добро избран тест ја изразува деловната последица и граничниот услов што не смее тивко да се олабави.

public function test_an_already_confirmed_order_cannot_be_confirmed_again(): void
{
    $order = Order::confirmed(OrderId::fromString('order-123'));

    $this->orders->save($order);

    $this->expectException(OrderAlreadyConfirmed::class);

    $this->confirmOrder->handle($order->id());
}

Таквите тестови прават јасна клучна разлика: неуспехот е дел од договорот, а не срамен исклучок што треба да се скрие. За API-ја, пренесете ја таа прецизност до границата. Дефинирајте како неуспесите во доменот стануваат стабилни кодови и тела на одговори, и тестирајте го тоа мапирање таму каде што е важно.

Одржувајте ги тестовите доволно читливи за да бидат поучни. Претерано умните помошници за тестови може да намалат пишување, а притоа да го замаглат сценариото. Краток тест треба да открие што е важно без да бара обиколка низ рамка за фикстури.

Нека базата на податоци ги искаже своите правила

Валидацијата во апликацијата е неопходна, но не е последниот авторитет за интегритетот на податоците. Истовремени барања, задачи во заднина, рачни скрипти и идни кодни патеки може да ги заобиколат претпоставките направени во еден метод на услуга. Важните инваријанти треба да се спроведуваат на ниво на база на податоци кога базата може да ги изрази.

Користете соодветни типови, надворешни клучеви, ограничувања за уникатност и колони што не смеат да бидат null за невалидните состојби тешко или невозможно да се складираат. Третирајте ги миграциите како продукциски код: подредени, прегледливи, повратни кога е практично и безбедни за големината и сообраќајните карактеристики на табелата.

Ограничување за уникатност, на пример, не е заменливо со проверка за постоечки ред пред внесување. Проверката може да се судри. Ограничувањето ја разрешува судирната состојба; апликацијата потоа треба намерно да се справи со настанатиот конфликт.

Промените во шемата, исто така, ги учат идните одржувачи на системот. Миграција именувана според деловната промена и јасно именувано ограничување кажуваат повеќе отколку што некогаш би кажала генеричка измена.

Документирајте го оперативниот договор

Кодот објаснува како функционира одлика. Оперативната документација објаснува како таа преживува допир со средина. Тука многу инаку чисти услуги стануваат тешки за безбедно менување.

Корисен README или водич за услуга треба да одговори на практични прашања: потребни променливи на средината, чекори за локално стартување, команди за тестирање, постапка за миграција на базата на податоци, зависности од редици или распоредувач и очекувања за проверка на здравјето. Чувајте го близу до услугата и ажурирајте го со промени што го менуваат оперативниот модел.

Конфигурацијата заслужува посебна грижа. Претпочитајте експлицитни променливи на средината и валидирана конфигурација наместо расфрлани повици до пристапувачи за средината. Чувајте ги тајните надвор од складиштето, но документирајте ја целта, форматот и безбедната развојна стандардна вредност на секое поставување, кога постои таква.

docker compose up --build
docker compose exec app php artisan migrate
docker compose exec app php artisan test

Командите како овие се вредни само кога ги одразуваат вистинските алатки на проектот. Застарена команда е полоша од никаква команда затоа што создава лажна сигурност. Третирајте ја развојната средина како дел од производот што инженерите го користат за да го изградат производот.

Дизајнирајте за преглед, не само за генерирање

ВИ може да го забрза првиот нацрт, но прегледот останува моментот во кој промената стекнува доверба. Структурирајте ја работата така што прегледувачот може да ја испита по слоеви: API-договорот, правилото на апликацијата, промената на податоците, тестовите и оперативниот ефект.

Малите, кохезивни промени го олеснуваат ова. Барање за повлекување што комбинира нова крајна точка, широко рефакторирање, преименувани конвенции и преработка на Docker им дава на прегледувачите премногу подвижни делови. Дури и точниот код станува тешко да се провери кога каузалноста е закопана.

Добрата хигиена на складиштето помага тука: значајни пораки за commits, фокусирани разлики, јасни застарувања и отстранување на застарените патеки откако миграцијата ќе заврши. Овие не се козметички навики. Тие се сигнали што ги разликуваат тековните конвенции од историските остатоци.

Потсетникот што го одржувате секој ден

Тимовите често прашуваат како да пишуваат подобри потсетници за ВИ. Тоа е корисно, но потрајното прашање е како да се изгради софтвер што се објаснува самиот. Јасните граници, извршливите тестови, спроведените правила за податоци и искрената оперативна документација ги подобруваат резултатите пред некој да отвори алатка за ВИ.

Добивката е поширока од генерирањето код. Новите инженери побрзо се воведуваат. Прегледите стануваат попрецизни. Инцидентите полесно се дијагностицираат. Рефакторирањето носи помалку страв затоа што системот наведува што има намера да зачува.

На крајот, ВИ не ја учи вашата архитектура од слоган. Таа учи од изборите што вашиот софтвер ги повторува. Направете ги тие избори доволно јасни за следниот инженер, човек или со машинска помош, да може да го прошири системот без да мора да нагаѓа што се обидувал да стане.

Портрет на автор на блогот

Mihajlo

Јас сум Михајло - развивач поттикнат од љубопитност, дисциплина и постојаната желба да создадам нешто значајно. Споделувам увиди, упатства и бесплатни услуги за да им помогнам на другите да ја поедностават својата работа и да растат во постојано развивачкиот свет на софтверот и вештачката интелигенција.