bigonotes
AIUsing LLM APIs

Messages

How an LLM API request is built from system, user and assistant messages, and why your app resends the whole conversation.

4 min readLast updated

When you call an LLM API, you don't send a single string of text. You send a structured list of messages, and each message has a role and some content. The shape of that list decides how the model behaves, what it remembers and how much each request costs.

The three roles#

Every message carries one of three roles. Together they describe who is speaking.

Role What it holds
system Standing instructions: who the model is, how it should behave, what it can and can't do. Sent once, at the top.
user What the human says.
assistant What the model replied. Your app includes past assistant turns so the model knows what it already said.

A typical request has the system message first, then alternating user and assistant turns, then the latest user message at the bottom.

A request's message list: the system message at the top, alternating user and assistant turns, and the latest user message last

As data, that list looks like this.

messages = [
    {"role": "system", "content": "You are a support agent for Acme Corp."},
    {"role": "user", "content": "How do I reset my password?"},
    {"role": "assistant", "content": "Open Settings, then choose Reset."},
    # The newest user message always goes last.
    {"role": "user", "content": "And if I no longer have my old email?"},
]
reply = call_model(messages)  # generic helper: sends the list, returns text

What the system prompt controls#

The system prompt defines the model's behavior for your application. It does not add knowledge. It shapes how the model acts.

Typical uses:

  • The persona or tone to use.
  • Which topics to stay on or avoid.
  • The format to respond in.
  • What to do when the model doesn't know something.

For example, a customer support bot might have this system prompt: "You are a support agent for Acme Corp. Answer only questions about our products. If you don't know, say so and offer to escalate. Always respond in three sentences or fewer."

Every request includes the system prompt, even though the user never sees it. That is how the model behaves consistently across a whole conversation.

The system prompt is not a security boundary. A determined user can sometimes talk the model into ignoring it. Never put secrets in it, and never rely on it to hide data.

Why the model has no memory#

The model keeps nothing between requests. Each time you send one, it starts completely fresh and knows only what is in the message list you send with it.

That is why your app resends the whole conversation every time. The alternating user and assistant turns are the model's only way to know what was said before. Without them, every message would look like the start of a new conversation. The next note on stateless design goes deeper on this.

Why the order matters#

The model reads the messages from top to bottom, and later messages tend to carry more weight. If the latest user turn contradicts the system prompt, the model often sides with the more recent instruction. This is also why the latest user message always goes last.

The cost of resending#

Resending the history means a long conversation is expensive. Suppose the chat history is 5,000 tokens and the user sends a 10-token message. You pay for 5,000 + 10 = 5,010 tokens of input, not 10.

Every turn adds to the history, so every turn adds to the bill. Tokens are how that cost is counted (see Tokens), and the history also has to fit inside the limit described in Context window.

Short line#

An API request is a list of system, user and assistant messages, sent in full every time because the model has no memory. The system prompt shapes behavior, and it is not a place for secrets.

Key takeaways#

  • A request is a structured list of messages, each with a role and content.
  • The system role sets standing behavior, the user role is the human, and the assistant role is the model's earlier replies.
  • The system prompt controls behavior, not knowledge, and it is not a security boundary, so never put secrets in it.
  • The model has no memory, so your app resends the full conversation on every request.
  • Order matters: the model reads top to bottom, later messages weigh more, and the latest user message goes last.
  • You pay for the whole history on each turn: 5,000 tokens of history plus a 10-token message is 5,010 input tokens.
Revision notes · 1 min

Core idea#

An API request is a list of messages, each with a role and content. The model has no memory, so you send the whole list every time.

Key points#

  • Three roles: system, user, assistant.
  • The system message holds standing instructions. It goes first, once.
  • The user message is what the human says.
  • Assistant messages are earlier model replies. Your app resends them.
  • Order: system first, then alternating user and assistant turns, then the latest user message last.
  • The model reads top to bottom. Later messages weigh more.
  • Every request includes the system prompt, even if the user never sees it.

System prompt#

Controls Does not control
Persona and tone Model knowledge
Topics to stay on or avoid Security
Response format
What to do when unsure

Cost#

  • Input cost covers the whole history, not only the new message.
  • Example: 5,000 history tokens plus a 10-token message is 5,010 input tokens.
  • Every turn adds to the history, so every turn adds to the bill.

Pitfalls#

  • Do not put secrets in the system prompt. A determined user can talk the model into ignoring it.
  • Do not rely on the system prompt to hide data.
  • Do not expect the model to remember earlier requests. Resend the history.

Short line#

  • "A request is a list of system, user and assistant messages, resent in full each time because the model has no memory. The system prompt shapes behavior and is not a security boundary."

Found a mistake? Email ask@bigonotes.com