Building Your First AI Agent with LangChain and Python
Learn to create intelligent AI agents that can reason, plan, and execute tasks autonomously using LangChain, OpenAI, and Python. Complete with code examples and deployment guide.
Building Your First AI Agent with LangChain and Python
Published on December 15, 2024 • 14 min read
LangChain has revolutionized AI agent development by providing a powerful framework for building intelligent applications. This comprehensive guide teaches you how to create sophisticated AI agents that can reason, use tools, and interact with external systems.
Table of Contents
- Introduction to LangChain
- Setting Up Your Environment
- Basic Agent Architecture
- Building Your First Agent
- Adding Tools and Capabilities
- Memory and State Management
- Advanced Agent Patterns
- Production Deployment
Introduction to LangChain {#introduction}
LangChain is a framework for developing applications powered by language models. It enables you to build agents that can:
- Reason: Make decisions based on context and goals
- Use Tools: Interact with APIs, databases, and external services
- Remember: Maintain conversation history and context
- Plan: Break down complex tasks into steps
Key Components
- Agents: The core reasoning engine
- Tools: Functions the agent can call
- Memory: Storage for conversation history
- Chains: Sequences of operations
- Prompts: Templates for model interactions
Setting Up Your Environment {#setup}
Installation and Dependencies
1pip install langchain openai python-dotenv2pip install langchain-community langchain-experimental3pip install faiss-cpu # For vector storage4pip install requests beautifulsoup4 # For web scraping tools
Environment Configuration
1import os2from dotenv import load_dotenv3from langchain.llms import OpenAI4from langchain.chat_models import ChatOpenAI5from langchain.agents import initialize_agent, AgentType6from langchain.tools import Tool7from langchain.memory import ConversationBufferMemory89# Load environment variables10load_dotenv()1112# Configure OpenAI13os.environ["OPENAI_API_KEY"] = "your_openai_api_key"1415# Initialize language model16llm = ChatOpenAI(17 model_name="gpt-3.5-turbo",18 temperature=0.7,19 max_tokens=100020)2122print("LangChain environment configured successfully!")
Basic Agent Architecture {#architecture}
Understanding Agent Components
1from langchain.agents import AgentExecutor2from langchain.agents.format_scratchpad import format_to_openai_function_messages3from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser4from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder5from langchain.tools.render import format_tool_to_openai_function67class BaseAgent:8 def __init__(self, llm, tools, memory=None):9 self.llm = llm10 self.tools = tools11 self.memory = memory or ConversationBufferMemory(12 memory_key="chat_history",13 return_messages=True14 )15 self.agent_executor = self._create_agent()1617 def _create_agent(self):18 """Create the agent executor"""19 # Create prompt template20 prompt = ChatPromptTemplate.from_messages([21 ("system", """You are a helpful AI assistant. Use the available tools to help users accomplish their tasks.2223 Available tools:24 {tools}2526 Always think step by step and explain your reasoning.27 """),28 MessagesPlaceholder(variable_name="chat_history"),29 ("user", "{input}"),30 MessagesPlaceholder(variable_name="agent_scratchpad")31 ])3233 # Format tools for OpenAI functions34 llm_with_tools = self.llm.bind(35 functions=[format_tool_to_openai_function(t) for t in self.tools]36 )3738 # Create agent39 agent = (40 {41 "input": lambda x: x["input"],42 "agent_scratchpad": lambda x: format_to_openai_function_messages(43 x["intermediate_steps"]44 ),45 "chat_history": lambda x: x["chat_history"],46 "tools": lambda x: "\n".join([f"{tool.name}: {tool.description}" for tool in self.tools])47 }48 | prompt49 | llm_with_tools50 | OpenAIFunctionsAgentOutputParser()51 )5253 # Create executor54 agent_executor = AgentExecutor(55 agent=agent,56 tools=self.tools,57 memory=self.memory,58 verbose=True,59 max_iterations=560 )6162 return agent_executor6364 def run(self, input_text):65 """Run the agent with input"""66 return self.agent_executor.invoke({"input": input_text})6768# Usage example69tools = [] # We'll add tools in the next section70agent = BaseAgent(llm, tools)
Building Your First Agent {#first-agent}
Creating Basic Tools
1import requests2from datetime import datetime3import json45def get_current_time():6 """Get the current time"""7 return datetime.now().strftime("%Y-%m-%d %H:%M:%S")89def calculate_math(expression):10 """Calculate mathematical expressions safely"""11 try:12 # Only allow safe mathematical operations13 allowed_chars = set('0123456789+-*/.() ')14 if not all(c in allowed_chars for c in expression):15 return "Error: Invalid characters in expression"1617 result = eval(expression)18 return f"Result: {result}"19 except Exception as e:20 return f"Error: {str(e)}"2122def search_web(query):23 """Search the web for information"""24 try:25 # Using a simple search API (replace with your preferred service)26 url = f"https://api.duckduckgo.com/?q={query}&format=json&no_html=1&skip_disambig=1"27 response = requests.get(url)28 data = response.json()2930 if data.get('Abstract'):31 return data['Abstract']32 elif data.get('RelatedTopics'):33 return data['RelatedTopics'][0].get('Text', 'No results found')34 else:35 return "No results found"36 except Exception as e:37 return f"Search error: {str(e)}"3839def write_file(filename, content):40 """Write content to a file"""41 try:42 with open(filename, 'w') as f:43 f.write(content)44 return f"Successfully wrote to {filename}"45 except Exception as e:46 return f"Error writing file: {str(e)}"4748def read_file(filename):49 """Read content from a file"""50 try:51 with open(filename, 'r') as f:52 content = f.read()53 return content54 except Exception as e:55 return f"Error reading file: {str(e)}"5657# Create LangChain tools58tools = [59 Tool(60 name="get_current_time",61 description="Get the current date and time",62 func=get_current_time63 ),64 Tool(65 name="calculate_math",66 description="Calculate mathematical expressions. Input should be a valid mathematical expression.",67 func=calculate_math68 ),69 Tool(70 name="search_web",71 description="Search the web for information. Input should be a search query.",72 func=search_web73 ),74 Tool(75 name="write_file",76 description="Write content to a file. Input should be 'filename|content'.",77 func=lambda x: write_file(*x.split('|', 1))78 ),79 Tool(80 name="read_file",81 description="Read content from a file. Input should be the filename.",82 func=read_file83 )84]8586# Create agent with tools87agent = BaseAgent(llm, tools)8889# Test the agent90response = agent.run("What time is it and what's 25 * 4?")91print(response)
Simple Agent Example
1class SimpleTaskAgent:2 def __init__(self):3 self.llm = ChatOpenAI(temperature=0.7)4 self.tools = self._create_tools()5 self.memory = ConversationBufferMemory(6 memory_key="chat_history",7 return_messages=True8 )910 self.agent = initialize_agent(11 tools=self.tools,12 llm=self.llm,13 agent=AgentType.OPENAI_FUNCTIONS,14 memory=self.memory,15 verbose=True16 )1718 def _create_tools(self):19 """Create basic tools for the agent"""20 return [21 Tool(22 name="calculator",23 description="Useful for mathematical calculations",24 func=calculate_math25 ),26 Tool(27 name="timer",28 description="Get current time and date",29 func=get_current_time30 ),31 Tool(32 name="web_search",33 description="Search the internet for information",34 func=search_web35 )36 ]3738 def chat(self, message):39 """Chat with the agent"""40 try:41 response = self.agent.run(message)42 return response43 except Exception as e:44 return f"Error: {str(e)}"4546# Usage47simple_agent = SimpleTaskAgent()48print(simple_agent.chat("What's the weather like today in New York?"))49print(simple_agent.chat("Calculate 15% tip on a $45 bill"))
Adding Tools and Capabilities {#tools}
Database Integration Tool
1import sqlite32from langchain.tools import BaseTool3from typing import Optional, Type4from pydantic import BaseModel, Field56class DatabaseQueryInput(BaseModel):7 query: str = Field(description="SQL query to execute")89class DatabaseTool(BaseTool):10 name = "database_query"11 description = "Execute SQL queries on the database"12 args_schema: Type[BaseModel] = DatabaseQueryInput1314 def __init__(self, db_path: str):15 super().__init__()16 self.db_path = db_path17 self._init_database()1819 def _init_database(self):20 """Initialize sample database"""21 conn = sqlite3.connect(self.db_path)22 cursor = conn.cursor()2324 # Create sample table25 cursor.execute('''26 CREATE TABLE IF NOT EXISTS users (27 id INTEGER PRIMARY KEY,28 name TEXT NOT NULL,29 email TEXT NOT NULL,30 age INTEGER31 )32 ''')3334 # Insert sample data35 cursor.execute("INSERT OR IGNORE INTO users (id, name, email, age) VALUES (1, 'John Doe', 'john@example.com', 30)")36 cursor.execute("INSERT OR IGNORE INTO users (id, name, email, age) VALUES (2, 'Jane Smith', 'jane@example.com', 25)")3738 conn.commit()39 conn.close()4041 def _run(self, query: str) -> str:42 """Execute database query"""43 try:44 conn = sqlite3.connect(self.db_path)45 cursor = conn.cursor()4647 cursor.execute(query)4849 if query.strip().upper().startswith('SELECT'):50 results = cursor.fetchall()51 columns = [description[0] for description in cursor.description]5253 if results:54 formatted_results = []55 for row in results:56 row_dict = dict(zip(columns, row))57 formatted_results.append(row_dict)58 return json.dumps(formatted_results, indent=2)59 else:60 return "No results found"61 else:62 conn.commit()63 return f"Query executed successfully. Rows affected: {cursor.rowcount}"6465 except Exception as e:66 return f"Database error: {str(e)}"67 finally:68 conn.close()6970# API Integration Tool71class APITool(BaseTool):72 name = "api_request"73 description = "Make HTTP requests to APIs"7475 def _run(self, url: str, method: str = "GET", data: dict = None) -> str:76 """Make API request"""77 try:78 if method.upper() == "GET":79 response = requests.get(url)80 elif method.upper() == "POST":81 response = requests.post(url, json=data)82 else:83 return f"Unsupported method: {method}"8485 return f"Status: {response.status_code}\nResponse: {response.text[:500]}"86 except Exception as e:87 return f"API error: {str(e)}"8889# Email Tool90class EmailTool(BaseTool):91 name = "send_email"92 description = "Send emails (simulation)"9394 def _run(self, to: str, subject: str, body: str) -> str:95 """Send email (simulated)"""96 # In production, integrate with actual email service97 email_log = {98 "to": to,99 "subject": subject,100 "body": body,101 "timestamp": datetime.now().isoformat()102 }103104 # Log email instead of actually sending105 with open("email_log.json", "a") as f:106 f.write(json.dumps(email_log) + "\n")107108 return f"Email sent to {to} with subject '{subject}'"109110# Create enhanced agent with new tools111enhanced_tools = tools + [112 DatabaseTool("sample.db"),113 APITool(),114 EmailTool()115]116117enhanced_agent = BaseAgent(llm, enhanced_tools)
Custom Tool Creation
1from langchain.tools import StructuredTool2from pydantic import BaseModel, Field34class WeatherInput(BaseModel):5 location: str = Field(description="City name or location")6 units: str = Field(default="metric", description="Temperature units (metric/imperial)")78def get_weather(location: str, units: str = "metric") -> str:9 """Get weather information for a location"""10 # Simulate weather API call11 weather_data = {12 "location": location,13 "temperature": "22°C" if units == "metric" else "72°F",14 "condition": "Partly cloudy",15 "humidity": "65%",16 "wind": "10 km/h" if units == "metric" else "6 mph"17 }1819 return f"Weather in {location}: {weather_data['temperature']}, {weather_data['condition']}, Humidity: {weather_data['humidity']}, Wind: {weather_data['wind']}"2021# Create structured tool22weather_tool = StructuredTool.from_function(23 func=get_weather,24 name="get_weather",25 description="Get current weather information for a specific location",26 args_schema=WeatherInput27)2829# Add to tools list30all_tools = enhanced_tools + [weather_tool]
Memory and State Management {#memory}
Different Memory Types
1from langchain.memory import (2 ConversationBufferMemory,3 ConversationBufferWindowMemory,4 ConversationSummaryMemory,5 ConversationSummaryBufferMemory6)78class MemoryManager:9 def __init__(self, llm):10 self.llm = llm1112 def create_buffer_memory(self, return_messages=True):13 """Create simple buffer memory"""14 return ConversationBufferMemory(15 memory_key="chat_history",16 return_messages=return_messages17 )1819 def create_window_memory(self, k=5):20 """Create window memory (keeps last k exchanges)"""21 return ConversationBufferWindowMemory(22 memory_key="chat_history",23 k=k,24 return_messages=True25 )2627 def create_summary_memory(self):28 """Create summary memory (summarizes old conversations)"""29 return ConversationSummaryMemory(30 llm=self.llm,31 memory_key="chat_history",32 return_messages=True33 )3435 def create_summary_buffer_memory(self, max_token_limit=1000):36 """Create summary buffer memory (hybrid approach)"""37 return ConversationSummaryBufferMemory(38 llm=self.llm,39 memory_key="chat_history",40 max_token_limit=max_token_limit,41 return_messages=True42 )4344# Usage45memory_manager = MemoryManager(llm)46smart_memory = memory_manager.create_summary_buffer_memory()4748# Create agent with smart memory49smart_agent = BaseAgent(llm, all_tools, smart_memory)
Persistent Memory with Vector Storage
1from langchain.vectorstores import FAISS2from langchain.embeddings import OpenAIEmbeddings3from langchain.memory import VectorStoreRetrieverMemory45class PersistentMemoryAgent:6 def __init__(self, llm, tools):7 self.llm = llm8 self.tools = tools9 self.embeddings = OpenAIEmbeddings()10 self.vector_store = self._create_vector_store()11 self.memory = self._create_vector_memory()12 self.agent = self._create_agent()1314 def _create_vector_store(self):15 """Create vector store for memory"""16 # Initialize with empty documents17 texts = ["Initial conversation started"]18 return FAISS.from_texts(texts, self.embeddings)1920 def _create_vector_memory(self):21 """Create vector-based memory"""22 retriever = self.vector_store.as_retriever(search_kwargs={"k": 5})23 return VectorStoreRetrieverMemory(24 retriever=retriever,25 memory_key="chat_history"26 )2728 def _create_agent(self):29 """Create agent with vector memory"""30 return initialize_agent(31 tools=self.tools,32 llm=self.llm,33 agent=AgentType.OPENAI_FUNCTIONS,34 memory=self.memory,35 verbose=True36 )3738 def chat(self, message):39 """Chat with persistent memory"""40 response = self.agent.run(message)4142 # Add to vector store for future retrieval43 self.vector_store.add_texts([f"User: {message}\nAssistant: {response}"])4445 return response4647 def save_memory(self, path):48 """Save vector store to disk"""49 self.vector_store.save_local(path)5051 def load_memory(self, path):52 """Load vector store from disk"""53 self.vector_store = FAISS.load_local(path, self.embeddings)54 self.memory = self._create_vector_memory()55 self.agent = self._create_agent()5657# Usage58persistent_agent = PersistentMemoryAgent(llm, all_tools)
Advanced Agent Patterns {#advanced}
Multi-Agent System
1class SpecializedAgent:2 def __init__(self, name, role, llm, tools, system_prompt):3 self.name = name4 self.role = role5 self.llm = llm6 self.tools = tools7 self.system_prompt = system_prompt8 self.memory = ConversationBufferMemory(9 memory_key="chat_history",10 return_messages=True11 )12 self.agent = self._create_agent()1314 def _create_agent(self):15 """Create specialized agent"""16 prompt = ChatPromptTemplate.from_messages([17 ("system", self.system_prompt),18 MessagesPlaceholder(variable_name="chat_history"),19 ("user", "{input}"),20 MessagesPlaceholder(variable_name="agent_scratchpad")21 ])2223 llm_with_tools = self.llm.bind(24 functions=[format_tool_to_openai_function(t) for t in self.tools]25 )2627 agent = (28 {29 "input": lambda x: x["input"],30 "agent_scratchpad": lambda x: format_to_openai_function_messages(31 x["intermediate_steps"]32 ),33 "chat_history": lambda x: x["chat_history"]34 }35 | prompt36 | llm_with_tools37 | OpenAIFunctionsAgentOutputParser()38 )3940 return AgentExecutor(41 agent=agent,42 tools=self.tools,43 memory=self.memory,44 verbose=True45 )4647 def run(self, input_text):48 """Run the specialized agent"""49 return self.agent.invoke({"input": input_text})5051class MultiAgentSystem:52 def __init__(self, llm):53 self.llm = llm54 self.agents = self._create_agents()55 self.coordinator = self._create_coordinator()5657 def _create_agents(self):58 """Create specialized agents"""59 agents = {}6061 # Research Agent62 agents['researcher'] = SpecializedAgent(63 name="researcher",64 role="Research and information gathering",65 llm=self.llm,66 tools=[weather_tool, Tool(name="web_search", description="Search web", func=search_web)],67 system_prompt="You are a research specialist. Your job is to gather accurate information from various sources."68 )6970 # Data Agent71 agents['data_analyst'] = SpecializedAgent(72 name="data_analyst",73 role="Data analysis and calculations",74 llm=self.llm,75 tools=[Tool(name="calculator", description="Calculate math", func=calculate_math), DatabaseTool("sample.db")],76 system_prompt="You are a data analysis expert. You excel at mathematical calculations and data interpretation."77 )7879 # Communication Agent80 agents['communicator'] = SpecializedAgent(81 name="communicator",82 role="Communication and file operations",83 llm=self.llm,84 tools=[EmailTool(), Tool(name="write_file", description="Write files", func=lambda x: write_file(*x.split('|', 1)))],85 system_prompt="You are a communication specialist. You handle all external communications and file operations."86 )8788 return agents8990 def _create_coordinator(self):91 """Create coordinator agent"""92 return SpecializedAgent(93 name="coordinator",94 role="Task coordination and delegation",95 llm=self.llm,96 tools=[],97 system_prompt="""You are a coordinator agent. Your job is to:98 1. Analyze user requests99 2. Determine which specialized agents should handle different parts100 3. Coordinate the workflow between agents101 4. Provide final responses to users102103 Available agents:104 - researcher: For gathering information and research105 - data_analyst: For calculations and data analysis106 - communicator: For sending emails and file operations107 """108 )109110 def process_request(self, user_input):111 """Process user request through multi-agent system"""112 # Coordinator analyzes the request113 coordination_prompt = f"""114 User request: {user_input}115116 Analyze this request and determine:117 1. Which agents should be involved118 2. What tasks each agent should perform119 3. The order of operations120121 Provide a plan in JSON format with agent assignments.122 """123124 plan = self.coordinator.run(coordination_prompt)125126 # Execute plan (simplified version)127 results = {}128129 # For demonstration, route based on keywords130 if any(word in user_input.lower() for word in ['weather', 'search', 'find', 'research']):131 results['research'] = self.agents['researcher'].run(user_input)132133 if any(word in user_input.lower() for word in ['calculate', 'math', 'data', 'analyze']):134 results['analysis'] = self.agents['data_analyst'].run(user_input)135136 if any(word in user_input.lower() for word in ['email', 'send', 'write', 'file']):137 results['communication'] = self.agents['communicator'].run(user_input)138139 # Coordinator synthesizes final response140 synthesis_prompt = f"""141 User request: {user_input}142 Agent results: {json.dumps(results, indent=2)}143144 Provide a comprehensive response to the user based on all agent results.145 """146147 final_response = self.coordinator.run(synthesis_prompt)148 return final_response149150# Usage151multi_agent_system = MultiAgentSystem(llm)152response = multi_agent_system.process_request("What's the weather in Paris and calculate 15% of 200?")153print(response)
Self-Improving Agent
1class SelfImprovingAgent:2 def __init__(self, llm, tools):3 self.llm = llm4 self.tools = tools5 self.performance_log = []6 self.improvement_suggestions = []78 def run_with_feedback(self, user_input):9 """Run agent and collect performance feedback"""10 start_time = datetime.now()1112 try:13 # Create agent14 agent = initialize_agent(15 tools=self.tools,16 llm=self.llm,17 agent=AgentType.OPENAI_FUNCTIONS,18 verbose=True19 )2021 # Execute task22 response = agent.run(user_input)2324 # Log performance25 execution_time = (datetime.now() - start_time).total_seconds()2627 self.performance_log.append({28 'input': user_input,29 'response': response,30 'execution_time': execution_time,31 'timestamp': datetime.now().isoformat(),32 'success': True33 })3435 # Analyze performance36 self._analyze_performance()3738 return response3940 except Exception as e:41 # Log failure42 self.performance_log.append({43 'input': user_input,44 'error': str(e),45 'execution_time': (datetime.now() - start_time).total_seconds(),46 'timestamp': datetime.now().isoformat(),47 'success': False48 })4950 return f"Error: {str(e)}"5152 def _analyze_performance(self):53 """Analyze recent performance and suggest improvements"""54 if len(self.performance_log) < 5:55 return5657 recent_logs = self.performance_log[-5:]5859 # Calculate metrics60 success_rate = sum(1 for log in recent_logs if log['success']) / len(recent_logs)61 avg_execution_time = sum(log['execution_time'] for log in recent_logs) / len(recent_logs)6263 # Generate improvement suggestions64 if success_rate < 0.8:65 self.improvement_suggestions.append({66 'type': 'error_handling',67 'suggestion': 'Improve error handling and input validation',68 'timestamp': datetime.now().isoformat()69 })7071 if avg_execution_time > 10:72 self.improvement_suggestions.append({73 'type': 'performance',74 'suggestion': 'Optimize tool usage and reduce execution time',75 'timestamp': datetime.now().isoformat()76 })7778 def get_performance_report(self):79 """Generate performance report"""80 if not self.performance_log:81 return "No performance data available"8283 total_runs = len(self.performance_log)84 successful_runs = sum(1 for log in self.performance_log if log['success'])85 success_rate = successful_runs / total_runs86 avg_time = sum(log['execution_time'] for log in self.performance_log) / total_runs8788 report = f"""89 Performance Report:90 - Total runs: {total_runs}91 - Success rate: {success_rate:.2%}92 - Average execution time: {avg_time:.2f} seconds93 - Recent improvements suggested: {len(self.improvement_suggestions)}94 """9596 return report9798# Usage99self_improving_agent = SelfImprovingAgent(llm, all_tools)
Production Deployment {#deployment}
FastAPI Web Service
1from fastapi import FastAPI, HTTPException2from pydantic import BaseModel3import uvicorn45app = FastAPI(title="LangChain Agent API")67# Initialize agent8production_agent = BaseAgent(llm, all_tools)910class ChatRequest(BaseModel):11 message: str12 session_id: str = "default"1314class ChatResponse(BaseModel):15 response: str16 session_id: str1718@app.post("/chat", response_model=ChatResponse)19async def chat_endpoint(request: ChatRequest):20 """Chat with the AI agent"""21 try:22 response = production_agent.run(request.message)23 return ChatResponse(24 response=response['output'],25 session_id=request.session_id26 )27 except Exception as e:28 raise HTTPException(status_code=500, detail=str(e))2930@app.get("/health")31async def health_check():32 """Health check endpoint"""33 return {"status": "healthy", "agent": "ready"}3435@app.get("/tools")36async def list_tools():37 """List available tools"""38 return {39 "tools": [40 {"name": tool.name, "description": tool.description}41 for tool in all_tools42 ]43 }4445if __name__ == "__main__":46 uvicorn.run(app, host="0.0.0.0", port=8000)
Docker Deployment
1FROM python:3.9-slim23WORKDIR /app45# Install dependencies6COPY requirements.txt .7RUN pip install --no-cache-dir -r requirements.txt89# Copy application10COPY . .1112# Expose port13EXPOSE 80001415# Run application16CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Monitoring and Logging
1import logging2from datetime import datetime3import json45class AgentMonitor:6 def __init__(self, agent):7 self.agent = agent8 self.logger = self._setup_logging()910 def _setup_logging(self):11 """Setup logging configuration"""12 logging.basicConfig(13 level=logging.INFO,14 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',15 handlers=[16 logging.FileHandler('agent.log'),17 logging.StreamHandler()18 ]19 )20 return logging.getLogger('LangChainAgent')2122 def monitored_run(self, user_input, session_id="default"):23 """Run agent with monitoring"""24 start_time = datetime.now()2526 self.logger.info(f"Session {session_id}: Processing request: {user_input}")2728 try:29 response = self.agent.run(user_input)30 execution_time = (datetime.now() - start_time).total_seconds()3132 self.logger.info(f"Session {session_id}: Request completed in {execution_time:.2f}s")3334 # Log metrics35 metrics = {36 'session_id': session_id,37 'input_length': len(user_input),38 'response_length': len(response['output']),39 'execution_time': execution_time,40 'timestamp': start_time.isoformat(),41 'success': True42 }4344 self.logger.info(f"Metrics: {json.dumps(metrics)}")4546 return response4748 except Exception as e:49 execution_time = (datetime.now() - start_time).total_seconds()5051 self.logger.error(f"Session {session_id}: Error after {execution_time:.2f}s: {str(e)}")5253 # Log error metrics54 error_metrics = {55 'session_id': session_id,56 'input_length': len(user_input),57 'execution_time': execution_time,58 'timestamp': start_time.isoformat(),59 'success': False,60 'error': str(e)61 }6263 self.logger.error(f"Error metrics: {json.dumps(error_metrics)}")6465 raise6667# Usage68monitored_agent = AgentMonitor(production_agent)
Best Practices
Error Handling and Resilience
1class ResilientAgent:2 def __init__(self, llm, tools, max_retries=3):3 self.llm = llm4 self.tools = tools5 self.max_retries = max_retries6 self.agent = self._create_agent()78 def _create_agent(self):9 """Create agent with error handling"""10 return initialize_agent(11 tools=self.tools,12 llm=self.llm,13 agent=AgentType.OPENAI_FUNCTIONS,14 handle_parsing_errors=True,15 max_iterations=5,16 early_stopping_method="generate"17 )1819 def run_with_retry(self, user_input):20 """Run agent with retry logic"""21 for attempt in range(self.max_retries):22 try:23 response = self.agent.run(user_input)24 return response25 except Exception as e:26 if attempt == self.max_retries - 1:27 return f"Sorry, I encountered an error after {self.max_retries} attempts: {str(e)}"2829 print(f"Attempt {attempt + 1} failed: {str(e)}. Retrying...")30 time.sleep(1) # Brief delay before retry3132# Usage33resilient_agent = ResilientAgent(llm, all_tools)
Conclusion
LangChain provides a powerful framework for building sophisticated AI agents. Start with simple tools and gradually add complexity as you understand the patterns and requirements of your specific use case.
Key takeaways:
- Start simple and iterate
- Design tools carefully for your domain
- Implement proper error handling and monitoring
- Use appropriate memory strategies for your use case
- Consider multi-agent architectures for complex tasks
This guide provides a comprehensive foundation for building AI agents with LangChain. Experiment with different configurations to find what works best for your specific requirements.
Related Posts
Creating Intelligent Chatbots with OpenAI and Node.js
Build sophisticated chatbots with memory, context awareness, and custom functions using OpenAI GPT-4, Node.js, and modern web technologies.
Building an Automated Development Harness with Claude Code
How I wired Claude Code into my entire development loop — from a ticket to a verified release — using small triggers, focused skills, and feedback loops that make the system improve itself.
AI-Powered Data Analysis: Automating Insights with Python
Leverage AI to automate data analysis, generate insights, and create intelligent reports using Python, pandas, and machine learning libraries.