docs: documented graph-based agent llm skills usage
+56
@@ -68,6 +68,10 @@ global_tools: # global tools available to nodes
|
||||
- web_search_coyote.sh
|
||||
mcp_servers: # MCP servers available to nodes
|
||||
- pubmed-search
|
||||
skills_enabled: true # optional; master switch for skills in `llm` nodes
|
||||
enabled_skills: # optional; the *universe* of skills referenceable by any llm node
|
||||
- code-review
|
||||
- git-master
|
||||
conversation_starters: # suggested prompts in the UI
|
||||
- "Research WebAssembly outside of the browser"
|
||||
variables: # optional; agent variables
|
||||
@@ -138,6 +142,13 @@ nodes:
|
||||
write in the same super-step (the validator catches missing reducers at
|
||||
load time). See [Parallel Execution](#parallel-execution) for the full
|
||||
reducer reference and merge semantics.
|
||||
- **`skills_enabled` / `enabled_skills`:** Optional [skills](Skills) policy
|
||||
for the graph. `skills_enabled: false` turns skills off for every `llm`
|
||||
node in the graph regardless of node-level settings. `enabled_skills` is
|
||||
the *universe*: the set of skill names any `llm` node may reference in
|
||||
its own `enabled_skills`. Subset-violations are caught by the validator at
|
||||
load time. See [Skills in Graph Agents](Skills#skills-in-graph-agents) for
|
||||
the full per-node story.
|
||||
|
||||
### `{{initial_prompt}}`: Automatically Seeded
|
||||
|
||||
@@ -458,6 +469,51 @@ failure message containing one of: `timed out`, `rate limit`, `429`,
|
||||
other error fails immediately without consuming further attempts. The
|
||||
default is `1` (no retries).
|
||||
|
||||
### Skills on `llm` nodes
|
||||
|
||||
`llm` nodes are the only place [skills](Skills) attach inside a graph. Two
|
||||
optional fields, mirroring the same fields on roles and agents:
|
||||
|
||||
```yaml
|
||||
implement:
|
||||
type: llm
|
||||
prompt: "{{plan_summary}}"
|
||||
tools: [fs_write, fs_patch, fs_cat]
|
||||
skills_enabled: true # optional; default inherits from graph level
|
||||
enabled_skills: # optional per-node restriction; must be a subset
|
||||
- code-review # of graph-level enabled_skills
|
||||
- verification-gates
|
||||
```
|
||||
|
||||
Semantics (discovery-only, no auto-load):
|
||||
|
||||
- **`skills_enabled`:** Per-node override of the skills master switch.
|
||||
`false` disables skills for this node only: no `skill__list` /
|
||||
`skill__load` / `skill__unload` meta-tools are exposed to the model.
|
||||
`true` or omitted inherits the graph-level / agent-level setting.
|
||||
- **`enabled_skills`:** Per-node restriction of which skills the model can
|
||||
see and load. The graph-level `enabled_skills` is the universe; the
|
||||
per-node list must be a subset (the validator catches violations at
|
||||
load time). When set, `skill__list` shows only these skills and
|
||||
`skill__load` only accepts these names.
|
||||
- **The model loads what it needs.** Nothing is auto-loaded. While the
|
||||
node runs, the model uses `skill__list` to discover what's available
|
||||
and `skill__load` to bring a skill's body / tools / MCP servers into
|
||||
scope when it actually needs them. This matches the design intent of
|
||||
skills as a dynamic capability layer.
|
||||
- **Per-node policy isolation.** The node temporarily narrows the active
|
||||
agent's skill policy to the node's `enabled_skills`. The original
|
||||
policy is restored when the node finishes, so subsequent nodes see
|
||||
their own policy. Any skills the model loaded during the node persist
|
||||
into subsequent nodes by default; they're real registry insertions,
|
||||
not node-scoped state. (Use the skill's own `auto_unload: true`
|
||||
frontmatter for skills that should clean up automatically at turn
|
||||
end.)
|
||||
|
||||
Agent nodes (which spawn full sub-agents) intentionally have no
|
||||
`enabled_skills` field. The spawned child agent's own
|
||||
`config.yaml`/`graph.yaml` declares its skill policy.
|
||||
|
||||
---
|
||||
|
||||
## rag
|
||||
|
||||
+84
@@ -198,6 +198,90 @@ Four validation points enforce these rules:
|
||||
|
||||
---
|
||||
|
||||
# Skills in Graph Agents
|
||||
|
||||
[Graph agents](Graph-Agents) integrate with the skill system at two levels: a graph-wide *universe* set at the top of
|
||||
`graph.yaml`, and a per-node *auto-load* set on `llm` nodes. Other node types (script, approval, input, rag, map, end)
|
||||
have no skill surface. Skills only apply where a model call happens.
|
||||
|
||||
## Graph level — the universe
|
||||
|
||||
The top-level `skills_enabled` and `enabled_skills` fields in `graph.yaml` work just like they do on a normal agent's
|
||||
`config.yaml`: they declare the policy ceiling for the whole graph.
|
||||
|
||||
```yaml
|
||||
name: coder
|
||||
skills_enabled: true
|
||||
enabled_skills:
|
||||
- code-review
|
||||
- git-master
|
||||
- verification-gates
|
||||
```
|
||||
|
||||
- **`skills_enabled: false`** at the graph level turns skills off for every `llm` node in the graph regardless of
|
||||
node-level fields. Equivalent to "skills don't exist for this graph."
|
||||
- **`enabled_skills`** at the graph level is the *universe*: the set of skill names any `llm` node in the graph is
|
||||
allowed to reference in its own `enabled_skills`. The validator rejects per-node entries that aren't in this set at
|
||||
load time.
|
||||
- Omitting `enabled_skills` inherits whatever the role / global cascade resolves to (typically "all visible").
|
||||
|
||||
## Per-node: discovery-only on `llm` nodes
|
||||
|
||||
`llm` nodes can independently declare `skills_enabled` and `enabled_skills`. The graph-level field gates what's
|
||||
*allowed* in the graph at all; the node-level field narrows that universe to what *this* node's model can see and
|
||||
load. Nothing is auto-loaded. The model uses `skill__list` and `skill__load` to bring skills in as it needs them,
|
||||
matching the rest of Coyote's skill model.
|
||||
|
||||
```yaml
|
||||
nodes:
|
||||
implement:
|
||||
type: llm
|
||||
prompt: "{{plan_summary}}"
|
||||
tools: [fs_write, fs_patch, fs_cat]
|
||||
enabled_skills: # must be a subset of graph-level enabled_skills
|
||||
- code-review
|
||||
- verification-gates
|
||||
# skills_enabled: false # would disable skills for this node only
|
||||
```
|
||||
|
||||
Semantics:
|
||||
|
||||
- **Discovery, not auto-load.** When the node runs, `skill__list` is exposed to the model along with `skill__load`
|
||||
and `skill__unload`. The model decides which skills (if any) to load based on the task at hand. Loaded skills
|
||||
compose into the system prompt and union tools/MCP servers via the standard `effective_role` pipeline; the
|
||||
loading itself goes through the same `refresh_tool_scope` path as `.skill load` in the REPL.
|
||||
- **Per-node policy.** When `enabled_skills` is set on the node, the graph's effective skill policy is temporarily
|
||||
narrowed to that subset for the duration of the node. `skill__list` will only show those skills and `skill__load`
|
||||
will only accept those names. When the node finishes, the original policy is restored so the next node sees its
|
||||
own.
|
||||
- **`skills_enabled: false`** at the node level is an off-switch: no `skill__*` meta-tools are exposed and no skills
|
||||
can be loaded from this node. Useful when one node in an otherwise skill-enabled graph should run with a strict,
|
||||
narrow context (for example a structured-output extraction step that shouldn't load editorial conventions).
|
||||
- **Skill state carry-over.** Skills the model loads during a node persist into subsequent nodes (they're real
|
||||
registry insertions, not node-scoped state). If you want a skill to clean up automatically at turn end, mark it
|
||||
`auto_unload: true` in the skill's own frontmatter.
|
||||
|
||||
## Agent nodes have no skill surface
|
||||
|
||||
`agent` nodes spawn a full child agent (graph or normal). That child agent declares its own skill policy in its own
|
||||
`config.yaml` / `graph.yaml`. Adding a skill field on the agent node would be redundant at best and surprising at
|
||||
worst. The child author already controls what skills the child uses. So agent nodes intentionally don't accept
|
||||
`enabled_skills` / `skills_enabled`.
|
||||
|
||||
## Validation
|
||||
|
||||
| Where | Check | Severity |
|
||||
|----------------|------------------------------------------------------------------------------------------------------------|------------|
|
||||
| Graph load | Per-node `enabled_skills` entries are non-empty strings | Hard error |
|
||||
| Graph load | Per-node `enabled_skills` are a subset of graph-level `enabled_skills` (when set) | Hard error |
|
||||
| Node execution | Each auto-loaded skill resolves to a real installed skill (otherwise that skill is skipped with a warning) | Warn |
|
||||
| Node execution | Each auto-loaded skill's MCP / function-calling requirements are satisfied | Warn |
|
||||
|
||||
The validator only runs `validate_before_run` (the default); inspecting a graph via `coyote --info -a <name>` does
|
||||
not trigger validation, so subset-violation errors surface on the first real run.
|
||||
|
||||
---
|
||||
|
||||
# Auto-unload
|
||||
|
||||
Skills with `auto_unload: true` in their frontmatter are removed from the registry at the end of each turn. Specifically,
|
||||
|
||||
Reference in New Issue
Block a user