Przejdź do głównej zawartości

Wzorce serverless dla agentów AI to przepisy, dzięki którym Claude Code, Codex i Cursor piszą dla AWS Lambda, Cloudflare Workers i Vercel kod, który przetrwa produkcję: handlery idempotentne przy ponownym dostarczeniu zdarzeń, bindingi Workera zgodne z wrangler.toml i poprawki cold startów przed provisioned concurrency. Każdy przepis kończy się testem albo bramką, a nie ręcznym czytaniem kodu.

Ta strona jest dla backend developerów, którzy już wdrażają funkcje, a teraz większość z nich pisze za nich agent. Sytuacja, którą rozwiązuje: Lambda przetwarzająca obrazy odpala się dwa razy na ten sam upload do S3, CloudWatch to ściana nieustrukturyzowanych console.log, a poranny skok p99 ktoś „naprawił” provisioned concurrency na każdej funkcji, co podwoiło rachunek. Serverless usuwa serwery, a nie problemy systemów rozproszonych. Ponowienia, idempotencja, cold starty i limity platform to nadal twój kod, a agent pisze tylko ścieżkę bez błędów, dopóki nie poprosisz o więcej.

Przepisy zakładają projekt w TypeScripcie z Vitestem; jeśli nie masz jeszcze tego zestawu narzędzi, przygotuj go najpierw według przepisów na Node.js albo wybierz inny stos w recepturach backendowych.

  • Prompt, który tworzy idempotentny handler S3 → Lambda, oraz poprawny kształt handlera do porównania z wynikiem.
  • Prompt testowy, który dowodzi, że handler przetrwa podwójne dostarczenie i awarię w trakcie pracy, więc weryfikujesz zachowanie zamiast czytać diff.
  • Prompt na API gateway w Cloudflare Workers z pasującym wrangler.toml i dwie komendy, które przed wdrożeniem łapią rozjazd bindingów i puchnięcie bundla.
  • Konfigurację serwera MCP Cloudflare i skilli Cloudflare dla każdego narzędzia, z kosztem kontekstu serwera MCP.
  • Prompt do triage cold startów, który mówi, kiedy provisioned concurrency jest warte swojej ceny.
  • Tryby awarii, które docierają na produkcję (podwójne dostarczenia z SQS, rekurencyjne wyzwalacze S3, limity CPU w Workers, zablokowane rekordy idempotencji), i sposób wyjścia z każdego.

Daj agentowi jedną konkretną usługę, region, runtime i źródła zdarzeń. Wszystkie trzy narzędzia sterują tymi samymi CLI frameworków (Serverless Framework, AWS SAM, Wrangler), więc wybieraj narzędzie według tego, gdzie toczy się praca, a nie według możliwości. Poniższy prompt używa Serverless Framework v4 (serverless 4.43.0 w npm, sprawdzone 2026-09-26) i Node.js 22.

Uruchom w pustym repozytorium w terminalu. Przy pierwszym uruchomieniu podaj --permission-mode manual, żeby samodzielnie zatwierdzać każdą edycję (od v2.1.283, na obu kanałach wydań w stanie na 2026-10-12, sesje interaktywne startują w trybie auto). Przejdź na --permission-mode acceptEdits, jak poniżej, gdy już ufasz planowi.

Okno terminala
claude --permission-mode acceptEdits "Set up a Serverless Framework v4 service in TypeScript for AWS eu-central-1: one HTTP Lambda behind API Gateway (GET /health), one S3-triggered image Lambda that only fires for the uploads/ prefix, and a DynamoDB table 'media' (PK id) plus a 'dedupe' table with TTL on 'ttl'. esbuild bundling, Node.js 22 runtime, dev and prod stages. Add a vitest setup and an npm 'test' script. Do not deploy."

Użyj claude -p z tym samym promptem, gdy szkielet ma być powtarzalny w skrypcie.

S3, SQS i EventBridge dostarczają zdarzenia co najmniej raz. Handler ze skutkami ubocznymi (zapisy, e-maile, obciążenia kart) musi zająć stabilny klucz, zanim cokolwiek zrobi, pominąć pracę, gdy klucz jest już zajęty, i zwolnić go, gdy praca się nie uda, żeby ponowienie mogło się wykonać. Wygenerowane handlery często robią dobrze dwie pierwsze rzeczy i pomijają trzecią: zapisują rekord deduplikacji, padają w sharp, a każde ponowienie jest odtąd pomijane jako „duplikat”. Obiekt nigdy nie zostaje przetworzony.

Porównaj wynik z tym wzorcem handlera. Liczy się kolejność operacji, nie styl:

