Specialists are delegatable sub-agent definitions. When the agent encounters a focused task, it can spawn a real OS child process running the pvyai binary in stream-json mode, with a custom system prompt and a restricted tool set. The specialist does its work and returns a result to the parent agent.
A specialist is a markdown file with YAML frontmatter that defines:
The specialist runs as a child process — it has its own agent loop, its own conversation, and its own session in the lineage. It can run in the foreground (blocking the parent) or in the background (the parent continues other work).
PVYai ships with three built-in specialists:
| Name | Tools | Purpose |
|---|---|---|
worker |
read-only + edit + execute + plan | General delegated coding tasks; can read, write, and execute |
explorer |
read-only | Fast read-only codebase exploration; no writes, no shell |
code-review |
read-only | Reviews changes for correctness bugs, regressions, unsafe behavior, missing tests |
These are always available. You can override them by creating a user or project specialist with the same name.
pvyai specialist create api-reviewer \
--description "Reviews API endpoints for REST conformance and error handling" \
--prompt "You are an API review specialist. Review endpoints for REST conformance, error handling, idempotency, and missing input validation." \
--tools read-only \
--model claude-sonnet-4.5 \
--reasoning-effort high
Create a .md file in the specialists directory:
User-level: ~/.config/pvyai/specialists/api-reviewer.md
Project-level: <project>/.pvyai/specialists/api-reviewer.md
---
name: "api-reviewer"
description: "Reviews API endpoints for REST conformance and error handling"
model: "claude-sonnet-4.5"
reasoningEffort: "high"
tools:
- "read-only"
- "plan"
---
You are an API review specialist inside PVYai.
Review endpoints for REST conformance, error handling, idempotency, and
missing input validation. Prioritize actionable findings.
For each endpoint reviewed:
1. Check HTTP method semantics (GET idempotent, POST creates, etc.)
2. Verify status codes are correct (not 200 for everything)
3. Check error response format is consistent
4. Look for missing input validation
5. Report findings as a prioritized list: critical → important → nice-to-have
| Location | Path | Scope |
|---|---|---|
| Built-in | (in-memory) | Always available |
| User | ~/.config/pvyai/specialists/<name>.md |
Personal, all projects |
| Project | <project>/.pvyai/specialists/<name>.md |
Shared with team (checked into repo) |
Precedence on name collision: project overrides user overrides built-in.
| Field | Required | Description |
|---|---|---|
name |
Yes (or inherited from extends) |
Lowercase, ^[a-z][a-z0-9-]{0,63}$ |
description |
Yes (or inherited) | When to use this specialist |
extends |
No | Base specialist to inherit from |
model |
No | Model ID (e.g. claude-sonnet-4.5); omit to inherit the parent’s model |
reasoningEffort |
No | none, minimal, low, medium, high, xhigh, max |
tools |
No | Tool categories (defaults to read-only) |
| Category | Includes |
|---|---|
read-only |
read_file, read_minified_file, list_directory, glob, grep, lsp_navigate, skill |
edit |
All of read-only + write_file, edit_file, apply_patch, update_plan |
execute |
All of read-only + exec_command, write_stdin, bash |
plan |
update_plan (just the plan tool) |
A specialist can combine categories:
tools:
- "read-only"
- "edit"
- "execute"
- "plan"
Specialists cannot spawn their own specialists. These tools are always forbidden:
Task (spawn a specialist)TaskOutput (poll background task)TaskStop (kill background task)GenerateSpecialist (create a new specialist)extends)A specialist can inherit from another:
---
name: "strict-code-review"
extends: "code-review"
reasoningEffort: "max"
tools:
- "read-only"
---
You are even more thorough than the base code-review specialist.
In addition to the standard checks, also verify:
- All new functions have doc comments
- All exported types have examples
- No magic numbers (use named constants)
Inheritance rules:
description, model, reasoningEffort, and tools if not overriddenType @<specialist-name> at the start of your prompt:
@explorer find the authentication retry logic in this codebase
@code-review review the changes in the last 3 commits
@worker create unit tests for internal/auth/login.go
The @mention is expanded into a delegation prompt:
Use the Task tool to delegate this to the explorer specialist, then report
its result back to me:
find the authentication retry logic in this codebase
Autocomplete offers @name suggestions as you type @.
The agent can autonomously call the Task tool to delegate work:
{
"name": "Task",
"arguments": {
"name": "explorer",
"prompt": "Find all places where the database connection is opened",
"description": "Locate database connection points",
"run_in_background": false
}
}
The system prompt includes a <specialists> block listing available specialists:
<specialists>
- worker: General delegated coding tasks
- explorer: Fast read-only codebase exploration
- code-review: Reviews changes for correctness bugs
- api-reviewer: Reviews API endpoints for REST conformance
</specialists>
| Specialist tools | Permission |
|---|---|
read-only only |
Auto-approved (no permission prompt) |
Includes edit or execute |
Prompted (unless parent is in auto/unsafe mode) |
This means spawning @explorer (read-only) never prompts you — it just runs. Spawning @worker (which can edit) requires approval unless you’re in auto mode.
A specialist never gains more authority than its parent:
ask mode → specialist runs in auto low (read-only auto-approve, prompts for writes)auto mode → specialist runs in auto low (same)unsafe mode → specialist runs in auto high (full auto-approve)Permission rank: spec-draft (1) < ask (2) < auto (3) < unsafe (4). The child’s rank is clamped to the parent’s rank.
Specialists can nest up to 8 levels deep (maxSpecialistDepth = 8). A specialist at depth 8 cannot spawn another.
The specialist runs and the parent blocks until it completes. The result is returned as the Task tool’s output. The parent then continues with the specialist’s findings.
Set run_in_background: true in the Task tool call:
{
"name": "Task",
"arguments": {
"name": "worker",
"prompt": "Run the full test suite and report any failures",
"run_in_background": true
}
}
The specialist runs in a detached process. The parent gets a task_id and can continue other work. To check results later:
| Tool | Action |
|---|---|
TaskOutput |
Poll the background task’s output (optionally blocking with a timeout up to 20 minutes) |
TaskStop |
Kill the background task’s process group |
When a specialist is running, a status card appears in the transcript:
┌─ ◌ explorer ──────────────────────────────────┐
│ Find the auth retry logic │
│ ─ │
│ running · 2 tool calls · 1.2k tokens · 15s │
│ ↳ grep "retry" --include="*.go" │
└────────────────────────────────────────────────┘
| Element | Description |
|---|---|
| Icon | ◌ (running), ✓ (completed), ✗ (error) |
| Name | Specialist name |
| Description | The task description |
| Status | running / completed / error / handed-off |
| Stats | Tool call count, token count, elapsed time |
| Progress | Live ↳ toolName detail line showing current activity |
| Error | Error detail line (if failed) |
The card is clickable / Enter-drillable — you can open the specialist’s child session to see its full conversation.
A summary line above all cards shows:
3 specialists · 2 running · 1 completed · 4.5k tokens total
The context sidebar also shows running specialists with a spinner.
The agent can create new specialists at runtime using the GenerateSpecialist tool:
{
"name": "GenerateSpecialist",
"arguments": {
"name": "migration-helper",
"description": "Helps with database migration scripts",
"prompt": "You are a database migration specialist..."
}
}
This writes a new manifest to .pvyai/specialists/migration-helper.md. The new specialist is immediately available for the rest of the session and future sessions.
# List all specialists
pvyai specialist list
pvyai specialist list --json
# Show a specialist's full manifest
pvyai specialist show api-reviewer
# Create a specialist interactively
pvyai specialist create <name> [flags]
# Edit a specialist in $EDITOR
pvyai specialist edit api-reviewer
# Delete a specialist (user or project level)
pvyai specialist delete api-reviewer
# Show specialist search paths
pvyai specialist path
| Flag | Description |
|---|---|
--description |
One-line description |
--prompt |
System prompt body |
--tools |
Comma-separated tool categories (read-only,edit,execute,plan) |
--model |
Model ID override |
--reasoning-effort |
Reasoning effort (low, medium, high) |
--user |
Create in user directory (default) |
--project |
Create in project directory |
--force |
Overwrite existing |
Parent Agent (TUI)
│
├── Task(name="explorer", prompt="find auth logic")
│ │
│ ▼
│ ┌──────────────────────┐
│ │ Child Process │
│ │ pvyai exec ... │
│ │ --auto low │
│ │ --output-format │
│ │ stream-json │
│ │ --enabled-tools │
│ │ read-only │
│ │ --depth N+1 │
│ │ --tag specialist │
│ └──────────────────────┘
│ │
│ ▼ stream-json events
│ SummarizeStream()
│ BuildFinalResult()
│ │
│ ▼
└── Task tool result
(specialist's final answer)
The child process is in its own process group — if the parent cancels or times out, the entire group is killed (including any grandchildren the specialist might have spawned, like a build server).
| Scenario | Use a specialist? |
|---|---|
| Quick single-file edit | No — just let the main agent do it |
| Explore a large codebase to find something | ✓ — @explorer (read-only, no prompt) |
| Review a PR / changeset | ✓ — @code-review (read-only, no prompt) |
| Run a long test suite while you continue coding | ✓ — @worker in background |
| Implement a well-defined feature in isolation | ✓ — @worker (with edit tools) |
| Multiple independent tasks that can run in parallel | ✓ — spawn multiple specialists (see Swarms for team coordination) |
| Complex task requiring back-and-forth | No — keep it in the main conversation |