LangGraph Deep Agents Skills and AGENTS.md Memory
A LangGraph deep agent gives you two places to put domain knowledge: skills and memory. They look alike, since both are Markdown files the agent reads, but they cost different amounts. Skills load lazily: the agent sees one line per skill until it decides it needs one. Memory loads eagerly: AGENTS.md goes into the context at startup, every time. The rule this post builds on is simple. Skills are lazy, memory is eager, so put each fact where its load cost matches how often the agent uses it.
LangGraph Deep Agents, a 10-part series. ← Part 5 · Part 7 →
This part of the series covers the Agent Skills format (SKILL.md frontmatter and progressive disclosure), the memory= parameter, which backend stores the memory, and how the agent updates its own memory with edit_file. All of it comes from the public Deep Agents skills, customization and memory docs.
What are skills in LangGraph Deep Agents?
A skill is a folder of know-how the agent can pick up when a task needs it. Each skill is a directory with a SKILL.md file. It can also hold scripts/, references/ and assets/ folders. All skills sit under one top-level directory:
skills/
└── langgraph-docs/
├── SKILL.md
├── scripts/
│ └── fetch_docs.py
├── references/
│ ├── api-patterns.md
│ └── style-guide.md
└── assets/
└── report-template.md
SKILL.md starts with YAML frontmatter. The skills page lists these fields:
name(required): lowercase letters, numbers and hyphens, 1 to 64 characters, matching the parent directory name.description(required): what the skill does and when to use it, up to 1,024 characters.license,compatibility(up to 500 characters) andmetadata(free-form key-value pairs), all optional.allowed-tools(optional, experimental): tools the skill may use without asking.
Two limits are easy to miss. The name must match the folder name, and any SKILL.md over 10 MB is skipped at load time.
How does progressive disclosure work?
Progressive disclosure is why skills are cheap. They load in three layers:
- Metadata. At startup the agent sees only each skill's
nameanddescription. - Instructions. When the agent invokes a skill, it reads the full
SKILL.mdbody. - Resources. Files in
scripts/,references/andassets/load only when the instructions point to them.
The description field matters most. It is the only part the agent always sees, so it has to say when to use the skill as well as what the skill does. A vague description leaves a skill unused, because the agent cannot tell the skill applies.
How do you add skills to a LangGraph deep agent?
Pass skills= to create_deep_agent. Point it at the directory that holds the skill folders, not at one skill:
from deepagents import create_deep_agent
from deepagents.backends.filesystem import FilesystemBackend
backend = FilesystemBackend(root_dir="./my-project")
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
backend=backend,
skills=["./my-project/skills/"],
)
skills takes a list of source paths, resolved against the backend and written with forward slashes. When two sources contain a skill with the same name, the one listed later wins. That gives you layering for free: list a shared team skill set first and a project-specific set second, and the project versions override.
Skills are read through the backend, the same pluggable filesystem covered in part 04. On disk that is FilesystemBackend. With StateBackend or StoreBackend, the customization docs note that "you must add the expected skill or memory files to the backend before creating the agent." The harness will not create them for you.
What is AGENTS.md memory in LangGraph Deep Agents?
Memory is the eager half. You pass one or more file paths to memory=, and the memory page explains that the agent "can load memory files into the system prompt at startup, or read them on demand during the conversation." In the middleware stack this is MemoryMiddleware, and it is added "only when you pass memory."
Because AGENTS.md is read on every run, it should hold facts the agent needs on most turns:
- project conventions (naming, test command, where things live)
- preferences the user has stated ("answer in bullets", "never touch the migrations folder")
- corrections the agent was given and should not need again
Whatever is in AGENTS.md costs tokens on every call, whether or not it is used. A 200-line runbook for a task that comes up once a month belongs in a skill, where it costs one description line until it is needed.
Which backend stores AGENTS.md memory?
The memory file is a backend file, so where it lives depends on the backend, and that decides how long it lasts:
StateBackend(the default): the file lives in the thread's state. You seed it throughfileswhen you invoke the agent, and it lasts for that thread only.FilesystemBackend:memory=["./AGENTS.md"]reads a real file underroot_dir. This works well for a local coding agent.StoreBackend: a LangGraph store that the docs describe as "persisted across threads."
The usual production pattern mixes them with CompositeBackend. Scratch files stay in thread state, and /memories/ (here also /skills/) is routed to a store so it survives across conversations. This is the agent-scoped example from the memory docs, unchanged:
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
agent = create_deep_agent(
model="google_genai:gemini-3.6-flash",
memory=["/memories/AGENTS.md"],
skills=["/skills/"],
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(
namespace=lambda rt: (
rt.server_info.assistant_id,
),
),
"/skills/": StoreBackend(
namespace=lambda rt: (
rt.server_info.assistant_id,
),
),
},
),
)
The namespace sets who shares the memory. With (assistant_id,), every conversation with this agent reads and writes the same AGENTS.md. The customization docs also show a per-user namespace, rt.server_info.user.identity, which gives each user their own copy. Reading rt.server_info needs deepagents>=0.5.0. For local development, the docs pass an InMemoryStore() to create_deep_agent (not to the backend) and leave it out on LangSmith Deployment, where a store is provided.
Can a deep agent update its own memory?
Yes, and no special tool is involved. In the memory docs: "When the agent learns new information, it can use its built-in edit_file tool to update memory files." Since /memories/AGENTS.md is routed to a StoreBackend, the edit is saved, and the next conversation starts with the updated file in its system prompt.
That loop is what makes the agent improve over time: the user corrects it once, it writes the correction down, and it does not repeat the mistake. It also has two risks to plan for:
- Memory only grows. Every saved lesson costs tokens on every future run. Tell the agent in
AGENTS.mditself to keep the file short and to move long procedures into a skill. - Memory is shared state. With an assistant-scoped namespace, one user's correction changes the agent for everyone. Choose the namespace on purpose, and consider gating
edit_filewithinterrupt_on, the human-approval hook from part 09.
Skills vs memory: where should each fact go?
Use load cost as the test:
- Needed on most turns →
AGENTS.md. Conventions, preferences, standing corrections. Short and declarative. - Needed for one kind of task → a skill. Procedures, playbooks, reference docs, helper scripts. Make the description precise about when the skill applies.
- Needed for one step of that task → a skill resource. Large references and templates in
references/orassets/, loaded only whenSKILL.mdpoints to them.
If AGENTS.md keeps growing, it is usually holding skills in disguise. If a skill is invoked on every run, its core rule probably belongs in memory. Both cases connect to the context budget covered in part 07.
FAQ
Do skills and memory need a specific backend?
No. Both are read through whatever backend the agent uses. With StateBackend or StoreBackend, the files have to exist in that backend before you create the agent.
What happens if two skills have the same name?
The source listed later in skills=[...] wins, so you can override a shared skill with a project-specific one.
How do I stop the agent from writing bad memories?
Put the rules for memory in AGENTS.md (what is worth saving, how short to keep it), scope the store namespace per user if corrections should not be shared, and require human approval for edit_file with interrupt_on.
Series: 01 Harness · 02 Quickstart · 03 MCP Tools · 04 Filesystem · 05 Sandbox · 06 Skills and Memory · 07 Context · 08 Subagents · 09 Human-in-the-Loop · 10 Production
