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

使用 nodejs 从头开始​​创建 react agent(维基百科搜索)

介绍

我们将创建一个能够搜索维基百科并根据找到的信息回答问题的人工智能代理。该 react(理性与行动)代理使用 google generative ai api 来处理查询并生成响应。我们的代理将能够:

搜索维基百科获取相关信息。从维基百科页面中提取特定部分。对收集到的信息进行推理并制定答案。

[2] 什么是react代理?

react agent 是一种遵循反射-操作循环的特定类型的代理。它根据可用信息和它可以执行的操作反映当前任务,然后决定采取哪个操作或是否结束任务。

[3] 规划代理

3.1 所需工具

node.js用于 http 请求的 axios 库google 生成式 ai api (gemini-1.5-flash)维基百科 api

3.2 代理结构

我们的 react agent 将具有三个主要状态:

思想(反思)行动(执行)答案(回复)

[4] 实现代理

让我们逐步构建 react agent,突出显示每个状态。

4.1 初始设置

首先,设置项目并安装依赖项:

mkdir react-agent-projectcd react-agent-projectnpm init -ynpm install axios dotenv @google/generative-ai

在项目根目录创建一个 .env 文件:

google_ai_api_key=your_api_key_here

4.2 创建tools.js文件

使用以下内容创建 tools.js:

纳米搜索 纳米搜索

纳米搜索:360推出的新一代AI搜索引擎

纳米搜索 30 查看详情 纳米搜索

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("nn");    } 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 创建reactagent.js文件

使用以下内容创建 reactagent.js:

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. ><";    }  }  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 <<>>>>>>", finalanswer);    return finalanswer;  }}module.exports = reactagent;

4.4 运行代理(index.js)

使用以下内容创建index.js:

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] 维基百科部分如何运作

与维基百科的交互主要分为两个步骤:

初始搜索(维基百科功能):

向维基百科搜索 api 发出请求。最多返回 4 个相关的查询结果。对于每个结果,它都会获取页面的各个部分。

详细搜索(wikipedia_with_pageid函数):

使用页面 id 和部分 id 来获取特定内容。返回请求部分的文本。

此过程允许代理首先获得与查询相关的主题的概述,然后根据需要深入研究特定部分。

[6] 执行流程示例

用户提出问题。智能体进入思考状态并反思问题。它决定搜索维基百科并进入 action 状态。执行wikipedia函数并获取结果。返回thought状态反思结果。可能决定搜索更多详细信息或不同的方法。根据需要重复思想和行动循环。当它有足够的信息时,它进入answer状态。根据收集到的所有信息生成最终答案。只要维基百科没有可收集的数据,就会进入无限循环。用计时器修复它=p

[7] 最后的考虑

模块化结构可以轻松添加新工具或 api。实施错误处理和时间/迭代限制非常重要,以避免无限循环或过度资源使用。使用温度:99999 哈哈

以上就是使用 nodeJS 从头开始​​创建 ReAct Agent(维基百科搜索)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/451199.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月7日 23:12:33
下一篇 2025年11月7日 23:16:32

相关推荐

  • 什么是 x402 支付协议?2025 年值得关注的顶级 x402 生态系统代币汇总

    Binance币安 欧易OKX ️ Huobi火币️ x402 是一个开放的 HTTP 原生支付标准,它将即时、代币化的微支付带到网络,为可进程化商业的新时代重新启动了长期休眠的 HTTP 402「需要付款」代码。该标准由 Coinbase 撰写,并获得 Cloudflare 的 x402 基金会支…

    2025年12月11日 好文分享
    000
  • 以太坊为什么叫死亡币大白话解释

    许多人初次听到以太坊被称为“死亡币”时,可能会误以为这是对其前景的负面评价,担心它会走向终结。然而,这个绰号的真正含义与“归零”或“失败”毫无关系,它反而揭示了其创始人对这项技术未来应用场景的一种深刻且独特的构想。 以太坊买卖平台推荐 1、欧易okx 官网入口: 官方App: 2、币安Binance…

    2025年12月11日
    000
  • Switchboard(SWTCH)币是什么?是一个好投资吗?SWTCH代币经济与空投领取指南

    目录 什么是 SwitchboardSwitchboard技术架构与能力可信执行环境 (TEE)Oracle 队列节点架构SWTCH币是什么SWTCH代币经济学与治理代币分配代币功能和治理路径价值循环和费用分配SWTCH代币空投领取生态系统和最新进展Switchboard愿景与使命如何参与和风险控制…

    2025年12月11日 好文分享
    000
  • Switchboard:空投已开放查询

    Switchboard近期开放了空投查询,申领将于2025年9月9日20:00开始,并在30天后截止。 投资者可实时了解自己是否具备空投资格及可领取的奖励数量。这为持币者提供了便利,确保能够及时获取空投收益,同时了解项目的最新动态。 Switchboard空投资格查询 用户只需登录官方空投页面,绑定…

    2025年12月11日
    000
  • CoinMarketCap数据分析:Mega Matrix申请20亿美元架构建设Ethena稳定币治理财库

    公开上市的控股企业Mega Matrix正将战略重心转向Ethena生态中的ENA治理代币,意图从其合成稳定币USDe的收益机制中获取长期回报。 作为一家已转型布局数字资产领域的上市公司,Mega Matrix近日向美国证券交易委员会(SEC)提交了总额达20亿美元的“架构注册”(shelf reg…

    2025年12月11日 好文分享
    000
  • 探索加密货币市场的高频交易策略

    探索加密货币市场的高频交易策略,无疑是当下金融科技领域最令人振奋的话题之一。在这个24/7不间断运作的数字资产世界里,速度与效率成为了决定成败的关键。高频交易(hft)并非仅仅是快速买卖那么简单,它是一门集成了先进算法、复杂数学模型和尖端技术的艺术,旨在利用市场中稍纵即逝的微小机会。从市场微结构的不…

    好文分享 2025年12月11日
    000
  • 从降息信号到ETH历史新高解析:加密市场这一轮行情的多维驱动因素

    目录 鲍威 尔降息信号:从“死扛”到“鸽 派”的转变降息信号真的鸽 派过头了吗ETH 的暴涨逻辑:叙事、情绪与结构性力量的共振期权轧空与情绪共振机构进场以太坊生态的蓬勃发展金融化与风险偏好回升双轮驱动ETH 后市走势与政策落地节奏以太系项目能率先突破BMNR(BitMine Immersion Te…

    2025年12月11日 好文分享
    000
  • 《Stellar Blade遭黑客攻击:加密货币诈骗与警示故事》

    《stellar blade》官方x账号遭黑客攻击!粉丝被提醒谨防加密货币骗局,提高警觉! 握紧你的游戏手柄,玩家们!《Stellar Blade》的粉丝群体近日经历了一场堪比科幻电影的网络危机。该游戏的官方X账号(原Twitter)遭到黑客入侵,导致大量粉丝被引导至虚假的加密货币诈骗页面和可疑链接…

    2025年12月11日
    000
  • PHP怎么设置路由_PHP路由配置与重写方法

    路由是PHP程序响应URL请求的核心机制,它将不同URL映射到对应处理逻辑。在Laravel等框架中,通过Route::get(‘/users/{id}’, ‘UserController@show’)定义路由,框架自动解析URL并传递参数给控制器方法…

    2025年12月11日
    000
  • PHP如何使用GD库创建和修改图像_PHP GD库图像处理教程

    GD库是PHP处理图像的核心扩展,支持创建、编辑和输出图片。首先创建或加载图像资源,如imagecreatetruecolor()生成画布,imagecreatefromjpeg()等加载文件;接着分配颜色并绘图,可用imagettftext()写文字、imagerectangle()画形状;缩放裁…

    2025年12月11日
    000
  • php如何实现一个简单的REST API?php构建RESTful API基础教程

    核心是通过PHP处理HTTP请求并返回JSON响应。需设计URI、选择HTTP方法、实现路由与数据处理。示例中根据GET请求返回用户信息,支持单个或全部用户查询,并返回对应状态码。POST请求通过解析php://input获取JSON数据,验证后创建新用户并返回201状态码。安全方面需过滤输入防止注…

    2025年12月11日
    000
  • PHP如何解析JSON_PHP解析JSON数据的核心函数与实例

    PHP解析JSON的核心是json_decode()函数,它将JSON字符串转换为PHP对象或关联数组。关键规则包括:JSON对象转为stdClass对象或关联数组(由第二个参数决定),数组转为索引数组,字符串、数字、布尔值和null按类型直转。需注意UTF-8编码、严格语法(如双引号、无尾逗)、大…

    2025年12月11日
    000
  • php如何动态调用一个函数 php动态函数调用方法详解

    PHP动态调用函数的核心是运行时根据变量或条件决定调用目标,主要通过变量函数、call_user_func系列函数及对象方法动态调用实现;常用于回调处理、事件系统、路由分发和插件架构等场景;需警惕用户输入导致的安全风险(如远程代码执行)并避免高频循环中的性能损耗;高级机制包括反射API和__call…

    2025年12月11日
    000
  • php如何生成一个随机的颜色代码 php生成HEX格式随机颜色方法

    生成随机颜色代码需理解颜色构成及PHP随机函数。首先生成红、绿、蓝三色分量的0-255随机值,再转为十六进制并补零,组合成HEX格式颜色代码。颜色暗淡因RGB值偏小,可提高最小值以增强亮度。为生成特定色调如暖色,可限定各分量范围,例如提高红色、降低蓝色。除HEX外,还可输出RGB或HSL格式:RGB…

    2025年12月11日
    000
  • php如何创建和使用自定义的流包装器 php自定义Stream Wrapper开发指南

    自定义流包装器允许用文件操作函数处理非文件资源,通过继承StreamWrapper类并实现如stream_open、stream_read等方法,再使用stream_wrapper_register注册协议,即可实现如内存数据、远程API等统一文件式访问。 PHP自定义流包装器,说白了,就是让你能用…

    2025年12月11日
    000
  • php中的魔术方法__get和__set怎么用?PHP魔术方法__get与__set使用指南

    __get和__set用于拦截对象中不存在或不可访问属性的读写操作,实现动态属性访问、数据验证与惰性加载,常用于配置管理、ORM及代理模式,但需注意性能开销、可读性及IDE支持等问题。 PHP中的魔术方法 __get 和 __set 主要用于处理对象中“不存在”或“不可访问”的属性。简单来说,当你尝…

    2025年12月11日
    000
  • php如何生成缩略图?PHP图像缩略图生成教程

    PHP生成缩略图的核心是利用GD库或ImageMagick扩展,通过读取原图、创建新画布、计算尺寸、重采样复制和保存文件来实现。关键步骤包括:检测GD库、根据MIME类型加载图像、保持宽高比计算目标尺寸、处理透明度(PNG/GIF)、使用imagecopyresampled()进行高质量缩放或裁剪,…

    2025年12月11日
    000
  • PHP如何获取文件的MIME类型_PHP文件MIME类型检测方法

    最可靠的方法是使用finfo扩展,它通过读取文件内容的魔术字节来确定MIME类型,避免依赖不安全的文件扩展名或浏览器提供的$_FILES’file’信息。在文件上传场景中,应结合finfo_file()对临时文件进行真实类型检测,并与预定义的MIME类型白名单比对,确保安全性…

    2025年12月11日
    000
  • PHP匿名类:构造函数参数传递与内部属性初始化详解

    本文详细解析PHP匿名类中构造函数如何接收外部参数(如$_POST数据),并基于这些参数对类内部属性进行条件赋值的机制。通过实例代码,我们将深入探讨参数传递、__construct方法执行流程以及switch语句在属性初始化中的应用,帮助开发者掌握匿名类的核心用法。 匿名类与构造函数简介 在php中…

    2025年12月11日
    000
  • PHP 匿名类构造函数中的 POST 数据赋值详解

    本文旨在详细解释 PHP 匿名类中,通过 $_POST 数组传递数据到构造函数,并在构造函数内部根据条件对类成员变量进行赋值的机制。我们将通过一个具体的代码示例,深入剖析其工作原理,并提供一些使用建议。 PHP 匿名类与构造函数 PHP 7 引入了匿名类,允许我们在不定义类名的情况下创建对象。这在一…

    2025年12月11日
    000

发表回复

登录后才能评论
关注微信