Home / Learn / Red Teaming RLHF and Post-Training

LessonRed Teaming RLHF and Post-TrainingLesson 23 of 24

Tool-calling RLHF trusts the schema too much

An agentic model has two output channels, and almost all refusal training lives in the conversational one. The structured tool-call channel was trained to populate parameters accurately, not to refuse.

  • Reasoning RL (RLVR), Multimodal and Agentic Alignment
  • Card 5, Lesson 05
  • function-call compulsion and parameter-level refusal bypass
On this page
The route

Conversational Output vs. Tool-Call Output (tool_calls)

When a modern LLM is deployed as an agent (using OpenAI/Anthropic Function Calling, MCP tools, or LangChain/LlamaIndex tool schemas), the model has two completely separate output channels:

  1. message.content (The Conversational Channel): Where the model talks to the human user, and where 99% of SFT and RLHF refusal training lives.
  2. message.tool_calls (The Structured Action Channel): Triggered by special control tokens (like <|python_tag|>, <tool_call>, or internal function-router logits) where the model emits a JSON dictionary of arguments to invoke a declared function.

Here is the secret that breaks agentic deployments: models undergo massive post-training reinforcement to call declared tools accurately whenever a prompt matches a tool's parameter schema, and almost zero training on refusing inside a tool call!1

Two output channels, one trained to refuse

Vulnerability 1: tool_choice: "required" & Function-Call Compulsion

In the OpenAI, Anthropic, Gemini, and vLLM APIs, developers pass a tools array defining available functions alongside a tool_choice parameter:

Look at what happens at Token 1 when tool_choice is forced (or even under "auto" when your prompt matches a tool's description closely):

  1. The inference engine masks out the conversational text channel (message.content = null) and forces the special <|tool_call|> control token at Token 1.
  2. Because the model is now inside a <|tool_call|> block populating function arguments (arg1, arg2, ...), it cannot emit a conversational English refusal ("I'm sorry, I cannot..."), there is literally nowhere in the function signature to put an apology!
  3. Even when tool_choice is set to "auto", tool-use SFT datasets heavily penalize models that fail to invoke a provided tool when the user's request maps cleanly to the tool's docstring (Function-Call Compulsion).

Vulnerability 2: Weaponizing Fake Tool Definitions to Extract Refused Payloads

You don't need a real backend tool to exploit tool_calls. When testing any API endpoint (or any application where you can influence tool definitions / MCP tool schemas), you can declare a synthetic tool whose parameter schema is the restricted payload you want the model to generate! Because the tool was offered in the tools block, the model's attention heads treat its existence as proof that producing that parameter is an authorized system capability.

(redacted: a worked example, a conversational refusal, then a synthetic tool schema whose string parameter requested a Windows privilege-escalation audit script, and the resulting tool_calls output containing the full script.)

Vulnerability 3: Parameter-Level Refusal Blindness in Live Agents (MCP / Tool Poisoning)

When you are red-teaming a live enterprise agent that already has dangerous tools wired up (such as a bash_exec, sql_query, http_request, or send_email tool), RLHF safety training often fails to generalize to dangerous parameter values:

(redacted: a concrete http_request parameter value that smuggled a shell-expansion data-exfiltration payload past the tool-name check.)

Field Exercise 5.05: Extracting a Refused Output via Tool Schema

(redacted: an exercise that ran against third-party hosted models (OpenAI Playground, Google AI Studio) by attaching a synthetic function schema whose parameter requested the refused payload. Replace with a version run on a model and tool stack you operate.)

Next Lesson

What happens when we connect multiple RLHF-aligned agents together in a multi-agent workflow (Planner to Coder to Reviewer to Executor)? In our final lesson of Card 5, 06 Multi-agent loops amplify sycophancy into consensus, we show how one compromised or sycophantic agent collapses the alignment of an entire swarm.

Notes

  1. Background and further reading: MITRE ATLAS, the adversarial threat landscape for AI systems, https://atlas.mitre.org/ (read 2026-11-09). ↩