@ssheleg/agent-stack 0.7.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -0
- package/README.md +29 -4
- package/package.json +1 -1
- package/plugins/agent-stack/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-stack/skills/agent-harness/SKILL.md +163 -0
- package/plugins/agent-stack/skills/agent-harness/references/audit.md +141 -0
- package/plugins/agent-stack/skills/agent-harness/references/layers.md +104 -0
- package/plugins/agent-stack/skills/agent-harness/references/pi-sdk.md +318 -0
- package/plugins/agent-stack/skills/agent-harness/references/pi.md +241 -0
- package/plugins/agent-stack/skills/agent-harness/references/system-prompt.md +127 -0
- package/plugins/agent-stack/skills/agent-harness/references/techniques.md +115 -0
- package/plugins/agent-stack/skills/agent-harness/references/tools.md +154 -0
- package/plugins/agent-stack/skills/agent-harness/scripts/audit_agent.py +299 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# The system prompt — altitude, vocabulary, and what changes for reasoning models
|
|
2
|
+
|
|
3
|
+
**Load this when:** writing or fixing an agent's system prompt, or explaining why the same
|
|
4
|
+
prompt behaves differently across runs.
|
|
5
|
+
|
|
6
|
+
**Spec pinned:** Anthropic context-engineering and agent guidance; `promptingguide.ai` agents/* and guides/reasoning-llms · read 2026-08-14
|
|
7
|
+
|
|
8
|
+
## Contents
|
|
9
|
+
|
|
10
|
+
- The right altitude
|
|
11
|
+
- What actually belongs in there
|
|
12
|
+
- Enumerate the vocabulary
|
|
13
|
+
- Inject what the model cannot know
|
|
14
|
+
- Flexible while learning, strict in production
|
|
15
|
+
- Structure, examples, and the cost of formatting
|
|
16
|
+
- Reasoning models change three things
|
|
17
|
+
- Traps
|
|
18
|
+
|
|
19
|
+
## The right altitude
|
|
20
|
+
|
|
21
|
+
A system prompt fails in two directions and the middle is narrower than it looks.
|
|
22
|
+
|
|
23
|
+
**Too low** — hardcoded if-then branches for every case. It works on the cases you wrote and
|
|
24
|
+
is brittle everywhere else, and each new case costs another branch. You are writing a
|
|
25
|
+
program in prose, badly.
|
|
26
|
+
|
|
27
|
+
**Too high** — vague guidance that assumes a shared understanding the model does not have.
|
|
28
|
+
"Be helpful and use good judgement" tells it nothing it did not already believe.
|
|
29
|
+
|
|
30
|
+
The target: **specific enough to guide behaviour, flexible enough to give the model strong
|
|
31
|
+
heuristics.** A useful test — could a competent new colleague follow this without asking a
|
|
32
|
+
clarifying question, and without being insulted? If they would ask, it is too high. If they
|
|
33
|
+
would feel micromanaged into a corner where their judgement cannot help, it is too low.
|
|
34
|
+
|
|
35
|
+
## What actually belongs in there
|
|
36
|
+
|
|
37
|
+
In rough order of how much behaviour each buys:
|
|
38
|
+
|
|
39
|
+
1. **Tool usage instructions.** Not the tool schema — the *policy*. When to reach for which,
|
|
40
|
+
what order usually makes sense, what to do when one fails. The largest measured gains come
|
|
41
|
+
from here, and it is the part most teams leave to the schema alone.
|
|
42
|
+
2. **The role and its boundaries** — what this agent is for, and what it must hand off.
|
|
43
|
+
3. **The vocabulary** it must produce (below).
|
|
44
|
+
4. **Volatile context** it cannot know (below).
|
|
45
|
+
5. **Failure instructions** — what to do when a tool errors, when data is missing, when the
|
|
46
|
+
task is impossible. Absent, the model invents a recovery, and inventions are not uniform.
|
|
47
|
+
6. **Output contract** — shape, not prose about shape.
|
|
48
|
+
|
|
49
|
+
## Enumerate the vocabulary
|
|
50
|
+
|
|
51
|
+
**Be explicit about allowed values.** An agent asked to track task status will produce
|
|
52
|
+
`pending` in one turn and `to-do` in the next, `completed` here and `done` there — and any
|
|
53
|
+
code reading those strings now has a bug that appears intermittently and reads as
|
|
54
|
+
flakiness.
|
|
55
|
+
|
|
56
|
+
This generalises past status: every category, label, severity, priority or state the agent
|
|
57
|
+
emits should appear as an enumerated set in the prompt, or in the tool's parameter `enum`,
|
|
58
|
+
or both. It is the cheapest determinism available.
|
|
59
|
+
|
|
60
|
+
## Inject what the model cannot know
|
|
61
|
+
|
|
62
|
+
**Today's date is the canonical example**, and its absence has a specific failure signature:
|
|
63
|
+
the agent answers from training data instead of searching, confidently and with no error.
|
|
64
|
+
Inject the date and the behaviour changes without another word of instruction.
|
|
65
|
+
|
|
66
|
+
The general rule: anything volatile that the model would otherwise fill from memory —
|
|
67
|
+
current date, environment, tenant, available capabilities, the user's locale — is injected,
|
|
68
|
+
not assumed. A capability-aware prompt that lists only the tools actually connected beats a
|
|
69
|
+
static prompt describing tools that may be absent.
|
|
70
|
+
|
|
71
|
+
## Flexible while learning, strict in production
|
|
72
|
+
|
|
73
|
+
The same instruction should not survive the whole lifecycle.
|
|
74
|
+
|
|
75
|
+
- **While you are still learning what good looks like:** *"Use the tools in the order that
|
|
76
|
+
makes most sense to you."* This surfaces what the model thinks the task is, which is the
|
|
77
|
+
information you need.
|
|
78
|
+
- **Once the sequence is known and a skipped step is a defect:** *"You MUST execute a web
|
|
79
|
+
search for each task."* Flexibility here buys nothing and costs a silently missing step.
|
|
80
|
+
|
|
81
|
+
Teams get stuck at the first form because it felt elegant, then debug an agent that
|
|
82
|
+
"sometimes forgets" — which is not forgetting, it is permission.
|
|
83
|
+
|
|
84
|
+
## Structure, examples, and the cost of formatting
|
|
85
|
+
|
|
86
|
+
**Structure inputs and outputs** with delimiters, XML tags or JSON. Clear segmentation
|
|
87
|
+
reduces the class of error where the model treats data as instruction.
|
|
88
|
+
|
|
89
|
+
**Examples are worth more than description**, and the mistake is quantity. Curate a few
|
|
90
|
+
**diverse, canonical** examples rather than an exhaustive list of edge cases — the latter
|
|
91
|
+
reads as a lookup table and the model generalises from it badly.
|
|
92
|
+
|
|
93
|
+
**But formatting has a cost.** Keep formats close to natural internet text where you can;
|
|
94
|
+
elaborate escaping, deeply nested structures and unusual syntaxes spend the model's
|
|
95
|
+
attention on parsing rather than the task. Ask whether a human writing this by hand would
|
|
96
|
+
choose the format. If not, it is overhead.
|
|
97
|
+
|
|
98
|
+
## Reasoning models change three things
|
|
99
|
+
|
|
100
|
+
Treating a reasoning model like a completion model is now a common and expensive mistake.
|
|
101
|
+
|
|
102
|
+
1. **Do not add chain-of-thought instructions.** Native reasoning already happens.
|
|
103
|
+
Explicit step-by-step prompting is redundant and **can hurt instruction-following** —
|
|
104
|
+
which is the opposite of what the person adding it intends.
|
|
105
|
+
2. **Give goals, not procedures.** Be explicit about the high-level outcome and let the
|
|
106
|
+
model plan the route. Procedural micro-steps fight the thing you are paying for.
|
|
107
|
+
3. **Reasoning effort is a dial that did not exist before** — low/medium/high trades cost
|
|
108
|
+
against accuracy per call, so it is a per-stage decision, not a global setting.
|
|
109
|
+
|
|
110
|
+
Two more, worth knowing before you architect around them: **few-shot is still useful, but
|
|
111
|
+
mainly for output *format***, not for teaching the task; and **tool-calling remains weaker
|
|
112
|
+
in most reasoning models**, which is why the common shape is a reasoning model for planning
|
|
113
|
+
and a different one for execution.
|
|
114
|
+
|
|
115
|
+
## Traps
|
|
116
|
+
|
|
117
|
+
- **Growing the prompt instead of fixing it.** Every incident adds a sentence; nothing is
|
|
118
|
+
ever removed; a year later nobody can say which line does work. Prune on the same schedule
|
|
119
|
+
you add.
|
|
120
|
+
- **Describing tools twice**, in the schema and in the prompt, with the two drifting. Put
|
|
121
|
+
*policy* in the prompt and *contract* in the schema, and say which is which.
|
|
122
|
+
- **A prompt that assumes a tool exists.** Capability-aware assembly, or an explicit
|
|
123
|
+
fallback; never a promise the runtime may not keep.
|
|
124
|
+
- **Tuning the prompt with no eval.** You are optimising against the last thing you noticed.
|
|
125
|
+
See `agent-evals`.
|
|
126
|
+
- **One prompt for planning and execution.** Separation of concerns measurably improves
|
|
127
|
+
reliability and lets a cheaper model take the mechanical half.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# The technique catalogue, with a verdict on each
|
|
2
|
+
|
|
3
|
+
**Load this when:** choosing between ReAct, reflection, voting, planning and the rest — or
|
|
4
|
+
being asked why the system does not use one that appeared in a paper.
|
|
5
|
+
|
|
6
|
+
**Spec pinned:** `promptingguide.ai` techniques/* and guides/*; Anthropic agent guidance · read 2026-08-14
|
|
7
|
+
|
|
8
|
+
**How to read the verdicts.** Every technique here works somewhere; the column says whether
|
|
9
|
+
it earns its cost *in a production agent loop*, which is a narrower question than whether it
|
|
10
|
+
raised a benchmark. Costs are real: each of these multiplies calls, latency or context, and
|
|
11
|
+
several of them were measured on single-turn QA rather than a long-running agent.
|
|
12
|
+
|
|
13
|
+
## Contents
|
|
14
|
+
|
|
15
|
+
- The catalogue
|
|
16
|
+
- ReAct, in detail
|
|
17
|
+
- Reflection, in detail
|
|
18
|
+
- Voting and self-consistency
|
|
19
|
+
- What reasoning models made redundant
|
|
20
|
+
- Choosing one
|
|
21
|
+
|
|
22
|
+
## The catalogue
|
|
23
|
+
|
|
24
|
+
| Technique | What it is | Verdict for a production agent loop |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| **Zero-shot** | instruction alone | **Default.** Start here; everything below is a cost you must justify |
|
|
27
|
+
| **Few-shot** | input→output exemplars | **Yes, for format.** Curate a few diverse canonical examples. It teaches shape far better than it teaches judgement, and an exhaustive list makes the model brittle |
|
|
28
|
+
| **Chain-of-thought** | "think step by step" | **Legacy on reasoning models — actively harmful there** (it can degrade instruction-following). Still useful on non-reasoning models for arithmetic and multi-constraint tasks |
|
|
29
|
+
| **ReAct** | interleaved thought → action → observation | **Yes — this is the agent loop.** Most harnesses implement it without naming it. See below for what it does not fix |
|
|
30
|
+
| **Reflexion / self-critique** | actor, evaluator, self-reflection, with episodic memory | **Selectively.** Real gains where a *cheap objective signal* exists — tests pass, query runs, schema validates. Without one, the model grades its own homework |
|
|
31
|
+
| **Self-consistency** | sample N, take the majority | **Rarely.** N× cost and latency for a single answer; needs a well-defined answer to vote on. Use for a high-stakes classification, not for a whole trajectory |
|
|
32
|
+
| **Tree of Thoughts** | explore and prune a branching search | **Almost never in production.** Combinatorial cost, and the pruning heuristic is usually the hard part you have not solved. A planner plus a bounded retry gets most of the value |
|
|
33
|
+
| **ART** (automatic reasoning + tool use) | select exemplars and tools from a task library automatically | **Watch.** The idea — a library of trajectories rather than a hand-written prompt — is where prompt maintenance is heading; the tooling is not settled |
|
|
34
|
+
| **Prompt chaining** | fixed sequence with checks between | **Yes — and prefer it over an agent** wherever the steps are knowable |
|
|
35
|
+
| **Meta prompting** | prompt about the structure of the task, not its content | **Occasionally.** Useful for generating scaffolds; not a loop technique |
|
|
36
|
+
| **Generate-knowledge** | elicit facts first, then answer | **No.** Retrieval solves the same problem with grounding; this invents plausible knowledge |
|
|
37
|
+
| **RAG** | retrieve, then generate | **Yes, and it is a search problem.** Its quality lives outside this skill; what belongs here is *just-in-time* retrieval — see below |
|
|
38
|
+
| **Just-in-time retrieval** | hold lightweight identifiers (paths, queries, links); load at runtime via tools | **Yes.** The scalable default: it mirrors how people work, and keeps the window for reasoning rather than for data |
|
|
39
|
+
| **Structured note-taking** | write notes to durable memory outside the window, read them back | **Yes for long tasks.** Persistent memory at low overhead, and it survives compaction — which a summary of the discussion does not |
|
|
40
|
+
| **Sub-agents** | specialists returning distilled summaries | **Yes where the sub-task has its own context need.** The value is the *isolated window*; a sub-agent returns a 1–2k-token distilled summary, never a transcript |
|
|
41
|
+
|
|
42
|
+
## ReAct, in detail
|
|
43
|
+
|
|
44
|
+
**Thought → Action → Observation**, repeated. Reasoning traces and task actions generated in
|
|
45
|
+
an interleaved way, so the plan updates on what the world actually returned.
|
|
46
|
+
|
|
47
|
+
What it fixes: plain chain-of-thought is isolated from external information and therefore
|
|
48
|
+
suffers **fact hallucination and error propagation** — it reasons confidently past a wrong
|
|
49
|
+
premise. ReAct grounds each step in an observation.
|
|
50
|
+
|
|
51
|
+
**What it does not fix, and this is under-quoted:**
|
|
52
|
+
|
|
53
|
+
- It **constrains reasoning flexibility** compared with free-form CoT — the format itself is
|
|
54
|
+
a cost.
|
|
55
|
+
- **Non-informative results derail it.** A search returning nothing useful leaves the model
|
|
56
|
+
struggling to reformulate, and it will loop on near-identical queries. This is the failure
|
|
57
|
+
your iteration guard exists for, and it is why tool errors must teach (`tools.md`).
|
|
58
|
+
- It is strongest **combined** with CoT and self-consistency rather than alone — which is
|
|
59
|
+
the honest reading of the paper and rarely the reading in a blog post.
|
|
60
|
+
|
|
61
|
+
## Reflection, in detail
|
|
62
|
+
|
|
63
|
+
Three roles, and naming them separates the ones people conflate:
|
|
64
|
+
|
|
65
|
+
| Role | Does | In practice |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| **Actor** | generates text and actions, produces a trajectory | your existing loop |
|
|
68
|
+
| **Evaluator** | scores the trajectory | **the part that decides whether this works at all** |
|
|
69
|
+
| **Self-reflection** | turns the score into verbal guidance stored for next time | an extra call, plus memory |
|
|
70
|
+
|
|
71
|
+
**The evaluator is the whole question.** Where the signal is objective and cheap — the test
|
|
72
|
+
suite ran, the SQL executed, the JSON validated, the build passed — reflection is one of the
|
|
73
|
+
strongest available techniques. Where the evaluator is the same model judging its own
|
|
74
|
+
output with no ground truth, you have added cost and a confident second opinion.
|
|
75
|
+
|
|
76
|
+
Stated limitations worth carrying: it depends on **accurate self-evaluation**, its memory is
|
|
77
|
+
typically a **sliding window**, and it struggles where correctness is non-deterministic.
|
|
78
|
+
|
|
79
|
+
## Voting and self-consistency
|
|
80
|
+
|
|
81
|
+
Sample the same task several times and take the majority. It genuinely reduces variance —
|
|
82
|
+
and it multiplies cost and latency by N, needs a discrete answer to vote on, and does
|
|
83
|
+
nothing for a long trajectory where the runs diverge at step three.
|
|
84
|
+
|
|
85
|
+
Reach for it on a **single high-stakes decision** — a routing classification, a safety
|
|
86
|
+
judgement, an extraction that everything downstream depends on. Not on a whole agent run.
|
|
87
|
+
|
|
88
|
+
## What reasoning models made redundant
|
|
89
|
+
|
|
90
|
+
A live shift, and it invalidates a lot of otherwise-good advice:
|
|
91
|
+
|
|
92
|
+
- **Do not instruct step-by-step thinking.** It is native, and explicit CoT can hurt
|
|
93
|
+
instruction-following.
|
|
94
|
+
- **Give high-level goals rather than procedures**, and let planning happen inside the model.
|
|
95
|
+
- **Reasoning effort** is now a per-call dial, which is a cheaper knob than most of the
|
|
96
|
+
techniques above.
|
|
97
|
+
- But **tool-calling stays weaker** in most reasoning models — so the common production shape
|
|
98
|
+
is a reasoning model that plans and a different model that executes tools. That is
|
|
99
|
+
*separation of concerns*, and it also lets the cheap half be cheap.
|
|
100
|
+
|
|
101
|
+
## Choosing one
|
|
102
|
+
|
|
103
|
+
Ask in this order, and stop at the first yes:
|
|
104
|
+
|
|
105
|
+
1. **Are the steps knowable?** → prompt chaining, not an agent.
|
|
106
|
+
2. **Is there a cheap objective signal?** → evaluator–optimizer or reflection.
|
|
107
|
+
3. **Does the sub-task need its own window?** → a sub-agent returning a distilled summary.
|
|
108
|
+
4. **Is one decision disproportionately expensive to get wrong?** → voting, on that decision only.
|
|
109
|
+
5. **Otherwise** → a plain ReAct loop with a bounded iteration guard, and spend the effort on
|
|
110
|
+
the tools and the prompt instead. That is where the measured gains are.
|
|
111
|
+
|
|
112
|
+
**The anti-pattern this section exists to prevent:** adopting a technique because it appears
|
|
113
|
+
in a paper, without naming the signal it consumes or the cost it adds. If you cannot say
|
|
114
|
+
what the evaluator measures, you are not doing reflection — you are paying for a second
|
|
115
|
+
opinion from the same source.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Tools — the agent–computer interface
|
|
2
|
+
|
|
3
|
+
**Load this when:** the model picks the wrong tool, calls none, calls one with bad arguments,
|
|
4
|
+
or you are deciding what to expose in the first place.
|
|
5
|
+
|
|
6
|
+
**Spec pinned:** Anthropic *Writing tools for agents* and *Building effective agents*; `promptingguide.ai` agents/function-calling · read 2026-08-14
|
|
7
|
+
|
|
8
|
+
Anthropic's framing is worth adopting whole: this is the **agent–computer interface**, and it
|
|
9
|
+
deserves the same craft a human interface gets. Most teams spend their effort on the model
|
|
10
|
+
and none on the ACI, then conclude the model is bad at tool use.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- Fewer tools than you think
|
|
15
|
+
- Namespacing
|
|
16
|
+
- The description is the product
|
|
17
|
+
- Return meaning, not identifiers
|
|
18
|
+
- Token efficiency is a correctness issue
|
|
19
|
+
- Errors that teach
|
|
20
|
+
- Poka-yoke: make the wrong call impossible
|
|
21
|
+
- Evaluating tools
|
|
22
|
+
- Traps
|
|
23
|
+
|
|
24
|
+
## Fewer tools than you think
|
|
25
|
+
|
|
26
|
+
**More tools do not lead to better outcomes.** The reflex — wrap every API endpoint, ship
|
|
27
|
+
forty tools, let the model choose — produces an agent that chooses badly, because selection
|
|
28
|
+
degrades with the size of the set and every definition costs context.
|
|
29
|
+
|
|
30
|
+
Build **a few thoughtful tools targeting specific high-impact workflows.** The test:
|
|
31
|
+
consolidate where a human would. `search_and_summarize` beats `search` + `fetch` +
|
|
32
|
+
`summarize` when the three are always used together, because it removes two decisions and
|
|
33
|
+
two round trips.
|
|
34
|
+
|
|
35
|
+
**The honest check, and it is brutal:** *if your engineers cannot definitively say which
|
|
36
|
+
tool applies to a case, the model cannot either.* Ambiguity between two tools is a design
|
|
37
|
+
defect, not a prompting problem.
|
|
38
|
+
|
|
39
|
+
## Namespacing
|
|
40
|
+
|
|
41
|
+
Group related tools under a common prefix — `asana_search`, `asana_create_task`,
|
|
42
|
+
`jira_search`. Boundaries become visible, and the model stops crossing services by accident.
|
|
43
|
+
|
|
44
|
+
This also matters at the federation layer: behind a gateway, tool names commonly gain a
|
|
45
|
+
prefix from their source server, and a name that changes between sessions invalidates every
|
|
46
|
+
prompt and eval that referenced it. See `agent-interop/references/gateway.md`.
|
|
47
|
+
|
|
48
|
+
## The description is the product
|
|
49
|
+
|
|
50
|
+
**Even small refinements to tool descriptions yield dramatic improvements.** The rule that
|
|
51
|
+
makes them good: **write as if explaining to a new team member**, and make implicit context
|
|
52
|
+
explicit.
|
|
53
|
+
|
|
54
|
+
A description must answer **when and why**, not only what:
|
|
55
|
+
|
|
56
|
+
```jsonc
|
|
57
|
+
// weak — restates the name, and says nothing about choosing it
|
|
58
|
+
{ "name": "search_users", "description": "Searches for users." }
|
|
59
|
+
|
|
60
|
+
// strong — the model can now decide
|
|
61
|
+
{ "name": "search_users",
|
|
62
|
+
"description": "Find users by name, email or team. Use this before any operation \
|
|
63
|
+
that needs a user ID — IDs are never guessable. Returns at most 20 matches; narrow \
|
|
64
|
+
with `team` rather than paging when you can. Do NOT use for the current user: \
|
|
65
|
+
`get_current_user` is cheaper and always correct." }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Note what the strong version carries: **when to reach for it, what it costs, how to narrow,
|
|
69
|
+
and the neighbouring tool it is confused with.** That last clause is the highest-value
|
|
70
|
+
sentence in most tool descriptions and almost nobody writes it.
|
|
71
|
+
|
|
72
|
+
**Parameters carry their own guidance.** Use `enum` to constrain values rather than
|
|
73
|
+
describing the constraint in prose, give examples in parameter descriptions, and mark
|
|
74
|
+
required versus optional honestly — an optional parameter the tool actually needs is a
|
|
75
|
+
silent failure.
|
|
76
|
+
|
|
77
|
+
## Return meaning, not identifiers
|
|
78
|
+
|
|
79
|
+
Prioritise **contextual relevance over flexibility**. A response of
|
|
80
|
+
`{"id": "u_8f3a", "gid": "1209...", "rid": 44}` gives the model nothing to reason with; it
|
|
81
|
+
will echo identifiers into prose and hallucinate what they mean. Return
|
|
82
|
+
`{"name": "Ada Lovelace", "team": "Platform", "id": "u_8f3a"}` — the id stays for the next
|
|
83
|
+
call, the meaning arrives for the reasoning.
|
|
84
|
+
|
|
85
|
+
## Token efficiency is a correctness issue
|
|
86
|
+
|
|
87
|
+
Not merely a cost issue: a tool that returns 40,000 tokens of JSON has consumed the window
|
|
88
|
+
the agent needed to finish the task, and no amount of history trimming recovers it (see
|
|
89
|
+
`agent-orchestrator/references/context-engineering.md` → *tool-output offload*).
|
|
90
|
+
|
|
91
|
+
Build in **pagination, range selection, filtering and truncation — with sensible defaults**.
|
|
92
|
+
The default matters more than the capability: an agent will rarely opt into a limit it was
|
|
93
|
+
not given.
|
|
94
|
+
|
|
95
|
+
## Errors that teach
|
|
96
|
+
|
|
97
|
+
A tool error is a turn in a conversation. Compare:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
Error: 422 Unprocessable Entity
|
|
101
|
+
```
|
|
102
|
+
```
|
|
103
|
+
Error: `due_date` must be ISO-8601 (e.g. 2026-08-14). You sent "next friday".
|
|
104
|
+
Call `resolve_date` first, or pass an absolute date.
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The second costs nothing extra and converts a dead end into a recovery. **Return informative
|
|
108
|
+
messages that help the agent recover or try an alternative** — naming the alternative is the
|
|
109
|
+
part that gets skipped.
|
|
110
|
+
|
|
111
|
+
Two structural notes: under MCP a failed tool arrives as a *successful* response carrying
|
|
112
|
+
`isError: true`, so code that only catches transport exceptions treats every tool failure as
|
|
113
|
+
a success containing an apology (`agent-interop/references/mcp.md`). And in code-mode
|
|
114
|
+
harnesses, generated wrappers should convert that into a thrown exception so model-authored
|
|
115
|
+
code can `try`/`catch`.
|
|
116
|
+
|
|
117
|
+
## Poka-yoke: make the wrong call impossible
|
|
118
|
+
|
|
119
|
+
Borrowed from manufacturing, and the highest-leverage idea here: **change the interface so
|
|
120
|
+
the mistake cannot be made**, rather than documenting the mistake.
|
|
121
|
+
|
|
122
|
+
- Absolute paths instead of relative ones, when relative paths get resolved against a
|
|
123
|
+
directory the agent guessed.
|
|
124
|
+
- An `enum` instead of a free-text field with a list of valid values in the description.
|
|
125
|
+
- One tool that does the two-step correctly instead of two tools that must be ordered.
|
|
126
|
+
- A required `confirm: true` on a destructive action, so a partially-formed call fails
|
|
127
|
+
closed.
|
|
128
|
+
|
|
129
|
+
## Evaluating tools
|
|
130
|
+
|
|
131
|
+
Tools deserve **thorough documentation and testing**, and testing means running the agent
|
|
132
|
+
against real tasks and reading which tool it picked, with what arguments, and what came
|
|
133
|
+
back. Enable intermediate-step visibility and look for the three recurring faults:
|
|
134
|
+
|
|
135
|
+
| Symptom | Almost always |
|
|
136
|
+
|---|---|
|
|
137
|
+
| wrong tool chosen | two descriptions do not distinguish themselves; add the "do NOT use for…" clause |
|
|
138
|
+
| bad arguments | the parameter description assumes context the model does not have, or the type is too loose |
|
|
139
|
+
| result misread | the response returned identifiers, or too much, or both |
|
|
140
|
+
|
|
141
|
+
Fix the interface, not the prompt, when the fault is in this table.
|
|
142
|
+
|
|
143
|
+
## Traps
|
|
144
|
+
|
|
145
|
+
- **Wrapping the API you have** instead of designing the tools the agent needs.
|
|
146
|
+
- **A description written for a human reading docs** rather than a model choosing under
|
|
147
|
+
uncertainty.
|
|
148
|
+
- **Unbounded responses** with an optional `limit` nobody sets.
|
|
149
|
+
- **Errors that are true and useless.** `null is not an object` names the symptom the model
|
|
150
|
+
can do nothing with.
|
|
151
|
+
- **Treating tool output as trusted.** It is attacker-controlled input if the server is; the
|
|
152
|
+
specification says descriptions and annotations are untrusted unless the server is.
|
|
153
|
+
- **Adding a tool to fix a prompt problem.** The set grows, selection degrades, and the
|
|
154
|
+
original defect is still there.
|