Wskazówki praktyczne: Agenci AI kontra tradycyjne aplikacje backendowe: co tak naprawdę
Praktyczne wskazówki: Agenci AI kontra tradycyjne aplikacje backend – co faktycznie istnieje: umowy, sprawdzania oraz gotowe miejsca na kod dla zespołów wdrażających ten wzorzec.
Niech to służy jako wersja przeznaczona dla operatorów, zawierająca zasady przedstawione w artykule „AI Agents vs Traditional Backend Applications: What’s Actually Different?”: wyraźne etapy, uporządkowane sekcje kodu oraz notatki dotyczące przywracania stanu po przeniesieniu obowiązków. Etap Przeglądu działa najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny poufnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
1. Liniowe pipeline’y vs. Pętla rozumowania
Dla 1 liniowego pipeline w porównaniu z etapem należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. W przypadku, gdy następnym krokiem jest kod lub wywołanie narzędzia, należy preferować ustrukturyzowane wyniki z walidacją schematu zamiast tekstów w formie swobodnej.
Klasyczne backendy: statyczny DAG
Dla tradycyjnych backendów na etapie statycznym należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy dany krok zawiedzie, powinno to wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Zastosowanie ludzkiej aprobaty jest konieczne w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności biznesowej.
[Request] ──> [Validate Input] ──> [Database Query] ──> [Transform Data] ──> [Response]
│
└── (Invalid) ──> [Return 400]
Agenci AI: Pętla ReAct
Dla agentów AI w fazie ReAct należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań. Wprowadź ludzką aprobatę dla operacji, które wiążą się z wydawaniem pieniędzy lub modyfikacją danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności biznesowej. Dla agentów AI w fazie ReAct należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
┌────────────────────────┐
▼ │
[Objective] ──> [LLM Evaluates State] │
│ │
Does it need more info? │
├── Yes ──> [Select Tool & Arguments]
│ │
│ [Execute Tool] ────────┘
│ (API, DB, Search)
│
└── No ──> [Return Final Answer]
2. Konkretne porównanie: automatyzacja zgłoszeń obsługi klienta
Podczas przechodzenia przez etap 2 „Konkretne porównanie”, najpierw zapisz warunki umowy: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez człowieka oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Ustal punkty kontrolne po kosztownych krokach. System powinien unikać ponownego naliczania opłat za tę samą operację LLM, gdy operator próbuje ponownie zrealizować późniejszy etap.
Tradycyjne podejście
Gdy przechodzisz przez etap „Tradycyjne podejście”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. System powinien unikać ponownego pobierania opłat za tę samą funkcję LLM, gdy operator próbuje ponownie wykonać późniejszy element.
// Traditional Backend: Strict, deterministic logic
async function handleRefund(orderId: string, customerReason: string) {
const order = await db.orders.findById(orderId);
if (!order) {
throw new NotFoundError("Order not found");
}
// Strict business rule written by an engineer
const isEligible = order.status === "DELAYED" && order.daysDelayed > 5;
if (!isEligible) {
return { status: "rejected", reason: "Delay does not meet refund criteria." };
}
const refund = await paymentGateway.refund(order.paymentIntentId);
await db.orders.update(orderId, { status: "REFUNDED" });
await emailService.sendRefundNotice(order.customerEmail);
return { status: "success", refundId: refund.id };
}
Podejście agentowe
Gdy przechodzisz przez etap The Agentic Approach, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań. Ustaw punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy przechodzisz przez etap The Agentic Approach, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
// Agent Loop: The model decides which tools to call
import { generateText, tool } from "ai";
import { z } from "zod";
const tools = {
fetchOrder: tool({
description: "Fetch order details and shipping history",
parameters: z.object({ orderId: z.string() }),
execute: async ({ orderId }) => db.orders.findById(orderId),
}),
issueRefund: tool({
description: "Issue a monetary refund to the customer",
parameters: z.object({
paymentIntentId: z.string(),
amount: z.number(),
reason: z.string()
}),
execute: async (args) => paymentGateway.refund(args.paymentIntentId, args.amount),
}),
escalateToHuman: tool({
description: "Escalate edge cases or physical damage to a support manager",
parameters: z.object({ ticketSummary: z.string() }),
execute: async ({ ticketSummary }) => supportDesk.createEscalation(ticketSummary),
})
};
// The execution is governed by an evaluation loop
const response = await generateText({
model: yourConfiguredLLM,
tools,
maxSteps: 5, // Prevents infinite execution loops
prompt: `Customer Issue: "The package arrived on time, but the driver ran over my mailbox. Order #1234."
Evaluate policy guidelines and take appropriate action.`,
});
3. Różnice architektoniczne porównawcze
Etap 3 Różnic architektonicznych porównawczych działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań przed rozszerzeniem zakresu. Zdokumentuj razem ścieżkę prawidłowego działania oraz ścieżkę przywracania. Próby ponowne, mechanizmy kontroli ludzkiej oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w formie prostych, spójnych struktur. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane w danym polu, i powodują przerwanie kontynuacji po przerwach.
4. Co dzieje się w tle: Okno kontekstowe jako pamięć cache CPU
Cztery elementy z etapu „Co się dzieje w tle” działają najlepiej, gdy traktuje się je jako mierzalną powierzchnię. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, co utrudnia kontynuację pracy po przerwach.
5. Rodzaje awarii: Dlaczego agenci są trudniejsze w utrzymaniu
5 trybów awarii – dlaczego ta etapa funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Traktuj tę etapę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wkładki nawiasowe ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po przerwach. 5 trybów awarii – dlaczego ta etapa funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą audytować bez konieczności czytania całego grafu.
Nieskończony cykl
Dla etapu The Infinite Loop należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżki naprawcze. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Konieczna jest ludzka akceptacja w przypadku operacji, które powodują wydatki lub zmieniają dane produkcyjne. Połączenia realizowane w czasie kompilacji nie równają się kompletności rozwiązania biznesowego.
Hallucynowane argumenty narzędzia
W fazie Hallucinated Tool Arguments należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy krok się nie powiedzie, przyczyna błędu powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną strukturę przepływu. Autoryzuj procesy przy bramie wejściowej, a ponownie nadawaj uprawnienia na poziomie warstwy danych. Sam token nie stanowi granicy między poszczególnymi użytkownikami.
// Expected:
{ "customerId": "cust_123", "amount": 50 }
// What the model occasionally outputs under high temperature:
{ "user_id": "cust_123", "refund_value": "$50.00" }
Niedeterministyczne routowanie
W fazie nieterministycznego routingu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadań. Wprowadź ludzką aprobatę dla operacji, które wiążą się z wydawaniem pieniędzy lub modyfikacją danych produkcyjnych. Podłączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego. W fazie nieterministycznego routingu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, składy z danymi poufnymi oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całego pliku.
aph.6. Kiedy używać której architektury
Podczas przechodzenia przez etap „6. Kiedy używać”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Ustal punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
Używaj tradycyjnego kodu backendowego, gdy:
Gdy przechodzisz przez etap „Użyj tradycyjnego kodu backend”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolij małe, testowalne jednostki nad rozbudowane skrypty. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
Korzystaj z agentów AI, gdy:
Gdy przechodzisz przez etap „Use AI Agents When”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Ustaw punkty kontrolne po kosztownych krokach. Program powinien unikać ponownego pobierania opłat za tę samą operację LLM, gdy operator próbuje ponownie wykonać późniejszy element. Gdy przechodzisz przez etap „Use AI Agents When”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury.
Optymalny punkt produkcji: architektura hybrydowa
Etap Optymalnego punktu produkcji działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę przywracania do normy. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.
[Incoming Request] ──> [Traditional API Gateway] ──> Authentication / Rate Limiting
│
▼
[Standard Business Logic] ──> Fast DB Reads / Validation
│
▼
[Targeted Agent Boundary] ──> Handles unstructured task
│ (Restricted to 3 safe tools)
▼
[Standard Business Logic] ──> Validates agent output
│
▼
[Final Response] <─── [Structured DB Write]
Wniosek
Etap konkluzji działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwę w kontynuacji pracy po zakłóceniach.
Karta kontrolna operacyjna
Podczas pracy nad etapem karty kontrolnej operacyjnej najpierw zapisz warunki umowy: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowej awarii. Taka karta zapewnia uczciwość późniejszych zmian w kodzie.
Zapisz czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do wspólnych środowisk.
Punkt kontrolny po kosztownych krokach. Przy wznowieniu pracy nie powinno dochodzić do ponownego naliczania opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
Zamrożone wersje zależności oraz zapis digestu obrazu, który uruchomił demonstrację. Reprodukowalność jest ważniejsza od lokalnej wiedzy specjalistów.
Konfigurację należy przechowywać oddzielnie od kodu aplikacji. Pliki środowiskowe, magazyny tajemnic oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności analizowania całego grafu.
Punkt kontrolny po kosztownych krokach. Przy wznowieniu pracy nie powinno dochodzić do ponownego naliczania opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.
Zanim zastosuje się nową architekturę, należy zamrozić wersje oprogramowania, utworzyć dokładny zapis działań dla kluczowej ścieżki oraz potwierdzić kroki odwracające zmiany. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji dostępu oraz wyraźnego właściciela odpowiedzialnego za rotację tajemnic. Lepiej mieć nudną, ale niezawodną architekturę niż genialne, jednorazowe demonstracje.
Uwagi dotyczące partii 0b07728dd3ea: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok plików testowych, aby późniejsze zmiany modeli pozostały porównywalne.