」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 nodeJS 從頭開始建立 ReAct Agent(維基百科搜尋)

使用 nodeJS 從頭開始建立 ReAct Agent(維基百科搜尋)

發佈於2024-11-08
瀏覽:598

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如有侵犯,請聯絡study_golang@163. com刪除
最新教學 更多>
  • 大批
    大批
    [2 數組是對象,因此它們在JS中也具有方法。 切片(開始):在新數組中提取部分數組,而無需突變原始數組。 令ARR = ['a','b','c','d','e']; // USECASE:提取直到索引作...
    程式設計 發佈於2025-03-13
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-03-13
  • 如何在HTML和CSS中訂購的列表編號後刪除該期間?
    如何在HTML和CSS中訂購的列表編號後刪除該期間?
    在html和css中訂購列表:刪除期間要刪除週期,以這樣的列表:這將在每個列表項目之前顯示自定義數字。 請記住,此解決方案依賴於:偽selector之前,該解決方案可能無法在IE6和IE7之類的較舊瀏覽器中使用。要解決這個問題,請使用專門針對這些瀏覽器的其他CSS規則:
    程式設計 發佈於2025-03-13
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-03-13
  • 為什麼我的CSS背景圖像出現?
    為什麼我的CSS背景圖像出現?
    故障排除:CSS背景圖像未出現 ,您的背景圖像儘管遵循教程說明,但您的背景圖像仍未加載。圖像和样式表位於相同的目錄中,但背景仍然是空白的白色帆布。 而不是不棄用的,您已經使用了CSS樣式: bockent {背景:封閉圖像文件名:背景圖:url(nickcage.jpg); 如果您的html,cs...
    程式設計 發佈於2025-03-13
  • 為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    The Mystery of "Broken" Two-Phase Template Instantiation in Microsoft Visual C Problem Statement:Users commonly express concerns that Micro...
    程式設計 發佈於2025-03-12
  • UTF-8 vs. Latin-1:字符編碼大揭秘!
    UTF-8 vs. Latin-1:字符編碼大揭秘!
    [utf-8和latin1 在他們的應用中,出現了一個基本問題:什麼辨別特徵區分了這兩個編碼? 超出其字符表現能力,UTF-8具有額外的幾個優勢。從歷史上看,MySQL對UTF-8的支持僅限於每個字符的三個字節,這阻礙了基本多語言平面(BMP)之外的字符的表示。但是,隨著MySQL 5.5的出現...
    程式設計 發佈於2025-03-12
  • 如何在Java字符串中有效替換多個子字符串?
    如何在Java字符串中有效替換多個子字符串?
    在java 中有效地替換多個substring,需要在需要替換一個字符串中的多個substring的情況下,很容易求助於重複應用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    程式設計 發佈於2025-03-12
  • Part SQL注入系列:高級SQL注入技巧詳解
    Part SQL注入系列:高級SQL注入技巧詳解
    [2 Waymap pentesting工具:单击此处 trixsec github:单击此处 trixsec电报:单击此处 高级SQL注入利用 - 第7部分:尖端技术和预防 欢迎参与我们SQL注入系列的第7部分!该分期付款将攻击者采用的高级SQL注入技术 1。高...
    程式設計 發佈於2025-03-12
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-03-12
  • 如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    如何修復\“常規錯誤:2006 MySQL Server在插入數據時已經消失\”?
    How to Resolve "General error: 2006 MySQL server has gone away" While Inserting RecordsIntroduction:Inserting data into a MySQL database can...
    程式設計 發佈於2025-03-12
  • 我們如何保護有關惡意內容的文件上傳?
    我們如何保護有關惡意內容的文件上傳?
    對文件上載上傳到服務器的安全性問題可以引入重大的安全風險,因為用戶可能會提供潛在的惡意內容。了解這些威脅並實施有效的緩解策略對於維持應用程序的安全性至關重要。 用戶可以將文件名操作以繞過安全措施。避免將其用於關鍵目的或使用其原始名稱保存文件。 用戶提供的MIME類型可能不可靠。使用服務器端檢查確定...
    程式設計 發佈於2025-03-12
  • 如何使用JavaScript中的正則表達式從字符串中刪除線路斷裂?
    如何使用JavaScript中的正則表達式從字符串中刪除線路斷裂?
    在此代碼方案中刪除從字符串在JavaScript中解決此問題,根據操作系統的編碼,對線斷裂的識別不同。 Windows使用“ \ r \ n”序列,Linux採用“ \ n”,Apple系統使用“ \ r。” 來滿足各種線路斷裂的變化,可以使用以下正則表達式: [&& && &&&&&&&&&&&...
    程式設計 發佈於2025-03-12
  • 為什麼使用Firefox後退按鈕時JavaScript執行停止?
    為什麼使用Firefox後退按鈕時JavaScript執行停止?
    導航歷史記錄問題:JavaScript使用Firefox Back Back 此行為是由瀏覽器緩存JavaScript資源引起的。要解決此問題並確保在後續頁面訪問中執行腳本,Firefox用戶應設置一個空功能。 警報'); }; alert('inline Alert')...
    程式設計 發佈於2025-03-12
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call fil...
    程式設計 發佈於2025-03-12

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3