Using Skills With LangGraph Deep Agents
Building a deep research agent is not only about connecting a model to search tools, MCP servers, document readers, and summarizers. The hardest problem is deciding which instructions the agent should carry at each step.
A research agent may need different capabilities during the same task. It may need to search the web, inspect documents, compare sources, extract evidence, write a report, or check citations. If every workflow is placed in one large system prompt, the agent becomes harder to maintain and the context window fills up quickly.
LangGraph Deep Agents address this problem with Skills.
A Skill is an on-demand capability packaged as a small folder. Each skill contains a SKILL.md file that explains when the skill should be used and how the agent should perform that workflow. The agent reads lightweight metadata from each skill at startup, then loads the full skill content only when the task requires it.
In this tutorial, we will build a small SRE-style Deep Agent that uses Skills as runbooks. The same pattern can be used for a deep research agent, documentation agent, coding agent, incident assistant, or any agent that needs multiple specialized workflows without loading all instructions upfront.
What you will build
You will create a simple LangGraph Deep Agent with two skills:
| Skill | Purpose |
|---|---|
triage-alert |
Used when the user wants to triage an alert or decide whether to page someone. |
write-postmortem |
Used when the user wants to write a postmortem for a resolved incident. |
The goal is to demonstrate how the agent discovers skills, selects the relevant one, loads its full instructions, and uses those instructions to complete the task.
Conceptual workflow
The loading model is similar to how an on-call engineer uses runbooks.
An engineer does not memorize every runbook. They know the index: one line per incident type saying which runbook applies. When an alert fires, they match the alert to the index and open the right runbook.
Skills work the same way for the agent context window.
The important part is progressive disclosure. The agent knows what skills exist, but it does not load every procedure into context upfront. It loads only the skill that matches the current request.
How a Skill is structured
Each skill is a directory. The main file is always SKILL.md.
The directory name and skill name should match.
A typical skill looks like this:
skills/
βββ triage-alert/
βββ SKILL.md
βββ reference.md
βββ scripts/
βββ build_timeline.py
The SKILL.md file has two parts:
- Frontmatter: metadata used for discovery and routing.
- Body: the detailed procedure loaded only when the skill is activated.
Example:
---
name: triage-alert
description: Use when the user wants to triage an alert or decide how to respond to one.
---
# Triage an Alert
Follow these steps when investigating an alert.
1. Classify severity based on user-facing impact.
2. Identify the blast radius.
3. Check recent deploys, config changes, and feature-flag changes.
4. Decide whether to page, create a ticket, or monitor.
The description is the routing signal. It should describe when the skill applies, not the full procedure.
The body can be longer because it is not loaded until the skill is selected.
Why frontmatter matters
At startup, the agent reads the frontmatter from registered skills and creates a skill index. Conceptually, that index looks like this:
## Skills System
Available skills:
- **triage-alert**: Use when the user wants to triage an alert or decide how to respond to one.
-> Read skills/triage-alert/SKILL.md for full instructions.
- **write-postmortem**: Use when the user wants to write a postmortem for a resolved incident.
-> Read skills/write-postmortem/SKILL.md for full instructions.
This index is small. Only the skill names, descriptions, and file paths are placed in the initial context. The full instructions remain on disk until the agent needs them.
The token-saving effect is straightforward:
Project layout
Create a project directory called langgraph-deepagent-skills-demo:
langgraph-deepagent-skills-demo/
βββ sre_agent.py
βββ skills/
βββ triage-alert/
β βββ SKILL.md
βββ write-postmortem/
βββ SKILL.md
This gives the agent two skills to choose from.
Step 1: Create the alert triage skill
Create this file:
langgraph-deepagent-skills-demo/skills/triage-alert/SKILL.md
Add the following content:
---
name: triage-alert
description: Use when the user wants to triage an alert or decide how to respond to one.
---
# Triage an Alert
Decide fast, but show the reasoning. Every conclusion must name the signal it is based on.
## Step 1: Severity
Classify severity by user-facing impact, not by which metric fired.
A 2s p99 latency increase on checkout is more important than a crashed batch job with no customer impact.
State the trend:
- getting worse
- stable
- recovering
## Step 2: Blast radius
Identify which services and customer segments are affected.
Check dependencies in both directions:
- what this service calls
- what calls this service
## Step 3: Recent changes
Check deploys, config changes, and feature-flag flips in the last hour before considering exotic causes.
Most incidents follow a change.
## Step 4: Page or ticket
Page if user-facing impact is active or the trend is worsening.
Create a ticket if the impact is past, contained, or the alert is a known false positive.
Never page on a metric alone.
## Output
Return:
- **Severity**: level, with the one signal that decided it
- **Blast radius**: services and customer segments affected
- **Suspected cause**: the most recent correlated change, if any
- **Decision**: page or ticket, and the first status update to send
This skill focuses only on alert triage. It does not include postmortem writing, stakeholder communication, or incident review. Keeping the skill narrow makes routing easier.
Step 2: Create the postmortem skill
Create this file:
langgraph-deepagent-skills-demo/skills/write-postmortem/SKILL.md
Add the following content:
---
name: write-postmortem
description: Use when the user wants to write a postmortem for a resolved incident.
---
# Write a Postmortem
Write in a blameless style. Name systems and gaps, never people.
If a draft sentence contains a person's name next to a mistake, rewrite it.
## Step 1: Timeline from records
Build the timeline from logs, deploy history, and alert timestamps, not from memory.
Mark every entry that could not be confirmed from a record.
## Step 2: Contributing factors
List at least two contributing factors.
Single root causes are usually the last factor noticed, not the only factor involved.
For each factor, state which safeguard was missing or failed.
## Step 3: What limited the damage
Record what went well and what was luck.
Luck is a gap wearing a disguise.
## Step 4: Action items
Each action item needs an owner and a test.
For each item, state whether it would have:
- prevented the incident
- shortened the incident
- improved detection
Drop items that do none of these.
## Output
Return:
- **Summary**: impact, duration, detection method, one paragraph
- **Timeline**: timestamped entries, with unconfirmed entries marked
- **Contributing factors**: each with the missing safeguard
- **Action items**: owner, prevent-or-shorten label, due date
This skill sits at the other end of the incident lifecycle. Because the description is specific, the agent should not confuse it with alert triage.
Step 3: Wire the skills into the agent
Create the agent file:
langgraph-deepagent-skills-demo/sre_agent.py
Add the following code:
import os
from pathlib import Path
from langchain.chat_models import init_chat_model
from deepagents import create_deep_agent
from deepagents.backends.filesystem import FilesystemBackend
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model("openai:gpt-4o")
sre_dir = Path(__file__).parent
backend = FilesystemBackend(
root_dir=str(sre_dir),
virtual_mode=True,
)
agent = create_deep_agent(
model=model,
name="SRE_Assistant",
backend=backend,
skills=["/skills"],
system_prompt="You are an SRE assistant.",
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": (
"Triage this alert: p99 latency on the checkout API jumped "
"from 180ms to 2.4s over the last 10 minutes. "
"Error rate is normal. A deploy to the pricing service "
"went out 15 minutes ago."
),
}
]
}
)
print(result["messages"][-1].content)
The important parameter is this one:
skills=["/skills"]
That tells the agent where to scan for skills inside the backend filesystem.
With this configuration, the agent expects these files to exist:
/skills/triage-alert/SKILL.md
/skills/write-postmortem/SKILL.md
The frontmatter from both files is read at startup. The bodies remain on disk until the agent calls read_file for the selected skill.
Step 4: Run the alert triage example
Run the script:
uv run sre_agent.py
The agent should select the triage-alert skill because the user is asking to triage an active alert.
A typical response should classify the incident based on user-facing impact, mention that the checkout API latency is the deciding signal, identify the pricing-service deploy as a likely correlated change, and recommend whether to page or create a ticket.
**Severity**: High, due to significant increase in latency from 180ms to 2.4s affecting the checkout process, which is critical for users.
**Blast radius**: The alert directly affects the checkout API. Given that error rates are normal, it indicates customers are experiencing slower response times but not failures. Itβs vital to trace dependencies on what services the checkout API calls and which services call it to determine if others are indirectly affected.
**Suspected cause**: The deploy to the pricing service 15 minutes ago is a likely suspect, as it closely precedes the latency increase.
**Decision**: Page. The user-facing impact is active with worsening latency, necessitating immediate attention. The status update should include the observed latency increase, suspected linkage to the recent pricing service deploy, and the absence of elevated error rates.
Step 5: Run the postmortem example
Now test the second skill with this input:
Write a postmortem: yesterday the payment service was down for 43 minutes.
A config change doubled the connection pool size, which exhausted database connections.
Rolling back the config restored service.
The agent should select the write-postmortem skill because the user is asking for a postmortem after a resolved incident.
Expected behavior:
User request
β
Skill index is available in context
β
Agent matches request to write-postmortem description
β
Agent reads /skills/write-postmortem/SKILL.md
β
Agent follows the postmortem procedure
β
Agent returns summary, timeline, contributing factors, and action items
The triage-alert body should not be loaded for this request. It remains available only as one line in the skill index.
Step 6: Chain skills across a workflow
Skills can also chain naturally across a conversation.
Start with triage:
Triage this alert: p99 latency on the checkout API jumped from 180ms to 2.4s over the last 10 minutes.
Error rate is normal. A deploy to the pricing service went out 15 minutes ago.
Then follow up:
We rolled back the pricing deploy and latency recovered. Write the postmortem.
The agent should first load triage-alert, then later load write-postmortem. The second skill can reuse the triage findings already present in the conversation.
No custom orchestration code is needed for this transition. The model routes to the next skill using the same skill index and description matching.
Summary
Skills give LangGraph Deep Agents a practical way to manage context.
Instead of putting every workflow into one large system prompt, you package each workflow as a focused SKILL.md file. The agent reads the frontmatter at startup, uses the description as a routing signal, and loads the full skill body only when needed.
The result is a cleaner agent architecture:
Memory
Always-relevant conventions
System prompt
Core role and boundaries
Skills
On-demand workflows loaded when relevant
For deep research agents, this pattern is especially useful because research is naturally multi-stage. The agent may need to plan, search, compare, validate, and write, but it does not need all those instructions in context at the same time.
Start with two focused skills. Check the trace. Confirm that the right SKILL.md file is loaded. Then add more skills as your agent’s workflow becomes clearer.
Find more about Skills in LangGraph Documentation here