”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 nodeJS 从头开始​​创建 ReAct Agent(维基百科搜索)

使用 nodeJS 从头开始​​创建 ReAct Agent(维基百科搜索)

发布于2024-11-08
浏览:538

Creating a ReAct Agent from the scratch with nodeJS ( wikipedia search )

Introduction

We'll create an AI agent capable of searching Wikipedia and answering questions based on the information it finds. This ReAct (Reason and Act) Agent uses the Google Generative AI API to process queries and generate responses. Our agent will be able to:

  1. Search Wikipedia for relevant information.
  2. Extract specific sections from Wikipedia pages.
  3. Reason about the information gathered and formulate answers.

[2] What is a ReAct Agent?

A ReAct Agent is a specific type of agent that follows a Reflection-Action cycle. It reflects on the current task, based on available information and actions it can perform, and then decides which action to take or whether to conclude the task.

[3] Planning the Agent

3.1 Required Tools

  • Node.js
  • Axios library for HTTP requests
  • Google Generative AI API (gemini-1.5-flash)
  • Wikipedia API

3.2 Agent Structure

Our ReAct Agent will have three main states:

  1. THOUGHT (Reflection)
  2. ACTION (Execution)
  3. ANSWER (Response)

[4] Implementing the Agent

Let's build the ReAct Agent step by step, highlighting each state.

4.1 Initial Setup

First, set up the project and install dependencies:

mkdir react-agent-project
cd react-agent-project
npm init -y
npm install axios dotenv @google/generative-ai

Create a .env file at the project's root:

GOOGLE_AI_API_KEY=your_api_key_here

4.2 Creating the Tools.js File

Create Tools.js with the following content:

const axios = require("axios");

class Tools {
  static async wikipedia(q) {
    try {
      const response = await axios.get("https://en.wikipedia.org/w/api.php", {
        params: {
          action: "query",
          list: "search",
          srsearch: q,
          srwhat: "text",
          format: "json",
          srlimit: 4,
        },
      });

      const results = await Promise.all(
        response.data.query.search.map(async (searchResult) => {
          const sectionResponse = await axios.get(
            "https://en.wikipedia.org/w/api.php",
            {
              params: {
                action: "parse",
                pageid: searchResult.pageid,
                prop: "sections",
                format: "json",
              },
            },
          );

          const sections = Object.values(
            sectionResponse.data.parse.sections,
          ).map((section) => `${section.index}, ${section.line}`);

          return {
            pageTitle: searchResult.title,
            snippet: searchResult.snippet,
            pageId: searchResult.pageid,
            sections: sections,
          };
        }),
      );

      return results
        .map(
          (result) =>
            `Snippet: ${result.snippet}\nPageId: ${result.pageId}\nSections: ${JSON.stringify(result.sections)}`,
        )
        .join("\n\n");
    } catch (error) {
      console.error("Error fetching from Wikipedia:", error);
      return "Error fetching data from Wikipedia";
    }
  }

  static async wikipedia_with_pageId(pageId, sectionId) {
    if (sectionId) {
      const response = await axios.get("https://en.wikipedia.org/w/api.php", {
        params: {
          action: "parse",
          format: "json",
          pageid: parseInt(pageId),
          prop: "wikitext",
          section: parseInt(sectionId),
          disabletoc: 1,
        },
      });
      return Object.values(response.data.parse?.wikitext ?? {})[0]?.substring(
        0,
        25000,
      );
    } else {
      const response = await axios.get("https://en.wikipedia.org/w/api.php", {
        params: {
          action: "query",
          pageids: parseInt(pageId),
          prop: "extracts",
          exintro: true,
          explaintext: true,
          format: "json",
        },
      });
      return Object.values(response.data?.query.pages)[0]?.extract;
    }
  }
}

module.exports = Tools;

4.3 Creating the ReactAgent.js File

Create ReactAgent.js with the following content:

require("dotenv").config();
const { GoogleGenerativeAI } = require("@google/generative-ai");
const Tools = require("./Tools");

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_AI_API_KEY);

class ReActAgent {
  constructor(query, functions) {
    this.query = query;
    this.functions = new Set(functions);
    this.state = "THOUGHT";
    this._history = [];
    this.model = genAI.getGenerativeModel({
      model: "gemini-1.5-flash",
      temperature: 2,
    });
  }

  get history() {
    return this._history;
  }

  pushHistory(value) {
    this._history.push(`\n ${value}`);
  }

