Agentic AI Chatbot With Node.js and LangChain: Weather & Google Search
Creating an Agentic AI chatbot involves designing a system that operates autonomously, reasons through multi-step tasks, and integrates with external tools. Hi, I’m Mikey Sharma, and today I’m going to explore in depth how to build an advanced Agentic chatbot using LangChain (JavaScript/TypeScript), integrating it seamlessly with a Node.js Express backend.
This guide outlines how to build a simple yet powerful Agentic AI chatbot using LangChain (JavaScript/TypeScript) and a Node.js Express backend. The chatbot will autonomously handle user queries related to weather information and Google search results, incorporating memory for context-aware conversations, custom tools, error handling, and security for a production-ready system.
Deep Dive: Agentic AI & Implementation Guide
What is Agentic AI?
Agentic AI is about giving machines the power to make decisions on their own. It's not just a sysytem that follows a list of instructions or waits for direction Instead, it can take action based on what it understands about a situation, set its own goals, and adjust as things evolve. Think of it as an AI that doesn't need constant guidance. It learns, adapts, and make choices to keep things moving forward. It's all about autonomy and intelligence that grows as it goes.
1. Core Concepts of Agentic AI
- Autonomy: Operates without constant human input.
- Goal-Oriented: Executes tasks to achieve specific objectives.
- Adaptability: Learns from interactions and adjusts behavior.
- Multi-Step Reasoning: Breaks complex tasks into sub-tasks.
- Human-AI Collaboration: Understands context and collaborates with users.
2. Benefits of Agentic AI
-
Autonomous Decision-Making
Agentic AI can independently make choices without constant human input, increasing efficiency. -
Goal-Directed Behavior
It can plan and execute multi-step tasks to achieve specific objectives, enabling complex problem solving. -
Improved Productivity
By automating repetitive or complex workflows, agentic AI frees up human time for higher-level work. -
Context Awareness
Agentic AI often maintains memory or context over interactions, allowing more coherent and relevant responses. -
Adaptive and Flexible
It can dynamically adjust its actions based on changing environments or feedback. -
Integration with Tools and APIs
Can interact with various software, databases, and hardware, making it highly versatile. -
Scalability
Capable of managing multiple tasks or agents simultaneously, suitable for large-scale automation. -
Reduced Human Error
By handling routine or precision tasks, it minimizes mistakes that humans might make. -
24/7 Availability
Agentic AI systems can operate continuously without fatigue or breaks. -
Personalization
Can tailor actions and responses based on user preferences and past interactions.
Applications of Agentic AI
i. Customer Support Chatbots
- Handle queries like order status, refunds, and product info.
- Escalate complex issues to human agents.
- Remember conversation context and personalize responses.
- Integrate with CRM and support multi-channel communication.
ii. Virtual Personal Assistants
- Manage calendars, schedule meetings, and send reminders.
- Automate email drafting and follow-ups.
- Help with travel planning and bookings.
- Learn user preferences over time for better suggestions.
iii. Autonomous Vehicles
- Navigate roads using sensors and real-time data.
- Make driving decisions such as lane changes and braking.
- Plan routes to optimize time and fuel efficiency.
- Adapt to dynamic traffic and weather conditions.
iv. Robotic Process Automation (RPA) Agents
- Automate repetitive business workflows (e.g., invoicing, data entry).
- Interact with multiple software systems and databases.
- Detect anomalies and escalate exceptions.
- Continuously improve processes through learning.
v. Healthcare AI Agents
- Monitor patient vitals and alert healthcare providers.
- Assist in diagnostics by analyzing medical data.
- Schedule appointments and send medication reminders.
- Provide personalized health advice based on history.
vi. Financial Trading Bots
- Analyze market trends and execute trades autonomously.
- Manage portfolio rebalancing based on risk preferences.
- Monitor compliance and report anomalies.
- Adapt strategies based on real-time financial news.
Agentic AI VS Generative AI
| Feature | Generative AI | Agentic AI |
|---|---|---|
| Definition | AI that creates new content based on data patterns | AI that acts autonomously to pursue goals |
| Main Function | Generates text, images, code, etc. | Makes decisions, plans, and takes multi-step actions |
| Autonomy | Generally no autonomy; responds to prompts | Autonomous; initiates actions and plans |
| Goal Orientation | Task-driven but no self-set goals | Goal-directed, can set or receive goals |
| Examples | ChatGPT, DALL·E, GPT-generated code | AI assistants, autonomous bots, multi-step agents |
| Capabilities | Content generation | Decision-making, planning, tool use, memory |
| Interaction with Environment | Minimal or none, mostly text-based | Can interact with external systems, APIs, tools |
| Use Case Focus | Content creation, idea generation | Task completion, automation, problem-solving |
| Relation | Often a component within agentic systems | Builds upon generative AI with added layers |
Visual Diagrams to Understand Things Easily
1. Agentic AI System Architecture
2. LangChain Agent Workflow
3. Memory Context Flow
4. Tool Selection Decision Tree
Implementation Steps
1. Project Setup
Create project directory
mkdir agentic-chatbot-weather
cd agentic-chatbot-weather
Initialize with default package.json:
npm init -y
Install runtime dependencies
npm install express cors dotenv axios zod @langchain/langgraph @langchain/openai
Install development dependencies
npm install -D typescript ts-node @types/express @types/cors eslint @eslint/js typescript-eslint globals
Optional: Initialize TypeScript and ESLint
npx tsc --init
npx eslint --init
Optional: ESLint Setup
Follow these steps to configure ESLint for your Node.js + TypeScript project:
✔ What do you want to lint? · JavaScript
✔ How would you like to use ESLint? · To check syntax, find problems
✔ What type of modules does your project use? · ESM
✔ Which framework does your project use? · None of these
✔ Does your project use TypeScript? · Yes
✔ Where does your code run? · Node
✔ Would you like to install them now? · Yes
✔ Which package manager do you want to use? · npm
Update your eslint.config.mjs with below content:
import js from "@eslint/js";
import globals from "globals";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
export default defineConfig([
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], plugins: { js }, extends: ["js/recommended"] },
{ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"], languageOptions: { globals: globals.node } },
tseslint.configs.recommended,
]);
Update your tsconfig.json with below content:
{
"compilerOptions": {
"target": "ES6",
"module": "CommonJS",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Update your package.json with below contents for start, run and dev scripts:
{
"name": "agentic-chatbot-weather",
"version": "1.0.0",
+ "main": "dist/app.js",
"scripts": {
+ "start": "tsc && node dist/app.js",
+ "dev": " nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/app.ts",
+ "build": "npx tsc",
+ "lint": "eslint . --ext .ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@eslint/js": "^9.27.0",
"@types/cors": "^2.8.18",
"@types/express": "^5.0.2",
"eslint": "^9.27.0",
"globals": "^16.1.0",
"typescript": "^5.8.3",
"typescript-eslint": "^8.32.1"
},
"dependencies": {
"@langchain/langgraph": "^0.2.73",
"@langchain/openai": "^0.5.11",
"axios": "^1.9.0",
"cors": "^2.8.5",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"ts-node": "^10.9.2",
"zod": "^3.25.20"
}
}
2. Folder Setup and Environment Variables Setup
Here is the folder structure of the project:
agentic-chatbot-weather
├── eslint.config.mjs
├── package.json
├── package-lock.json
├── readme.md
├── src
│ ├── agents
│ │ └── openAIAgentSetup.ts
│ ├── app.ts
│ ├── routes
│ │ └── chatbot.routes.ts
│ └── tools
│ ├── serpapi.tools.ts
│ └── weather.tools.ts
└── tsconfig.json
Execute below commands to create a src/agents, src/routes, src/tools:
mkdir -p src/agents src/routes src/tools
The -p flag ensures that all parent directories (src/) are created if they don't exist.
Environment Variables (.env):
PORT=3000
OPENAI_API_KEY="your_key"
OPENWEATHER_API_KEY="your_key"
SERPAPI_API_KEY="your_key"
3. Create src/app.ts and update it with below code:
import express from "express";
import cors from "cors";
import dotenv from "dotenv";
import ChatbotRoutes from "./routes/chatbot.routes";
// Load environment variables from .env file
dotenv.config();
// Initialize Express app
const app = express();
// Middleware
app.use(cors()); // Enable CORS
app.use(express.json()); // Parse JSON bodies
app.use(express.urlencoded({ extended: true })); // Parse URL-encoded bodies
// Routes
app.use("/api/chatbot", ChatbotRoutes);
// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`✅ Server running on port ${PORT}`);
});
4. Create src/routes/chatbot.routes.ts and update it with below code:
Defines API endpoints for handling chatbot interactions using OpenAI agent logic.
import express, { Request, Response } from 'express';
import { runOpenAIAgent } from '../agents/openAIAgentSetup';
const router = express.Router();
// Health check or base route
router.get('/', (_req: Request, res: Response) => {
res.send('Chatbot API is working!');
});
// Handle chatbot questions via POST
router.post('/', async (req: Request, res: Response) => {
const { question, threadId } = req.body;
// Input validation
if (!question || !threadId) {
res.status(400).json({
error: 'Question and threadId are required.',
});
return;
}
try {
// Get response from the OpenAI agent
const response = await runOpenAIAgent(question, threadId);
res.json({ response });
} catch (error) {
console.error('Error running agent:', error);
res.status(500).json({
error: 'An error occurred while processing your request.',
});
}
});
export default router;
5. Initialize LangChain Agent with Memory, create src/agents/openAIAgentSetup.ts and update your file with below code:
Sets up and runs a LangGraph React agent using OpenAI (ChatGPT) to handle user queries, enhanced with custom tools like weather and search.
import dotenv from "dotenv";
import { ChatOpenAI } from "@langchain/openai";
import { MemorySaver } from "@langchain/langgraph";
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { weatherTool } from "../tools/weather.tools";
import { serpApiTool } from "../tools/serpapi.tools";
// Load environment variables
dotenv.config();
process.env.OPENAI_API_KEY = process.env.OPENAI_API_KEY || "your-openai-api-key";
// 🔧 Define tools the agent can use
const agentTools = [weatherTool, serpApiTool];
// 💬 Initialize the LLM model
const agentModel = new ChatOpenAI({
model: "gpt-4o-mini", // Recommended model (update as needed)
temperature: 0, // Low temperature for deterministic responses
});
// 🧠 System prompt to define behavior and tone
const SYSTEM_PROMPT = `You are MikeyBot, the dedicated AI assistant for Mikey Sharma's users.
Important: Always sign off with "⚡ - MikeyBot (powered by Mikey Sharma)" at the end of your responses.`;
// 🧾 Memory management to preserve context across sessions
const agentCheckpointer = new MemorySaver();
// 🧠 Create the reactive agent
const agent = createReactAgent({
llm: agentModel,
tools: agentTools,
checkpointSaver: agentCheckpointer,
});
// 🚀 Function to run the agent
export async function runOpenAIAgent(question: string, threadId: string) {
const state = await agent.invoke(
{
messages: [
new SystemMessage(SYSTEM_PROMPT), // Sets system context
new HumanMessage(question), // User input
],
},
{
configurable: { thread_id: threadId }, // Thread-specific memory
}
);
// Get the assistant's reply
const response = state.messages[state.messages.length - 1].content;
return response;
}
6. Custom Tools for Enhanced Functionality
Create tools for database access, refund processing, and human escalation.
src/tools/serpapi.tools.ts:
A dynamic tool using SerpAPI to perform real-time Google searches. Designed for LangChain agents to fetch current web data like news, facts, or URLs.
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";
import axios from "axios";
import { config } from "dotenv";
config(); // Load environment variables from .env file
// 🔑 SERPAPI Configuration
const SERPAPI_API_KEY = process.env.SERPAPI_API_KEY || "your_api_key_here";
const BASE_URL = "https://serpapi.com/search";
// 🛠️ Google Search Tool for LangChain Agent
export const serpApiTool = new DynamicStructuredTool({
name: "google_search",
description:
"Perform a Google search and retrieve results. Useful for finding current information, news, or websites about a topic.",
// 🧾 Define input schema
schema: z.object({
query: z.string().describe("The search query to look up on Google"),
num_results: z
.number()
.optional()
.default(5)
.describe("Number of results to return (1-20)"),
recent: z
.boolean()
.optional()
.default(false)
.describe("Whether to prioritize recent results"),
}),
// 🔄 Function executed by the agent
func: async ({ query, num_results = 3, recent = false }) => {
try {
// Clamp result count between 1 and 20
const limit = Math.min(Math.max(num_results, 1), 20);
// Fetch search results from SerpAPI
const response = await axios.get(BASE_URL, {
params: {
q: query,
api_key: SERPAPI_API_KEY,
num: limit,
...(recent ? { tbs: "qdr:d" } : {}), // Filter for last day if recent = true
},
});
const searchData = response.data;
let output = `🔎 Google search results for "${query}":\n\n`;
if (searchData.organic_results?.length > 0) {
searchData.organic_results.slice(0, limit).forEach(
(
result: { title: string; link: string; snippet: string },
index: number
) => {
output += `${index + 1}. ${result.title}\n`;
output += ` ${result.link}\n`;
if (result.snippet) {
output += ` ${result.snippet}\n`;
}
output += "\n";
}
);
} else {
output += "No results found for this query.";
}
return output;
} catch (error) {
console.error("❌ Error fetching search results:", error);
return "Unable to fetch search results at the moment. Please try again later.";
}
},
});
src/tools/weather.toools.ts:
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";
import axios from "axios";
import { config } from "dotenv";
config(); // Load .env variables
// 🔑 OpenWeatherMap API Configuration
const OPENWEATHER_API_KEY = process.env.OPENWEATHER_API_KEY || "your_api_key_here";
const BASE_URL = "https://api.openweathermap.org/data/2.5/weather";
// 🌤️ Weather Tool for LangChain Agents
export const weatherTool = new DynamicStructuredTool({
name: "get_current_weather",
description: "Get the current weather in a given location",
// 📦 Input validation schema
schema: z.object({
location: z
.string()
.describe("The city and state/country, e.g. San Francisco, CA or London, UK"),
}),
// 🚀 Execution logic
func: async ({ location }) => {
try {
// API call to OpenWeatherMap
const response = await axios.get(BASE_URL, {
params: {
q: location,
appid: OPENWEATHER_API_KEY,
units: "imperial", // Use "metric" for Celsius if needed
},
});
const weatherData = response.data;
// 🔍 Extract useful data
const city = weatherData.name;
const country = weatherData.sys?.country || "";
const temp = Math.round(weatherData.main.temp);
const description = weatherData.weather[0].description;
const humidity = weatherData.main.humidity;
const windSpeed = Math.round(weatherData.wind.speed);
// 📦 Return formatted weather report
return `Current weather in ${city}, ${country}:
- Temperature: ${temp}°F
- Conditions: ${description}
- Humidity: ${humidity}%
- Wind: ${windSpeed} mph`;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 404) {
return `Could not find weather data for location: ${location}. Please check the spelling or try a nearby city.`;
}
console.error("❌ Error fetching weather data:", error);
return "Unable to fetch weather data at the moment. Please try again later.";
}
},
});
5. Testing with Complex Queries
curl -X POST http://localhost:3000/api/chatbot \
-H "Content-Type: application/json" \
-d '{"question": "What's the weather like in Tokyo, Japan right now?", "threadId": "07"}'
Expected Response:
{ "response": "
Current weather in Tokyo, JP:
- Temperature: 72°F
- Conditions: broken clouds
- Humidity: 68%
- Wind: 9 mph
⚡ - MikeyBot (powered by Mikey Sharma)
" }
Advanced Enhancements
1. Multi-Modal Capabilities
Integrate image processing using OpenAI's GPT-4 Vision or Google's Gemini:
import { GoogleGenerativeAI } from "@google/generative-ai";
const genAI = new GoogleGenerativeAI(process.env.GEMINI_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-pro-vision" });
async function analyzeImage(imageBuffer) {
const result = await model.generateContent([{ image: imageBuffer }, "Describe this image"]);
return result.response.text();
}
2. Human-in-the-Loop Escalation
Use websockets to hand off conversations:
import WebSocket from "ws";
const wss = new WebSocket.Server({ port: 8080 });
wss.on("connection", (ws) => {
ws.on("message", (message) => {
if (message === "escalate") {
// Transfer chat context to human agent dashboard
}
});
});
3. Ethical Safeguards
Add content moderation middleware:
app.use(async (req, res, next) => {
const moderation = await openai.moderations.create({ input: req.body.message });
if (moderation.results[0].flagged) {
return res.status(403).json({ error: "Violates content policy" });
}
next();
});
Deployment & Monitoring
- Deploy: Containerize with Docker and deploy on AWS ECS.
- Monitor: Use Prometheus/Grafana for performance metrics.
- Log: Log interactions to Elasticsearch for analysis.
👉 Want to explore the full code? Check out the GitHub repo here: Agentic Chatbot
Feel free to star ⭐️, fork 🍴, and contribute! Looking forward to connecting with fellow AI enthusiasts and developers.
