LangChain Chatbot with Tools

Simple stdin chatbot using LangChain with tool calling (OpenRouter).


Installation

1pip install langchain langchain-openai python-dotenv

Environment Setup

1# .env
2OPENROUTER_API_KEY=your_api_key_here
3OPENROUTER_MODEL=openai/gpt-4-turbo-preview

Basic Chatbot

 1import os
 2from dotenv import load_dotenv
 3from langchain_openai import ChatOpenAI
 4from langchain.schema import HumanMessage, AIMessage, SystemMessage
 5
 6load_dotenv()
 7
 8# Initialize OpenRouter LLM
 9llm = ChatOpenAI(
10    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
11    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
12    openai_api_base="https://openrouter.ai/api/v1",
13    temperature=0.7,
14)
15
16def chat():
17    """Simple chat loop"""
18    messages = [
19        SystemMessage(content="You are a helpful assistant.")
20    ]
21    
22    print("Chatbot ready! Type 'quit' to exit.\n")
23    
24    while True:
25        user_input = input("You: ").strip()
26        
27        if user_input.lower() in ['quit', 'exit', 'q']:
28            print("Goodbye!")
29            break
30        
31        if not user_input:
32            continue
33        
34        # Add user message
35        messages.append(HumanMessage(content=user_input))
36        
37        # Get AI response
38        response = llm.invoke(messages)
39        messages.append(AIMessage(content=response.content))
40        
41        print(f"AI: {response.content}\n")
42
43if __name__ == "__main__":
44    chat()

Chatbot with Tools

  1import os
  2from dotenv import load_dotenv
  3from langchain_openai import ChatOpenAI
  4from langchain.agents import AgentExecutor, create_tool_calling_agent
  5from langchain.tools import tool
  6from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
  7from langchain.schema import HumanMessage, AIMessage
  8
  9load_dotenv()
 10
 11# Define tools
 12@tool
 13def add_numbers(a: float, b: float) -> float:
 14    """Add two numbers together.
 15    
 16    Args:
 17        a: First number
 18        b: Second number
 19    
 20    Returns:
 21        Sum of a and b
 22    """
 23    return a + b
 24
 25@tool
 26def subtract_numbers(a: float, b: float) -> float:
 27    """Subtract b from a.
 28    
 29    Args:
 30        a: First number
 31        b: Second number
 32    
 33    Returns:
 34        Difference of a and b
 35    """
 36    return a - b
 37
 38@tool
 39def multiply_numbers(a: float, b: float) -> float:
 40    """Multiply two numbers together.
 41    
 42    Args:
 43        a: First number
 44        b: Second number
 45    
 46    Returns:
 47        Product of a and b
 48    """
 49    return a * b
 50
 51@tool
 52def divide_numbers(a: float, b: float) -> float:
 53    """Divide a by b.
 54    
 55    Args:
 56        a: Numerator
 57        b: Denominator
 58    
 59    Returns:
 60        Quotient of a divided by b
 61    """
 62    if b == 0:
 63        raise ValueError("Cannot divide by zero")
 64    return a / b
 65
 66# Initialize LLM
 67llm = ChatOpenAI(
 68    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
 69    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
 70    openai_api_base="https://openrouter.ai/api/v1",
 71    temperature=0,
 72)
 73
 74# Create tools list
 75tools = [add_numbers, subtract_numbers, multiply_numbers, divide_numbers]
 76
 77# Create prompt
 78prompt = ChatPromptTemplate.from_messages([
 79    ("system", "You are a helpful math assistant. Use the provided tools to help users with calculations."),
 80    MessagesPlaceholder(variable_name="chat_history"),
 81    ("human", "{input}"),
 82    MessagesPlaceholder(variable_name="agent_scratchpad"),
 83])
 84
 85# Create agent
 86agent = create_tool_calling_agent(llm, tools, prompt)
 87agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
 88
 89def chat_with_tools():
 90    """Chat loop with tool support"""
 91    chat_history = []
 92    
 93    print("Math Chatbot ready! Type 'quit' to exit.")
 94    print("Try: 'What is 15 + 27?' or 'Calculate 100 divided by 4'\n")
 95    
 96    while True:
 97        user_input = input("You: ").strip()
 98        
 99        if user_input.lower() in ['quit', 'exit', 'q']:
