# Exploring AI Agents: Step-by-Step Implementation Insights

Artificial Intelligence (AI) has evolved significantly over the years, with Large Language Models (LLMs) leading the way in natural language understanding and generation. However, a new paradigm is emerging—AI Agents. Unlike traditional LLMs, AI Agents possess autonomy, memory, and the ability to perform goal-oriented tasks, making them more efficient in real-world applications. In this blog, we will explore what AI Agents are, how they differ from LLMs, how to develop custom AI Agents, and their real-world use cases. Finally, we will walk through an example of an AI Agent designed for customer support in an online ticket booking system.

---

### **How AI Agents Differ from Traditional LLMs**

While both AI Agents and LLMs leverage natural language processing, they differ in key aspects:

| Feature | Traditional LLMs | AI Agents |
| --- | --- | --- |
| **Autonomy** | Passive, responds to prompts | Active, initiates tasks based on goals |
| **Memory** | Stateless, no memory retention | Stateful, can store and retrieve information |
| **Task Execution** | Provides responses without action | Can execute tasks and interact with external systems |
| **Multi-Step Reasoning** | Processes a single query at a time | Can break complex problems into sub-tasks and complete them |

Traditional LLMs require human intervention to drive conversations, whereas AI Agents can operate independently, making decisions and performing tasks dynamically.

---

### **How to Develop Custom AI Agents**

Developing a custom AI Agent involves several key steps:

1. **Define the Objective:** Identify the purpose of the AI Agent. For example, automating customer service interactions.
    
2. **Choose a Framework:** Libraries such as LangChain, AutoGen, and OpenAI's Function Calling API can help build AI Agents.
    
3. **Implement Memory:** Utilize vector databases like Pinecone or Redis to provide persistent memory.
    
4. **Incorporate Tools & APIs:** Equip the agent with access to databases, APIs, and external tools to complete tasks.
    
5. **Implement a Decision-Making Process:** Use reinforcement learning or rule-based logic for better decision-making.
    
6. **Deploy and Monitor:** Deploy the agent to production and continuously optimize its performance.
    

#### **Coding Example Using LangChain**

Below is a simple example of building a custom AI Agent using LangChain:

```python
from langchain.llms import OpenAI
from langchain.agents import initialize_agent, AgentType
from langchain.tools import Tool

# Define an LLM instance
llm = OpenAI(model_name="gpt-4")

# Define a tool for the agent to use
def fetch_ticket_availability(query):
    return "Available tickets for your destination: Flight A, Flight B, Flight C"

tool = Tool(
    name="TicketAvailability",
    func=fetch_ticket_availability,
    description="Fetch available tickets based on user query"
)

# Initialize the agent
agent = initialize_agent(
    tools=[tool],
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# Test the agent
response = agent.run("Find me flights from New Delhi to New York for next Monday")
print(response)
```

This example demonstrates how to integrate a LangChain-powered AI Agent with an external tool to fetch flight availability based on user input.

**The agent determines whether to call a tool based on the input query** and its internal reasoning process. In LangChain, this is achieved through a combination of:

