First, I generated an Anthropic API key from the Anthropic dashboard and stored it securely in a local .env file using the following format:

ANTHROPIC_API_KEY=sk-…

To ensure the key remains private, I added .env to my .gitignore file. This prevents the credentials from being accidentally committed to version control or deployed.

At the start of the script, a conversation is initiated with Claude. The script sends the question, “What is the capital of the moon?”, and then prints out Claude’s response.

// testing the file
// console.log("Agent started");

import { ChatAnthropic } from "@langchain/anthropic";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const llm = new ChatAnthropic({
  modelName: "claude-3-7-sonnet-latest",
});

const agent = createReactAgent({ llm, tools: [] });

const results = await agent.invoke({
  messages: [{ role: "user", content: "What is the capital of the moon?" }],
});

console.log(results);
{
messages: [
HumanMessage {
"id": "868aadf1-0da4-4877-810f-f0f159fd96c8",
"content": "What is the capital of the moon?",
"additional_kwargs": {},
"response_metadata": {}
},
AIMessage {
"id": "msg_01A1iq6ad6Dvmbt4sdAxMCPS",
"content": "The Moon doesn't have a capital city because it doesn't have any permanent human settlements or political structures that would designate a capital. Unlike Earth with its countries and governments, the Moon remains largely unexplored territory with only temporary scientific missions having visited its surface. No nation claims sovereignty over the Moon, as the 1967 Outer Space Treaty establishes that celestial bodies cannot be claimed by any country.",
"additional_kwargs": {
"id": "msg_01A1iq6ad6Dvmbt4sdAxMCPS",
"type": "message",
"role": "assistant",
"model": "claude-3-7-sonnet-latest",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 15,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 87
}
},
"response_metadata": {
"id": "msg_01A1iq6ad6Dvmbt4sdAxMCPS",
"model": "claude-3-7-sonnet-latest",
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": {
"input_tokens": 15,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 87
},
"type": "message",
"role": "assistant"
},
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": {
"input_tokens": 15,
"output_tokens": 87,
"total_tokens": 102,
"input_token_details": {
"cache_creation": 0,
"cache_read": 0
}
}
}
]
}

Next, I refined the output by extracting and printing only the AI’s latest response, rather than displaying the entire message array:

// Log out the last result
console.log(results.messages.at(-1)?.content);
The Moon doesn't have a capital as it has no permanent human settlements or political structures that would designate a capital city. While there have been various lunar missions and temporary human presence through the Apollo program, and some nations have plans for future lunar bases, there is currently no established governance system or populated areas on the Moon that would require a capital.

At this stage, the chatbot functions as a basic language model (LLM), responding to prompts based on its training data. To transform it into an agent, it needs access to additional capabilities, such as retrieving external information, calling APIs, or interacting with tools, enabling it to reason and act beyond simple question-answering.

Step 1: Indexing

1.1 ~ Loading:

Once the text is scraped, it needs to be broken into manageable segments for embedding. To do this, we use the RecursiveCharacterTextSplitter from LangChain, which intelligently splits documents while maintaining semantic coherence.

import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { Document } from "@langchain/core/documents";
// import scraped data using brightdata
import data from "./data.js";

const video1 = data[0]; // first scraped video data
const docs = [
  new Document({
    pageContent: video1.transcript,
    metadata: { video_id: video1.video_id },
  }),
];

1.2 ~ Splitting: