AI FDE 之路 #01:LLM 應用請求流程剖析
The path to AI FDE #01: Anatomy of an LLM app request
Dhanush Kumar Sivaji 將一次 LLM 應用請求拆解為九個步驟,涵蓋用戶端呼叫、輸入驗證、提示詞組裝、模型生成、串流回傳、輸出驗證、重試與記錄。
I've spent 8+ years building React/TypeScript front ends. Now I'm learning applied AI in public, working toward AI Engineer, then AI Solution Architect, and (I hope) AI Forward Deployed Engineer. Before tokens, RAG or agents, I wanted one map: what actually happens when a user clicks "Summarize"?
Each step below gets its own figure first, then the short version in words.
Before the call: steps 1–4
1. The client sends a request. From the browser's side, an LLM feature is just an HTTP call to your backend: POST /summarize with the user's text, plus a conversation id if it's a chat. OpenAI's docs say never to expose an API key in client-side code, so the key lives on your server and only the server talks to the provider.
2. Your API validates the input. FastAPI checks the body against a Pydantic model. Invalid data never reaches your handler: FastAPI raises a RequestValidationError, and its default handler returns HTTP 422. Once validation passes, Pydantic guarantees the fields match their declared types. It's the cheapest place to stop bad input.
3. You assemble the prompt. The model sees only what you send. Anthropic's Messages API is stateless, so you resend the full history every time. OpenAI also calls each request independent and stateless, and offers optional server-side conversation state, but notes that earlier input tokens in the chain are still billed on each turn. Later in this series, retrieved documents (RAG) join the prompt here.
4. Count tokens and check the budget. Models read tokens, not characters, and tokenizers are tied to the model, so counts differ between models. System prompt, tool definitions, history and the output all share the context window. If the input alone is over the limit, the request fails (Anthropic returns a 400, "prompt is too long"). Estimate tokens before sending and set a maximum output length.
Inside the model: steps 5–6
5. Prefill: the model reads all the input at once. Inference has two phases. In prefill, the model processes every input token in parallel. It's compute-heavy, and it's the main model-side driver of time to first token (TTFT). Network time and provider queueing add to that pause.
6. Decode: one token at a time. Then the model generates autoregressively: score every token in the vocabulary, pick one, append it, repeat. A KV cache keeps earlier work so each step doesn't start over, and the per-step pace is the time per output token. It stops at an end-of-sequence token, a stop sequence or the token limit.
How it picks is a sampling setting: greedy, or sampled with temperature, top-k or top-p. Don't assume those settings exist on every model: Anthropic's docs say Claude 4.7 and later return a 400 if you set them to non-default values.
After the call: steps 7–9
7. Stream the tokens back. OpenAI and Anthropic both stream tokens as server-sent events (SSE) while decoding is still running, so steps 6 and 7 overlap. Two catches from the docs: an error can arrive mid-stream, after a 200 status, and partial output is harder to moderate than a finished response.
8. Validate the output too. Structured outputs constrain the model to a JSON Schema you supply (OpenAI supports a subset), but OpenAI's guide says they can still contain mistakes, and documents two cases to handle: refusals and responses cut off at the token limit. If you stream, validate once the stream completes. FastAPI's response_model is a second check: a mismatch becomes a server error, not wrong data. A valid shape isn't a correct answer; evals cover correctness later in this series.
9. Retry safely, then record. The same status can mean different things: a 429 can be a rate limit, but Anthropic also uses it when you hit your monthly spend cap, so read the error body before retrying. Never retry quota or billing errors. For transient errors, honor Retry-After when present, otherwise use exponential backoff with jitter, and cap attempts and total time. Official SDKs already retry some errors (Anthropic's twice by default), so count that in your limits rather than nesting loops. Then log input/output token usage, latency and the provider's request id. Those records feed debugging, cost tracking and, eventually, evaluation.
Takeaway
As a front-end engineer, I found this oddly familiar: it's a request lifecycle with an unusual backend in the middle. Two of the nine steps are the model. The other seven are contracts, budgets, streams and failure handling, the parts an engineer owns. My working rule from here on: treat the model as an unreliable, metered, remote dependency, and put validation on both sides of it.
Where this fits in my roadmap: this post is the map I'm following into the foundations block: Python typing and async, FastAPI and Pydantic, and LLM mechanics (tokens, context, inference). Next post: Python for AI backends: a TypeScript engineer's refresher.
Over to you: which of these nine steps broke first in the first LLM feature you built?
Sources
- OpenAI API reference: Authentication (don't expose API keys in client-side code). https://developers.openai.com/api/reference/overview
- FastAPI: Handling Errors (
RequestValidationErrorand its default handler). https://fastapi.tiangolo.com/tutorial/handling-errors/ - FastAPI source:
exception_handlers.py(default validation handler returns 422). https://github.com/fastapi/fastapi/blob/master/fastapi/exception_handlers.py - Pydantic: Models (post-validation type guarantees). https://pydantic.dev/docs/validation/latest/concepts/models/
- Anthropic: Working with the Messages API (stateless, resend full history; sampling parameters on Claude 4.7+). https://platform.claude.com/docs/en/build-with-claude/working-with-messages
- OpenAI: Conversation state (requests independent and stateless; optional state management; earlier input tokens still billed). https://developers.openai.com/api/docs/guides/conversation-state
- Hugging Face LLM Course, Ch. 2: Tokenizers (subword tokenization, "token" + "ization"). https://huggingface.co/learn/llm-course/chapter2/4
- Anthropic: Context windows (what counts toward the window; oversize input returns 400; token counting). https://platform.claude.com/docs/en/build-with-claude/context-windows
- Hugging Face LLM Course, Ch. 1: Deep dive into text generation inference (prefill/decode, TTFT, TPOT, KV cache, sampling, stop conditions). https://huggingface.co/learn/llm-course/chapter1/8
- Vaswani et al., "Attention Is All You Need" (2017), the transformer/attention paper. https://arxiv.org/abs/1706.03762
- OpenAI: Streaming API responses (SSE, moderation risk for partial output). https://developers.openai.com/api/docs/guides/streaming-responses
- Anthropic: Streaming Messages (SSE). https://platform.claude.com/docs/en/build-with-claude/streaming
- OpenAI: Structured model outputs (schema adherence, supported subset, refusals, incomplete responses, mistakes still possible). https://developers.openai.com/api/docs/guides/structured-outputs
- FastAPI: Response Model (server error instead of invalid returned data). https://fastapi.tiangolo.com/tutorial/response-model/
- Anthropic: Errors (429 incl. spend caps, 402 billing, 400 spend limit, 529 overloaded, SDK retries, mid-stream errors after a 200, request ids). https://platform.claude.com/docs/en/api/errors
- OpenAI: Rate limits (429/503,
Retry-After, backoff with jitter, cap retries, nested SDK retries, don't retry quota/billing errors). https://developers.openai.com/api/docs/guides/rate-limits
Sources checked Oct 18, 2026. Provider APIs change quickly. Re-check model-specific details (status codes, sampling support) right before publishing.
Originally published on The Path to AI FDE on Substack. Subscribe for one diagram-led post every weekday: https://dhanushkumarsivaji.substack.com/p/the-path-to-ai-fde-01-anatomy-of
來源:DEV Community · dev.to