// handler.ts: claim, work, release on failure
import type { S3Event } from 'aws-lambda';
import { DynamoDBClient, PutItemCommand, DeleteItemCommand } from '@aws-sdk/client-dynamodb';
import { resizeAndWrite } from './resize';
const ddb = new DynamoDBClient({});
const TABLE = process.env.DEDUPE_TABLE!;
export const handler = async (event: S3Event) => {
for (const rec of event.Records) {
const start = Date.now();
const bucket = rec.s3.bucket.name;
const key = decodeURIComponent(rec.s3.object.key.replace(/\+/g, ' '));
const pk = `${bucket}/${key}#${rec.s3.object.eTag}`;
const log = { requestId: rec.responseElements['x-amz-request-id'], bucket, key, pk };
try {
await ddb.send(new PutItemCommand({
TableName: TABLE,
Item: { pk: { S: pk }, ttl: { N: String(Math.floor(start / 1000) + 7 * 86400) } },
ConditionExpression: 'attribute_not_exists(pk)',
}));
} catch (err) {
if ((err as Error).name !== 'ConditionalCheckFailedException') throw err;
console.log(JSON.stringify({ ...log, status: 'duplicate-skipped' }));
continue;
}
try {
await resizeAndWrite(bucket, key);
console.log(JSON.stringify({ ...log, status: 'ok', durationMs: Date.now() - start }));
} catch (err) {
await ddb.send(new DeleteItemCommand({ TableName: TABLE, Key: { pk: { S: pk } } }));
console.error(JSON.stringify({ ...log, status: 'failed', error: (err as Error).message }));
throw err;
}
}
};

Timeout wciąż może zabić funkcję między zajęciem klucza a jego zwolnieniem, a wtedy rekord blokuje każde ponowienie. Jeśli nie chcesz ręcznie pisać dzierżawy z terminem wygaśnięcia, poproś agenta o @aws-lambda-powertools/idempotency (2.35.0 w npm, sprawdzone 2026-09-26): biblioteka zapisuje rekord „w toku” z własnym terminem wygaśnięcia i rekord ukończenia z wynikiem, więc obsługuje także ten przypadek.

Jak udowodnić, że handler przetrwa podwójne dostarczenie?

Dział zatytułowany „Jak udowodnić, że handler przetrwa podwójne dostarczenie?”

Nie czytaj handlera linijka po linijce. Zapisz cztery zachowania, które mają znaczenie, i spraw, żeby test padał, gdy którekolwiek się zepsuje. Powiedz agentowi, że testy są specyfikacją, więc czerwony test prowadzi do poprawki handlera, a nie do zmiany asercji. Dlaczego to polecenie jest ważne, wyjaśnia strona chroń wyrocznię testową.

Potem uruchom bramki. Każda z nich zapala się na czerwono przy konkretnym błędzie i właśnie dlatego możesz ufać wynikowi bez przeglądania każdej linijki:

BramkaKomenda (terminal lub CI)Czerwona, gdy
Testy zachowanianpx vitest runDuplikat zostaje przetworzony dwa razy, klucz nie zostaje zwolniony po nieudanym skalowaniu obrazu albo klucz obiektu nie jest zdekodowany
Typynpx tsc --noEmitHandler czyta pole, którego nie ma w typie zdarzenia
Paczkanpx serverless package --stage devserverless.yml się nie parsuje albo ścieżka handlera jest błędna
Bindingi Workeranpx wrangler types, potem npx tsc --noEmitKod Workera czyta binding, którego nie deklaruje wrangler.toml
Bundle Workeranpx wrangler deploy --dry-run --outdir distWypisany Total Upload przekracza budżet rozmiaru, z którym porównuje go krok CI (np. błąd powyżej 1 MiB); sam dry run nigdy nie pada z powodu rozmiaru i nic nie jest wysyłane
Sygnał z produkcjiCloudWatch Logs Insights: stats count(*) by statusPo wydaniu zmienia się liczba duplicate-skipped albo failed

Testy i bramki należą do ciebie. Zmiany w politykach IAM, miejscach docelowych na błędy (on-failure destination) i konfiguracji etapów trafiają do przeglądu przez człowieka, bo błędne uprawnienie IAM przejdzie wszystkie powyższe testy. Wdrożenia uruchamia CI, a nie sesja agenta. Jak dołączyć wyniki bramek do pull requesta, pokazuje strona o pakiecie dowodów.

Aby agent sam uruchomił bramki i poprawił to, co padnie:

Okno terminala
claude -p "Run npx vitest run and npx tsc --noEmit. If anything fails, fix src/, never tests/, and rerun until both pass. Print which behaviour was wrong and what you changed." \
--permission-mode acceptEdits \
--allowedTools "Bash(npx vitest *)" "Bash(npx tsc *)" \
--disallowedTools "Edit(tests/**)" "Write(tests/**)"

Sam prompt tylko prosi agenta, żeby nie ruszał tests/. W Claude Code --disallowedTools zamienia to w regułę, której sesja nie złamie. W Codexie i Cursorze wymuś to poza agentem: wpisem w CODEOWNERS, który wymaga przeglądu tests/ przez człowieka, albo sprawdzeniem w CI, które pada, gdy gałąź agenta zmienia pliki w tests/.

Jak zbudować API gateway w Cloudflare Workers ze zgodnymi bindingami?

Dział zatytułowany „Jak zbudować API gateway w Cloudflare Workers ze zgodnymi bindingami?”

Workers domyślnie nie mają runtime’u Node.js, mają budżet czasu CPU na żądanie i bindingi zamiast klientów SDK. Poproś o Workera i jego konfigurację w jednym prompcie, żeby nazwy bindingów w kodzie i w wrangler.toml pochodziły z tej samej odpowiedzi.

# wrangler.toml: binding names must match the Worker's Env type
name = "api-gateway"
main = "src/index.ts"
compatibility_date = "2026-09-01"
[vars]
ORIGIN = "https://origin.internal.example.com"
[[kv_namespaces]]
binding = "TOKENS"
id = "KV_NAMESPACE_ID"
[[durable_objects.bindings]]
name = "RATE_LIMITER"
class_name = "RateLimiter"
[[migrations]]
tag = "v1"
new_sqlite_classes = ["RateLimiter"]

Zastąp KV_NAMESPACE_ID identyfikatorem, który wypisze npx wrangler kv namespace create TOKENS. Potem uruchom npx wrangler types: komenda generuje typ Env z tego pliku, więc Worker czytający env.TOKEN zamiast env.TOKENS padnie na tsc, a nie w runtime.

Jak dać agentowi dostęp do żywego stanu Cloudflare?

Dział zatytułowany „Jak dać agentowi dostęp do żywego stanu Cloudflare?”

Wygenerowany kod to połowa pracy. Druga połowa to stan, na którym działa: literówka w identyfikatorze namespace, nieaktualna wartość w KV, trasa rzucająca błędy na produkcji. Cloudflare daje dwa sposoby, żeby pokazać to agentowi, i każdy rozwiązuje inny problem.

  • Serwer MCP Cloudflare czyta i zmienia twoje żywe konto. Zalecany serwer Code Mode pod https://mcp.cloudflare.com/mcp udostępnia trzy narzędzia (search, execute, docs) nad całym API Cloudflare. Cloudflare szacuje koszt jego schematów na około 1000 tokenów wobec około 244 000 dla natywnych schematów narzędzi tego samego API (Cloudflare, README cloudflare/mcp, odczyt 2026-09-26). Wyniki są domyślnie przycinane do około 6000 tokenów. Serwery domenowe, takie jak https://observability.mcp.cloudflare.com/mcp, obejmują po jednym obszarze.
  • Skille Cloudflare (cloudflare/skills, 14 skilli dla Workers, Wranglera, Durable Objects i innych) uczą agenta konwencji platformy. Wersja w postaci pluginu zawiera ten sam serwer MCP Code Mode.

Serwer MCP wymaga wpisu z adresem URL w każdym narzędziu. Uwierzytelnienie to OAuth przy pierwszym użyciu albo token API Cloudflare wysyłany jako bearer token.

Okno terminala
claude mcp add --transport http cloudflare https://mcp.cloudflare.com/mcp
# or the plugin, which brings the skills and the MCP server together:
# /plugin marketplace add cloudflare/skills
# /plugin install cloudflare@cloudflare

Bez --transport http Claude Code 2.1.283 i tak zapisze adres URL jako komendę stdio. Wypisze ostrzeżenie, ale wpis trafi do konfiguracji i padnie przy łączeniu.

Przed MCP znalezienie nieaktualnego tokena oznaczało kopiowanie identyfikatorów namespace między kartami dashboardu. Z MCP jeden prompt odpowiada na podstawie żywego konta:

Wybierz skill, gdy agent ma tylko znać komendy i konwencje wrangler. Wybierz serwer MCP, gdy musi czytać albo zmieniać żywy stan, i nie dawaj uprawnień do zapisu w sesjach, które ich nie potrzebują. Odpowiednikiem dla AWS jest zestaw pluginów samego AWS (aws/agent-toolkit-for-aws, z pluginem aws-core do pracy z serverless i CDK). W Claude Code zainstalujesz go przez /plugin install aws-core@claude-plugins-official. W Codexie uruchom codex plugin marketplace add aws/agent-toolkit-for-aws, a potem zainstaluj aws-core z /plugins. Pełna lista serwerów i szczegóły OAuth są na stronie MCP Cloudflare.

Więcej promptów serverless: cold starty, kolejki i Vercel

Dział zatytułowany „Więcej promptów serverless: cold starty, kolejki i Vercel”

Co się psuje, gdy kod serverless od agenta trafia na produkcję?

Dział zatytułowany „Co się psuje, gdy kod serverless od agenta trafia na produkcję?”

Czy ten artykuł Ci pomógł?

Jedno kliknięcie, bez logowania.

wcale bardzo