100            print("Goodbye!")
101            break
102        
103        if not user_input:
104            continue
105        
106        try:
107            # Invoke agent
108            response = agent_executor.invoke({
109                "input": user_input,
110                "chat_history": chat_history
111            })
112            
113            # Update history
114            chat_history.append(HumanMessage(content=user_input))
115            chat_history.append(AIMessage(content=response["output"]))
116            
117            print(f"AI: {response['output']}\n")
118            
119        except Exception as e:
120            print(f"Error: {e}\n")
121
122if __name__ == "__main__":
123    chat_with_tools()

Advanced: Custom Tools

  1import os
  2from datetime import datetime
  3from dotenv import load_dotenv
  4from langchain_openai import ChatOpenAI
  5from langchain.agents import AgentExecutor, create_tool_calling_agent
  6from langchain.tools import tool
  7from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
  8from langchain.schema import HumanMessage, AIMessage
  9
 10load_dotenv()
 11
 12@tool
 13def get_current_time() -> str:
 14    """Get the current time.
 15    
 16    Returns:
 17        Current time as a formatted string
 18    """
 19    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 20
 21@tool
 22def calculate_age(birth_year: int) -> int:
 23    """Calculate age from birth year.
 24    
 25    Args:
 26        birth_year: Year of birth
 27    
 28    Returns:
 29        Current age
 30    """
 31    current_year = datetime.now().year
 32    return current_year - birth_year
 33
 34@tool
 35def convert_temperature(temp: float, from_unit: str, to_unit: str) -> float:
 36    """Convert temperature between Celsius, Fahrenheit, and Kelvin.
 37    
 38    Args:
 39        temp: Temperature value
 40        from_unit: Source unit (C, F, or K)
 41        to_unit: Target unit (C, F, or K)
 42    
 43    Returns:
 44        Converted temperature
 45    """
 46    from_unit = from_unit.upper()
 47    to_unit = to_unit.upper()
 48    
 49    # Convert to Celsius first
 50    if from_unit == 'F':
 51        celsius = (temp - 32) * 5/9
 52    elif from_unit == 'K':
 53        celsius = temp - 273.15
 54    else:
 55        celsius = temp
 56    
 57    # Convert from Celsius to target
 58    if to_unit == 'F':
 59        return celsius * 9/5 + 32
 60    elif to_unit == 'K':
 61        return celsius + 273.15
 62    else:
 63        return celsius
 64
 65@tool
 66def calculate_compound_interest(
 67    principal: float,
 68    rate: float,
 69    time: float,
 70    compounds_per_year: int = 1
 71) -> dict:
 72    """Calculate compound interest.
 73    
 74    Args:
 75        principal: Initial amount
 76        rate: Annual interest rate (as percentage, e.g., 5 for 5%)
 77        time: Time period in years
 78        compounds_per_year: Number of times interest is compounded per year
 79    
 80    Returns:
 81        Dictionary with final amount and interest earned
 82    """
 83    rate_decimal = rate / 100
 84    amount = principal * (1 + rate_decimal / compounds_per_year) ** (compounds_per_year * time)
 85    interest = amount - principal
 86    
 87    return {
 88        "final_amount": round(amount, 2),
 89        "interest_earned": round(interest, 2),
 90        "principal": principal,
 91        "rate": rate,
 92        "time": time
 93    }
 94
 95# Initialize LLM
 96llm = ChatOpenAI(
 97    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
 98    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
 99    openai_api_base="https://openrouter.ai/api/v1",
100    temperature=0,
101)
102
103# Create tools list
104tools = [
105    get_current_time,
106    calculate_age,
107    convert_temperature,
108    calculate_compound_interest
109]
110
111# Create prompt
112prompt = ChatPromptTemplate.from_messages([
113    ("system", """You are a helpful assistant with access to various tools.
114    Use the tools when needed to provide accurate information.
115    Always explain your calculations and reasoning."""),
116    MessagesPlaceholder(variable_name="chat_history"),
117    ("human", "{input}"),
118    MessagesPlaceholder(variable_name="agent_scratchpad"),
119])
120
121# Create agent
122agent = create_tool_calling_agent(llm, tools, prompt)
123agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
124
125def advanced_chat():
126    """Advanced chat with multiple tools"""
127    chat_history = []
128    
129    print("Advanced Chatbot ready! Type 'quit' to exit.")
130    print("Available capabilities:")
131    print("- Get current time")
132    print("- Calculate age from birth year")
133    print("- Convert temperatures")
134    print("- Calculate compound interest")
135    print()
136    
137    while True:
138        user_input = input("You: ").strip()
139        
140        if user_input.lower() in ['quit', 'exit', 'q']:
141            print("Goodbye!")
142            break
143        
144        if not user_input:
145            continue
146        
147        try:
148            response = agent_executor.invoke({
149                "input": user_input,
150                "chat_history": chat_history
151            })
152            
153            chat_history.append(HumanMessage(content=user_input))
154            chat_history.append(AIMessage(content=response["output"]))
155            
156            print(f"AI: {response['output']}\n")
157            
158        except Exception as e:
159            print(f"Error: {e}\n")
160
161if __name__ == "__main__":
162    advanced_chat()

