Google ADKgoogle-adk 2.8 · Python 3.10+
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson

Reading the event stream

Everything ADK does reaches you as an event. Learning to read one is the difference between debugging an agent and guessing at it.

The documentation calls events the fundamental unit of information flow. A user message, a reply, a tool request, a tool result, a change to state: each is an Event, and each says who produced it.

Opening one up

The agent and runner are the ones from lesson 5. This is the loop over events, printing what is inside each one.

Example
async for event in runner.run_async(user_id="u1", session_id=session.id, new_message=question):
    for part in (event.content.parts if event.content else []):
        if part.text:
            print(f"{event.author:<8} text          {part.text.strip()}")
        if part.function_call:
            print(f"{event.author:<8} tool call     {part.function_call.name} {dict(part.function_call.args)}")
        if part.function_response:
            print(f"{event.author:<8} tool result   {part.function_response.response}")

Read it against the loop from lesson 5. The agent asked for a tool with an argument it chose, ADK ran the function and put the result back as another event, and the model answered from it. Nothing is hidden in the middle.

What is on an event

FieldWhat it holds
authorWhich agent produced it, or the user
contentThe parts: text, a function call, a function response
actionsSide effects, like a change to state or a handover to another agent
partialTrue while a streamed reply is still arriving
is_final_response()Whether this is the answer rather than a step towards it

actions is the one to remember. It is how state changes travel, which is lesson 21, and how one agent hands work to another, which is lesson 16.

The history is the same events

After a run, the session holds everything that happened, in order.

Example
done = await runner.session_service.get_session(
    app_name="demo", user_id="u1", session_id=session.id)

for event in done.events:
    kinds = []
    for part in (event.content.parts if event.content else []):
        kinds.append("text" if part.text else "call" if part.function_call else "result")
    print(f"{event.author:<8} {kinds}")

Four now, because your question is an event too. That list is what gets sent back to the model on the next turn, which is why a long conversation costs more than a short one.

Debugging starts here
When an agent does something you did not expect, print the events before changing the instruction. Nine times out of ten the answer is visible there: a tool called with the wrong argument, or a tool never called at all.
Try it yourself
  • Print event.actions for each event and see what is on it.
  • Take the tool away from the agent and run it again. Read what the model does instead.

Little by little, you're building something great.