  async run() {
    this.pushHistory(`**Task: ${this.query} **`);
    try {
      return await this.step();
    } catch (e) {
      if (e.message.includes("exhausted")) {
        return "Sorry, I'm exhausted, I can't process your request anymore. >>>>>>>", finalAnswer);
    return finalAnswer;
  }
}

module.exports = ReActAgent;

4.4 Running the agent (index.js)

Create index.js with the following content:

const ReActAgent = require("./ReactAgent.js");

async function main() {
  const query = "What does England border with?";
  const functions = [
    [
      "wikipedia",
      "params: query",
      "Semantic Search Wikipedia API for snippets, pageIds and sectionIds >> \n ex: Date brazil has been colonized? \n Brazil was colonized at 1500, pageId, sections : []",
    ],
    [
      "wikipedia_with_pageId",
      "params : pageId, sectionId",
      "Search Wikipedia API for data using a pageId and a sectionIndex as params.  \n ex: 1500, 1234 \n Section information about blablalbal",
    ],
  ];

  const agent = new ReActAgent(query, functions);
  try {
    const result = await agent.run();
    console.log("THE AGENT RETURN THE FOLLOWING >>>", result);
  } catch (e) {
    console.log("FAILED TO RUN T.T", e);
  }
}

main().catch(console.error);

[5] How the Wikipedia Part Works

The interaction with Wikipedia is done in two main steps:

  1. Initial search (wikipedia function):

    • Makes a request to the Wikipedia search API.
    • Returns up to 4 relevant results for the query.
    • For each result, it fetches the sections of the page.
  2. Detailed search (wikipedia_with_pageId function):

    • Uses the page ID and section ID to fetch specific content.
    • Returns the text of the requested section.

This process allows the agent to first get an overview of topics related to the query and then dive deeper into specific sections as needed.

[6] Execution Flow Example

  1. The user asks a question.
  2. The agent enters the THOUGHT state and reflects on the question.
  3. It decides to search Wikipedia and enters the ACTION state.
  4. Executes the wikipedia function and obtains results.
  5. Returns to the THOUGHT state to reflect on the results.
  6. May decide to search for more details or a different approach.
  7. Repeats the THOUGHT and ACTION cycle as necessary.
  8. When it has sufficient information, it enters the ANSWER state.
  9. Generates a final answer based on all the information collected.
  10. Enters infinite loop whenever the wikipedia doesn't have the data to collect. Fix it with a timer =P

[7] Final Considerations

