Hi everyone! ![]()
I’ve been building agents with the Deep Agents Skills system and ran into a frustrating issue: when a SKILL.md is malformed (wrong name format, missing description, invalid YAML…), the agent silently ignores the skill with no actionable error message.
I’d love to propose a small, self-contained feature to fix this: a SkillValidator and a langchain skills lint CLI command.
The Problem
SKILL.md files must follow a strict schema:
name→ lowercase, alphanumeric + hyphens, max 64 charsdescription→ required, max 1024 chars (agent reads this at startup)
Currently, mistakes are invisible until runtime. For example, this is a real scenario when you have 10+ skills in a team setting:
skills/
code-review/SKILL.md ← missing `description`
web-search/SKILL.md ← name has uppercase: “Web_Search”
sql-generator/SKILL.md ← description is 1200 chars (too long)
The agent will either skip these skills silently or misbehave — no feedback at all.
Proposed Solution
1. Python API
python
from langchain.skills.validator import validate_skill_directory
reports = validate_skill_directory(“./skills”)
for report in reports:
if not report.is_valid:
print(f"❌ {report.skill_path}")
for error in report.errors:
print(f" ERROR: {error}")
for warning in report.warnings:
print(f" WARNING: {warning}")
2. CLI Command
bash
$ langchain skills lint ./skills
skills/code-review/SKILL.md
ERROR: Missing required field: `description`
skills/web-search/SKILL.md
ERROR: `name` must be lowercase alphanumeric with hyphens. Got: “Web_Search”
skills/sql-generator/SKILL.md
WARNING: `description` exceeds 1024 characters (1200). Agent context may be impacted.
3 skill(s) checked — 2 error(s), 1 warning(s)
Useful flags:
--fail-fast→ stop at first error (great for CI pipelines)--format json→ machine-readable output for tooling
Validation Rules
| Rule | Severity |
|---|---|
Missing name or description |
|
name contains invalid characters (e.g. uppercase, spaces) |
|
name exceeds 64 characters |
|
| Invalid / unparseable YAML frontmatter | |
No SKILL.md found in skill directory |
|
description exceeds 1024 characters |
Implementation Scope
This is 100% additive — no breaking changes.
Repo question (see below): The Skills system is primarily documented under Deep Agents. I’m not yet sure whether this belongs in
langchain-ai/langchainorlangchain-ai/deepagents. I’ve listed a tentative file layout below — maintainers, please correct me!
Tentative layout (if in langchain-ai/langchain):
| File | What |
|---|---|
libs/langchain/langchain/skills/validator.py |
Core validation logic |
libs/langchain/langchain/skills/schemas.py |
Pydantic schema for frontmatter |
libs/langchain/tests/unit_tests/skills/test_validator.py |
Unit tests |
libs/cli/langchain_cli/namespaces/skills.py |
langchain skills lint CLI command |
Tentative layout (if in langchain-ai/deepagents):
| File | What |
|---|---|
deepagents/skills/validator.py |
Core validation logic |
deepagents/skills/schemas.py |
Pydantic schema for frontmatter |
tests/skills/test_validator.py |
Unit tests |
cli/namespaces/skills.py |
langchain skills lint CLI command |
No new dependencies — uses pydantic, pyyaml, and typer, which are already in the codebase.
Questions for the maintainers
Before I open a PR, I’d love to align on a few design decisions:
- [Most important] Which repository should host this? The Skills system is documented under Deep Agents, which suggests the validator might belong in
langchain-ai/deepagentsrather thanlangchain-ai/langchain. However, the CLI (langchain skills lint) would naturally live inlangchain-ai/langchainalongsidelangchain-cli. Which repo (or both) is the right target for this contribution? - Is
libs/langchain/langchain/skills/the right module path, or should this live inlangchain-core? - Preferred CLI command name:
langchain skills lintorlangchain skill validate? - Are there planned frontmatter fields beyond
nameanddescriptionthat I should account for? - Should warnings produce a non-zero exit code by default (strict mode), or only errors?
Happy to implement this and open a PR once the approach is aligned. Looking forward to the community’s feedback! ![]()
— Amine