Home/AI & Automation/[Advanced Guide] Building an Action-Taking LLM Agent with the ReAct Pattern Combining Tool Calling and Memory
AI & AutomationLLM agentsReAct

[Advanced Guide] Building an Action-Taking LLM Agent with the ReAct Pattern Combining Tool Calling and Memory

This guide covers how to go beyond a simple chatbot and build a real agent with external API calls and long-term memory. It walks through how the ReAct pattern works and through fully automated, hands-on code examples that combine Tool Call

[Advanced Guide] Building an Action-Taking LLM Agent with the ReAct Pattern Combining Tool Calling and Memory
Contents
  1. Why You Need an Action-Taking Agent, Not Just a Chatbot
  2. Connecting to the Outside World: How Tool Calling Works and How to Implement It in Depth
  3. An Agent That Remembers Over Time: Memory Management Strategy
  4. 🚀 Putting It Together: The ReAct Pattern and Error Handling

[Advanced Guide] Building an Action-Taking LLM Agent with the ReAct Pattern Combining Tool Calling and Memory

The pace of LLM progress is remarkable. LLMs have moved beyond simple text generators and are entering a stage where they reason and act like software. Yet the first LLM calls most developers make still amount to a one-way conversation: prompt in $\rightarrow$ text out.

If your product needs to “tell the user today’s weather in Seoul and, based on that, put together a personalized outing plan,” a simple chatbot will not cut it. You have to call external APIs and remember prior conversation.

This post goes beyond LLM theory. It walks through a practical, code-first methodology for building a genuinely intelligent agent by combining working complex logic—external tool use (Tool Calling) and long-term memory (Memory).

Why You Need an Action-Taking Agent, Not Just a Chatbot

The AI we actually want does not merely answer questions. It is given a goal and then plans and executes the sequence of steps needed to achieve it. That is the definition of an agent.

Three core capabilities are required to become an agent:

  1. Reasoning: In what order should I think to achieve the given goal? (→ ReAct pattern)
  2. Action: Can I interact with the outside world based on that reasoning? (→ Tool Calling)
  3. Memory: Can I retain and use past experience and external knowledge? (→ Memory Management)

Only when these three work together do you get complex, service-level automation.

Connecting to the Outside World: How Tool Calling Works and How to Implement It in Depth

Tool Calling (also called Function Calling) is the core mechanism that lets an LLM go beyond its own knowledge: it can invoke a specific external function or API to fetch up-to-date information or computation results.

The key idea is to tell the LLM explicitly, “you can use these capabilities,” and let it decide on its own, “I should use this one.”

Simple Prompting vs. Structured Tool Calling: A Performance Comparison

AspectSimple prompt-based callingStructured Tool Calling
How it worksYou must describe how to use the API in the prompt as text.The LLM decides to call based on a defined function signature (schema).
StabilityLow. Easy to omit or misinterpret in complex logic.Very high. Call parameters are enforced via structured JSON/schema.
ReliabilityLow. Heavily dependent on LLM hallucination.High. Results are verified because real code execution happens.
Best forSimple Q&A, creative writingData lookup, calculation, external system integration—any case that requires execution

Hands-on: Defining and Wiring a Custom Tool

Assume the agent we are building needs an “exchange rate lookup” capability. We will define that as a tool.

Python
import json
from typing import List, Dict, Any
# LangChain Tool .

def get_exchange_rate(base_currency: str, target_currency: str) -> str:
    """
 when .
 example: get_exchange_rate("USD", "KRW") call when, USD KRW .
    """
 print(f"--- [SYSTEM LOG] API call when: {base_currency} -> {target_currency} ---")
 # external API call .
    if base_currency == "USD" and target_currency == "KRW":
        return json.dumps({"rate": 1350.5, "source": "Mock_API"})
 return json.dumps({"error": " ."})

# list (LLM tool )
available_tools = [
    {
        "name": "get_exchange_rate",
 "description": " .",
        "parameters": {
            "type": "object",
            "properties": {
 "base_currency": {"type": "string", "description": " (: USD)"},
 "target_currency": {"type": "string", "description": " (: KRW)"}
            },
            "required": ["base_currency", "target_currency"]
        }
    }
]

An Agent That Remembers Over Time: Memory Management Strategy

The moment an agent loses conversational context, its intelligence drops sharply. Memory management determines whether the agent can persist.

Short-term vs. Long-term Memory

  • Short-term memory (context window): The recent conversation still sitting in the current chat. It is strictly limited by how many tokens the LLM can process at once (the context window). (e.g., the last 10 turns)
  • Long-term memory (vector DB): All past conversations, user-uploaded documents, and external knowledge bases are embedded and stored in a vector database. When needed, the agent retrieves relevant information and injects it into context. (the core of RAG)

In a real implementation you combine both. As the conversation grows, the oldest turns are summarized into the context, and important information is stored in a vector DB so it can be retrieved whenever needed. That is the standard approach.

🚀 Putting It Together: The ReAct Pattern and Error Handling

The strongest agents follow the ReAct (Reasoning + Acting) pattern. They solve complex problems through a loop of Thought $\rightarrow$ Action $\rightarrow$ Observation $\rightarrow$ next Thought.

Below is a conceptual flow that combines tool use and error handling on top of this pattern.

Python
# --- ---

def run_agent_cycle(initial_query: str, tools: dict):
 """
 ReAct run.
 """
 current_state = initial_query
 max_iterations = 5
 
 print(f"--- [START] : {initial_query} ---")

 for i in range(max_iterations):
 print(f"\n===== [Iteration {i+1}] =====")
 
 # 1. Thought : 
 thought = f" '{current_state}' , tool ."
 print(f"[Thought]: {thought}")
 
 # 2. Action : tool 
 # ( LLM )
 action_name = "search_weather" # example 
 action_input = {"city": "", "date": ""}
 print(f"[Action]: {action_name} run, : {action_input}")

 try:
 # 3. Tool Execution (tool run): call
 if action_name in tools:
 tool_function = tools[action_name]
 observation = tool_function(action_input)
 
 # 4. Observation : tool run Result
 print(f"[Observation]: {observation}")
 
 # 5. : Result 
 current_state = f"tool run Result: {observation}. ."
 else:
 current_state = ": tool."
 break
 
 except Exception as e:
 # : tool failed when, when 
 error_message = f"tool run : {str(e)}"
 print(f"[Observation]: {error_message}")
 current_state = error_message
 break
 
 print("\n--- [END] ---")
 return current_state

# --- tool (Tool Definition) ---
def search_weather(params: dict) -> str:
 """when ."""
 city = params.get("city")
 date = params.get("date")
 if not city:
 raise ValueError("when required.")
 return f"'{city}' '{date}' 25. (API call )"

def get_user_profile(user_id: str) -> str:
 """User ID ."""
 return f"User ID {user_id} ' '."

available_tools = {
 "search_weather": search_weather,
 "get_user_profile": get_user_profile
}

# --- run ---
final_result = run_agent_cycle(" .", available_tools)
print(f"\n[ Result ]: {final_result}")
✦ ✦ ✦
Sources and verification

Sources and checks vary by article. Only articles with a recorded check date, scope and sources below were checked, and only within that scope. For other articles, verify against the current docs for your version before applying anything, and email us about errors. Editorial policy · email us

This article has no recorded human check (date and scope) yet.

Published ·
Topic-related official docs (auto-linked · not per-claim sources)LangChain documentation ↗

Comments

Be the first to comment.