With Memory

 1import os
 2from dotenv import load_dotenv
 3from langchain_openai import ChatOpenAI
 4from langchain.agents import AgentExecutor, create_tool_calling_agent
 5from langchain.tools import tool
 6from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
 7from langchain.memory import ConversationBufferMemory
 8
 9load_dotenv()
10
11@tool
12def add_numbers(a: float, b: float) -> float:
13    """Add two numbers together."""
14    return a + b
15
16llm = ChatOpenAI(
17    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
18    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
19    openai_api_base="https://openrouter.ai/api/v1",
20    temperature=0,
21)
22
23tools = [add_numbers]
24
25# Memory
26memory = ConversationBufferMemory(
27    memory_key="chat_history",
28    return_messages=True
29)
30
31prompt = ChatPromptTemplate.from_messages([
32    ("system", "You are a helpful assistant. Remember the conversation context."),
33    MessagesPlaceholder(variable_name="chat_history"),
34    ("human", "{input}"),
35    MessagesPlaceholder(variable_name="agent_scratchpad"),
36])
37
38agent = create_tool_calling_agent(llm, tools, prompt)
39agent_executor = AgentExecutor(
40    agent=agent,
41    tools=tools,
42    memory=memory,
43    verbose=True
44)
45
46def chat_with_memory():
47    """Chat with conversation memory"""
48    print("Chatbot with memory ready! Type 'quit' to exit.\n")
49    
50    while True:
51        user_input = input("You: ").strip()
52        
53        if user_input.lower() in ['quit', 'exit', 'q']:
54            print("Goodbye!")
55            break
56        
57        if not user_input:
58            continue
59        
60        try:
61            response = agent_executor.invoke({"input": user_input})
62            print(f"AI: {response['output']}\n")
63        except Exception as e:
64            print(f"Error: {e}\n")
65
66if __name__ == "__main__":
67    chat_with_memory()

