Skip to content

Chapter 5 · State Management and Tool Calling ​

Chapter goals:

  • Master MessagesState message structure
  • Learn to define custom state (TypedDict extension)
  • Understand @tool decorator and ToolNode
  • Implement complete Agent graph (LLM node + ToolNode)

5.1 MessagesState Deep Dive ​

MessagesState is LangGraph's built-in state type, containing messages field:

python
from langgraph.graph import MessagesState
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage

# Example state
state = {
    "messages": [
        HumanMessage(content="What is the weather in Tokyo?"),
        AIMessage(
            content="",
            tool_calls=[
                {
                    "id": "call_123",
                    "name": "get_weather",
                    "args": {"city": "Tokyo"}
                }
            ]
        ),
        ToolMessage(content="Sunny, 25°C", tool_call_id="call_123")
    ]
}

5.1.1 Message Roles ​

RolePurpose
HumanMessageUser input
AIMessageLLM response (can include tool_calls)
ToolMessageTool execution result
SystemMessageSystem instructions

5.2 Custom State Definition ​

Extend TypedDict for application-specific state:

python
from typing import TypedDict, Annotated
import operator
from langchain_core.messages import BaseMessage

class AgentState(TypedDict):
    # Auto-appending messages
    messages: Annotated[list[BaseMessage], operator.add]
    
    # Custom fields
    user_id: str
    conversation_id: str
    context: dict
    iterations: int

5.2.1 State Update Patterns ​

python
# Pattern 1: Return dict (merge with existing state)
def my_node(state: AgentState) -> dict:
    return {
        "iterations": state["iterations"] + 1,
        "context": {**state["context"], "processed": True}
    }

# Pattern 2: Full state replacement
def replace_node(state: AgentState) -> AgentState:
    return {
        "messages": [],  # Clear messages
        "iterations": 0,
        "context": {},
        "user_id": state["user_id"]  # Preserve
    }

5.3 @tool Decorator ​

Convert functions to tools compatible with LLMs:

python
from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    # Implementation
    return f"Sunny, 25°C in {city}"

@tool
def search_knowledge_base(query: str) -> str:
    """Search internal knowledge base."""
    # RAG implementation
    return "Relevant documents..."

5.3.1 Tool Registration ​

python
from langchain_core.tools import convert_to_openai_tool

tools = [get_weather, search_knowledge_base]
openai_tools = convert_to_openai_tool(tools)

5.4 ToolNode: Automatic Tool Execution ​

ToolNode automatically executes tool calls from LLM:

python
from langgraph.prebuilt import ToolNode

tool_node = ToolNode([get_weather, search_knowledge_base])

# In graph node
def agent_node(state: AgentState) -> dict:
    # Call LLM
    response = llm.invoke(state["messages"])
    
    # If tool_calls, execute them
    if response.tool_calls:
        result = tool_node.invoke({
            "messages": [response]
        })
        return {"messages": [response] + result["messages"]}
    
    return {"messages": [response]}

5.4.1 Complete Agent Loop ​

python
from langgraph.graph import StateGraph, START, END

# Build graph
workflow = StateGraph(AgentState)
workflow.add_node("agent", agent_node)
workflow.add_node("tools", tool_node)

workflow.add_edge(START, "agent")
workflow.add_conditional_edges(
    "agent",
    lambda x: "tools" if x["messages"][-1].tool_calls else "end",
    {"tools": "tools", "end": END}
)
workflow.add_edge("tools", "agent")

graph = workflow.compile()

Chapter Summary ​

  1. MessagesState: Built-in state with automatic message handling;
  2. Custom State: Extend TypedDict with operator.add for list fields;
  3. @tool Decorator: Convert functions to LLM-compatible tools;
  4. ToolNode: Automatic tool execution from LLM responses;
  5. Agent Loop: Conditional edges route between agent and tools.

🛠️ Hands-on Practice ​

  1. Define a custom state with user_id, conversation_history, and tool_results fields.

  2. Create two tools: one for searching, one for summarizing. Wire them into an Agent loop.

  3. Add iteration limit to prevent infinite loops when tools keep calling each other.


🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. What does operator.add annotation do in LangGraph state?

2. What is the purpose of ToolNode in LangGraph?

3. How do you prevent infinite loops in Agent graphs?

4. Which message role contains tool execution results?