LangGraph agent
LangGraph agent in JavaScript for answering questions via web search.
src/main.js
src/tools.js
1// eslint-disable-next-line import/extensions2import { HumanMessage } from '@langchain/core/messages';3import { ChatOpenAI } from '@langchain/openai';4import { Actor, log } from 'apify';5import { createAgent } from 'langchain';6
7import { webSearchTool } from './tools.js';8
9await Actor.init();10
11log.info('Charging Actor start event.');12await Actor.charge({ eventName: 'actor-start' });13
14// Follow these steps to run this template:15// 1. If running locally, authenticate to the Apify platform by executing `apify login` in your terminal.16// This is necessary to run the Website Content Crawler Actor for data gathering.17// 2. Set the `OPENAI_API_KEY` environment variable with your OpenAI API key, which can be obtained from18// https://platform.openai.com/account/api-keys. Refer to19// https://docs.apify.com/cli/docs/vars#set-up-environment-variables-in-apify-console for guidance20// on setting environment variables.21const { OPENAI_API_KEY, APIFY_TOKEN } = process.env;22const { query, modelName } = (await Actor.getInput()) ?? {};23
24if (!OPENAI_API_KEY) {25 throw new Error('Please configure the OPENAI_API_KEY as environment variable.');26}27if (!APIFY_TOKEN) {28 throw new Error('Please configure the APIFY_TOKEN environment variable. Call `apify login` in your terminal.');29}30
31const agent = createAgent({32 model: new ChatOpenAI({ temperature: 0, model: modelName }),33 tools: [webSearchTool],34});35
36log.info('Starting agent...');37const agentFinalState = await agent.invoke(38 { messages: [new HumanMessage(query)] },39 { configurable: { thread_id: '1' } },40);41
42if (!agentFinalState?.messages?.length) {43 throw new Error('Agent did not return a valid response.');44}45
46const answer = agentFinalState.messages.at(-1).content;47
48log.info(`Question: ${query}`);49log.info(`Agent response: ${answer}`);50log.info(`Number of messages: ${agentFinalState.messages.length}`);51
52log.info('Pushing data to the dataset');53await Actor.pushData({ question: query, answer });54
55log.info('Charging for task completion');56await Actor.charge({ eventName: 'task-completed' });57
58await Actor.exit();LangGraph is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows.
This template provides a basic structure and an example of a LangGraph ReAct agent that answers questions using web search.
The LangGraph agent follows these steps:
- Determines whether to answer questions using internal knowledge or by searching the web.
- If a web search is needed, it uses the RAG Web Browser to gather relevant data from websites.
- Utilizes the gathered data to generate an answer using the OpenAI model.
In LangGraph.js, agents use tools, which are functions designed to perform specific tasks.
This agent has one tool, webSearchTool, defined in src/tools.js, which allows it to search the web for relevant data.
- How to build a LangGraph agent on the Apify platform?
To run this template locally or on the Apify platform, you need:
- An Apify account and an Apify API token .
- An OpenAI account and API key.
When running the agent locally, set the OpenAI API key as an environment variable:
$export OPENAI_API_KEY=your-openai-api-key
When running the agent on the Apify platform, set the OpenAI API key in the environment variables of the Actor.
To do this, go to Actor settings → Source → Code, then scroll down to the Environment variables tab and add a new variable named OPENAI_API_KEY with your OpenAI API key.
This template uses the Pay Per Event (PPE) monetization model, which provides flexible pricing based on defined events.
To charge users, define events in JSON format and save them on the Apify platform. Here is an example of pay_per_event.json with the task-completed event:
[{"task-completed": {"eventTitle": "Task completed","eventDescription": "Cost per query answered.","eventPriceUsd": 0.1}}]
In the Actor, trigger the event with:
await Actor.charge({ eventName: 'task-completed' });
This approach allows you to programmatically charge users directly from your Actor, covering the costs of execution and related services, such as LLM input/output tokens.
Useful resources to help you get started:
Crawlee + Cheerio
A scraper example that uses Cheerio to parse HTML. It's fast, but it can't run the website's JavaScript or pass JS anti-scraping challenges.
One‑Page HTML Scraper with Cheerio
Scrape single page with provided URL with Axios and extract data from page's HTML with Cheerio.
Crawlee + Puppeteer + Chrome
Example of a Puppeteer and headless Chrome web scraper. Headless browsers render JavaScript and are harder to block, but they're slower than plain HTTP.
Crawlee + Playwright + Chrome
Web scraper example with Crawlee, Playwright and headless Chrome. Playwright is more modern, user-friendly and harder to block than Puppeteer.
Crawlee + Playwright + Camoufox
Web scraper example with Crawlee, Playwright and Camoufox. Camoufox is a custom stealthy fork of Firefox. Try this template if you're facing anti-scraping challenges.
Bootstrap CheerioCrawler
Skeleton project that helps you quickly bootstrap `CheerioCrawler` in JavaScript. It's best for developers who already know Apify SDK and Crawlee.