🤖 AI Agents & Autonomous Systems

AI that can plan, act, and use tools

What are AI Agents?

AI Agents are systems that can autonomously plan, execute tasks, use tools, and achieve goals with minimal human intervention. Unlike simple chatbots that respond to prompts, agents can break down complex tasks and work towards objectives.

Key Capabilities:

  • Planning: Break down goals into steps
  • Tool Use: Call APIs, run code, search the web
  • Memory: Remember context and previous actions
  • Reflection: Learn from mistakes and improve
  • Autonomy: Work independently towards goals

🧠 Agent Architecture

Core Components:

  1. Perception: Understand the task and environment
  2. Planning: Create action plan to achieve goal
  3. Tool Use: Execute actions using available tools
  4. Memory: Store and retrieve relevant information
  5. Reflection: Evaluate results and adjust strategy

🔧 Building a Simple Agent with LangChain

from langchain.agents import initialize_agent, Tool, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools import DuckDuckGoSearchRun
from langchain.utilities import PythonREPL
import os

os.environ["OPENAI_API_KEY"] = "your-key-here"

# Initialize LLM
llm = ChatOpenAI(model="gpt-4", temperature=0)

# Define tools
search = DuckDuckGoSearchRun()
python_repl = PythonREPL()

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="Useful for finding current information on the internet. Input should be a search query."
    ),
    Tool(
        name="Python REPL",
        func=python_repl.run,
        description="Useful for running Python code. Input should be valid Python code."
    )
]

# Create agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    max_iterations=5
)

# Use the agent
result = agent.run("What's the current stock price of Apple? Calculate the market cap if it has 15 billion shares.")

# Agent will:
# 1. Search for Apple stock price
# 2. Use Python to calculate market cap
# 3. Return the answer

🎯 ReAct Pattern (Reasoning + Acting)

The ReAct framework combines reasoning and acting:

# Agent's internal thought process:

Question: What's the weather in Paris and should I bring an umbrella?

Thought: I need to find the current weather in Paris.
Action: Search
Action Input: "current weather in Paris"
Observation: Partly cloudy, 15°C, 60% chance of rain

Thought: There's a 60% chance of rain, so I should recommend an umbrella.
Action: None (I have enough information)
Final Answer: The weather in Paris is partly cloudy at 15°C with a 60% chance of rain. 
Yes, you should bring an umbrella as there's a significant chance of precipitation.

Implementing ReAct

from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(model="gpt-4", temperature=0)

# Load pre-built tools
tools = load_tools(
    ["wikipedia", "llm-math"],
    llm=llm
)

# Create ReAct agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    handle_parsing_errors=True
)

# Complex multi-step task
result = agent.run(
    "Who is the current president of France and what's their age in months?"
)

# Agent will:
# 1. Search Wikipedia for current French president
# 2. Find their birthdate
# 3. Calculate age in months using calculator tool

🚀 Advanced Agent: AutoGPT-style

from langchain.agents import Tool
from langchain.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.experimental import AutoGPT
from langchain.utilities import SerpAPIWrapper

# More comprehensive tools
search = SerpAPIWrapper()
memory = ConversationBufferMemory(memory_key="chat_history")

tools = [
    Tool(
        name="search",
        func=search.run,
        description="Search the internet"
    ),
    Tool(
        name="write_file",
        func=lambda x: open(x.split(":")[0], "w").write(x.split(":")[1]),
        description="Write content to file. Format: filename:content"
    ),
    Tool(
        name="read_file",
        func=lambda x: open(x).read(),
        description="Read file contents"
    )
]

# AutoGPT agent
agent = AutoGPT.from_llm_and_tools(
    ai_name="ResearchAgent",
    ai_role="Assistant that researches topics and creates reports",
    tools=tools,
    llm=ChatOpenAI(model="gpt-4", temperature=0.7),
    memory=memory.buffer
)

# Give it a goal and let it work autonomously
agent.run([
    "Research the latest developments in quantum computing",
    "Summarize the key findings",
    "Write a report to report.txt"
])

