Building Autonomous AI Agents with LangChain and Node.js
What is an Autonomous AI Agent?
Most developers interact with Large Language Models (LLMs) via simple prompt-and-response mechanisms (like ChatGPT). You ask a question, and it answers. However, an Autonomous AI Agent is fundamentally different. Instead of just answering a question, an agent is given a goal, a set of tools, and the ability to reason about how to achieve that goal.
If you ask an agent to "Find the current CEO of Apple and email them a greeting," the agent will:
- Think: "I need to find the current CEO of Apple. I will use the Web Search tool."
- Action: Uses Google Search API for "Current CEO of Apple".
- Observation: The result is Tim Cook.
- Think: "Now I need to email Tim Cook. I will use the Email tool."
- Action: Uses SendGrid API to send the email.
To build this loop in Node.js, we use LangChain.
Setting Up LangChain in Node.js
First, you need to install the required packages. We will use the @langchain/openai package for the LLM and langchain/agents for the reasoning engine.
npm install langchain @langchain/openai
1. Initialize the LLM
Agents require highly capable models to reason correctly. Models like GPT-4o or Claude 3.5 Sonnet are highly recommended.
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI({
temperature: 0, // Keep temperature at 0 for deterministic agent behavior
modelName: "gpt-4o",
openAIApiKey: process.env.OPENAI_API_KEY,
});
2. Define Custom Tools
Tools are regular JavaScript functions that the LLM can call. You must provide a clear description so the LLM knows when to use it.
import { DynamicTool } from "@langchain/core/tools";
const weatherTool = new DynamicTool({
name: "get_weather",
description: "Use this tool to get the current weather for a specific city. Input should be the city name.",
func: async (city) => {
// In reality, you would call a real Weather API here
if (city.toLowerCase().includes("faridpur")) return "32°C and Sunny";
return "25°C and Cloudy";
},
});
const tools = [weatherTool];
3. Create the Agent Executor
The Agent Executor is the infinite loop that manages the Thought -> Action -> Observation cycle. We use the createOpenAIFunctionsAgent which leverages OpenAI's native function calling capabilities.
import { createOpenAIFunctionsAgent, AgentExecutor } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
// Define the prompt
const prompt = ChatPromptTemplate.fromMessages([
["system", "You are a helpful AI assistant. Use the provided tools to answer questions."],
["human", "{input}"],
new MessagesPlaceholder("agent_scratchpad"),
]);
// Create the agent
const agent = await createOpenAIFunctionsAgent({
llm,
tools,
prompt,
});
// Create the executor
const agentExecutor = new AgentExecutor({
agent,
tools,
verbose: true, // This will log the Thought/Action process to the console
});
4. Run the Agent
Now we can ask our agent a question that requires it to use a tool.
const result = await agentExecutor.invoke({
input: "What is the weather like in Faridpur right now?",
});
console.log(result.output);
// The LLM will decide to call get_weather("Faridpur")
// Output: "The current weather in Faridpur is 32°C and sunny."
Moving Beyond Linear Scripts
While this example is simple, the true power of LangChain agents is realized when you give them 10+ tools. You can give them tools to execute SQL queries, read PDFs, navigate websites using Puppeteer, or interact with your company's internal APIs.
By defining tools rather than writing hardcoded logic, you allow the AI to adapt to unexpected scenarios dynamically. This is the foundation of the future of software engineering.