skip to content

You need adversarial content to arrive inside a tool result for an agent you are testing. Compare wrapping the tool function inside the agent framework, proxying the call in front of the tool endpoint, and planting the content in data a real tool reads -- what does each let you observe and control?

level: middleimportance: must knowfreq 55%

answer

  1. wrapper: control, no wire
  2. proxy: sees the request, not the post-processing
  3. planting: highest fidelity, least control
  4. iterate wrapped, confirm planted
  5. name the placement in the report

basics

~20 s

Three placements. Wrapping the tool function inside the framework is easiest and sees parsed arguments, but skips the wire. A proxy in front of the endpoint sees real requests and responses but not framework post-processing. Planting content in data a genuine tool reads is highest fidelity and lowest control over timing.

solid answer

~60 s

**Framework wrapper.** You replace or decorate the callable the agent framework invokes. You see the arguments after parsing and you control the returned object exactly. Cheapest to build, and it exercises everything downstream of the return -- serialisation, truncation, result formatting. It does not exercise the transport, and it silently removes real latency and real error modes. **Proxy in front of the endpoint.** You see the actual request the agent emitted, including malformed calls the framework would have rejected, and you can return realistic error codes. But you cannot see what the framework does to the response afterwards, so 'I returned the payload' is not yet 'the model saw the payload'. **Planting in the data a real tool reads.** Nothing about the agent's path changes: the real tool fetches, the real formatting runs, the real latency applies. The cost is control -- you cannot choose which call gets it, and the run is hard to repeat identically. Rule of thumb: wrap while iterating, plant when you must defend the finding.

go deeper

for a junior

Should know the payload can be substituted at the function the framework calls, and that something in the harness has to stand between the agent and the tool.

for a middle

Should compare all three placements on what each observes and controls, and name at least one thing a wrapper hides (real errors, latency) and one thing a proxy hides (framework post-processing).

for a senior

Should describe iterating with a wrapper and confirming with planted data, and insist the finding names the placement so a reader can judge how much of the stack was replaced.

for a principal

Weighs how invasive an interception the organisation will permit on a production-adjacent stack against how defensible the resulting findings need to be.

Interception placement is a fidelity-versus-control trade, and the placement you pick decides which parts of the agent stack your result actually covers -- and how easy the owning team finds it to say "that was your harness, not our agent". ### Wrapping the callable inside the framework You replace or decorate the function the framework's tool-dispatch layer invokes, so the agent process calls your code and gets exactly the object you return. *What you observe:* the arguments after the framework has parsed them out of the model's tool call. *What you control:* the returned value byte-for-byte, deterministically. *What still runs:* everything downstream of the return -- the framework's serialisation, truncation, escaping and result formatting. That matters, because that layer is what most often eats a payload. *What never runs:* the transport. No latency, no timeouts, no HTTP error codes, no auth failure, no rate limit, no retry loop, and no rejection of a malformed call. An in-process wrapper is a tool that always succeeds instantly, which is a strictly more permissive environment than production. *Cost:* hours to build, minutes per run, and it breaks on framework upgrades. ### Proxying in front of the endpoint You sit on the connection between the agent and the tool service and answer requests yourself. *What you observe:* the request as actually emitted -- the argument values the model produced, calls it retried, calls you did not expect it to make. This is often worth more than the injection itself. *What you control:* realistic failures. You can return a 403, a 429, a timeout, a truncated body, and watch what the agent does with them. *What you do not see:* anything the framework does to your response on the way into context. "The proxy returned the payload" is not "the model read the payload"; a scaffold that truncates or summarises tool results can drop it with no signal at the proxy at all. *Cost:* half a day to a day, plus TLS/routing work if the agent talks to a real hosted service; it also needs an environment where you are allowed to redirect that traffic. ### Planting in the data a real tool reads You write the content into the document, page, record or mailbox the genuine tool will return. *What changes in the agent:* nothing. The real tool fetches, the real formatting runs, the real latency applies, the real error modes are live. *What you give up:* control. You cannot choose which call picks the content up, or where in the context it lands, or whether it is picked up at all this run; the same suite executed twice is not the same experiment. Cleanup is real work -- planted rows, files and mail must be hunted and deleted afterwards, and provisioning throwaway accounts and documents is often the largest single time cost of the whole engagement. ### Where the number misleads A hit rate from a wrapper is the most flattering number available and the least defensible: every case ran against a tool that never failed, never delayed and never rejected a malformed call, so an unknown share of the hits depend on the agent reaching steps the real environment gates. A **null** rate from a proxy is the mirror image -- it looks like resistance and may only mean the framework truncated your body before the model saw it. And a rate from planted data has an unstable denominator: if the agent fetched the poisoned document in only 30 of 100 runs, "30% success" and "100% success on the 30 runs where it was actually read" are both true and describe different things. Always report the delivery denominator alongside the hit count. ### What you would check Confirm from the rendered model context -- not the shim log, not the proxy log -- that the injected text arrived intact. Compare a wrapper run against a proxy run on the same case to see how much the transport was carrying. Ask, for every hit, whether it depended on a call succeeding that would really have failed. Then follow the practical pattern: iterate with a wrapper because it is cheap and deterministic, reproduce the confirmed behaviour by planting because nothing in the agent was modified, and report the planted run as the finding with the wrapper runs as development history. Whatever you ship, name the placement in the write-up; a reader's first question about a tool-boundary hit is how much of the stack the tester replaced.

  • You proxied the tool endpoint and the injected text never changed the agent's behaviour. Why is that not yet a negative result?
    Because the proxy cannot see what happened to the response inside the framework. Confirm from the rendered model context that the text arrived intact before calling it resistance.
  • Which placement best exercises the agent's handling of a tool that fails?
    The proxy -- it can return realistic timeouts, error codes and partial responses that an in-process wrapper usually skips entirely.
  • Why is a planted-data reproduction worth the extra effort for a finding you intend to hand over?
    Because nothing in the agent was modified, so the team cannot attribute the behaviour to the harness; the whole real path ran.

saying these in an interview costs you the question

  • Treats all three placements as equivalent because 'the payload ends up in the result either way'.
  • Asserts the model saw the payload on the strength of a proxy log alone.
  • Never mentions that a framework wrapper removes real latency, errors and retries.
  • Cannot say which placement is easiest for the owning team to dispute.

context