Course navigation
AgentsLesson 5 of 9

Agent Execution Flow

ReAct Framework let you read Thought lines in verbose output. With create_agent most scripts only grab result["messages"][-1]. Here we print the full list after each invoke.

invoke

Input is a dict with messages — same role / content pairs as LangChain Basics.

Output is a longer messages list. LangChain added ai and tool rows while it looped. The last ai row is what you show the user.

result = agent.invoke({
    "messages": [{"role": "user", "content": question}],
})

for msg in result["messages"]:
    print(msg.type, msg.content)

msg.type values

Loop result["messages"] and check the type on each row:

human — your question.

ai — model reply. First pass may be tool_calls with no text.

tool — string your @tool function returned.

When a tool runs:

human row added
ai row (tool_calls)
tool row (function return)
ai row (answer text)
Direct answer stops after the first ai row — no tool row in between.

2 rows

[0] human: <title>?
[1] ai: sets tab title…

4 rows

[0] human: <a>?
[1] ai tool_calls
[2] tool: <a>: hyperlink…
[3] ai: answer
Demo runs both. Row count is the fastest way to spot a tool call.

Print every row

Use this when the answer looks wrong but you are not sure if the tool ran — look for an ai row with tool_calls and a tool row after it.

for i, msg in enumerate(result["messages"]):
    if msg.type == "ai" and msg.tool_calls:
        names = [t["name"] for t in msg.tool_calls]
        print(f"[{i}] ai tool_calls: {names}")
    else:
        print(f"[{i}] {msg.type}: {msg.content}")

Building a chat UI? stream fires on each new row instead of waiting for invoke to finish:

for chunk in agent.stream(
    {"messages": [{"role": "user", "content": question}]},
    stream_mode="values",
):
    print(len(chunk["messages"]))

Run the demo

Venv from Project Setup. Download, then:

agent_execution_flow_demo.py

<title> then <a> question

OPENAI_API_KEY in .env, same as Tool Calling.
agent_execution_flow_demo.py
"""agent_execution_flow_demo.py"""
# print_messages() over result["messages"]
runs = [
"no tool", "with tool"
]
python agent_execution_flow_demo.py
PowerShell — (.venv) active
(.venv) PS C:\projects\langchain-course> python agent_execution_flow_demo.py
Question: What does the <title> tag do? One sentence.
=== no tool (2 messages) ===
[0] human: What does the <title> tag do? One sentence.
[1] ai: The <title> tag sets the browser tab title.
Question: What does the <a> tag do? Use lookup_html_tag.
=== with tool (4 messages) ===
[0] human: What does the <a> tag do? …
[1] ai tool_calls: ['lookup_html_tag']
[2] tool: <a>: Creates a hyperlink. Use href for the URL.
[3] ai: The <a> tag creates a hyperlink…
Script prints the count in the header line before listing rows.

Multi-turn memory needs a checkpointer — see Agent docs.

What's Next

Next: Creating Custom Tools.