concept
LangGraph Skills Pattern
LangGraph Skills Pattern
Pluggable, prompt-driven specializations that agents load on-demand. The lightest multi-agent pattern — augments rather than replaces the current agent.
Core Idea
A skill is a bundle of instructions + context + optional tools that an agent loads when it matches a user request. Unlike subagents (which run in isolation), skills inject into the current agent’s context window.
Three Tiers of Skills
Simple Skills = Tool Calls
API wrappers, database queries, search functions. Always available, atomic.
@tool
def search_archive(query: str) -> str:
"""Search the editorial archive."""
return archive_client.search(query)
Complex Skills = Sub-Graphs
Multi-step workflows with their own state and logic. Wrapped as tools for the outer agent.
# A sub-graph with its own nodes and edges
editor_graph = StateGraph(EditorState)
editor_graph.add_node("analyze", analyze_article)
editor_graph.add_node("suggest_edits", suggest_edits)
editor_graph.add_node("apply_edits", apply_edits)
# ... edges ...
editor_subgraph = editor_graph.compile()
@tool("article_editor", description="Run multi-step article editing workflow")
def run_editor(article_text: str):
result = editor_subgraph.invoke({"article": article_text, "messages": []})
return result["edited_article"]
Skill Bundles = Named Collections
Composed at runtime based on user role, task type, or explicit selection.
BUNDLES = {
"article_research": ["search_archive", "web_search", "source_verifier"],
"financial_profile": ["get_person", "financial_analyzer"],
"quick_edit": ["article_editor"],
"full_workflow": ["search_archive", "web_search", "source_verifier",
"article_editor", "financial_analyzer"],
}
Implementation Approaches
1. Prompt-Based (Deep Agents Style)
Skills are SKILL.md files loaded into context:
from deepagents import create_deep_agent
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-6",
skills=["/skills/article-editor/", "/skills/financial-analysis/"],
checkpointer=checkpointer,
)
2. Dynamic Graph Composition
Build different graphs at runtime based on enabled skills:
def build_agent(enabled_skills: list[str]):
builder = StateGraph(AgentState)
builder.add_node("agent", agent_node)
tools = []
for skill_name in enabled_skills:
if skill_name in SIMPLE_SKILLS:
tools.append(SIMPLE_SKILLS[skill_name])
elif skill_name in COMPLEX_SKILLS:
# Wrap sub-graph as tool
tools.append(wrap_subgraph_as_tool(skill_name, COMPLEX_SKILLS[skill_name]))
# Build agent node with selected tools
return compile_agent_with_tools(builder, tools)
3. MCP-Based (Maximum Decoupling)
Each skill is an MCP server. Bundle = which servers to connect:
async def build_from_bundle(bundle_name: str):
skill_names = BUNDLES[bundle_name]
client = MultiServerMCPClient({
name: MCP_SERVERS[name] for name in skill_names if name in MCP_SERVERS
})
tools = await client.get_tools()
return create_agent("anthropic:claude-sonnet-4-6", tools)
Skills vs Subagents vs Tools
| Aspect | Tool | Skill | Subagent |
|---|---|---|---|
| Complexity | Atomic function | Instructions + tools + context | Full agent with own loop |
| Loading | Always available | On-demand | Invoked as tool |
| Context | No overhead | Adds to current window | Isolated window |
| State | Stateless | Shares parent state | Own state |
| Token cost | Minimal | Grows with context | Contained per invocation |
| Development | Single function | SKILL.md + optional code | Full agent definition |
JournalistBoost Application
For fajb-next, skills map naturally to journalist workflows:
| Skill | Type | Contains |
|---|---|---|
| Archive Search | Simple | search_archive tool |
| Person Lookup | Simple | get_person_profile tool |
| RSS Monitor | Simple | fetch_rss tool |
| Article Editor | Complex | analyze → suggest → apply sub-graph |
| Financial Analyzer | Complex | fetch data → compute → visualize sub-graph |
| Source Verifier | Complex | cross-reference → fact-check → score sub-graph |
Journalists select a bundle (“Article Research”, “Financial Profile”, etc.) and the agent assembles with only the relevant capabilities.
Production Reference: Vibe-Trading
vibe-trading runs 74 skills across 8 categories as a concrete data point. Pattern observations from a real deployment:
- Skills shipped as data files (YAML/MD), not code — registry-driven loading.
- Self-evolving: agent creates and refines skills from session experience (CRUD over the registry).
- Bundled via category rather than ad-hoc selection — Strategy / Analysis / Asset Class / Crypto / Flow / Tool / Risk / Data Source.
- Bundled-skill regression tests: each skill pinned by tests so registry-format drift breaks CI, not user runs.
- Tool-call reliability is the real bottleneck: weak models (
*-nano,*-flash-lite) skip skill loading entirely and answer from training data. Skill systems amplify model-quality differences.
Related
- AI Agent Architectures — full architecture guide
- LangGraph Multi-Agent Patterns — all five patterns
- Model Context Protocol — MCP-based skill delivery
- ReAct Pattern — the base loop skills extend
- fajb-next — production platform for implementation
- vibe-trading — 74-skill production reference (finance domain)