1\. **Tool Descriptions**: Each tool (like \`TicketAvailability\` in this case) has a description that helps the agent understand when to use it.

2\. **LLM Decision-Making**: The agent uses an LLM to analyze the input query and decide if any tool needs to be invoked.

3\. **REACT Framework**: LangChain's \`ZERO\_SHOT\_REACT\_DESCRIPTION\` agent type follows the ReAct (Reasoning + Acting) paradigm, meaning it first reasons about the input, decides on an action, and then executes the appropriate tool.

4\. **Execution Flow:**

\- The agent receives a user query.

\- It parses the intent (e.g., finding flights).

\- If the query matches the function of a registered tool (e.g., fetching ticket availability), the agent calls that tool.

\- The tool executes its function and returns a response.

\- The agent processes the response and provides a final answer to the user.

Thus, when the user asks, \*"Find me flights from New Delhi to New York for next Monday"\*, the agent:

\- Recognizes that the query is related to flight availability.

\- Identifies \`TicketAvailability\` as a relevant tool.

\- Calls the function \`fetch\_ticket\_availability()\`, retrieves the results, and returns them to the user.

---

### **Use Cases of AI Agents**

AI Agents can be applied in multiple domains, including:

* **Customer Support:** Handling queries, resolving complaints, and managing bookings.
    
* **Healthcare:** Assisting with medical diagnoses and patient follow-ups.
    
* **Finance:** Providing investment recommendations and fraud detection.
    
* **E-commerce:** Offering personalized shopping assistance and order tracking.
    
* **Software Development:** Automating bug detection and generating code snippets.
    

---

### **Example: AI Agent for Customer Support in Online Ticket Booking**

Let’s walk through an example of an AI Agent designed for customer support in an online ticket booking system.

#### **Objective**

To automate customer queries, assist with ticket bookings, cancellations, and modifications.

#### **Architecture**

1. **LLM for Natural Language Understanding** - GPT-based model for conversational interface.
    
2. **Memory Store** - A Redis-based database for storing user history.
    
3. **APIs for Integration** - Connecting with ticket booking systems (e.g., airline, train, event platforms).
    
4. **Decision Engine** - Rule-based or reinforcement learning model for handling customer queries.
    

#### **Workflow**

1. **User Query:** "I want to book a flight from New Delhi to New York for next Monday."
    
2. **Intent Recognition:** The agent extracts key details: origin (New Delhi), destination (New York), date (next Monday).
    
3. **API Call:** The agent fetches available flights and presents options.
    
4. **User Confirmation:** The user selects a preferred flight.
    
5. **Booking Completion:** The agent books the flight and provides a confirmation.
    
6. **Follow-up:** If needed, the agent can assist with cancellations, seat selection, or meal preferences.
    

---

### Sample Implementation of **AI Agent for Customer Support** based on above

```python
from langchain.chat_models import ChatOpenAI
from langchain.memory import RedisChatMessageHistory
from langchain.agents import initialize_agent, Tool
from langchain.tools import tool
import requests
import datetime

# Define a function to fetch available flights
def fetch_flights(origin, destination, date):
    # Placeholder function: Replace with actual API calls to airline or travel service
    return [
        {"flight": "AI 101", "departure": "10:00 AM", "arrival": "2:00 PM", "price": "$500"},
        {"flight": "UA 202", "departure": "1:00 PM", "arrival": "5:00 PM", "price": "$550"},
    ]

# Define a function to book flights
def book_flight(flight_id, user_details):
    # Placeholder function: Replace with actual API call to book the flight
    return {"status": "confirmed", "flight_id": flight_id, "user": user_details}

# LangChain Tool for fetching flights
@tool
def get_flights(origin: str, destination: str, date: str):
    """Fetches available flights given origin, destination, and date."""
    flights = fetch_flights(origin, destination, date)
    return flights

# LangChain Tool for booking flights
@tool
def book_flight_tool(flight_id: str = None, user_details: dict = None):
    """Books a flight given flight ID and user details. If missing, prompts user for input."""
    
    if not flight_id:
        return "Please provide a flight ID from the available options."

    if not user_details or "name" not in user_details or "email" not in user_details:
        return "Please provide user details including name and email."

    booking = book_flight(flight_id, user_details)
    return booking


# Memory store (Redis)
memory = RedisChatMessageHistory(url="redis://localhost:6379/0")

# Initialize LLM
llm = ChatOpenAI(model_name="gpt-4")

# Define the agent
tools = [get_flights, book_flight_tool]
agent = initialize_agent(
    tools, llm, agent="zero-shot-react-description", verbose=True, memory=memory
)

# Example query
response = agent.run("I want to book a flight from New Delhi to New York for next Monday.")
print(response)
```

**How AI Agents handle memory**

The agent writes conversation history into Redis using the `RedisChatMessageHistory` memory store. Specifically, it stores messages exchanged between the user and the agent, allowing the AI to maintain context across interactions.

**What Gets Stored in Redis?**

1. **User Messages:** The queries or requests made by the user (e.g., *"I want to book a flight from New Delhi to New York for next Monday."*).
    
2. **Agent Responses:** The replies generated by the AI (e.g., *"Here are the available flights for your route."*).
    
3. **Contextual Memory:** If the user continues the conversation (e.g., *"Book the first one."*), the agent remembers the previous flight options presented.
    

**How Redis Stores the Data?**

* The `RedisChatMessageHistory` class stores messages as a key-value structure in Redis.
    
* Each user session is typically associated with a unique key (e.g., `chat:<session_id>`).
    
* Messages are stored in chronological order, allowing retrieval for context-based responses.
    

**Example of Stored Data in Redis**

```json
{"chat:session_123": [
        {"role": "user", "message": "I want to book a flight from New Delhi to New York for next Monday."},
        {"role": "agent", "message": "Here are the available flights: AI 101 - $500, UA 202 - $550."},
        {"role": "user", "message": "Book AI 101."},
        {"role": "agent", "message": "Your booking for AI 101 is confirmed."}
    ]
}
```

The agent utilizes the message history stored in Redis to maintain context and continuity in the conversation. Here’s how it works:

---

**1\. Retrieving Conversation History**

The `RedisChatMessageHistory` memory store acts as a persistent message history. Each time the user interacts with the agent, it retrieves past interactions from Redis, allowing it to remember the conversation.

* When a user starts a new session, Redis retrieves previous messages using a unique session key (e.g., `chat:<session_id>`).
    
* The LangChain memory module feeds this history into the LLM, enabling it to generate responses based on past exchanges.
    

---

**2\. Contextual Understanding**

Since the agent maintains history, it can:

✅ **Understand Follow-up Queries**  
If a user says:

* **User:** *"I want to book a flight from New Delhi to New York for next Monday."*
    
* **Agent:** *"Here are the available flights: AI 101 - $500, UA 202 - $550."*
    
* **User:** *"Book the first one."*
    

The agent remembers "AI 101" as the first option without needing the user to repeat.

✅ **Maintain Personalization**  
If a user previously requested vegetarian meals or window seats, the agent can recall this preference.

✅ **Handle Multi-turn Conversations**

* **User:** *"What’s my booking status?"*
    
* **Agent:** (retrieves previous booking confirmation) *"Your flight AI 101 is confirmed."*
    

---

**3\. How LangChain Uses History?**

LangChain’s memory mechanism ensures that past interactions are passed as part of the conversation context.

* **Example without memory:**
    
    * User: *"Book the first one."*
        
    * Agent: *"I don’t understand. Which flight?"*
        
* **Example with memory:**
    
    * User: *"Book the first one."*
        
    * Agent: *(Remembers previous options)* *"Your flight AI 101 is confirmed."*
        

---
