🚀
langraph
9. React Agent

ReAct Agent 📱

Think

  • LLM first thinks about the user prompt/problem

Action

  • LLM decides if it can answer by itself or if it should use a tool

Action Input

  • LLM provides the input argument for the tool (Here, langChain executes the tool and returns the output to the LLM)

Observe

  • LLM observe the result of the tool

Final Answer

  • "This is your final answer"
Objectives ✅
  1. Learn how to create Tools in LangGraph.
  2. How to create a ReAct Graph.
  3. Work with different types of Messages such as ToolMessages.
  4. Test out robustness of our graph.
Annotated
  • provides additional context without affecting the type itself.
  • for example, email addresses, phone numbers, or other strings that follow a specific format.
email = Annotated[str, "a valid email address"]
 
print(email.__metadata__)  # Output: 'a valid email address'
Sequence
  • automatically handle the state updates for sequence such as by adding new messages to a chat history
Reducer function (add_messages)
  • Rule that controls how updates from nodes are combined with existing state.

  • Tells us how to merge new data into the current state

  • Without a reducer, the new data would replace the existing state entirely.

Without a reducer:

state = {'messages': ['Hi!']}
update = {'messages': ['Nice to meet you!']}
new_state = {'messages': ['Nice to meet you!']}

With a reducer:

state = {'messages': ['Hi!']}
update = {'messages': ['Nice to meet you!']}
new_state = {'messages': ['Hi!', 'Nice to meet you!']}

Agent

"./images/9.react-agent.png"

from typing import Annotated, Sequence, TypedDict
from dotenv import load_dotenv
from langchain_core.messages import (
    BaseMessage,
    ToolMessage,
    SystemMessage,
    AIMessage,
    HumanMessage,
)
from langchain_ollama import ChatOllama
from langchain_core.tools import tool
from langgraph.graph.message import add_messages
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode
@tool
def add(a: int, b: int):
    """This is an addition function that adds 2 numbers together"""
    return a + b
 
 
@tool
def subtract(a: int, b: int):
    """Subtraction function"""
    return a - b
 
 
@tool
def multiply(a: int, b: int):
    """Multiplication function"""
    return a * b
 
tools = [add, subtract, multiply]
 
ollama_model = "llama3.1:8b"
 
# bind tools once here
model = ChatOllama(temperature=0.8, model=ollama_model).bind_tools(tools)
def model_call(state: AgentState) -> AgentState:
    system_prompt = SystemMessage(content="You are my AI assistant.")
    response: AIMessage = model.invoke([system_prompt] + state["messages"])
    return {"messages": state["messages"] + [response]}
 
 
def should_continue(state: AgentState):
    messages = state["messages"]
    last_message = messages[-1]
    if hasattr(last_message, "tool_calls") and last_message.tool_calls:
        return "continue"
    else:
        return "end"
graph = StateGraph(AgentState)
graph.add_node("our_agent", model_call)
 
tool_node = ToolNode(tools=tools)
graph.add_node("tools", tool_node)
 
graph.set_entry_point("our_agent")
 
graph.add_conditional_edges(
    "our_agent",
    should_continue,
    {"continue": "tools", "end": END},
)
 
graph.add_edge("tools", "our_agent")
 
app = graph.compile()
def print_stream(stream):
    for s in stream:
        message = s["messages"][-1]
        if isinstance(message, tuple):
            print(message)
        else:
            message.pretty_print()
 
 
inputs = {
    "messages": [
        HumanMessage(
            content="Add 40 + 12 and then multiply the result by 6. Also tell me a joke please."
        )
    ]
}
 
print_stream(app.stream(inputs, stream_mode="values"))
OUTPUT:
 
================================ Human Message =================================
 
Add 40 + 12 and then multiply the result by 6. Also tell me a joke please.
================================== Ai Message ==================================
 
}
{"type":"function","function":{"name":"jokes","description":"","parameters":{"type":"object","required":[],"properties":{}}}}
Tool Calls:
  multiply (6d4f6af9-dfe8-47d1-84dd-147f013d492e)
 Call ID: 6d4f6af9-dfe8-47d1-84dd-147f013d492e
  Args:
    a: 52
    b: 6
  add (b741d73f-a6f9-4720-a640-6d0b396ec21c)
 Call ID: b741d73f-a6f9-4720-a640-6d0b396ec21c
  Args:
    properties: {}
    required: []
    type: object
================================= Tool Message =================================
Name: add
 
Error: 2 validation errors for add
a
  Field required [type=missing, input_value={'properties': {}, 'requi...': [], 'type': 'object'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.11/v/missing
b
  Field required [type=missing, input_value={'properties': {}, 'requi...': [], 'type': 'object'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.11/v/missing
 Please fix your mistakes.
================================== Ai Message ==================================
 
Firstly, let's calculate the result of 40 + 12:
40 + 12 = 52
 
Now, we multiply the result by 6:
52 * 6 = 312
 
And here's a joke for you:
 
Why don't eggs tell jokes?
 
Because they'd crack each other up!

© 2024 Driptanil Datta.All rights reserved

Made with Love ❤️

Last updated on Mon Oct 20 2025