How Your Message Actually Reaches the AI Model — And What You're Really Sending A developer explains how messages travel from a chat interface or application to a large language model, breaking down the request-and-response cycle and the three deployment options: cloud-hosted models like Gemini, GPT, and Claude accessed via API keys; local models run through tools such as Ollama and LM Studio; and self-hosted models on private infrastructure. The writeup compares the approaches on cost, setup, model quality, speed, privacy, and internet requirements, noting that the underlying concepts stay the same and only the URL and authentication key change. You've used ChatGPT. You've used Gemini. You type something, it replies. But have you ever stopped and wondered — what is actually happening when you hit send? Because when you're building AI systems, that question matters. A lot. Let's take the simplest example. You open ChatGPT and type: "Explain what a token is in simple terms." You hit enter. A few seconds later, you get a response. What just happened? Your message travelled over the internet to a server — a very powerful one, running a very large model — where it was processed, and text was generated back to you. That's it. At the core, it is a request and a response. Text goes in, text comes out. Now here's the important part: that model lives somewhere. It doesn't run in your browser. It doesn't run on your laptop. It runs on a server, hosted by OpenAI in this case. You're connected to it over the internet without even thinking about it. This is the same thing that happens when you build an AI backend. You send text to a model. You get text back. The difference is — you're the one writing the code that sends and receives it, not a chat UI. Here's something most tutorials skip: the model doesn't have to be on someone else's server. There are three places a model can live: 1. Cloud — hosted by the company Gemini, ChatGPT, Claude Google hosts Gemini on their servers. OpenAI hosts GPT. Anthropic hosts Claude. You connect to them over the internet using an API key — a secret key they give you that proves you're allowed to use their model. You pay per use. Every token you send and receive costs a small amount. The models are powerful, always up to date, and you don't manage any infrastructure. This is what we use in this series — Gemini, hosted by Google. 2. Local — running on your own machine Ollama, LM Studio Yes, you can download a model and run it on your laptop. Tools like Ollama https://ollama.com let you pull a model — Llama 3, Mistral, Phi — and run it locally. No internet needed. No API key. No cost per call. The model runs on your CPU or GPU and responds to requests at http://localhost:11434 . The tradeoff: smaller models, slower responses, and your laptop fans will make their presence known. But for learning, experimentation, or privacy-sensitive use cases — it's a great option. 3. Self-hosted — your own server, your own model Companies with strict data privacy requirements sometimes host their own models on their own infrastructure. Same idea as Ollama but on a cloud server they control. No data ever leaves their network. This is less common for individual developers but worth knowing exists. | | Cloud Gemini, GPT, Claude | Local Ollama | |---|---|---| | Cost | Pay per token | Free | | Setup | API key, done | Download model, install Ollama | | Model quality | State of the art | Smaller, less capable | | Speed | Fast their hardware | Depends on your machine | | Privacy | Data goes to their servers | Stays on your machine | | Internet needed | Yes | No | | Good for | Production, serious projects | Learning, experiments, privacy | For this series, we use Gemini — cloud hosted, API key, fast, capable. But if you want to experiment without spending money, Ollama is a great companion tool. The concepts are identical. Only the URL and key change. When you use a cloud-hosted model, you authenticate with an API key. Think of it like a password. You create one in the provider's dashboard, store it securely, and include it in every request you make. The server checks the key, confirms you're allowed to use the model, and processes your request. Your app ──── request + API key ────▶ Gemini servers Your app ◀─── response ──────────── Gemini servers For local models with Ollama, there's no key. You just call http://localhost:11434 directly. The model is on your machine — no authentication needed. The structure of what you send is the same either way. Only the destination changes. One rule about API keys — never break this: Never hardcode your API key directly in your source code. The moment you push that code to GitHub — even a private repo — the key is at risk. Always store it in an environment variable and read it from there. // Never do this String apiKey = "AIzaSyD-xxxxxxxxxxxxxxxxxxxxxxxx"; // Always do this String apiKey = System.getenv "GEMINI API KEY" ; This is not optional. API keys get scraped from public repos within minutes. Some providers will suspend your account automatically if they detect a leaked key. Now that you know where the model lives and how you connect — what do you actually put in the request? This is where most people expect something complicated. It's not. Every request to an LLM is a list of messages. Each message has two things: who sent it, and what they said. There are three senders — three roles : A real request looks like this: { "messages": { "role": "system", "content": "You are a travel assistant for India. Only help with travel questions." }, { "role": "user", "content": "What are the best places to visit in Rajasthan?" }, { "role": "assistant", "content": "Rajasthan has many beautiful destinations — Jaipur, Jodhpur, Udaipur..." }, { "role": "user", "content": "Which one is best for a 3-day trip?" } } The model reads this list top to bottom and writes the next assistant message. That's it. Three roles, in a list, sent on every call. The system message is where you tell the model who it is and what it should do. It's the first thing the model reads, and it sets the frame for everything else. Without a system message, the model behaves like a general-purpose assistant. With one, it becomes your travel assistant, your coding helper, your customer support agent — whatever you define. A few things I learned about writing them: Be specific, not general. "Be helpful" tells the model nothing. "Keep all responses under 5 sentences and always suggest at least one specific hotel" gives the model something concrete to follow. Put critical rules at the top. The model pays more attention to what comes first. If there's one rule you really need followed — put it first. Keep it short. I once wrote a 400-word system prompt. The model started contradicting itself. Five focused sentences beat twenty vague paragraphs. Remember from earlier articles — the model is stateless. No memory between calls. So how does a chatbot remember that your name is Sham from three messages ago? You sent it. Every time the user sends a new message, you include all the previous messages too. The model sees the full conversation and can answer in context. By message 5, your request looks like: { "role": "system", "content": "You are a travel assistant." }, { "role": "user", "content": "Hi, I'm Sham." }, { "role": "assistant", "content": "Hi Sham Where are you planning to travel?" }, { "role": "user", "content": "I want to go to Goa." }, { "role": "assistant", "content": "Great choice When are you planning to go?" }, { "role": "user", "content": "Next month. Any hotel recommendations?" } The model knows your name, knows you're going to Goa, knows when — all because you sent the history. And because history = tokens, you manage how much you send. In production, most apps keep the last 10-15 messages. Beyond that, old messages eat tokens without adding much value. Along with messages, you pass a few settings. The one you'll tune most is temperature . It controls how creative or consistent the model is with its responses. Imagine a dial: Use 0 when you need structure — generating SQL, extracting data, filling templates. Use 0.5–0.7 for natural conversations — enough variation to sound human, enough consistency to be reliable. I left temperature at default for my database agent and got slightly different SQL queries for the same question on different runs. Setting it to 0 fixed it immediately. When the model ignores your instructions or gives a strange response, there is one move that fixes 90% of issues: Log the full messages array. Read it as if you are the model. Most of the time the bug is right there. A user message that contradicts the system prompt. A history so long the instructions are buried. A missing piece of context that makes the model guess. The model isn't broken. It responded to exactly what you sent it. Reading the full payload shows you what you accidentally told it to do. Build this habit from day one. It saves hours. You now understand what goes into every LLM call — where the model lives, how you connect, and the structure of what you send. The concepts are the same whether you use Gemini, GPT, Claude, or a local Ollama model. Time to write actual code. Next up: Spring AI — what it gives you over plain HTTP, and how to build your first chat endpoint in Spring Boot. If you're just starting out — try Ollama first. Free, no API key, runs on your machine. Get comfortable with the concepts, then move to a cloud model when you're ready to build something real. Drop in the comments which one you picked and what you're building. Sham Prakash K — Backend Engineer, 4+ years in Java, Spring Boot, and distributed systems. Building AI backend infrastructure. Writing about what I actually learned, mistakes included.