Core lesson
ChatGPT-Style LLM Inference System
How to design a chat assistant serving system that streams large language model responses while managing context, latency, GPU memory, safety, and reliability.
After this, you will understand
How ChatGPT-Style LLM Inference System helps you see how models, data, product constraints, latency, cost, and reliability shape an AI product architecture.
Article guideprerequisites, mental models, and concepts
Article overview
Three useful mental models
Start with the word in plain English before adding machinery.
The idea becomes unclear when it is mixed with LLM Inference Serving, Prompt Assembly, and Context Window too early.
Connect the word to inputs, outputs, model behavior, product boundaries, and evaluation.
Think before reading
Before learning the mechanics, what should a beginner understand about LLM Inference Serving and Prompt Assembly?
As you read, separate the vocabulary from the implementation details. The word should feel clear before the system design gets complex.
Supporting resources
Open these concepts when the study introduces a decision you want to inspect.Concepts Covered
- LLM inference serving
- Prompt assembly
- Conversation state
- Context-window budgeting
- Streaming responses
- KV cache
- Request scheduling and batching
- Model routing
- Safety checks
- Observability and regression evaluation
1. Introduction
A ChatGPT-style assistant looks like a simple chat box: the user writes a message, waits for the assistant, and sees text stream back. Underneath that interface is an inference system. It must turn conversation history, instructions, uploaded context, tool results, and policy constraints into a model request that can be served at acceptable latency and cost.
The naive mental model is:
user message -> model -> assistant answer
That model is useful as a first sketch, but production chat systems are shaped by the work around the model. The system must assemble context, enforce limits, route requests, stream tokens, survive overload, observe quality, and handle failures without making the user feel like the product is random.
This is a style study, not a claim about any private implementation. The goal is to understand the architecture pressure behind a conversational large language model product.
2. Product Requirements
Functional Requirements
- Users can send chat messages and receive assistant responses.
- The assistant can use conversation history as context.
- The response can stream token by token.
- The system can attach system instructions, product policy, and user-visible context.
- The system can reject or transform requests that violate policy.
- The system can record traces for debugging, evaluation, and abuse investigation.
- The product can route different requests to different model tiers when appropriate.
Non-Functional Requirements
- Time to first token should feel interactive.
- Long conversations should not exceed context limits silently.
- The system should degrade gracefully under traffic spikes.
- Serving should control GPU memory and cost per request.
- The product should protect user data and preserve tenant boundaries.
- Failures should be explainable through traces and metrics.
- Model changes should be evaluated before broad rollout.
3. Core Engineering Challenges
| Challenge | Why it matters |
|---|---|
| Context assembly | The model only sees what is placed in the prompt for this request. |
| Latency | Users notice slow first tokens more than slow internal stages. |
| GPU memory pressure | Active requests consume memory through model weights and KV cache. |
| Uneven workloads | A short question and a long uploaded-document request stress the system differently. |
| Safety and policy | Some checks must happen before generation, some during or after generation. |
| Quality regression | Prompt, routing, retrieval, and model changes can improve one workflow while breaking another. |
The system fails when these concerns are treated as afterthoughts. A chat product that blindly appends every previous message will become expensive and eventually exceed context limits. A serving layer that accepts every long request immediately can starve interactive users. A product that only logs final answers cannot explain why a response went wrong.
4. High-Level Architecture
flowchart LR User[User] --> ChatAPI[Chat API] ChatAPI --> Auth[Auth and quota checks] Auth --> ContextBuilder[Context builder] ContextBuilder --> ConversationStore[(Conversation store)] ContextBuilder --> Policy[Safety and policy checks] Policy --> Router[Model router] Router --> Queue[Inference queue] Queue --> Scheduler[Batch scheduler] Scheduler --> ModelWorkers[Model serving workers] ModelWorkers --> Stream[Streaming gateway] Stream --> User ModelWorkers --> TraceStore[(Trace and metrics store)] ChatAPI --> EvalSink[Evaluation event sink]
The chat API owns the product boundary. It authenticates the user, applies quotas, receives the message, and starts a trace. The context builder turns product state into model-visible input. The router decides which model or serving pool should handle the request. The scheduler manages batching and active decode work. The streaming gateway sends partial output back to the client as tokens arrive.
5. Core Components
Chat API: validates the request, starts the trace, checks account state, and hands work to the AI pipeline. It should not perform heavy model work directly.
Conversation store: keeps durable chat messages, metadata, attachments, and references to generated responses. It is the product memory, not the model memory. The model only receives selected history from it.
Context builder: chooses what to include in the prompt. It may summarize older turns, trim low-value content, attach user profile hints, include tool results, or reserve token budget for the answer.
Policy layer: applies safety, abuse, privacy, and product rules. Some rules run before inference. Others inspect generated output or stream chunks.
Model router: chooses between model classes, regions, providers, or internal pools based on task, account tier, latency target, cost budget, and availability.
Inference scheduler: batches requests and manages prefill and decode pressure. It must balance throughput against interactive latency.
Streaming gateway: maintains the user connection and forwards partial output. It handles cancellation, timeouts, and network disconnects.
Trace and evaluation store: records request shape, prompt version, model version, routing decision, latency, errors, and selected quality signals.
6. Data Modeling
The product data model separates durable user-facing records from transient serving state.
conversation(id, user_id, title, created_at, updated_at)
message(id, conversation_id, role, content_ref, token_count, created_at)
assistant_response(id, message_id, model_id, prompt_version, status)
inference_trace(id, request_id, model_id, prompt_tokens, output_tokens, latency_ms)
policy_event(id, request_id, rule_id, action, created_at)
The conversation store should not be treated as a prompt. A long conversation may contain thousands of tokens, tool artifacts, irrelevant turns, or stale assumptions. The context builder creates a request-specific view:
system instructions
developer/product instructions
selected conversation turns
optional summaries
attachments or retrieved context
current user request
Useful indexes include conversation by user, messages by conversation and time, traces by request ID, and failures by model version or prompt version. The model-serving layer also has transient state, especially active sequences and KV cache blocks, but that state usually belongs to the serving runtime rather than the product database.
7. Request Lifecycle
- The client sends a message to the chat API.
- The API authenticates the user, checks quota, and creates a request trace.
- The context builder loads the conversation and selects the model-visible context.
- The policy layer checks the request and may block, transform, or annotate it.
- The model router chooses a serving pool.
- The request enters the inference queue.
- The scheduler runs prefill for the prompt and then decode for generated tokens.
- The streaming gateway sends tokens to the client as they arrive.
- The final response is stored with model, prompt, latency, and token metadata.
- Evaluation events and operational metrics are emitted.
Cancellation is part of the lifecycle. If the user stops generation, the gateway should propagate cancellation so expensive decode work does not continue invisibly.
8. Scaling Problems
The main scaling pressure is not only request count. It is token work.
Long prompts increase prefill cost. Long answers increase decode time. Many simultaneous conversations increase KV cache pressure. A few very large requests can reduce capacity for many small interactive requests.
Common bottlenecks include:
- prompt assembly doing too many database reads
- context windows growing without summarization or selection
- GPU memory fragmentation from uneven sequence lengths
- low utilization because batching is too conservative
- poor tail latency because long requests share queues with short ones
- trace stores receiving too much high-cardinality data without retention policy
- retries duplicating expensive model work
Scaling usually requires workload classes. Interactive chat, long document analysis, background summarization, and tool-heavy workflows should not always share the same queue, model, or latency target.
9. Distributed Systems Concepts
This system touches familiar distributed systems ideas.
Backpressure: when inference queues grow, the API must slow intake, reject low-priority requests, or degrade gracefully.
Admission control: not every request should reach the model. Quotas, token limits, and policy checks protect capacity.
Tail latency: users feel the slowest common path, especially before the first token.
Idempotency: retries should not create duplicate user-visible messages or double-charge token accounting.
Isolation: one tenant, region, or workload class should not consume all serving capacity.
Eventual consistency: evaluation pipelines and analytics do not need to update synchronously before the user sees the answer.
10. Reliability & Failure Handling
Failures should preserve user trust.
If a serving pool is overloaded, the router can shift traffic to another pool, choose a smaller model, or return a clear retry message. If streaming breaks, the product should mark the response as interrupted rather than pretending it completed. If context assembly fails because an attachment is unavailable, the assistant should not answer as though it saw the attachment.
Operational signals include:
- time to first token
- tokens per second
- queue depth by workload class
- GPU memory utilization
- cancellation rate
- policy block rate
- model and prompt version error rate
- malformed output rate
- user retry or regeneration rate
Good reliability design also includes canarying model changes, rolling back prompt versions, and keeping enough trace detail to reproduce failures without retaining unnecessary sensitive data.
11. Real-World Company Approaches
A company building this kind of product might use multiple model tiers, specialized serving pools, prompt-version tracking, and offline evaluation before rollout. It might separate interactive chat from long-running analysis jobs. It might use routing policies that consider latency, cost, safety, and account entitlement.
Public product behavior suggests that modern assistants often stream output, preserve conversation history, apply safety layers, and evolve model versions over time. Those facts do not reveal private internals. The reusable engineering lesson is that chat assistants are online serving systems with quality, memory, latency, and policy constraints.
12. Tradeoffs & Alternatives
| Design choice | Benefit | Cost |
|---|---|---|
| Always use the strongest model | Better quality on hard tasks | Higher latency and cost |
| Route by task type | Better cost and latency control | Requires classification and monitoring |
| Keep full history | More conversational continuity | Context bloat and stale details |
| Summarize old turns | Saves tokens | Summary can lose important nuance |
| Stream tokens | Better perceived latency | More complex cancellation and moderation |
| Heavy tracing | Better debugging | Privacy, storage, and retention burden |
No single design is universally right. The system should match the product's promises.
13. Evolution Path
- Start with a simple chat API and one model endpoint.
- Add durable conversation storage and prompt versioning.
- Add streaming responses and cancellation.
- Add context budgeting, summarization, and attachment handling.
- Add quota, abuse controls, and safety policy.
- Add model routing and separate serving pools.
- Add evaluations, traces, canaries, and rollback controls.
- Add specialized workflows for retrieval, tools, and long-running jobs.
Each step appears because the previous version becomes hard to reason about under real usage.
14. Key Engineering Lessons
- A chat assistant is not just a model call; it is a serving system.
- Conversation history is stored data, but context is a selected runtime input.
- Latency is shaped by prompt size, queueing, prefill, decode, and streaming.
- GPU capacity is managed through scheduling, batching, memory control, and admission limits.
- Quality needs evaluation traces, not only final user-visible text.
- Product trust depends on honest failure handling when context, policy, or serving fails.
15. Related Topics
Finished reading?
Your reading history is saved in this browser so you can continue later.
Recommended Next
Perplexity-Style RAG Search SystemAI System Studies8 min readThis applies the core AI concepts inside a complete production system.
Optional exploration
These links add context, but they do not replace the recommended next lesson.
Arcflow Plus is coming — review drills, research breakdowns, more AI. Get one email at launch.