-
Notifications
You must be signed in to change notification settings - Fork 3k
docs: document async tools, deserialization allowlist, and SkillToolset #11877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
f748f44
docs: document async tools, deserialization allowlist, and SkillToolset
julian-risch 2e321b3
docs: note that SkillToolset does not execute scripts
julian-risch ba076b1
docs: fix allowlist pattern-matching wording, drop stale AsyncPipelin…
julian-risch 27fb26d
Merge branch 'main' into docs/v3-simple-doc-updates-5
julian-risch 59cc73d
docs: clarify SKILL.md frontmatter (description required, name optional)
julian-risch File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| --- | ||
| title: "SkillToolset" | ||
| id: skilltoolset | ||
| slug: "/skilltoolset" | ||
| description: "Let agents discover and read skills — reusable instruction sets with bundled files — through progressive disclosure." | ||
| --- | ||
|
|
||
| # SkillToolset | ||
|
|
||
| Let agents discover and read skills — reusable instruction sets with bundled files — through progressive disclosure. | ||
|
|
||
| <div className="key-value-table"> | ||
|
|
||
| | | | | ||
| | --- | --- | | ||
| | **Mandatory init variables** | `store`: A `SkillStore` instance that provides the skills | | ||
| | **API reference** | [SkillToolset](/reference/tools-api#skilltoolset) | | ||
| | **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/tools/skills/skill_toolset.py | | ||
| | **Package name** | `haystack-ai` | | ||
|
|
||
| </div> | ||
|
|
||
| ## Overview | ||
|
|
||
| A *skill* is a directory (or equivalent storage unit) containing a `SKILL.md` file with YAML frontmatter (`description` is required; `name` is optional and defaults to the directory name) and a markdown body of instructions. Skills may bundle additional files, such as reference docs, examples, or templates. | ||
|
|
||
| `SkillToolset` lets an [`Agent`](../pipeline-components/agents-1/agent.mdx) use skills through *progressive disclosure*, similar to how coding assistants like Claude Code expose skills: the model first sees only each skill's name and description, loads the full instructions when a task calls for them, and fetches bundled files only when the instructions reference them. This keeps the context small even with many detailed skills. | ||
|
|
||
| The toolset exposes two tools: | ||
|
|
||
| - `load_skill`: Returns a skill's full instructions on demand, plus a manifest of its bundled files. The names and descriptions of all discovered skills are baked into this tool's description at warm-up, so the model can see which skills exist without any system prompt injection. | ||
| - `read_skill_file`: Reads a file bundled with a skill (with path-traversal protection). | ||
|
|
||
| Skills are discovered when the toolset is warmed up — the `Agent` does this automatically before a run. Constructing the toolset does not read any skills. | ||
|
|
||
| `SkillToolset` is backed by a `SkillStore`. Use the built-in `FileSystemSkillStore` to load skills from a local directory, or implement the `SkillStore` protocol (`list_skills`, `load_skill`, `read_skill_file`, plus serialization methods) to back the toolset with any storage system — a database, a remote API, and so on. | ||
|
|
||
| :::info | ||
| The tool names `load_skill` and `read_skill_file` are fixed, so an `Agent` can use at most one `SkillToolset`. It also does not support adding tools or concatenation with other toolsets — to combine it with other tools, pass it to the `Agent` alongside them, for example `tools=[skills_toolset, other_tool]`. To serve skills from multiple sources, back a single toolset with a custom store that merges them. | ||
| ::: | ||
|
|
||
| ### Skill format | ||
|
|
||
| `FileSystemSkillStore` expects one sub-directory per skill under a root directory: | ||
|
|
||
| ``` | ||
| skills/ | ||
| pdf-forms/ | ||
| SKILL.md # frontmatter (description required, name optional) + markdown instructions | ||
| reference/forms.md # optional bundled file | ||
| ``` | ||
|
|
||
| A minimal `SKILL.md` looks like this: | ||
|
|
||
| ```markdown | ||
| --- | ||
| name: pdf-forms | ||
| description: Fill in PDF forms programmatically. Use when the user asks to complete or fill a PDF form. | ||
| --- | ||
|
|
||
| # Filling PDF forms | ||
|
|
||
| 1. Inspect the form fields first... | ||
| 2. For the full field reference, read `reference/forms.md`. | ||
| ``` | ||
|
|
||
| Only the frontmatter of each `SKILL.md` is read at warm-up to build the catalog; instruction bodies and bundled files are read lazily when the agent calls the corresponding tool. | ||
|
|
||
| ### Multimodal skill assets | ||
|
|
||
| `read_skill_file` returns text files as strings, images as [`ImageContent`](../concepts/data-classes/imagecontent.mdx), and PDFs as [`FileContent`](../concepts/data-classes/filecontent.mdx). Image and file results are passed to the model as content parts of the tool result instead of being converted to a string, so an `Agent` backed by a multimodal chat generator that supports these inputs (for example, `OpenAIResponsesChatGenerator`) can read a skill's visual assets — such as a reference screenshot or a showcase PDF — directly. Binary files that are neither images nor PDFs are rejected with an error. | ||
|
|
||
| ### Executing bundled scripts | ||
|
|
||
| `SkillToolset` only *reads* skills — `load_skill` and `read_skill_file` never execute anything. If your skills bundle executable scripts (for example, a Python helper that the instructions tell the model to run), pass a script-execution tool of your own to the `Agent` alongside the toolset: | ||
|
|
||
| ```python | ||
| agent = Agent( | ||
| chat_generator=OpenAIChatGenerator(), | ||
| tools=[skills_toolset, run_shell_command_tool], # your own execution tool | ||
| ) | ||
| ``` | ||
|
|
||
| The agent can then read a bundled script with `read_skill_file` and run it through your execution tool. Since such a tool runs model-chosen commands, scope it carefully — restrict what it can execute, sandbox it, or guard it with a [Human in the Loop](../pipeline-components/agents-1/human-in-the-loop.mdx) confirmation strategy. | ||
|
|
||
| ## Usage | ||
|
|
||
| ### With an Agent | ||
|
|
||
| ```python | ||
| from haystack.components.agents import Agent | ||
| from haystack.components.generators.chat import OpenAIChatGenerator | ||
| from haystack.dataclasses import ChatMessage | ||
| from haystack.skill_stores.file_system import FileSystemSkillStore | ||
| from haystack.tools import SkillToolset | ||
|
|
||
| store = FileSystemSkillStore("skills/") | ||
| skills_toolset = SkillToolset(store) | ||
|
|
||
| agent = Agent(chat_generator=OpenAIChatGenerator(), tools=skills_toolset) | ||
|
|
||
| # The agent sees the available skills in the `load_skill` tool description, | ||
| # loads the matching skill, and follows its instructions. | ||
| result = agent.run(messages=[ChatMessage.from_user("Fill in this PDF form for me.")]) | ||
| print(result["last_message"].text) | ||
| ``` | ||
|
|
||
| ### Inspecting discovered skills | ||
|
|
||
| The `skills` property returns the metadata of all discovered skills as a mapping of skill name to `SkillInfo` (warming up the toolset first if needed): | ||
|
|
||
| ```python | ||
| from haystack.skill_stores.file_system import FileSystemSkillStore | ||
| from haystack.tools import SkillToolset | ||
|
|
||
| skills_toolset = SkillToolset(FileSystemSkillStore("skills/")) | ||
| for name, info in skills_toolset.skills.items(): | ||
| print(f"{name}: {info.description}") | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth adding a note how users can enable executing scripts bundled with tools. E.g. Include their own custom bash tool or script execution tool alongside the SkillsToolset.
Otherwise by default SkillsToolset only supports reading skill files and not executing anything.