  • The modular structure allows for easy addition of new tools or APIs.
  • It's important to implement error handling and time/iteration limits to avoid infinite loops or excessive resource use.
  • Use Temperature : 99999 lol
版本声明 本文转载于:https://dev.to/allan_felipemurara_9aa7d/creating-a-react-agent-from-the-scratch-with-nodejs-wikipedia-search--584e?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 掌握 JavaScript 函数:开发人员综合指南
    掌握 JavaScript 函数:开发人员综合指南
    JavaScript Functions A JavaScript function is a block of code designed to perform a particular task. A JavaScript function is executed when "...
    编程 发布于2024-11-08
  • Next.js 缓存:通过高效的数据获取来增强您的应用程序
    Next.js 缓存:通过高效的数据获取来增强您的应用程序
    Next.js 中的缓存不仅仅是为了节省时间,还在于减少冗余网络请求、保持数据新鲜并使您的应用程序像摇滚明星一样运行。 无论您是想将数据缓存更长时间还是按需刷新,Next.js 都能为您提供所需的所有工具。在本文中,我们将详细介绍如何在 Next.js 中有效地使用缓存 Next.js 扩展了 f...
    编程 发布于2024-11-08
  • 为什么我的 Go 模板条件检查失败?
    为什么我的 Go 模板条件检查失败?
    Go 模板:条件检查故障排除在 Go 模板渲染中,结构体字段的条件检查有时无法按预期工作。考虑以下示例,其中 bool 字段 isOrientRight 未正确计算:type Category struct { ImageURL string
    编程 发布于2024-11-08
  • 如何解决 MySQL 时区错误:Java 中的“服务器时区值中欧时间”?
    如何解决 MySQL 时区错误:Java 中的“服务器时区值中欧时间”?
    MySQL 连接器在 Java 数据库连接期间出现“服务器时区值中欧时间”错误使用建立数据库连接时会出现此问题Java 中的 MySQL 连接器。该错误消息表明提供的服务器时区值“中欧时间”无法识别或代表多个时区。要解决此问题,必须使用 serverTimezone 配置属性显式指定服务器时区值。一...
    编程 发布于2024-11-08
  • 为什么应该避免在 JSX Props 中使用箭头函数或绑定?
    为什么应该避免在 JSX Props 中使用箭头函数或绑定?
    为什么在 JSX Props 中使用箭头函数或 Bind 是禁忌使用 React 时,避免使用箭头函数或 Bind 非常重要在 JSX 属性中绑定。这种做法可能会导致性能问题和不正确的行为。性能问题在 JSX props 中使用箭头函数或绑定会强制在每次渲染时重新创建这些函数。这意味着:旧函数被丢弃...
    编程 发布于2024-11-08
  • 自动模式的 CSS 主题选择器 [教程]
    自动模式的 CSS 主题选择器 [教程]
    This tutorial shows you how to create a theme selector in Svelte, enabling multiple theme options for your website. It also includes an automatic them...
    编程 发布于2024-11-08
  • 了解 Java 中的静态实用方法
    了解 Java 中的静态实用方法
    在现代软件开发中,非常重视干净、可重用和有效的编码。 Java 中的一项功能对实现这一目标大有帮助,称为静态实用方法。本文将探讨什么是静态实用方法、它们的好处、常见用例以及有效实现这些方法的最佳实践。 什么是静态实用方法? 静态实用方法是属于类的方法,而不是属于类的实例。这些方法是使...
    编程 发布于2024-11-08
  • ## 如何在 JavaScript 中限制函数执行:自定义解决方案与库解决方案
    ## 如何在 JavaScript 中限制函数执行:自定义解决方案与库解决方案
    通过自定义实现实现 JavaScript 中的简单节流使用 JavaScript 时,控制函数执行速率至关重要。节流函数限制函数调用的频率,防止繁重的处理或重复的用户操作。在这篇文章中,我们提出了一个简单的自定义节流函数来实现此目的,而不依赖于 Lodash 或 Underscore 等外部库。 提...
    编程 发布于2024-11-08
  • 了解 WebSocket:React 开发人员综合指南
    了解 WebSocket:React 开发人员综合指南
    Understanding WebSockets: A Comprehensive Guide for React Developers In today’s world of modern web applications, real-time communication is ...
    编程 发布于2024-11-08
  • 如何在 macOS 上安装并启用 Imagick for PHP
    如何在 macOS 上安装并启用 Imagick for PHP
    如果您在 macOS 上工作并且需要安装 Imagick for PHP 8.3,则可能会遇到默认安装较旧版本 PHP(例如 PHP 8.0)的问题。在这篇文章中,我将引导您完成确保 Imagick 已安装并针对 PHP 8.3 正确配置的步骤。 第 1 步:通过 Homebrew ...
    编程 发布于2024-11-08
  • 如何使用 JavaScript 为对象数组添加附加属性?
    如何使用 JavaScript 为对象数组添加附加属性?
    扩展具有附加属性的对象数组编程中普遍存在的任务涉及使用附加属性增强现有对象数组。为了说明这个概念,请考虑包含两个元素的对象数组:Object {Results:Array[2]} Results:Array[2] [0-1] 0:Object id=1 name: "R...
    编程 发布于2024-11-08
  • 如何解决 CSS 中可变字体的文本笔划问题?
    如何解决 CSS 中可变字体的文本笔划问题?
    文本描边难题:解决 CSS 兼容性问题使用 -webkit-text-lines 创建引人注目的文本效果是网页设计师的一项基本技术。但是,当将此属性与可变字体一起使用时,可能会出现意外的笔划行为。这种不一致不仅限于 Chrome,而是不同浏览器中更普遍的问题。问题的症结:可变字体和笔画冲突可变字体具...
    编程 发布于2024-11-08
  • C++ 中的私有虚拟方法:平衡封装和重写
    C++ 中的私有虚拟方法:平衡封装和重写
    了解 C 中私有虚拟方法的好处 在面向对象编程中,私有方法封装实现细节并限制其在一个班级。然而,在 C 中,虚函数提供后期绑定并允许对象的多态行为。通过结合这些概念,私有虚拟方法提供了独特的优势。考虑以下用法,其中 HTMLDocument 继承自多个基类:class HTMLDocument : ...
    编程 发布于2024-11-08
  • 斋浦尔数据科学研究所:传统与技术的邂逅
    斋浦尔数据科学研究所:传统与技术的邂逅
    斋浦尔,粉红之城,长期以来一直是一座拥有丰富文化遗产、雄伟宫殿和充满活力的传统的城市,但这座城市的另一个特征是教育和技术进步。这是通过斋浦尔的几个数据科学研究所推出的,通过这些机构引导学生和专业人士进入快速变化的技术世界。 这些机构融合了传统与创新,在培养这座城市的未来科技人才方面发挥着重要作用。在...
    编程 发布于2024-11-08
  • 如何根据多个条件过滤 JavaScript 对象数组?
    如何根据多个条件过滤 JavaScript 对象数组?
    基于多个条件过滤JavaScript中的数组问题陈述给定一个对象数组和一个过滤器对象,目标是过滤和根据过滤器中指定的多个条件简化数组。但是,当过滤器包含多个属性时,会出现一个特定问题。建议的解决方案考虑以下代码段:function filterUsers(users, filter) { var...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3