diff options
Diffstat (limited to 'skills/pi-subagent/SKILL.md')
| -rw-r--r-- | skills/pi-subagent/SKILL.md | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/skills/pi-subagent/SKILL.md b/skills/pi-subagent/SKILL.md new file mode 100644 index 0000000..c5f1bfb --- /dev/null +++ b/skills/pi-subagent/SKILL.md @@ -0,0 +1,209 @@ +--- +name: pi-subagent +description: >- + Delegates work to one or more headless `pi` subagents on any provider/model, + run in the background, and collects each one's final answer plus its actual + billed cost. Covers a single delegated task, the same task fanned out to + several models for independent answers, or a job split into separate tasks + run in parallel, followed by verifying what came back. Use when the user + asks for subagents, to hand something to another model, to get several + models' takes, or to parallelize work across pi runs — and when another + skill (such as pi-review-panel) builds on it. Spawning costs money: never + start subagents on your own initiative without the user asking. +--- + +# pi subagents + +Run `pi` headless as a subagent: a fresh process, a written brief, no memory of +this conversation, one final answer. You stay the orchestrator. Subagents +produce raw material; you check it before it reaches the user. + +The fiddly parts (hang avoidance, output extraction, cost accounting, keeping +failed attempts) are solved in `run-agent.sh` next to this file. Use it. Don't +hand-roll `pi -p` invocations — the flag set and the redirection shape are +load-bearing, and the failure modes are silent hangs. The reasons are at the +top of the script. `$SK` below is this skill's directory. + +## 0. Shape the job + +Pick one of three shapes, and say which to the user if it isn't obvious: + +| shape | what | when | +|---|---|---| +| **delegate** | one task, one model | a self-contained job worth running elsewhere: a long investigation, a second opinion from a specific model, work you want off your own context | +| **fan-out** | one brief, N models | you want independent answers to compare: reviews, designs, hard questions. Disagreement is the signal | +| **split** | N briefs, one model each | a job that divides cleanly into parts that don't depend on each other's results | + +A subagent knows nothing you don't write down, can't ask you anything, and +can't see your other subagents. If the parts of a split need each other's +output, it's a sequence, not a split — run it in stages. + +**Models.** Use exactly the provider/model pairs the user names; don't add +others. If they named none, ask — or, for a fan-out, offer the default panel in +the pi-review-panel skill. Check a name resolves first: +`pi --offline --list-models <search>`. Credentials are already configured in +`pi`. + +## 1. Set up a workdir + +```bash +P="$(mktemp -d -t pi-subagent)"; mkdir -p "$P/out" +``` + +`$P` is scratch. One workdir per job; several briefs can live in it +(`$P/brief-<part>.md`), and every run writes `$P/out/<name>.*`. + +**Snapshot the inputs.** If the subagents will read files someone else may be +editing — including you — record their content hash now and re-check before you +use the answers. Input that changes mid-run invalidates parts of their +reasoning, and you need to know that happened. + +## 2. Write the brief + +The brief is the whole interface. Write it as if for a capable contractor who +has never seen the project and will not get to ask questions: + +- **The task, first sentence.** What you actually want. "Find bugs in this + diff" and "propose a better design than this one" produce very different + work; don't leave it to be guessed. +- **Context.** One paragraph on the project (from its README) and on why this + task exists. +- **The material, inline** in fenced blocks, even if you also give paths — the + subagent should not have to go looking for the thing it's about. +- **Absolute paths** of relevant files and directories, so it can read the + surroundings with its tools. +- **Criteria**, as hard requirements. If the user gave criteria, quote them + verbatim. +- **Evidence rules.** Verify empirically before asserting, and say which + command, interpreter, or version produced each claim. Distinguish what was + run from what was reasoned. +- **What it may touch** — see §3 — stated plainly. `pi` has edit and write + tools and will use them unless told, or prevented. +- **The deliverable**: format, sections, length. End with a **fixed final + line** where answers will be compared — `VERDICT: SHIP` / + `VERDICT: DO NOT SHIP`, `ANSWER: <x>`, `STATUS: DONE` / + `STATUS: BLOCKED — <why>`. Fixed strings make the tally and the success check + mechanical. +- **No questions, no follow-ups.** Deliver the full result as the final answer; + don't ask for confirmation, don't offer further work. + +## 3. Decide what it may touch + +Subagents share this machine and its filesystem. Constrain them in this order +of preference: + +1. **Read-only by construction**: `--tools read,grep,find,ls`. No shell, so it + can't run or change anything. Right for pure reading and reasoning. +2. **Read-only by instruction**: default tools (bash included), with the brief + saying everything is read-only. Needed when the subagent must run things to + verify claims — tests, interpreters, measurements. Tell it to put scratch + files under its own `$P/scratch-<name>/` and nowhere else. +3. **Writes, isolated**: give each writing subagent its own git worktree and + pass it as `--cwd`; never let two writers share a tree, and never point one + at the user's working copy. Worktrees go under + `~/x/worktrees/<repo>/<name>`. You review and bring over the result; the + subagent doesn't commit, push or post anything — say so in the brief. + +Context files (AGENTS.md/CLAUDE.md) are off by default, so the brief is the +only instruction a subagent gets. Pass `--context-files` when it works inside +a repo whose conventions it must follow. + +## 4. Launch + +Always in the background, so you can keep working: + +```bash +"$SK/run-agent.sh" "$P" <provider> "<model>" <name> > "$P/out/_<name>.log" 2>&1 & +``` + +Options go before the positionals: `--brief FILE` (default `$P/brief.md`), +`--timeout SECS` (default 1800), `--thinking LEVEL` (default `high`), +`--tools LIST`, `--cwd DIR`, `--context-files`, `--deliver TEXT`. Names must be +unique within a workdir; a natural scheme is `<provider-abbrev>-<model>` for a +fan-out and `<part>` for a split. + +A fan-out of one brief to three models: + +```bash +"$SK/run-agent.sh" "$P" fireworks "accounts/fireworks/models/kimi-k3" fw-kimi-k3 > "$P/out/_fw-kimi-k3.log" 2>&1 & +"$SK/run-agent.sh" "$P" openrouter "z-ai/glm-5.3" or-glm-5.3 > "$P/out/_or-glm-5.3.log" 2>&1 & +"$SK/run-agent.sh" "$P" openrouter "google/gemini-3.7-flash" or-gemini > "$P/out/_or-gemini.log" 2>&1 & +``` + +A split, each part with its own brief: + +```bash +for part in parser cli docs; do + "$SK/run-agent.sh" --brief "$P/brief-$part.md" "$P" openrouter "z-ai/glm-5.3" "$part" \ + > "$P/out/_$part.log" 2>&1 & +done +``` + +## 5. Monitor — and work meanwhile + +Expect minutes to tens of minutes per run. Check progress with: + +```bash +"$SK/status.sh" "$P" # once: running names, then the table so far +"$SK/status.sh" --wait 60 "$P" # block until all are done (exit 0) +``` + +`status.sh` exits 3 while anything is still running, and also prints free disk +space — the event streams are big while runs are in flight. + +**Don't sit on the wait loop.** Launching early is only worth it if you use the +time: do your own investigation of the same question, build whatever harness +you'll need to check the answers, establish baselines. You need your own +evidence in §7 regardless. When you do block, give the shell call a timeout +and loop, rather than one unbounded wait. + +## 6. Handle failures + +A run succeeded if `$P/out/<name>.md` is non-empty and (when you asked for one) +ends with the fixed final line. Exit 124 is the timeout firing. `<name>.err` +and `<name>.jsonl` say what happened otherwise. + +Retry a failure once, under the same name: `run-agent.sh` moves the failed +run's files to `<name>.attempt<N>.*` first, cost included. If it fails twice, +report it with its cost and carry on — one dead provider must not sink the job. +For a split, a failed part is a gap you either fill yourself or report. + +## 7. Verify, then use + +What comes back is raw material, not results: + +- **Reproduce every substantive claim** before passing it on. Models + hallucinate line numbers, APIs, file contents and measurements, with + confidence. +- **Disagreement is where the answer is.** When answers conflict, run the + experiment that decides it and say who was right. +- **Consensus is weak evidence.** Several models agreeing can all be making the + same mistake, or testing the same wrong version. One claim you confirmed + outranks four you didn't. +- **Check what was actually tested.** Watch for a claim true of a variant but + not of the thing written — a subagent "verifying" code it silently fixed + first. +- **Distrust your own harness too.** A test extracted to run standalone can + fail for reasons of its own (a missing import, a swallowed exception) that + look exactly like the bug under discussion. Check the baseline passes what it + should. +- **Written work**, from a worktree: read the whole diff and run the tests + yourself before bringing any of it over. Never merge it unseen. + +Say what you dropped and why, alongside what you kept — that's what makes the +kept part trustworthy. + +## 8. Report cost + +Every report that used subagents ends with the cost table; the user should +never have to ask. `status.sh` prints it: per run, from the provider's own +per-message `usage.cost` — billed figures, not estimates — failed attempts as +their own rows, then the total. A timed-out run bills for every token it +generated and can be the most expensive line. When cost per useful result +varies a lot across models, say so: it informs who to use next time. + +## 9. Keep what matters + +`$P` won't survive the session. If the answers matter, copy the `.md` outputs, +the cost files, and any verification scripts somewhere durable in the project, +and link those instead of `$P`. |
