Closing the loop
You've routed to the right tool and called it — but a tool call is only half the
job, and the missing half is where agents quietly break. Picture it: the model
decides to call get_weather("Paris"), the runtime runs it and gets back 14C…
and then the model writes "The current temperature in Paris is 20C." It ignored
its own tool. The call succeeded and the answer is still a hallucination, because
the model answered from the guess it had already half-formed instead of from what
came back.
That last step is the observe step, and it's what closes the loop: call →
result → fold the result into the answer. The intuition is that the returned
value must become the source of the sentence, not a decoration next to it. In
code, that's the difference between a hard-coded string and one built by
interpolating the returned value into the sentence. The moment the answer is
derived from toolResult, it can't drift: change the tool's output to 9C and
the sentence follows automatically.
This is why it matters in real agents. A model that talks over its tools gives you the worst of both worlds — you paid for the call and still shipped a wrong answer, and now it looks grounded, so nobody catches it. Trust in an agent comes from the answer provably tracking the tool, every time.
Here the runtime has already called get_weather("Paris") and handed you
toolResult. Build the final answer from it — interpolate the value — so the
line reads exactly The current temperature in Paris is 14C. Done is that
sentence reflecting the real returned value with no number you typed yourself.
The loop closes when the tool's real output becomes the answer. Anything else is the model talking over its own tools.