Skip to content

Navigation Menu

Sign in
Sign up

feat(agent): validate an action before dispatching it, not after it fails #3393

Open

Description

GAIA proposes actions that cannot work. Benchmarked across 40 real decision points on three
models, 32 of the flagship's proposed actions would have failed outright — 40% of them on
one model. The reference harness produced zero on the same inputs.

They are not subtle. One was write_file called with no arguments at all. Ten named a
file path the agent had never seen. Nine were shell commands wrong for the state it was in.

Every one of those is checkable before dispatch, against information the agent already
holds. The loop has the known-path set, the tool schema, and the shell allowlist — it just
never consults them between choosing an action and running it.

This is distinct from #3381, which verifies work after it is done. This is refusing to
dispatch a call that is malformed on its face, and asking the model again with the reason.

🔍 Technical details

Breakdown of the 32 broken actions (judge score 0 = would error immediately, wrong tool, or
names something with no reason to exist):

Cause n
Named a path never seen in this run 10
Shell command wrong for the state 9
Other (mostly unreachable fetch_page URLs) 11
Searched instead of acting 1
Called a tool with no arguments 1

Most-broken tools: run_shell_command 9, fetch_page 9, search_file_content 6,
read_file 4, write_file 2.

Cheap checks, in rough order of value:

  1. Required arguments present and typed. The tool schema already declares them.
    write_file: {} should never reach dispatch.
  2. Path plausibility. The agent tracks paths it has seen. A path outside that set, and
    outside any directory it has listed, is a guess — worth one clarifying round trip rather
    than a failed call.
  3. Binary availability. The shell layer already owns an allowlist; consult it before
    dispatch instead of failing at execution.
  4. Refusal carries the reason. A rejected call must tell the model what was wrong, or
    the retry is blind. fix(tools): ambiguous old_content silently edits the first match #3377 makes the same argument for ambiguous edits.

One caveat on the path number, stated because it cuts against the finding. The benchmark
feeds scrubbed state, so paths appear as <WORKSPACE>/... placeholders. 8 of the 32 broken
actions expanded that placeholder into a concrete C:\... path — a form GAIA would not meet
in production, so that portion is partly an artefact of the harness rather than a defect.
The reference harness saw the identical input and preserved the placeholder, so a robustness
difference is real; the magnitude is inflated. The write_file: {} and wrong-command cases
are unaffected by this.

Depends on #3392 for diagnosis — without argument capture in the turn record you cannot tell
whether a validator is firing correctly or masking a different bug.

Acceptance criteria

  • A tool call missing required arguments is refused before dispatch, with the reason
    returned to the model
  • A path outside the agent's known-path set triggers a check rather than a blind call
  • An unavailable binary is reported before execution, naming what is missing
  • Every refusal states what was wrong, so the retry is informed
  • Refusals are counted in turn metrics, so the rate is visible rather than inferred
  • Re-running the step-level benchmark shows the broken-action rate fall from its
    current 40% (sonnet-5) / 15% (opus-5) / 28% (gemma-4-31b)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request p2low priority

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    AltStyle によって変換されたページ (->オリジナル) /