Streaming Responses

 1import os
 2from dotenv import load_dotenv
 3from langchain_openai import ChatOpenAI
 4from langchain.schema import HumanMessage, SystemMessage
 5
 6load_dotenv()
 7
 8llm = ChatOpenAI(
 9    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
10    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
11    openai_api_base="https://openrouter.ai/api/v1",
12    streaming=True,
13    temperature=0.7,
14)
15
16def chat_streaming():
17    """Chat with streaming responses"""
18    messages = [SystemMessage(content="You are a helpful assistant.")]
19    
20    print("Streaming Chatbot ready! Type 'quit' to exit.\n")
21    
22    while True:
23        user_input = input("You: ").strip()
24        
25        if user_input.lower() in ['quit', 'exit', 'q']:
26            print("Goodbye!")
27            break
28        
29        if not user_input:
30            continue
31        
32        messages.append(HumanMessage(content=user_input))
33        
34        print("AI: ", end="", flush=True)
35        full_response = ""
36        
37        for chunk in llm.stream(messages):
38            content = chunk.content
39            print(content, end="", flush=True)
40            full_response += content
41        
42        print("\n")
43        messages.append(AIMessage(content=full_response))
44
45if __name__ == "__main__":
46    chat_streaming()

Complete Example Script

  1#!/usr/bin/env python3
  2"""
  3LangChain Chatbot with OpenRouter
  4Usage: python chatbot.py
  5"""
  6
  7import os
  8import sys
  9from dotenv import load_dotenv
 10from langchain_openai import ChatOpenAI
 11from langchain.agents import AgentExecutor, create_tool_calling_agent
 12from langchain.tools import tool
 13from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
 14from langchain.schema import HumanMessage, AIMessage
 15
 16load_dotenv()
 17
 18# Validate environment
 19if not os.getenv("OPENROUTER_API_KEY"):
 20    print("Error: OPENROUTER_API_KEY not set in .env file")
 21    sys.exit(1)
 22
 23# Tools
 24@tool
 25def add(a: float, b: float) -> float:
 26    """Add two numbers."""
 27    return a + b
 28
 29@tool
 30def subtract(a: float, b: float) -> float:
 31    """Subtract b from a."""
 32    return a - b
 33
 34@tool
 35def multiply(a: float, b: float) -> float:
 36    """Multiply two numbers."""
 37    return a * b
 38
 39@tool
 40def divide(a: float, b: float) -> float:
 41    """Divide a by b."""
 42    if b == 0:
 43        raise ValueError("Cannot divide by zero")
 44    return a / b
 45
 46# Setup
 47llm = ChatOpenAI(
 48    model=os.getenv("OPENROUTER_MODEL", "openai/gpt-4-turbo-preview"),
 49    openai_api_key=os.getenv("OPENROUTER_API_KEY"),
 50    openai_api_base="https://openrouter.ai/api/v1",
 51    temperature=0,
 52)
 53
 54tools = [add, subtract, multiply, divide]
 55
 56prompt = ChatPromptTemplate.from_messages([
 57    ("system", "You are a helpful math assistant. Use tools for calculations."),
 58    MessagesPlaceholder(variable_name="chat_history"),
 59    ("human", "{input}"),
 60    MessagesPlaceholder(variable_name="agent_scratchpad"),
 61])
 62
 63agent = create_tool_calling_agent(llm, tools, prompt)
 64agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
 65
 66def main():
 67    """Main chat loop"""
 68    chat_history = []
 69    
 70    print("🤖 Math Chatbot (OpenRouter)")
 71    print("=" * 40)
 72    print("Commands: quit, exit, q")
 73    print("Example: 'What is 15 + 27?'")
 74    print("=" * 40)
 75    print()
 76    
 77    while True:
 78        try:
 79            user_input = input("You: ").strip()
 80            
 81            if user_input.lower() in ['quit', 'exit', 'q']:
 82                print("👋 Goodbye!")
 83                break
 84            
 85            if not user_input:
 86                continue
 87            
 88            response = agent_executor.invoke({
 89                "input": user_input,
 90                "chat_history": chat_history
 91            })
 92            
 93            chat_history.append(HumanMessage(content=user_input))
 94            chat_history.append(AIMessage(content=response["output"]))
 95            
 96            print(f"🤖: {response['output']}\n")
 97            
 98        except KeyboardInterrupt:
 99            print("\n👋 Goodbye!")
100            break
101        except Exception as e:
102            print(f"❌ Error: {e}\n")
103
104if __name__ == "__main__":
105    main()

Related Snippets