Системска архитектура за ВИ: Градење бекенд-системи што поучуваат
Бекендот прави повеќе од обработка на барања. Тој го учи секој развивач што ќе го допре што цени системот: дали грешките се безбедни за постапување, дали границите се реални, дали податоците имаат сигурно значење и дали промената е рутина или причина за страв.
Ова е уште поважно кај производите со овозможена ВИ. ВИ-функција често пристигнува како мало барање — испрати промпт, зачувај одговор, прикажи одговор — но внесува неизвесност, асинхрона работа, скапи зависности и нови прашања за приватноста. Бекенд што ова го третира како „само уште еден API повик“ има тенденција да ја рашири сложеноста насекаде. Бекенд со јасна архитектура го учи тимот како да се справува со неизвесноста без да го нормализира хаосот.
Направете архитектурата сама да се објаснува
Добрата архитектура не е дијаграм зачуван во заборавена папка. Таа е збирот одлуки што остануваат видливи во кодот, интерфејсите, ограничувањата во базата на податоци, логовите и конфигурацијата за распоредување.
Започнете со одвојување на тоа што го прави системот од тоа како работат надворешните услуги. Контролерот треба да преведе HTTP барање во апликациска акција. Апликацискиот слој треба да ги координира правилата и перзистентноста. Интеграцискиот слој треба да комуницира со ВИ-провајдер, редица, услуга за е-пошта или складиште за објекти. Тоа одвојување не е формалност; спречува деталите специфични за провајдерот да станат јазик на целата апликација.
final class GenerateSummaryController
{
public function __invoke(Request $request, GenerateSummary $action): JsonResponse
{
$result = $action->handle(
documentId: $request->input('document_id'),
requestedBy: $request->user()->id,
);
return response()->json($result, 202);
}
}
Контролерот не одлучува кој модел да се повика, колку повторни обиди се прифатливи или каде припаѓа резултатот. Тие одлуки се наоѓаат зад акција на апликациско ниво. Тоа ја прави патеката на барањето читлива: побарано е резиме, барањето е прифатено и работата ќе продолжи на друго место.
Дизајнирајте API-ja што го откриваат вистинскиот работен тек
Работата со ВИ често е бавна, подложна на грешки и со променливо траење. Преправањето дека не е така создава кршливи API-ja со модел барање-одговор и лоши очекувања кај корисниците. Ако генерирањето може да трае подолго од типично веб-барање, моделирајте го како задача.
Практичниот тек е едноставен:
- Валидирајте го барањето и авторизирајте пристап до изворниот материјал.
- Создадете запис во базата на податоци со статус како
pending. - Ставете ја работата за генерирање во редица.
- Вратете
202 Acceptedсо идентификатор и крајна точка за статус. - Ажурирајте го записот на
completedилиfailed.
Овој дизајн ги учи потрошувачите на API дека завршувањето е набљудлива состојба, а не претпоставка. Исто така, им дава на оперативните тимови нешто конкретно што можат да го проверат кога зависност ќе откаже.
interface TextGenerator
{
public function summarize(string $source): GeneratedText;
}
Одржувајте го интерфејсот фокусиран на способноста што ѝ е потребна на вашата апликација. Избегнувајте да протекуваат објектот за барање на провајдерот, името на моделот или структурата на одговорот во контролерите и кодот на доменот. Адаптерот за провајдерот може да ги преведе тие детали на работ. Ако се смени моделот, радиусот на влијание треба да биде мал и очигледен.
Идемпотентноста заслужува ист третман. Повторување од клиентот, повторување во редицата и повторно испраќање на webhook се вообичаени настани. Онаму каде што дупликат би бил штетен, прифатете клуч за идемпотентност или користете трајно правило за единственост. „Веројатно нема да биде испратено двапати“ не е својство на системот.
Нека базата на податоци носи дел од вистината
Базите на податоци често се третираат како пасивно складиште. Во издржлив бекенд, тие наметнуваат важни факти. Странските клучеви, ограничувањата за единственост, колоните што не дозволуваат null, трансакциите и внимателно избраните индекси го отежнуваат создавањето невалидни состојби.
За генерирана содржина, зачувајте доволно контекст за подоцна да го разберете резултатот: верзијата или идентификаторот на изворот, побараната операција, статусот, временските ознаки и референца до излезот. Не зачувувајте небрежно секој суров промпт, одговор или товар што содржи акредитиви. Задржувањето податоци е архитектонска одлука, а не погодност за логирање.
Користете ги премините меѓу статусите намерно. Записот не треба тивко да премине од pending во completed ако worker никогаш не ја примил задачата. Можеби ќе му треба меѓусостојба processing, причина за неуспех безбедна за клиентот и оперативни детали зачувани одделно. Целта не е голема машина на состојби; туку вистинита.
Ограничете ги ненадежните зависности
Надворешните ВИ-услуги може да истечат по време, да одбијат барања, да вратат неправилно форматиран излез или привремено да станат недостапни. Апликацијата треба да прави разлика меѓу барање што може повторно да се обиде и такво што не може.
Поставете експлицитни временски ограничувања за поврзување и за вкупното траење. Повторувајте само неуспеси што веројатно се привремени и ограничете го бројот на обиди. Политика за повторни обиди без ограничувања претвора инцидент кај провајдерот во заостаток во редицата. Временско ограничување без патека за опоравување претвора минлив проблем во мистерија видлива за корисникот.
Валидирајте го генерираниот излез пред да го објавите во системите надолу по текот. Ако интеграцијата очекува структурирани податоци, валидирајте ја структурата и задолжителните полиња. Третирајте го генерираниот текст како недоверлив влез сè додека не ги помине истите проверки за авторизација, екранување и деловни правила што се применуваат на секој друг надворешен влез.
Најкорисната граница во ВИ-бекенд често е онаа што спречува неизвесноста тивко да стане податок.
Користете Docker за да ги направите видливи претпоставките за извршување
Контејнерите се вредни кога го прават локалниот развој, тестовите и распоредувањето поконзистентни. Помалку се корисни кога само кријат сложено опкружување за извршување зад една команда.
Контејнерот за PHP-услуга треба јасно да ги декларира своите потреби при извршување: верзијата на PHP, потребните екстензии, инсталацијата на зависности, корисник за извршување што не е root каде што е соодветно и командата што го стартува процесот. Одделете ги апликациските услуги од придружните услуги, како база на податоци, кеш или worker за редица. Веб-процесот и worker-от за редица може да делат слика, но обично имаат различни команди и начини на откажување.
Конфигурацијата треба да влегува преку поставки специфични за околината, додека валидацијата се случува при стартувањето. Недостигот на задолжителна конфигурација треба јасно да откаже, наместо да произведе делумна услуга што откажува при првото вистинско барање. Чувајте ги тајните надвор од сликите, контролата на изворниот код и вообичаените логови на апликацијата.
Мерете го однесувањето, не само достапноста
HTTP одговор 200 не е доказ дека бекендот е здрав. За асинхрони ВИ-работни текови, корисни сигнали вклучуваат длабочина на редицата, старост на задачите, стапка на завршување, категории на неуспех, латентност на провајдерот и број на повторни обиди. Логовите треба да вклучуваат стабилни идентификатори како ID на барање, ID на задача и ID на ресурс, за да може инцидентот да се следи низ услугите.
Бидете внимателни со податоците за набљудливост. Логирањето на целосни промптови или генерирани излези може да открие информации за клиентите. Запишувајте ги метаподатоците потребни за дијагностика, редактирајте ги чувствителните полиња и намерно доделувајте пристап до деталните логови.
Градете системи што луѓето можат безбедно да ги менуваат
Одржливоста не се постигнува со избор на модерен framework или со исцртување повеќе слоеви. Таа доаѓа од тоа следната промена да не биде изненадувачка. Развивачот треба да може да одговори: каде влегува ова барање, кое правило ја поседува оваа одлука, кои податоци се менуваат, што се случува ако зависноста откаже и како ќе знаеме?
Така изгледа бекенд што учи. Неговите интерфејси ја соопштуваат намерата. Неговата база на податоци ги штити инваријантите. Неговите задачи ја признаваат реалноста. Неговите контејнери ги откриваат претпоставките. Неговите неуспеси оставаат корисни докази. Кога системот ги прави тие работи доследно, тој не само што поддржува ВИ-функција — туку му помага на целиот тим да ја изгради следната со подобра проценка.