100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Tool Use, Function Calling & MCP
30 minadvanced

Return Values: Shaping Tool Output for a Model

A tool's Python function and the message the model reads back are not the same object, even though it is tempting to write `return result` and let whatever `result` is fall straight into the tool_result content. Anthropic's Messages API expects the result of a tool call back as a content block of the form `{"type": "tool_result", "tool_use_id": ..., "content": ...}` inside a user-role message, with `"is_error": true` set when the call failed. Nothing about that contract says the content has to be your function's raw return value — it says the content has to be something the model can read and act on.

Returning the raw value is a decision, not a default, and it is usually the wrong one. An ORM object, a pandas DataFrame, or a raw upstream API response all carry structure that exists for your code's convenience — foreign keys, pagination envelopes, internal flags — none of which answers the question the model actually asked. Treating "what my function returns" and "what the model needs to see" as interchangeable is the single most common root cause of bloated, confusing agent context, and it compounds because every unshaped result gets re-sent on every later turn of the loop.

This lesson is about the gap between those two objects, and the concrete techniques for closing it: projecting to needed fields, flattening nesting, resolving ids to names, dropping nulls, summarising long collections, choosing a format the model can actually read, and making every result say what it is — including the results nobody wants to think about, like empty and truncated ones.

Analogy🏏Cricket
🏏 Think of it like cricket: When Jasprit Bumrah bowls a yorker at the death overs at the Wankhede, the Hawk-Eye system captures an enormous amount of raw data on that single delivery — ball speed at release, seam position, swing in millimetres, pitch coordinates, trajectory sampled hundreds of times a second, and predicted path had it continued. None of that raw sensor dump ever reaches the giant scoreboard at the ground. What the crowd sees, and what the third umpire actually rules on, is a shaped result: "OUT — LBW", or "NOT OUT — missing leg stump by 4mm". The Hawk-Eye engineers' raw output and the umpire's decision are two different things, produced from the same event but serving two completely different audiences. The engineers keep the full trajectory data for post-match analysis; the umpire, the players, and 40,000 fans in the stands only need the verdict, framed clearly enough to act on immediately. If the scoreboard tried to display the raw trajectory table instead of the ruling, nobody could use it — not because the data is wrong, but because it answers a question nobody standing in that stadium is asking. The insight is that a function's return value is the Hawk-Eye sensor dump, and the tool_result sent back to the model is the umpire's call: returning the raw dump instead of the ruling is a decision, and it is almost always the wrong one.
Lesson 9 of 35
0% complete