7.6 KiB
Contributing to Qdrant Skills
Skills encode solutions architect knowledge for AI agents. Familiarity with Qdrant documentation and the Agent Skills standard is recommended before contributing.
Philosophy
Skills are not a different form of documentation or tutorials.
Documentation answers "how?" Skills answer "when?" and "why?"
Skills serve as agentic-friendly navigation to Qdrant documentation, not a replacement for it. They encode the judgment of a Solutions Architect: given a symptom, which part of the docs matters, what order to try things, and what to avoid. If the guidance could be written by reading a getting-started page for 10 minutes, it's not a skill. Skills encode judgment that comes from operating Qdrant at scale.
Good skill
## What to do if memory usage is too high?
- Check collection parameters [link to docs]
- Apply quantization [link to choosing quantization]
- Monitor memory usage in prod [link to grafana dashboard]
Bad skill
## Multimodal RAG: Building Document Search
- Build a RAG system using embeddings and Ollama for generation
- Implement basic retrieval from a collection
## Integrating Qdrant with Framework X
- Install the framework package
- Configure the vector store
- Run a similarity search
The first is a tutorial. The second is an integration guide. Neither is a skill, because neither requires operational judgment to write.
Skills should not create maintenance obligations across external frameworks or SDKs. Reference the docs, don't replicate them.
Structure
skills/
<skill-name>/
SKILL.md # skill definition (frontmatter + guidance)
<sub-skill>/
SKILL.md # sub-skill for a specific topic
meta/
qdrant-advisor/
SKILL.md # meta-skill: fetches skills.qdrant.tech live
Skills (skills/): passive knowledge triggered by description matching. Diagnosis and guidance. Read-only tools.
Meta-skill (meta/): the qdrant-advisor ships no static content of its own. It loads the relevant skills/ content live from skills.qdrant.tech at trigger time instead of shipping a static copy.
Writing a skill
Hub skills (navigation only)
Hub skills are directories containing sub-skills. They provide a framing paragraph and links to sub-skills.
- Declare
allowed-tools: [Read, Grep, Glob]in frontmatter - Include
nameanddescriptionwith trigger phrases - Body is navigation only: title, framing paragraph, links
Leaf skills (actual content)
Leaf skills contain the guidance an agent uses to help users.
- Omit
allowed-toolsfrom frontmatter (exception: skills that needBashfor external API calls) - Description contains
Use whenwith 5+ trigger phrases using exact user language - A skill
descriptionmust start with a sentence describing what the skill covers, then list trigger phrases - First paragraph corrects a wrong assumption or forces a diagnostic fork
- Sections named by symptom/scenario, not by feature
- Each section starts with
Use when:one-liner - Bullets are imperative with inline doc links at the end
- Ends with
## What NOT to Dosection - No code blocks in skills beyond absolutely minimal snippets (reference the docs instead)
- Links go to
skills.qdrant.tech/md/documentation/, not raw GitHub - Target 40-80 lines; if over 80, consider splitting into hub + sub-skills
Navigation breadcrumbs and symptom-to-sub-skill maps on hub pages are generated by scripts/generate_breadcrumbs.py as part of the build.
Don't hand-write or edit them; they're derived from the directory tree and frontmatter.
Testing
Build script tests
scripts/test_make_links_absolute.py covers the link-rewriting step in build.sh. It tests the two public entry points of scripts/make_links_absolute.py:
make_absolute(filepath, url, public_dir)— resolves a single URL relative to a file path. Unit tests cover: simple relative links at root and nested levels,../traversal, and all the passthrough cases (https://,http://,/,#,mailto:).run(public_dir)— walks a directory and rewrites all relative markdown links in every.mdfile. Integration tests write real files to a temporary directory and verify the output.
Run manually from the repo root:
cd scripts && python3 -m unittest test_make_links_absolute -v
Skill validation
scripts/validate_skills.py checks all SKILL.md files against the quality rules described in the Writing a skill section above. Run it from the repo root:
python3 scripts/validate_skills.py
It exits non-zero if any hard FAIL rules are violated.
Test prompts
If you add a new leaf skill, or change the guidance in an existing one enough that the right answer to a realistic question would change,
add or update a matching file in evals/test-prompts/. Use an existing file (e.g. evals/test-prompts/qdrant-sizing.json) as the template:
skill_url— the skill's URL onskills.qdrant.tech, must resolve to a real skillprompt— a realistic user question the skill should help answerrubric— a list ofmust(required),bonus(nice to have), andavoid(should not appear) items a grader checks for in the answer
These are what the weekly scoring and PR A/B test harnesses score against. A skill change with no matching test prompt can't be scored.
(evals/evals.json and scripts/run_eval.py, run on every push to main touching skills/** or evals/** via eval-skills.yml,
are a separate, older, smaller smoke check against a handful of hardcoded skill/prompt pairs — unrelated to the evals/test-prompts/ rubric format.)
Skill-test harness (skill-test/)
A separate, Docker-based harness for interactively running Claude Code against a single skill in a clean container, useful while iterating on a skill by hand.
Refer to skill-test/README.md. This is distinct from the automated evals/ scoring pipeline and isn't run in CI.
Scoring and A/B testing
Skill changes are scored, not just validated. Full detail on the methodology lives in SCORING.md; as a contributor, the two mechanisms to know about are:
- Periodic scoring (skill-scoring.yml,
manual dispatch) — runs the full prompt matrix across models, with and without each skill installed, and reports lift per skill. Results land in
evals/weekly/. - PR A/B test (skill-ab-test.yml,
manual dispatch, pass a PR number) — scores only the leaf skill(s) that PR touches, comparing
mainagainst the PR's version, using the test prompts that target those leaves. It posts a scorecard as a PR comment. Two things to keep in mind when relying on it:- It only matches prompts to the leaf skill they target — a PR that changes only a hub's shared navigation text won't be scored by it.
- It matches against
evals/test-prompts/onmain, so a new skill and its test prompt must land onmainbefore the pair can be A/B tested together — land the prompt first, then open the skill PR (or add the prompt in the same PR and re-run A/B testing after merge).
Conventions
Commit messages
- Lowercase, imperative, no period at end
- Short and direct:
"fix broken links","add sliding time window skill" - Multi-step changes use
*bullet points in body
PR titles
- Lowercase, technical, under 70 chars
- Action or problem focused:
"fix X","add docs for Y","refactor Z"
PRs
- Small, focused: one logical change per PR
- 1-2 sentence summary of what the PR does
- Link related PRs/issues