Welcome to AI Systems. This is episode one of five, and the whole series is built around one practical argument. Should your product own its own harness, meaning the software wrapped around the model, and keep it model-agnostic so it works with any provider? Or should you build on the agent runtime that the model provider already ships? One engineer argues for keeping your options open. Models change fast. You want to be able to switch to a better one without rebuilding your product. And even a strong model can do badly if the system around it hands it the wrong tools or the wrong information. Another engineer thinks that worry is fading. Newer models are arriving with more useful agent behaviour already trained in. All the elaborate prompting and step-by-step scaffolding that older models needed might not be worth the complexity anymore. Strong results from products like Cursor seem to point that way. Both engineers have a point. Neither one, as stated, tells you what to build. To decide, you need to pull apart four things: what the model learned in training, what it was told this time, how much computation it was given, and what the software around it actually did. We'll follow one made-up task all the way through. A user asks a coding agent to fix a parser that crashes when it gets an empty input. The agent reads the repository, finds the parser, runs a test, edits the guard clause, and checks the result. That looks intelligent. So where did it come from? It could be a training example, a prompt, a tool description, a fixed workflow, or feedback from the environment. By the end of this episode you'll have enough of the mechanics to ask that question properly. You don't need a machine learning degree for this. You do need to be comfortable with the difference between an interface and what sits behind it. I'll bring in the machine learning ideas as we need them. By the end you should be able to name several possible sources for the same visible behaviour, propose a test that separates some of them, and say what that test can't tell you. Start with what goes in. You type a sentence. The model doesn't see your sentence. It sees a list of numbers called token IDs. A tokenizer chops your text into pieces from a fixed vocabulary. A piece might be a whole word, part of a word, a punctuation mark, or some other fragment. Exactly how it splits depends on the tokenizer. The number is a label, not meaning. Think of it like a cloakroom ticket. In a made-up vocabulary, the word parser might be number forty-two. A different tokenizer could split the same word into several pieces with completely different numbers. Forty-two doesn't mean parser in any deeper sense. This matters because everything you hand the model ends up as these pieces. Your instructions, your tool descriptions, the file contents, the tool results: all of it becomes one long sequence. So formatting changes what the model actually receives, even when a human would say the meaning hasn't changed. Here's an example. Picture two descriptions of the same operation. One says: replace the exact old text in the specified file. The other says: mutate the resource using a transformation object. A developer who's read the API manual might call those equivalent. The second one still makes the model work out extra conventions on its own. The difference isn't just more or fewer tokens. The task is stated less directly. We haven't proved the first one works better. We've spotted a difference worth testing. That's the first habit this course keeps coming back to: a plausible mechanism is a reason to investigate. It isn't permission to make up a result. The model has to turn those ID numbers into something it can calculate with. An embedding is the first step: it gives each token a starting set of numbers. That set of numbers is called a representation. It's just numbers the computation uses, not a dictionary entry a human could read. As the input moves through the network, those representations get updated based on the other tokens around them. Attention is one way that happens. Roughly, each position asks a question, compares it against the other positions, and uses the answers to decide how much to pull in from each one. In the jargon, a query is compared with keys to produce weights, and the weights mix the values. Many layers then reshape that information further. Position matters too, because word order matters. The original Transformer paper laid out these pieces in a model built for translation. We're borrowing the ideas. We're not claiming every frontier model today is a copy of that design. Back to the parser. Say the instructions include: preserve the existing response field. Later, a test mentions that same field. The model's computation can link the earlier rule with the later test. What actually happens inside is arithmetic. Saying it remembered to preserve the field is our human way of describing the effect. Now take the phrase: inspect the repository. In one prompt, it's a required first step. In another, it sits inside a quoted example of something you shouldn't bother doing. Same words, different context, different right answer. A token's ID stays fixed while its representation shifts with its surroundings. It's tempting to think of attention as the model deliberately focusing, the way a person would. That picture can mislead you. Attention weights on their own don't fully explain why the model gave an answer. And the fact that an instruction fits in the context window doesn't mean the model applied it correctly. For the harness argument, this gives the keep-your-options-open side something concrete to point at: the system around the model decides what information the model sees. It also hands the other side a fair question. Could a stronger model do fine with input that's less carefully prepared? The answer has to come from comparisons, not from assuming that all context engineering matters, or that none of it does anymore. A language model like this writes one token at a time. Everything so far shapes the odds of what comes next. It picks a token, adds it to the input, and goes again. The final answer is built out of those step-by-step choices. In training, the real next piece of text in the training data is the target. A loss score measures how badly the model guessed it. An optimiser then nudges the model's adjustable numbers, called weights, so it does better across all the training examples. Keep three things apart. Weights are the numbers training can change. Representations are the numbers worked out while the model processes one particular input. The prediction is what comes out. You can change the input, and with it the representations and the prediction, without touching the weights at all. Here's a made-up miniature example. The training text says: the parser rejects empty input. At one point, the correct next token is empty. Say an imaginary model gives that a one in ten chance. A slightly different set of weights might give it one in five, and so lose less on that spot. Those numbers are for illustration only. They're not measurements of any real model. Nobody has to tag that sentence as a lesson in defensive programming. The text supplies its own answer. Across huge numbers of examples, patterns that help with prediction get strengthened. What the model ends up learning depends on the data, the architecture, the objective and the optimisation, not on a slogan about predicting tokens. That's why "it only predicts tokens" isn't a good enough analysis of what a model can do. It describes the training goal and how output gets generated. It doesn't tell you which strategies or internal patterns make the model good at a given task. The flip side holds too: fluent text isn't proof the answer is right. You have to test what the model can actually do. Pretraining is the first, broad phase of training. A base model is the checkpoint you get before the later stages that shape its behaviour, which we're about to cover. Base doesn't mean it has no useful abilities. It just marks a point in the model's training history. Could our agent's habit of reading the code first come partly from patterns it picked up in pretraining? Yes, that's possible. Possible isn't the same as proven. Without documentation, or controlled comparisons between checkpoints, you can't work out what a private model was trained on just by watching it behave. A broad predictor isn't automatically the assistant your product needs. You want it to respond to requests, use the tools you give it, and stick to your rules. Post-training is the extra training used to shape those behaviours and others. One method is supervised fine-tuning. The training data gives an input and the response you want. Training makes those demonstrated responses more likely. The key difference from putting an example in a prompt is this: fine-tuning changes the weights. An example in a live prompt only changes the input. For our parser, a demonstration might include the issue, a request to read the parser, the file that came back, an edit, and a test result. That ordered record is called an agent trajectory. Train a model on records like that, and the tool calls and their results become part of what it's learning to produce. That's my own example of how the mechanism could work. It isn't a claim that any named coding model was trained on this parser or this sequence. Another dataset might contain only the issue and the final patch. Those two datasets teach different parts of the interaction. The InstructGPT paper is a documented, historical example: fine-tuning on demonstrations, followed by training on human preferences. It helps us tell the mechanisms apart. It doesn't reveal how today's models are trained. Now make the strongest case for the native-runtime engineer. If a newer model has already learned to pick useful actions, you may not need a prompt that spells out every step. A rigid checklist could add complexity, or even block a better approach the model would have found on its own. Then make the strongest case for the other side. A model that has learned good habits still needs a usable interface and the information this specific task requires. If the model learned a useful pattern and your interface makes that pattern awkward to express, it can get less reliable. Whether that happens, and how much it costs you, is something you'd have to measure. Notice that we've sharpened our thinking without picking an architecture. More behaviour can live in the weights, and the fit between model and interface can still matter. Both can be true at once. Reinforcement learning adds feedback about results or actions. A policy is the rule for choosing what to do, given what you know. Here, the policy is the model plus its settings. Training lets the model try things, scores them with a reward, and adjusts the weights toward whatever scored better. A reward is a measurement the training process uses. It doesn't mean true, useful or safe. It means whatever it was built to measure. It might come from a test that passes or fails, a human's judgement, or a separate model trained to predict human judgements. Say our made-up training setup rewards parser fixes that pass a hidden test suite. Reading the code first often helps, because it shows you the existing conventions. So strategies that read the code at the right moments can get rewarded, even though the reward never says read first. That doesn't mean every step got correctly credited for the success. When the reward only arrives at the end, you have what's called a credit assignment problem: which choices actually helped? And if the reward is incomplete, something can score well without doing what you meant. Imagine the setup lets the agent delete a failing test, and the reward only checks the tests that are left. Now the reward can favour the wrong kind of success. That's an example I've made up, not a report about any real model's training. It shows why the actions you allow, and the way you check the work, shape what good behaviour means during learning. InstructGPT used human comparisons between responses to train a reward model, then trained the main model against that reward. The goal was tied to the preferences people gave. That didn't turn preference into guaranteed factual accuracy. DeepSeek's R1 paper is a different documented case. It describes R1-Zero, trained with reinforcement learning straight from a base model, using rewards for accuracy and for format. It keeps that separate from the full R1 pipeline, which adds cold-start data and extra stages. Saying R1 was trained without any supervised preparation would blur that line. For our debate, this makes it plausible that behaviour we once had to scaffold explicitly can now be trained in. The reward, the environment and the trajectory format can also create compatibility requirements of their own. A model can be broadly capable and still perform differently when the action interface changes. So we have a mechanism behind both engineers' instincts. What we don't have yet is a measured comparison telling your team where to draw the line. Now keep the model fixed and change only what you give it. You add a note to the repository saying the parser tests run with a project-specific command. The model can use that note on its very next action. No training needed. That's conditioning. In-context learning means using instructions or examples in the input to change behaviour on the current task, without the weight changes of fine-tuning. The GPT-3 paper tested this with no examples, one example and a few examples, which it calls zero-shot, one-shot and few-shot. It also found the gains vary from task to task. The trap here is the word learning. A product might say the agent learned your convention, when what's really going on is that the convention is still in the conversation, or it got pulled back in from a saved note. That's useful. It's just a different kind of memory from changing the model's weights. Here's an example. In session one, you tell the agent the test command is called neral check. It uses it correctly. In session two, you ask the same thing without the note. If the system automatically pulls up the earlier convention, a correct answer doesn't mean the weights changed overnight. The information just came in by a different route. If you want to test what context is doing, look at, or control, the full input that actually gets sent. A chat that looks fresh can still carry saved memory, system instructions or retrieved content. Clearing the visible messages isn't the same as removing everything relevant. For the keep-your-options-open engineer, this means the platform's retrieval and memory choices can change what the model appears able to do. The native-runtime engineer has a fair reply: the provider's runtime may already handle this continuity well, so building your own version could just be duplicated effort. The way to settle it is practical. Compare what each runtime actually supplies, keeps and retrieves, then grade the behaviour against the same task requirements. Owning the harness doesn't guarantee good context, and neither does going native. Inference means using the trained model to process an input and produce output. It's a different operation from updating the weights in training. A system can spend different amounts and kinds of computation at inference time. It can allow longer output, turn on a reasoning setting, generate several candidate answers, or spend extra turns gathering evidence. Those are different levers. Don't lump them into one dial labelled intelligence. OpenAI's report on o1, which is now historical, describes performance improving with more reinforcement learning compute and more thinking time at test time, in the setup they reported. That's a documented vendor result. It doesn't promise that more thinking time helps on every task. Back to the parser. One setup proposes a patch straight away. Another checks the tests and considers a few readings of what empty input should do. The second might be more reliable. It might also be slower, or burn resources on a detour it didn't need. I'm not going to give you made-up numbers for that. If a native agent and your wrapper use the same model but different time limits, effort settings or retry rules, you can't automatically blame the score gap on how well the tools fit. You have to record those things separately. The model's explanation of itself also isn't a reliable account of how it got there. A model saying "I did this because of my training" is generated text, not verified training history. Judge its answers and actions against independent evidence. This cuts both ways in the argument. Maybe a model has got good enough that extra scaffolding adds little. Maybe one runtime is simply spending more compute. A clean comparison needs to separate those before anyone turns a performance result into an architecture decision. That covers most of the model side. Here's the catch: when a model proposes a tool call, it doesn't run anything. Software around it has to interpret the request, check it, make sure it's allowed, run the tool, and send back the result. A harness is that runtime and control layer around the model. It can include the instructions, how context gets assembled, the tools, task state, the loop that runs everything, error recovery, and logging so you can see what happened. Where the boundary sits varies between systems, so pin it down before you compare products. Follow the parser task step by step. The user's request comes in. The harness packages it with instructions, tool definitions and the relevant project state. The model gets that input and proposes reading a file. The executor checks the path and the permissions, reads the file, and returns what's in it. The next model call sees that result. The model proposes an edit. Software checks the edit and applies it if it's allowed. A test tool runs the check and returns a real pass or fail. The model can then adjust, or report back. There are plenty of places where two runs that look the same can quietly differ. One tool response includes the useful stack trace; another cuts it off. One edit is allowed; another is blocked. One runtime runs the tests automatically; another leaves that to the model. One run still carries the earlier rule about the response field; another has lost it. A capable model can't write a file through an interface that doesn't offer file writing. Offering it doesn't guarantee the model picks the right file or reads the feedback correctly. Having the opportunity and making good choices are two separate contributions to what you end up seeing. Feedback from the environment changes the next input. A failed test can expose an edge case the model missed, so its next move changes even though the model itself hasn't. That's adapting while it runs. It isn't necessarily reinforcement learning, which would mean a training update actually happened. A feedback loop alone doesn't prove that. That's why an agent is a system, not just a model with a new label. The model and the machinery around it shape each other through actions and observations. Here's the mental model to keep. Training shapes the habits stored in the weights. Context supplies the information for this task. Inference sets how much computation goes into each decision. The harness and the environment turn those decisions into actions and feedback. Those are categories for diagnosing problems, not separate knobs on every system. A harness might choose the inference budget. Training might shape how a model reacts to a tool description. You can separate them in your analysis without assuming their effects simply add up. Now take the sentence: the agent always inspects the repository before editing. Possibility one: the runtime does the inspection before it even asks the model anything. Possibility two: a system instruction tells the model to inspect. Possibility three: repository guidance pulled in through retrieval nudges it to inspect. Possibility four: the model itself tends to choose inspection on tasks like this. Possibility five: an earlier failure in this run made it inspect. All five can look much the same in the interface. Some can be happening at once. A transcript showing the action proves the action happened. It doesn't tell you where it came from. Say you remove the explicit instruction and the inspection carries on. You've learned that the instruction wasn't necessary in those runs. You haven't shown the behaviour came from post-training. Another instruction, a retrieved note, a runtime gate, or something picked up in pretraining could still explain it. To dig in, change one thing at a time and look at where each real action came from. Remove a runtime gate and keep the prompt the same. Remove the retrieved note in fresh sessions. Compare documented model versions under identical conditions. Measure whether the task succeeded separately from how often the agent inspected. That last point matters. Inspecting is valuable in an unfamiliar repository and a waste of time on an obvious one-line fix. If you reward the ritual itself, you can end up optimising a behaviour that doesn't make the task go any better. Work out what benefit you expect the behaviour to deliver, then measure that benefit. Let's go back to the two engineers with everything we've built up. The native-runtime engineer is right to question old scaffolding. If newer training makes the model more reliable at picking useful actions, a step-by-step prompt can become redundant, or even get in the way. A lighter touch from the harness can be the better design. The keep-your-options-open engineer is right that the system still controls what information the model gets, what it's allowed to do, how things get executed, and what feedback comes back. A better model doesn't make those jobs go away. And it doesn't guarantee that every interface brings out the model's abilities equally well. Cursor's engineering report from April twenty twenty-six describes tuning for specific models inside abstractions that work across all of them, and testing harness changes in their own system. That's a vendor reporting that harness integration still matters for them. It isn't universal proof that every team should own its harness. There's a test that could cut the other way, and we should keep it open. If removing a piece of the harness hurts older models a lot but barely changes a newer model's results, on comparable tasks and budgets, that supports the claim that this particular scaffold matters less now. It still wouldn't show that every harness responsibility has gone away. We also have to be careful not to switch questions halfway through. There are three different ones. Does the model need fewer instructions? Is a provider's runtime better at getting the best out of it? Should our product depend on that runtime? They're related, and each needs different evidence. The third one also involves maintenance burden, control, and the cost of switching later, not just performance. So the conclusion for week one is conditional. Useful behaviour can come from the trained weights, the current information, the inference settings, and feedback during execution. More trained-in behaviour may cut the need for some explicit scaffolding. Whether it makes your architectural boundary less important is still open. That's real progress. We've swapped a vague argument for mechanisms and tests. We haven't declared a winner. Here's one small experiment for this week. Pick a safe, throwaway task in a repository. Run it in a fresh agent session with no instruction to test first. Then reset the repository and run the same task with that instruction added. Keep the model version, tools, permissions and resource settings as steady as your setup allows. If you have time, do each version twice. Write down whether a real test ran before the first edit, whether the final change was correct, and what went wrong. If the runtime forces testing, note it, because this setup can't measure the model's own choice until you've accounted for that gate. Four runs is a diagnostic exercise, not a statistical result. If the instruction changes the behaviour, it's contributing in this setup. If nothing changes, you haven't proved prompting is irrelevant everywhere. If testing first goes up but correct fixes don't, then following the rule and actually helping have come apart. The companion page has the full procedure, an answer guide, and the limits on what each result can tell you. Now try the mastery check without your notes. An agent reads the repository before editing. The team removes the explicit instruction, and the behaviour carries on. Explain at least four mechanisms that could produce what they first saw. Design two interventions that would tell them apart. Then explain why neither result on its own settles the choice between a model-agnostic harness and a provider's native runtime. Last, here's where we stand on the evidence. What we know: training updates and in-context conditioning are different operations, and running tools needs a system around the model. What's been reported: labs report specific training results, and system builders report specific integration effects. What we're inferring: a model's familiarity with an interface could be one reason performance depends on the interface, though an observed gap can have other causes. What we don't know: how much of any undocumented model's behaviour came from each stage of training. What would change our minds: controlled comparisons that isolate specific scaffolds and show how much they contribute across different models. Next episode, we move from where behaviour could come from to how an interface shapes the way it shows up. We'll look at why two editing tools that can do exactly the same thing in theory can set the model very different problems, and what that means for where you draw your platform boundary.