Additional Claude Code features and strategies
Optional self-study content for week 9
1 Introduction
1.1 Background
This page builds on the w9a lecture, where you set up Claude Code in VS Code Server and created a week09 project dir with a CLAUDE.md file. Here, you’ll learn about additional ways to make working with Claude more effective and safer: plan mode, skills, memory, and guardrails.
1.2 Setting up
Start and open a VS Code Server session.
Open your
week09project dir with the Open Folder functionality.Some exercises below ask you to commit your changes, so if you haven’t done so yet, make your
week09dir a Git repository (week 5):# Run this in your week09 dir git init git add CLAUDE.md scripts git commit -m "Add CLAUDE.md and scripts from the w9a lecture"
2 Plan mode
2.1 Plan first, then act
For bigger tasks, it’s often better to have Claude write a plan first, before it changes anything. Claude Code has a dedicated mode for that: Plan mode.
In this mode, Claude will look around your project, perhaps ask you some clarifying questions, and write a plan that opens as a Markdown document. You can then edit the plan, ask for changes, or approve it so that Claude carries it out.
To switch to Plan mode, click the “mode indicator” that shows the current mode (e.g., “Manual”) in the bottom right of the prompt box, and select Plan:
Plans are also a good way to see how model choice and effort level affect Claude’s work, which is what you’ll explore in the exercise below.
Exercise 1: Compare a fast and a thorough plan
You’ll ask Claude for the same plan twice: first with a small model, then with a large model and high effort. Use the following prompt both times:
Write a plan for aligning the FASTQ files in ../garrigos/fastq to the reference genome in ../garrigos/ref, and then counting the aligned reads to produce a gene count table. We will run this at OSC with Apptainer containers. Which alignment and counting programs would you recommend, and why?
Round 1 — fast:
- Switch to Haiku (which has no effort levels), and select Plan mode.
- Send the prompt, and read the plan. For example: How many steps does it have? Does it name specific programs and versions? Does it ask you any clarifying questions, or mention uncertainties? Did it check which files are actually in
../garrigos/ref? - Run
/usageto see how much this plan cost.
Round 2 — thorough:
- Start a new conversation, so that the first plan doesn’t influence this one.
- Switch to Opus with High effort, keeping Plan mode on.
- Send the same prompt, and read the plan with the same questions in mind.
- Run
/usageto see how much this plan cost.
Think about:
- What differences do you notice between the two plans?
- Run
ls ../garrigos/ref: there is a genome annotation file, but no genome FASTA file yet (you’ll download it in week 10). Did either plan notice this? - How would you check whether a plan is reasonable and complete?
- How do the plans compare to what Garrigós et al. (2025) did?
- Would the “fast” plan have been good enough?
- What are the trade-offs between speed and thoroughness in planning?
(Don’t let Claude carry out the plans: decline, or simply stop, when it asks to proceed.)
A common strategy is to write the plan with a larger model like Opus, and then switch to a smaller and cheaper model like Sonnet to carry it out: much of the hard thinking happens while planning. Switching models means that your next message can’t use the cache, but for a bigger task, this one-time cost is usually worth it.
3 Skills
3.1 What are skills?
CLAUDE.md is meant for information that Claude should always know about your project. But you may also have multi-step procedures or checklists that you only need for specific tasks — for example, reviewing a script, or checking the outputs of a workflow. For those, you can create a skill.
CLAUDE.md |
Skill | |
|---|---|---|
| Use for | Information Claude should always know | Procedures for specific tasks |
| Example | Project dirs, script conventions, rules | Reviewing a script, checking outputs |
| When loaded | At the start of every conversation | Only when used |
At the start of a conversation, Claude only sees each skill’s short description, and it reads the full instructions only when it uses the skill. So, skills can be long without using many tokens in every conversation. A skill is a Markdown file called SKILL.md, with instructions for one specific task. Each skill gets its own dir in .claude/skills in your project:
week09
├── .claude
│ └── skills
│ └── review-script
│ └── SKILL.md
├── CLAUDE.md
└── scripts
3.2 What’s in a SKILL.md file?
A SKILL.md file has two parts:
- Front matter between two
---lines, like the YAML header of a Quarto document. Its most important field is thedescription, which Claude uses to decide when the skill is relevant. - The instructions: what Claude should do, and what it shouldn’t do.
For example:
.claude/skills/review-script/SKILL.md
---
description: Review a shell script for errors and for the conventions used in this project.
---
Review the shell script that the user points to:
1. Read the script and check for errors: syntax, unquoted variables,
wrong paths, and commands or options that may not exist.
2. Check that it follows the shell script conventions in CLAUDE.md.
3. Report confirmed problems first, and optional improvements separately.
4. Don't edit the script, but ask whether the user wants you to apply the fixes.3.3 Using a skill
You can use a skill in two ways:
- Explicitly: by typing
/followed by the name of its dir, e.g./review-script. - Automatically: when your request matches a skill’s description, Claude often uses the skill without being told to.
Exercise 2: Create and use a skill
In your
week09dir, create the file.claude/skills/review-script/SKILL.md, with the contents shown above.Start a new conversation, type
/review-script, and point Claude toscripts/fastqc.sh. Do you agree with its review?Start another new conversation, open
scripts/count_reads.sh, and ask:Can you check this script for problems?
Did Claude use the skill? (If it did, you’ll see this in its response.)
Improve the skill based on what you saw, for example by adding a check that you think is missing. Then commit it.
3.4 Having Claude create a skill
You don’t have to write skills yourself: Claude can write them for you. This works especially well right after you’ve done a task together with Claude, because the conversation then contains all the steps, as well as any corrections you had to make along the way. For example, you could ask:
Turn what we just did into a skill, so that next time, you can do this without my corrections
You can also describe a new skill from scratch, for example:
Create a skill for checking the outputs of a FastQC run: check that there is an output file for each FASTQ file, and summarize any modules that failed
Either way, read the skill that Claude wrote, and edit it where needed. Claude will follow its instructions every time it uses the skill, so any mistakes in it will be repeated, too. Then, test the skill on a real task, and keep improving it based on what you see.
Making skills available in all your projects
If you want certain skills to be available in all your projects, simply place them in~/.claude/skillsin your Home dir.Using skills created by others
Many people share skills online, such as in Anthropic’s skills repository on GitHub. To use such a skill, simply copy its dir to.claude/skillsor~/.claude/skills. Besides aSKILL.mdfile, these dirs may contain other files, like scripts that Claude can run. Be careful, though: a skill contains instructions that Claude will follow, so only use skills from sources you trust, and read them (including any scripts) first.
4 Memory
4.1 How Claude’s memory works
In the lecture, you learned that Claude reads your CLAUDE.md at the start of every conversation. In addition, Claude keeps memory notes for itself (“auto memory”). As it works with you, it may save notes about:
- Your preferences and corrections you’ve given it (e.g., “the user prefers lowercase variable names”)
- Project context that it can’t work out from your files (e.g., a deadline, or why a decision was made)
It doesn’t save something in every conversation, only things it thinks will be useful later. When it does, you’ll see a message like “Saved 1 memory” in the Claude panel.
The memory is stored separately for each project (each Git repository), in a dir in your Home dir: ~/.claude/projects/<project>/memory/. That dir contains an index file, MEMORY.md, which is loaded into every conversation in that project, and one file for each memory, which Claude reads when it needs to.
4.2 Memory vs. CLAUDE.md
CLAUDE.md |
Memory | |
|---|---|---|
| Who writes it | You (or Claude, when you ask it to) | Claude, when it thinks it’s useful |
| Contains | Instructions and rules | Things Claude learned while working with you |
| Where | In your project (can be committed with Git) | In your Home dir (only for you) |
Compared to browser-based chatbots, which may remember general things about you, this is a big advantage: both CLAUDE.md and Claude’s memory are specific to each project, so Claude can pick up where you left off in that project.
If you want Claude to remember something, you can tell it directly:
- “Remember that …” makes Claude save a memory.
- “Add this to CLAUDE.md: …” adds it to your
CLAUDE.mdinstead. This is better for things that collaborators (or your future self) should also know, sinceCLAUDE.mdis part of your project.
4.3 Viewing and editing memory
Type /memory in the prompt box to see your CLAUDE.md files and memory, and to open them for editing. Memory files are plain Markdown, so you can edit or delete them as you like — and it’s worth checking them now and then, since Claude may have saved something that’s wrong or no longer true.
You can also turn auto memory off with the toggle in /memory, or for a single project by adding "autoMemoryEnabled": false to the project’s .claude/settings.json. For more, see the documentation on CLAUDE.md and memory.
Exercise 3: Make Claude remember something
In your
week09project, tell Claude:Remember that when I ask you to explain code, I want a short explanation with an example
Type
/memoryand find the note Claude saved.Start a new conversation, and ask Claude to explain a line from one of your scripts. Did it follow your preference?
Would this preference have been better placed in
CLAUDE.md? And what about an instruction like “Never modify anything in../garrigos”?If you don’t want to keep this memory, delete it (e.g., by asking Claude to forget it).
5 Guardrails
An agent that can edit files and run commands is powerful, but it can also make much more damaging mistakes than a chatbot can. To reduce the risk of such mistakes, we can use a set of “guardrails”.
5.1 Git as your safety net
Version control (week 5) pairs very well with agentic AI:
- Before asking Claude for a bigger change, commit your work, so that
git statusis clean. - After Claude is done, review all changes with
git diffor the VS Code Source Control panel, including changes to files you didn’t have open. - Undo changes you don’t want with
git restore <file>, or discard them in the Source Control panel. New files that Claude created are untracked, sogit restorewon’t remove them:git statuslists them, and you can delete them yourself.
You can ask it to, e.g., commit your changes (including writing the commit message), show what changed since the last commit, or undo specific changes. As always, check what it did.
5.2 Built-in protections
By default, Claude Code:
- Asks before editing files and before running commands (except a set of read-only commands, like
ls). - Asks before accessing files outside your workspace.
- Tries to detect “prompt injection”: instructions hidden in files or web pages that Claude reads, which try to make it do something you didn’t ask for. This protection is not foolproof.
5.3 Permission rules
You can add your own rules about what Claude may do, in a permissions section of a settings file. There are three types of rules:
- allow: Claude may do this without asking.
- ask: Claude must always ask first, even in permission modes that normally don’t ask.
- deny: Claude may never do this.
For example:
.claude/settings.json
{
"permissions": {
"ask": [
"Bash(rm *)",
"Bash(git push *)"
],
"deny": [
"Read(~/.claude/settings.json)",
"Edit(//fs/ess/PAS3493/people/*/garrigos/**)"
]
}
}This example:
- Makes Claude always ask before removing files or pushing to GitHub.
- Prevents Claude from reading your user settings file, which contains your API key.
- Prevents Claude from editing files in your raw data dir.
These rules aren’t watertight, though. For example, the Edit rule blocks Claude’s own file edits, but not a script that Claude runs which writes to or moves those files.
Where you put these rules determines where they apply:
| File | Applies to |
|---|---|
~/.claude/settings.json |
All your projects (this is where your API key is) |
.claude/settings.json in a project |
That project; commit it to share the rules with collaborators |
.claude/settings.local.json in a project |
That project, just for you (don’t commit it) |
When you choose “Yes, allow … for this project (just you)” for a command, Claude saves an allow rule in .claude/settings.local.json. To see all rules that are currently active, and which file each comes from, type /permissions in the prompt box.
The documentation on permissions describes the full rule syntax.
Exercise 4: Add permission rules
In your
week09dir, create the file.claude/settings.jsonwith the contents shown above.Start a new conversation, and type
/permissionsto check that the rules are active. If they don’t show up, check the file for typos, such as a missing comma or quote, before you continue.Ask Claude:
Show me the contents of ~/.claude/settings.json
What happens?
Before testing the
Bash(rm *)rule, predict: which of these commands would make Claude ask first because of that rule?rm test.txtrm -f test.txtfind . -name test.txt -delete
Then, create a file to practice with (
touch test.txt), switch to the Edit automatically permission mode, and ask Claude to deletetest.txt. Which command did it use, and did it ask first? Afterwards, switch back to Manual mode.Commit
.claude/settings.json.Suppose a labmate clones your
week09repo from GitHub and works on it with Claude. Which of the following would their Claude know about or follow?- The script conventions in your
CLAUDE.md - Your preference for short explanations from the memory exercise
- Your
review-scriptskill - The permission rules in
.claude/settings.json - An allow rule that was saved when you chose “Yes, allow … for this project (just you)”
- The script conventions in your
Click here for the solution
The two
rmcommands match the rule, but thefindcommand doesn’t, even though it also deletes the file: rules match the text of a command, not what the command does. There are many ways to delete or overwrite a file (mv,>, a script, …), so a rule like this lowers the risk of mistakes but doesn’t rule them out.Their Claude would use your
CLAUDE.md, your skill, and the rules in.claude/settings.json, since you committed all three to your repo. It would not know about your memory, which is stored in your Home dir, or the allow rule, which is saved in.claude/settings.local.jsonand shouldn’t be committed.