Skip to content

fix(agent): append system_prompt to the Claude Code preset instead of replacing - #92

Open
Mihaiii wants to merge 2 commits into
mainfrom
fix/sys-prompt-append
Open

fix(agent): append system_prompt to the Claude Code preset instead of replacing#92
Mihaiii wants to merge 2 commits into
mainfrom
fix/sys-prompt-append

Conversation

@Mihaiii

@Mihaiii Mihaiii commented Aug 7, 2026

Copy link
Copy Markdown

Why append instead of replace

ClaudeAgentOptions.system_prompt accepts either a plain string or the claude_code preset dict. A plain string replaces Claude Code's entire default system prompt — the only way to keep the default is {"type": "preset", "preset": "claude_code", "append": ...}. coder_eval passes the experiment's system_prompt straight through as a string, so any experiment that sets even a one-line prompt silently strips every behavioral instruction the harness ships with.

That is exactly what the skills-repo experiments do. The nightly config sets an innocuous sandbox guard:

https://github.com/UiPath/skills/blob/main/tests/experiments/nightly.yaml#L39-L40

system_prompt: |
  You are a coding agent. Do not access files in sibling runs/* directories. Everywhere else is permitted.

(same pattern in tests/experiments/default.yaml#L21, smoke.yaml#L39, smoke-windows.yaml#L23, and the skill-comparison templates)

One sentence of sandbox policy costs the whole Claude Code system prompt.

Observed impact (skills nightly, skill-rpa-execution-map-greenfield)

The task is a turn-budget gate (max_turns: 10, expected 6) that assumes the agent batches tool calls per turn. Every claude-sonnet-5 run exhausted the cap; pass/fail depended on where the cap happened to land. Transcript analysis across four runs (31172161551, 31174117722 ×3 attempts, 31178128981, 31179344004 ×2 attempts):

  1. Zero parallel tool calls, ever. Example distribution (run 31179344004, attempt 2): 30 assistant messages — 0 multi-tool, 19 single-tool, 11 with no tool call at all. The instruction to emit independent tool calls together in one message lives in the default system prompt; with it gone, Sonnet paid one turn per call and blew the 10-turn budget in 7/7 attempts. Skill-doc prose telling the agent to batch (added and strengthened twice in UiPath/skills) was read in-transcript and changed nothing — a reference file cannot substitute for the missing system-level contract.
  2. Narration bloat. 10–11 assistant messages per run contained no tool call, just interim commentary — the default prompt's conciseness/minimal-output rules were gone.
  3. Tool-choice drift. Runs used Bash cat/sed/find where the default prompt directs the dedicated Read/Grep/Glob tools (e.g. cd TextReport && cat project.json && cat Main.xaml), losing the harness's file-tracking and permission integration.

Beyond the observed items, replacing the prompt also drops the default guidance on code-reference formatting, task management, professional tone, and the security guardrails — none of which an experiment author intends to disable when adding a sandbox-scoping sentence.

The change

  • claude_code_agent.py: when system_prompt is configured, wrap it as SystemPromptPreset(type="preset", preset="claude_code", append=...) so the default prompt survives and the experiment text is appended. None still means the untouched SDK default.
  • agent_config.py: system_prompt field description updated ("appended to the agent's default system prompt" — previously "Replaces").
  • tests/test_agent.py: two tests via the existing _capture_sdk_options pattern (append wrapping; None passthrough).

Behavioral note for existing consumers

Every experiment that sets system_prompt switches from replace to append semantics with this release. For the known consumers (sandbox-scoping one-liners) this is the intended repair. An experiment that deliberately relied on full replacement to suppress default Claude Code behavior would need a different mechanism.

Judge (agent_judge.py) and user-simulator paths construct their own options and are unaffected.

🤖 Generated with Claude Code

… replacing

A plain-string ClaudeAgentOptions.system_prompt replaces Claude Code's
entire default system prompt. Every experiment that sets even a one-line
system_prompt silently strips the harness's behavioral guidance —
observed in skills nightly runs as zero parallel tool calls (the
batching instruction lives in the default prompt), heavy narration, and
raw cat/sed over Read/Grep. Wrap the configured prompt in the SDK's
claude_code preset with append so the default prompt survives.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Mihaiii
Mihaiii marked this pull request as ready for review August 7, 2026 13:34
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Claude finished @Mihaiii's task in 1m 46s —— View job


🔍 Reviewing PR #92: Fix system_prompt append behavior

Working on review...

Todo List:

  • Read .github/code_review.md for review guidelines
  • Read CLAUDE.md for project conventions
  • Review the full diff (git diff origin/main...HEAD)
  • Read each changed file in full context
  • Perform cross-file consistency checks
  • Check "what's missing" analysis
  • Post comprehensive review feedback

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant