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:
- Search Wikipedia for relevant information.
- Extract specific sections from Wikipedia pages.
- 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:
- THOUGHT (Reflection)
- ACTION (Execution)
- 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. ><"; } return "Unable to process your request, please try again? ><"; } } async step() { const colors = { reset: "\x1b[0m", yellow: "\x1b[33m", red: "\x1b[31m", cyan: "\x1b[36m", }; console.log("===================================="); console.log( `Next Movement: ${ this.state === "THOUGHT" ? colors.yellow : this.state === "ACTION" ? colors.red : this.state === "ANSWER" ? colors.cyan : colors.reset }${this.state}${colors.reset}`, ); console.log(`Last Movement: ${this.history[this.history.length - 1]}`); console.log("===================================="); switch (this.state) { case "THOUGHT": await this.thought(); break; case "ACTION": await this.action(); break; case "ANSWER": await this.answer(); break; } } async promptModel(prompt) { const result = await this.model.generateContent(prompt); const response = await result.response; return response.text(); } async thought() { const availableFunctions = JSON.stringify(Array.from(this.functions)); const historyContext = this.history.join("\n"); const prompt = `Your task to FullFill ${this.query}. Context contains all the reflection you made so far and the ActionResult you collected. AvailableActions are functions you can call whenever you need more data. Context: "${historyContext}" << AvailableActions: "${availableFunctions}" << Task: "${this.query}" << Reflect uppon Your Task using Context, ActionResult and AvailableActions to find your next_step. print your next_step with a Thought or FullFill Your Task `; const thought = await this.promptModel(prompt); this.pushHistory(`\n **${thought.trim()}**`); if ( thought.toLowerCase().includes("fullfill") || thought.toLowerCase().includes("fulfill") ) { this.state = "ANSWER"; return await this.step(); } this.state = "ACTION"; return await this.step(); } async action() { const action = await this.decideAction(); this.pushHistory(`** Action: ${action} **`); const result = await this.executeFunctionCall(action); this.pushHistory(`** ActionResult: ${result} **`); this.state = "THOUGHT"; return await this.step(); } async decideAction() { const availableFunctions = JSON.stringify(Array.from(this.functions)); const historyContext = this.history; const prompt = `Reflect uppon the Thought, Query and AvailableActions ${historyContext[historyContext.length - 2]} Thought <<< ${historyContext[historyContext.length - 1]} Query: "${this.query}" AvailableActions: ${availableFunctions} output only the function,parametervalues separated by a comma. For example: "wikipedia,ronaldinho gaucho, 1450"`; const decision = await this.promptModel(prompt); return `${decision.replace(/`/g, "").trim()}`; } async executeFunctionCall(functionCall) { const [functionName, ...args] = functionCall.split(","); const func = Tools[functionName.trim()]; if (func) { return await func.call(null, ...args); } throw new Error(`Function ${functionName} not found`); } async answer() { const historyContext = this.history; const prompt = `Based on the following context, provide a complete, detailed and descriptive formated answer for the Following Task: ${this.query} . Context: ${historyContext} Task: "${this.query}"`; const finalAnswer = await this.promptModel(prompt); this.history.push(`Answer: ${this.finalAnswer}`); console.log("WE WILL ANSWER >>>>>>>", 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:
-
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.
-
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
- The user asks a question.
- The agent enters the THOUGHT state and reflects on the question.
- It decides to search Wikipedia and enters the ACTION state.
- Executes the wikipedia function and obtains results.
- Returns to the THOUGHT state to reflect on the results.
- May decide to search for more details or a different approach.
- Repeats the THOUGHT and ACTION cycle as necessary.
- When it has sufficient information, it enters the ANSWER state.
- Generates a final answer based on all the information collected.
- 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
以上是Creating a ReAct Agent from the scratch with nodeJS ( wikipedia search )的详细内容。更多信息请关注PHP中文网其他相关文章!

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

SublimeText3汉化版
中文版,非常好用

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能