Agentic AI Chatbot With Node.js and LangChain: Weather & Google Search

Agentic AI Chatbot With Node.js and LangChain: Weather & Google Search

By Mikey SharmaMay 22, 2025

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

FeatureGenerative AIAgentic AI
DefinitionAI that creates new content based on data patternsAI that acts autonomously to pursue goals
Main FunctionGenerates text, images, code, etc.Makes decisions, plans, and takes multi-step actions
AutonomyGenerally no autonomy; responds to promptsAutonomous; initiates actions and plans
Goal OrientationTask-driven but no self-set goalsGoal-directed, can set or receive goals
ExamplesChatGPT, DALL·E, GPT-generated codeAI assistants, autonomous bots, multi-step agents
CapabilitiesContent generationDecision-making, planning, tool use, memory
Interaction with EnvironmentMinimal or none, mostly text-basedCan interact with external systems, APIs, tools
Use Case FocusContent creation, idea generationTask completion, automation, problem-solving
RelationOften a component within agentic systemsBuilds upon generative AI with added layers

Visual Diagrams to Understand Things Easily

1. Agentic AI System Architecture

Diagram ready to load

2. LangChain Agent Workflow

Diagram ready to load

3. Memory Context Flow

Diagram ready to load

4. Tool Selection Decision Tree

Diagram ready to load

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.

Share:

Scroll to top control (visible after scrolling)