# Agent will autonomously:
# 1. Plan research strategy
# 2. Search for information
# 3. Synthesize findings
# 4. Write report
# 5. Self-critique and improve

🧰 Custom Tools

from langchain.tools import BaseTool
from typing import Optional
from pydantic import Field

class DatabaseQueryTool(BaseTool):
    name = "database_query"
    description = "Query the company database for information. Input should be SQL query."
    
    def _run(self, query: str) -> str:
        # Connect to database and execute query
        # This is a simplified example
        import sqlite3
        conn = sqlite3.connect("company.db")
        cursor = conn.cursor()
        cursor.execute(query)
        results = cursor.fetchall()
        return str(results)
    
    async def _arun(self, query: str) -> str:
        # Async version
        raise NotImplementedError("Async not implemented")

class EmailTool(BaseTool):
    name = "send_email"
    description = "Send email. Input format: 'to@email.com|Subject|Body'"
    
    def _run(self, input_str: str) -> str:
        to, subject, body = input_str.split("|")
        # Send email logic here
        return f"Email sent to {to}"
    
    async def _arun(self, input_str: str) -> str:
        raise NotImplementedError("Async not implemented")

# Use custom tools
tools = [DatabaseQueryTool(), EmailTool()]
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION)

agent.run("Find all customers who spent over $1000 this month and send them a thank you email")

🎨 Multi-Agent Systems

from langchain.chat_models import ChatOpenAI
from langchain.agents import initialize_agent, AgentType

# Different specialized agents
researcher_llm = ChatOpenAI(model="gpt-4", temperature=0.7)
writer_llm = ChatOpenAI(model="gpt-4", temperature=0.9)
critic_llm = ChatOpenAI(model="gpt-4", temperature=0.3)

# Researcher agent
researcher = initialize_agent(
    tools=[search_tool],
    llm=researcher_llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)

# Writer agent
writer = initialize_agent(
    tools=[],
    llm=writer_llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)

# Critic agent
critic = initialize_agent(
    tools=[],
    llm=critic_llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)

# Workflow
topic = "Artificial General Intelligence"

# Step 1: Research
research_findings = researcher.run(f"Research the latest developments in {topic}")

# Step 2: Write
draft = writer.run(f"Write an article based on: {research_findings}")

# Step 3: Critique and improve
feedback = critic.run(f"Critique this article and suggest improvements: {draft}")
final_article = writer.run(f"Improve the article based on feedback: {feedback}\n\nOriginal: {draft}")

💾 Agent Memory Systems

Short-term Memory

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory
)

agent.run("My name is Alice")
agent.run("What's my name?")  # Remembers: "Your name is Alice"

Long-term Memory with Vector Store

from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.memory import VectorStoreRetrieverMemory

# Vector store for long-term memory
vectorstore = Chroma(embedding_function=OpenAIEmbeddings())
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

memory = VectorStoreRetrieverMemory(retriever=retriever)

# Store memories
memory.save_context(
    {"input": "User prefers Python over JavaScript"},
    {"output": "Noted, will recommend Python solutions"}
)

# Agent retrieves relevant memories automatically
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    memory=memory
)

🌟 Popular Agent Frameworks

LangChain Agents

  • ReAct pattern
  • Rich tool ecosystem
  • Memory systems
  • Production-ready

AutoGPT

  • Autonomous goal pursuit
  • Self-improvement
  • File operations
  • Internet access

BabyAGI

  • Task management
  • Priority queue
  • Lightweight
  • Educational

CrewAI

  • Multi-agent collaboration
  • Role-based agents
  • Workflow orchestration
  • Team dynamics

⚠️ Challenges & Safety

Key Challenges:

  • Cost: Multiple LLM calls add up quickly
  • Reliability: Agents can get stuck or make errors
  • Safety: Autonomous actions need guardrails
  • Hallucination: Can confidently do wrong things

Best Practices:

  • Set max iterations to prevent infinite loops
  • Implement human approval for critical actions
  • Use sandboxed environments for code execution
  • Log all actions for auditability
  • Test extensively before production

🎯 Key Takeaways