Context
The file the agent reads before it reads your code
The same prompt worked on Monday and failed on Friday. You changed nothing about the prompt, so the prompt is not the variable.
Ray AmjadOn this page
Every session starts with an agent that has never seen your codebase. It reads one file first. What is in that file decides whether the next hour is work or correction.
It is not documentation
Documentation explains what the code does. The agent can read the code. It does not need you for that.
What it cannot derive is everything that is true and unwritten: which of the
two patterns in lib/ is the current one and which you are migrating away from,
that the whole legacy/ directory is dead, that the tests run with one command
and not the obvious one.
Write the things a new hire would ask on day two and be embarrassed to ask on day ten.
Every line is paid for on every request
This file is not read once. It sits in front of the agent for every message, in every session, forever. A line that is nearly useful is not free. It is rent.
The failure mode is not a missing rule. It is forty rules, six of which matter, and no signal about which six. A file that says everything says nothing, and the agent picks for you.
It rots, and the rot is silent
Nothing fails when a rule names a file you deleted. The agent quietly does something slightly wrong, and you assume the model had a bad day.
Transcript
Okay, so the biggest point of leverage that you have when using Claude Code is your CLAUDE.md file. And many people, including the creator of Claude Code, says that you should be investing in it and ruthlessly editing it over time. In this video, I want to go through exactly what that means and some of the things you can be doing to your CLAUDE.md files to achieve better results with Claude Code. Now, I really like this graphic by Human Layer.
It will be linked down below where it shows you the hierarchy of leverage. And to appreciate why your CLAUDE.md file is so important, you want to consider this: one bad line of code is one bad line of code. A bad line of a plan when you're planning what code should be written by your coding agent equals hundreds of bad lines of code because you just have the wrong solution. One bad line of research can lead to many bad lines of a plan that leads to even more bad lines of code. And then finally, one bad line of specification can lead to many bad lines of research that leads to many bad lines of planning, code, and so forth. So you can see it's kind of cascading down here. And the thing that sits at the very top here is one bad line of your Claude.md file because it's affecting every other thing here. So with one bad line of your Claude.md file, you can get many bad lines of research that leads to even more bad lines of a plan that can lead to hundreds of bad lines of code. So the thing that you can control that has the highest amount of leverage after the model that you're actually using is your Claude.md file. So to 80/20 guarantee saving yourself from a big buggy codebase in the future, you want to focus on making your CLAUDE.md file as good as they can be. And I know that many people watching the video have basically not touched their CLAUDE.md file since their project was created, or touched it like a couple months ago and they haven't updated it since. But I found that this graphic by Human Layer gave me like a really deep appreciation for why I should be focusing more of my efforts up here. And I know that most of you watching this video will almost certainly have a bad CLAUDE.md file, And the reason I know this is because in the Claude Code system prompt, when it reads your CLAUDE.md file, for example, over here, you can see the Claude Code team wrote over here, "Important, this context may or may not be relevant to your tasks.
You should not respond to this context unless it's highly relevant to your tasks." Now, there are a couple of reasons why the Anthropic team may have written something like this. And I think the reality is that many people just have bad CLAUDE.md files that were distracting Claude Code from making good judgment calls. And they found this to be like a good hack workaround to counter the fact that most people just have bad files. And that's because when you look at a lot of the advice online and on Twitter, for example, people are downloading random prompts and putting into a CLAUDE.md file. They're like treating it as a history of all the changes that happen to a project. Their CLAUDE.md file is getting to like 1,000+ lines and they're basically never removing anything or updating it when their project changes. Now there's a pretty good paper from about 7 months ago called "How Many Instructions Can LLMs Follow at Once?" and they tested a bunch of LLMs to see how accurate they were as you increase the number of instructions. And you can see that Claude Opus 4.1, after about 150 instructions over here, its accuracy begins to fall. Other previous weaker models, their accuracy began to fall earlier, and other ones sustained accuracy for a longer period of time before falling. Now I'm sure that recent models have gotten better on this benchmark and maybe they drop after 250 or 300 instead. So you essentially have an instruction limit. Of how many instructions can be given to model before it will do your worst job at the task at hand. Now the Claude Code system prompt contains about 50 instructions. So that means the remaining, let's say this is 250 instead for argument's sake, because the models have gotten better since, you then have about 200 instructions left in your CLAUDE.md file and your plan and your prompt and anything else the coding agent may be reading. And because your CLAUDE.md file is loaded upon every single request, that is the biggest point in leverage that you can have. Now when researching this video, I got Claude Code to download download and analyze over 1,000 CLAUDE.md files from public repos on GitHub to kind of analyze and figure out what the average file looks like. And this is a distribution for the line count of all of these files. You can see some of these CLAUDE.md files are over 500 lines, so about 10% of them, which means that they have way too much instructions that are being loaded in all at once. So much so, it probably explains why the Claude Code team added this in the Claude Code system prompt. And before I was educated on this topic, when I was investigating one of my own CLAUDE.md files, I noticed it reached over 650 lines. And I was like, okay, this probably explains why the model was performing pretty bad on this particular part of the codebase. Now, essentially, because we do have an instruction budget, which is some number depending on the model that you're currently using, you want to start purging your CLAUDE.md file and only including the most relevant things inside of it. Now, one of the most important ideas to understand when editing and removing stuff from your CLAUDE.md files is that as we're getting better and better models, many of the best practices are being ingrained into the model itself. So you don't need to have it in your CLAUDE.md files. Now there's a good related blog post by Vercel that will show you what I mean. They were making an AI agent called D0 for understanding data. So they could ask questions kind of like this and it would just give them an answer on Slack. And when designing this agent, they basically gave it a bunch of tools to make sure that every edge case was covered. And they did all this heavy prompt engineering to kind of constrain the model's reasoning. And they found this success rate to only be 80%. It was taking longer to complete tasks and it was using more tokens. And then they were like, okay, what if we just remove all the tools and just give it 2 tools instead and rely more heavily on the underlying power of the model? Let's not do the model's thinking OpenAI, it's capable enough on its own.
And after doing this, they reached 100% on their benchmarks and they got it done in fewer steps, faster, and with less tokens. And this is a general trend that we're seeing as well going forwards. A lot of the things that people are adding to their prompts, so their CLAUDE.md files or their agents, they're trying to handle all these weird edge cases for the agent and trying to do the thinking of the model for the model itself. But as we get model upgrades, you actually want to be removing stuff. From your CLAUDE.md files and removing some of the tools that you have available. Because chances are those best practices are now ingrained into the model itself. So you don't have to fill your CLAUDE.md files with obvious things like saying use encryption when it comes to handling passwords or something, or doing what I did over here and telling it how to handle Git submodules because it already knows how to do that. Or giving it example code for how to do things like I have in my file here.
As the models are getting better, you don't need many of these things. Because many of these best practices are slowly being baked into the model itself. And ideally what you should be doing is that with every model release, you should be looking at what you can remove instead of thinking about what you can add instead. Because chances are, if you do have some best practices in your CLAUDE.md file, the newer model has even better practices than you have written.
And now you're just constraining the newer and more capable model from applying the even better practices that it has within itself to your codebase. It's also why many of these random things that people are finding on Twitter and sticking into their Claude.md file, hoping it will suddenly fix everything, ends up performing worse. Because either you're essentially wasting space by putting things into Claude.md file that it already knows not to do, like premature generalization. Newer models will be better at this than older models, so there's no reason to specify this.
Or stuff like not seeking clarifications when needed. And this is also why some people notice a newer model performs better on a brand new codebase that does not have a Claude.md file, because it's not being held back by any constraints that you wrote in your Claude.md file. To handle bad behaviors in older models. Now because of that, I can probably remove several hundred lines from this CLAUDE.md file because I know that recent models have gotten even better and they don't need all this like excess padding teaching it how to do something in probably a less efficient way than it already knows how to do. The better approach here is to start really small. Don't rely on any CLAUDE.md files that you find online or using the init command to auto-generate one because that ends up being way too verbose.
You should start small with the bare minimum and only add things as you find the model making mistakes. By only adding things when needs be and committing it to GitHub, you can go back to a point in your codebase where you added a new line that led to worse performance for the model. So at the very beginning of a brand new project, your CLAUDE.md file may be as small as this. So it just gives a description of what you're making.
So Claude Code, when it comes up with a plan, it knows exactly how everything ties back to the bigger picture. Then you have some short commands that may not be inferred from the codebase itself. Like using npm instead of pnpm or bun, for example. And then over time, as you're coding with Claude Code, you may notice that it makes a mistake. And then you add a brand new thing to your file such as this. When a library's types are unclear or cause errors, never use the anycasts. Instead, use an explorative agent to search through the packages-types file. And you may consider removing this a couple of months later when we have better models and a better Claude Code, because it may have a better way of handling this specific situation. So by doing this, you essentially ensure that Firstly, when you're adding new things to your CLAUDE.md file, you can know what line may have caused it to perform worse. And secondly, you prevent yourself from hitting your instruction budget too soon, whatever that may be, by not having a really long CLAUDE.md file. One thing you want to bear in mind when having your CLAUDE.md file is that positioning matters. So ideally it should be in the structure of project description, key commands near the top, because LLMs weigh things that are closer to the beginning and the end of their instructions more than things that are kind of in the middle.
And then also any caveats. But these caveats should instead be ingrained into hooks that I will be covering later. Now, something that I don't see people doing enough is to split up their Claude.md file into many smaller ones that they have distributed throughout their project in folders and subfolders. So to show you how this works, you have your root Claude.md file, which is always loaded in in the conversation at the beginning. And then when the model wants to read a file on your computer, Claude Code will then use a read tool and pass it back into model. So you can see it kind of looks like this. The model says, oh, this file looks interesting. I want to use the reads tool. Then our local version, like Claude Code, reads that file, passes it back into model on Anthropic servers. And it has like, this is line number 1, this is line 2, 3, 4, and so on.
And at the very end of the file, we have a system reminder. And then we have the nested CLAUDE.md file. So not the root one, we have the nested one. So this means if Claude Code were to read file 1, the CLAUDE.md file at the same hierarchy, the same level would be be appended onto the tool result. So if in another situation we had file 3 over here and Claude Code wanted to read that, then this Claude.md file would be appended onto it, then this one. And if it were to read file 2, then the blue Claude.md file and the red one would be ignored because they exist in different parts of the codebase. Now the reason this is powerful is because since your root Claude.md file is loaded in at the beginning of the conversation, it can end up forgetting certain things much later down in the conversation.
But by lazy loading any Claude.md files by appending it just after the file, we have any relevant context injected into the right point in the conversation at the right time. So this means your root Claude.md file can be really lightweight and you can have more context-heavy Claude.md files in other parts of your codebase. So as a quick example, in my root Claude.md file, I have this migration flow when it comes to creating Supabase migrations. And honestly, this should not be in the root Claude.md file because in many cases I simply won't be making a Supabase migration. So this is taking up tokens and space and instruction budget when it doesn't need to be. So what I can do is I can delete this from the root file, then go to my Supabase folder right over here, right-click, create a brand new Claude.md file, and then paste it in over here instead.
So this basically means whenever Claude Code reads a Supabase file because it's about to make another migration, then this will automatically be injected into conversation at the right point. Now there may be some times where you don't want to rely only on the Claude.md file to do something for you. So for example, this thing earlier where it says never run db push yourself, always let the user push migrations to remote after reviewing them, 1 in 30, 1 in 50 times Claude Code may ignore this particular hook and try to do db push. Partly because a session could end up going really badly and I confuse the model a lot during the session and partly because of this system reminder.
So what I can do instead is rely on a hook because that will work every single time. So tagging the Claude Code guide subagent, I can then say, can you search online to find every dangerous Supabase command like supabase db push and then block all those commands with a pre-tool use hook. And that will look through the Claude Cloudflare R2 code docs to understand how hooks work. And then also search online as well. So you can see that after searching online, it now made me a hook script and it's adding the hook to the pretool use hook. And if I look through the hook here, I can see that's blocking supabase db push. So I no longer need this in my CLAUDE.md file. I can delete this from over here.
And then it's blocking other commands like supabase db reset, migrations repair, and a bunch of other things because I want to do those commands instead. Instead of having a constraint in my CLAUDE.md file, such as never touch this particular folder, I can tell Claude Code to make a hook to prevent that happening to begin with. And then finally, especially if you're working in a team, you want to regularly audit your CLAUDE.md file. So there may be a new model release and you don't need as many things to teach it the correct behavior. You may notice that you are adding random things to your CLAUDE.md files throughout the week, and now you have conflicting instructions or instructions that should belong in another CLAUDE.md file in the codebase.
And if you don't do that, you may notice that you get a Claude Code file that is several hundred lines long because you kept telling Claude Code, hey, just add that to a CLAUDE.md file. And now every time you use Claude Code, your context window fills up way too quickly and you've also hit your instruction budget limit much sooner.
Get the next one
One email when something new goes up. No drip sequence, and nothing you have to unsubscribe from twice.