Back to template gallery

LangGraph agent

LangGraph agent in JavaScript for answering questions via web search.

Language

javascript

Tools

nodejs

src/main.js

src/tools.js

1import { HumanMessage } from '@langchain/core/messages';
2import { createReactAgent } from '@langchain/langgraph/prebuilt';
3import { ChatOpenAI } from '@langchain/openai';
4import { Actor, log } from 'apify';
5
6import { webSearchTool } from './tools.js';
7
8const Event = {
9    ACTOR_STARTED: 'actor-start-gb',
10    INPUT_100_TOKENS: 'openai-100-tokens-input',
11    OUTPUT_100_TOKENS: 'openai-100-tokens-output',
12    TASK_COMPLETED: 'task-completed',
13};
14
15await Actor.init();
16
17try {
18    const memoryMbytes = Actor.getEnv().memoryMbytes || 1024;
19    const memoryGB = Math.ceil(memoryMbytes / 1024);
20    log.info(`Required memory: ${memoryGB} GB. Charging Actor start event.`);
21    await Actor.charge({ eventName: Event.ACTOR_STARTED, count: memoryGB });
22} catch (error) {
23    log.error('Failed to charge for actor start event', { error });
24    await Actor.exit(1);
25}
26
27// Follow these steps to run this template:
28// 1. If running locally, authenticate to the Apify platform by executing `apify login` in your terminal.
29//    This is necessary to run the Website Content Crawler Actor for data gathering.
30// 2. Set the `OPENAI_API_KEY` environment variable with your OpenAI API key, which can be obtained from
31//    https://platform.openai.com/account/api-keys. Refer to
32//    https://docs.apify.com/cli/docs/vars#set-up-environment-variables-in-apify-console for guidance
33//    on setting environment variables.
34const { OPENAI_API_KEY, APIFY_TOKEN } = process.env;
35
36// You can configure the input for the Actor in the Apify UI when running on the Apify platform or editing
37// storage/key_value_stores/default/INPUT.json when running locally.
38const { query, modelName } = await Actor.getInput() || {};
39
40if (!OPENAI_API_KEY) throw new Error('Please configure the OPENAI_API_KEY as environment variable or enter it into the input!');
41if (!APIFY_TOKEN) throw new Error('Please configure the APIFY_TOKEN environment variable! Call `apify login` in your terminal to authenticate.');
42
43const agent = createReactAgent({
44    llm: new ChatOpenAI({ temperature: 0, model: modelName }),
45    tools: [webSearchTool],
46});
47
48let agentFinalState;
49try {
50    log.info('Starting agent ...');
51    agentFinalState = await agent.invoke(
52        { messages: [new HumanMessage(query)] },
53        { configurable: { thread_id: '1' } },
54    );
55} catch (error) {
56    log.error('Failed to run the agent', { error });
57    await Actor.exit(1);
58}
59
60if (!agentFinalState || !agentFinalState.messages?.length) {
61    log.error('Agent did not return a valid response.');
62    await Actor.exit(1);
63}
64
65const answer = agentFinalState.messages[agentFinalState.messages.length - 1].content;
66
67log.info(`Question: ${query}`);
68log.info(`Agent response: ${answer}`);
69
70log.info(`Number of messages: ${agentFinalState.messages.length}`);
71const usageTokens = agentFinalState.messages.reduce((acc, msg) => {
72    acc.input += msg?.usage_metadata?.input_tokens || 0;
73    acc.output += msg?.usage_metadata?.output_tokens || 0;
74    return acc;
75}, { input: 0, output: 0 });
76
77log.info(`Charging token usage. Input: ${usageTokens.input}, Output: ${usageTokens.output}`);
78
79try {
80    await Actor.charge({ eventName: Event.INPUT_100_TOKENS, count: Math.ceil(usageTokens.input / 100) });
81    await Actor.charge({ eventName: Event.OUTPUT_100_TOKENS, count: Math.ceil(usageTokens.output / 100) });
82} catch (error) {
83    log.error('Failed to charge for tokens usage', { error });
84    await Actor.exit(1);
85}
86
87log.info('Pushing data to the key-value store');
88await Actor.pushData({ question: query, answer });
89
90log.info('Task completion event charged');
91await Actor.charge({ eventName: Event.TASK_COMPLETED });
92
93await Actor.exit();

LangGraph.js agent template

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.

How it works

The LangGraph agent follows these steps:

  1. Determines whether to answer questions using internal knowledge or by searching the web.
  2. If a web search is needed, it uses the RAG Web Browser to gather relevant data from websites.
  3. 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.

Sample query

  • How to build a LangGraph agent on the Apify platform?

Before you start

To run this template locally or on the Apify platform, you need:

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 settingsSourceCode, then scroll down to the Environment variables tab and add a new variable named OPENAI_API_KEY with your OpenAI API key.

Monetization

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 .actor/pay_per_event.json with the task-completed event:

1[
2    {
3        "task-completed": {
4            "eventTitle": "Task completed",
5            "eventDescription": "Cost per query answered.",
6            "eventPriceUsd": 0.1
7        }
8    }
9]

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.

Resources

Useful resources to help you get started:

Already have a solution in mind?

Sign up for a free Apify account and deploy your code to the platform in just a few minutes! If you want a head start without coding it yourself, browse our Store of existing solutions.