Skill composition
Composing skills into workflows - call chains, shared outputs, error propagation, and design patterns.
Last updated: 2026-04-30
Skill composition
Skills are designed to compose. A complex workflow is a sequence of simple, well-tested skills wired together. This page covers the patterns for doing that reliably.
The call chain
The most direct composition pattern: skill A calls skill B, which calls skill C.
# skill: weekly-nav-summary
steps:
- call: get-nav-data # calls another skill
args:
fund: "{{ inputs.fund_id }}"
date: "{{ inputs.report_date }}"
capture: nav_data
- call: format-nav-report # uses the output of the first call
args:
data: "{{ nav_data }}"
template: "weekly-summary"
capture: report_doc
- call: distribute-report # sends the formatted output
args:
document: "{{ report_doc }}"
recipients: "{{ inputs.recipient_list }}"
Each step in the chain uses the capture key to name its output. Subsequent steps reference captured outputs by name.
Parallel execution
When two skills do not depend on each other’s outputs, they can run in parallel:
steps:
- parallel:
- call: check-feed-freshness
args:
feed_name: "equity-prices"
capture: equity_freshness
- call: check-feed-freshness
args:
feed_name: "fixed-income-prices"
capture: fi_freshness
- condition: "{{ !equity_freshness.is_fresh || !fi_freshness.is_fresh }}"
- call: send-data-ops-alert
args:
stale_feeds: "{{ [equity_freshness, fi_freshness] | selectattr('is_fresh', 'eq', false) }}"
- end_condition
Parallel steps complete before the next sequential step begins. If any parallel step fails and is not marked optional, the skill fails.
Error propagation
By default, any step failure propagates up and fails the calling skill. You can override this with on_error:
- call: get-external-price-feed
args:
ticker: "{{ inputs.ticker }}"
capture: external_price
on_error:
strategy: fallback
fallback_value:
price: null
source: "unavailable"
capture: external_price # overwrite with fallback
Options for on_error.strategy:
| Strategy | Behavior |
|---|---|
fail | Default. Propagates the error up. |
fallback | Continues with a defined fallback value. |
skip | Skips this step and continues. Captured variable is unset. |
retry | Retries the step up to max_retries times before failing. |
Skill design principles
One responsibility per skill
A skill should do one thing. “Get NAV data” is a skill. “Get NAV data and format it and send it” is three skills.
Why it matters: single-responsibility skills are testable in isolation, reusable in other workflows, and easier to debug when something goes wrong.
Never hardcode environment values
Anything that differs between sandbox and production - URLs, API keys, threshold values - belongs in vault.json or a knowledge document. Skills reference these via context variables:
# Good
- action: plexifact.catalog.connect
args:
catalog: "{{ vault.data.catalog }}"
# Bad
- action: plexifact.catalog.connect
args:
catalog: "plexifact://prod/catalog"
Document inputs and outputs
Every field in inputs and outputs should have a description. This documentation is what makes a skill usable by someone who did not write it - which includes you, six months from now.
Version intentionally
Increment the skill version when inputs or outputs change in a way that breaks existing callers. Agents reference skills by name; if an agent was written against version 1.0 and the output schema changes in 2.0, the agent needs updating.
Use the deprecated flag to signal that a skill is being replaced, giving callers time to migrate before the old version is removed.
Common fund-operations composition patterns
Pattern 1 - Monitor and alert
check-condition → if stale/anomalous → format-alert → send-notification → audit-log
Pattern 2 - Report generation
fetch-data → validate-data → transform-data → format-report → distribute → audit-log
Pattern 3 - Reconciliation
fetch-source-a → fetch-source-b → compare-values → if-mismatch → create-exception-ticket → audit-log
All three patterns share the same tail: audit-log. Every agent output, whether an alert, a report, or a reconciliation exception, should end with an audit entry. Operational processes require audit trails.
Was this page helpful?
Previous
Skill anatomy
Next
Agents overview