Crie um agente de IA com pesquisa na Web em tempo real em JavaScript — Amit Merchant — Um blog sobre PHP, JavaScript e muito mais

Grandes modelos de linguagem (LLMs) são ótimos para responder perguntas, mas têm uma limitação importante: eles não têm acesso inerente ao que está acontecendo na web no momento.
Pergunte a um LLM sobre um conceito de programação e ele provavelmente poderá responder com base em seu conhecimento existente. Pergunte sobre as estruturas JavaScript mais recentes, as notícias de hoje ou o preço atual de um produto, e sua resposta pode estar desatualizada.
Uma maneira de resolver isso é fornecer ao modelo uma ferramenta ou recurso que possa pesquisar na web antes de concluir sua resposta.
Você já deve ter visto esse padrão em assistentes de IA modernos. Por exemplo, aqui está o que parece em Gêmeos.
Neste tutorial conciso, construiremos algo semelhante, mas um pouco básico. Um pequeno agente de IA em JavaScript que pode decidir quando precisa pesquisar na web, usar SearchApi para recuperar os resultados de pesquisa do Google e, em seguida, usar esses resultados para formular sua resposta.
$ node agent.js "What are the latest developments in PHP 8.5?"
🤖 Thinking...
🔎 Searching the web for: "PHP 8.5 latest developments release"
📄 Found 5 results.
🤖 Thinking...
...
Como você pode ver, se a pergunta exigir uma pesquisa na web, o agente realizará a pesquisa na web e usará os resultados para responder à pergunta/solicitação.
O que torna algo um agente de IA?
Antes de começarmos a construir nosso agente de IA, vamos entender rapidamente o que torna algo um agente de IA.
Portanto, um LLM normal normalmente receberia uma solicitação e geraria uma resposta com base em seus dados de treinamento. Ou seja, a resposta que você obtém pode estar desatualizada ou não ser relevante para o contexto atual e isso não é ideal quando você procura informações atualizadas.
Por outro lado, um LLM com uma ferramenta pode receber uma solicitação, decidir se precisa usar uma ferramenta (como uma pesquisa na web), usar essa ferramenta para obter informações em tempo real e então gerar uma resposta com base nessas informações. Se a ferramenta não for necessária, ela poderá apenas gerar uma resposta com base em seus dados de treinamento.
User → LLM → Tool → Result → LLM → Answer
A distinção importante aqui é que o LLM não executa a ferramenta sozinho. Ele decide que uma ferramenta é necessária e gera uma chamada de ferramenta estruturada. Nosso aplicativo executa a função e envia seu resultado de volta ao modelo.
Por exemplo, OpenRouter (o gateway de API para LLMs), que usaremos neste tutorial, descreve isso exatamente como chamada de ferramenta. Essencialmente, dá ao LLM acesso a ferramentas externas.
E isso nos leva ao ciclo de agente. O loop do agente é um processo onde o LLM pode decidir usar uma ferramenta, obter o resultado e então decidir se precisa usar outra ferramenta ou gerar uma resposta final. Este ciclo continua até que o LLM decida que possui informações suficientes para responder à pergunta do usuário.

Um agente não precisa ser uma estrutura complicada. Na sua forma mais simples, é um LLM, um conjunto de ferramentas e um loop que permite ao modelo agir sobre os resultados.
A própria documentação do OpenRouter chama isso de loop de agente simples.
O que vamos construir
Como eu disse anteriormente, vamos construir um pequeno agente de IA em JavaScript que pode decidir quando precisa pesquisar na web, usar o SearchApi para recuperar os resultados de pesquisa do Google e, em seguida, usar esses resultados para formular sua resposta. O fluxograma do nosso agente é assim.

Vamos abordar todo o jargão do fluxograma acima para entendermos o que todos os componentes fazem.
- Nemotron — É um dos LLMs gratuitos do OpenRouter que decide se precisa pesquisar e qual consulta usar.
- JavaScript — Orquestra o agente e executa ferramentas.
- API de pesquisa — Recupera resultados de pesquisa do Google em tempo real.
- Loop de agente — Alimenta os resultados da ferramenta de volta ao LLM.
Com isso resolvido, vamos começar a construir nosso agente de IA.
Pré-requisitos
Para construir este agente de IA, você precisará do seguinte:
- Node.js 20+
- Uma chave de API OpenRouter
- Uma chave de API SearchApi
Depois de fazer isso, execute os seguintes comandos para criar um novo projeto Node.js e instalar as dependências necessárias.
mkdir web-search-agent
cd web-search-agent
npm init -y
npm install openai dotenv
Agora, crie um .env arquivo na raiz do seu projeto e adicione seu OpenRouter e API de pesquisa Chaves de API assim.
OPENROUTER_API_KEY=your_openrouter_api_key
SEARCHAPI_API_KEY=your_searchapi_api_key
Para este tutorial, estou usando o modelo Nemotron 3.5 Lightning do OpenRouter, que é um modelo gratuito que tem a capacidade de decidir quando precisa pesquisar na web e qual consulta usar. Você pode usar qualquer outro modelo que tenha a mesma capacidade, mas para este tutorial ficaremos com o Nemotron.
Além disso, você obtém uma chave de API SearchApi gratuita que permite fazer 100 solicitações, o que é mais que suficiente para este tutorial. Se precisar de mais, você pode atualizar para um plano pago.
Conectando-se ao LLM
Crie um novo arquivo chamado agent.js na raiz do seu projeto e adicione o código a seguir para conectar-se à API OpenRouter.
import "dotenv/config";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
Conforme discutido anteriormente, estamos usando a API do OpenRouter para conectar-se ao modelo Nemotron.
const MODEL = "nvidia/nemotron-3.5-lightning:free";
Em seguida, precisamos fornecer à IA uma ferramenta que ela possa usar para pesquisar na web. Para isso, precisamos de uma definição de ferramenta.
const tools = (
{
type: "function",
function: {
name: "search_web",
description:
"Search the web for current information. Use this when the user asks about recent, current, or up-to-date information.",
parameters: {
type: "object",
properties: {
query: {
type: "string",
description: "The search query to send to Google.",
},
},
required: ("query"),
},
},
},
);
Observe que não estamos dando ao LLM a implementação de search_web(). Estamos fornecendo uma descrição do que a função faz e dos parâmetros que ela aceita.
O modelo pode então gerar:
{
"type": "function",
"index": 0,
"id": "call-03f0d876-015c-403e-b2de-3f28973dacc1",
"function": {
"name": "search_web",
"arguments": {
"query": "latest JavaScript frameworks 2026 trends web development"
}
}
}
A documentação do OpenRouter usa o mesmo padrão: definir um esquema de função, receber tool_calls, execute a função solicitada em seu aplicativoe retornar o resultado para o modelo.
Implementar search_web() com SearchApi
Em seguida, precisamos implementar o search_web() função que usará SearchApi para recuperar resultados de pesquisa do Google.
async function searchWeb(query) {
console.log(`n🔎 Searching the web for: "${query}"`);
const url = new URL("https://www.searchapi.io/api/v1/search");
url.searchParams.set("engine", "google");
url.searchParams.set("q", query);
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.SEARCHAPI_API_KEY}`,
},
});
if (!response.ok) {
const error = await response.text();
throw new Error(
`SearchApi request failed (${response.status}): ${error}`
);
}
const data = await response.json();
/*
* We don't need to send the entire SearchApi response
* back to the LLM. Extract the useful organic results.
*/
const results = (data.organic_results || ())
.slice(0, 5)
.map((result) => ({
title: result.title,
link: result.link,
snippet: result.snippet,
}));
console.log(`📄 Found ${results.length} results.`);
return results;
}
Por que SearchApi? Um agente de IA precisa de uma maneira confiável de acessar informações atualizadas da web. SearchApi fornece resultados de pesquisa estruturados por meio de uma API, para que possamos expor a pesquisa na web como uma ferramenta sem precisar construir ou manter nossa própria infraestrutura de scraping. Isso o torna uma opção natural para um agente que precisa fundamentar suas respostas em dados atuais da web.
O Loop do Agente
Por último, precisamos construir o loop de agentes que permitirá ao LLM decidir quando precisa pesquisar na web e quando possui informações suficientes para responder à pergunta do usuário.
async function runAgent(userQuestion) {
const messages = (
{
role: "system",
content:
"You are a helpful research assistant. Use the search_web tool whenever you need current information. After receiving search results, use them to answer the user's question. Mention the sources you used by including their URLs.",
},
{
role: "user",
content: userQuestion,
},
);
/*
* The agent can go through multiple tool calls.
*
* For example:
*
* LLM → search_web()
* → search_web()
* → final answer
*/
for (let i = 0; i 5; i++) {
console.log(`n🤖 Thinking...`);
const response = await client.chat.completions.create({
model: MODEL,
messages,
tools,
/*
* We don't need the model's reasoning output for this demo.
*/
reasoning: {
exclude: true,
},
});
const message = response.choices(0).message;
/*
* Add the assistant's response to the conversation.
*/
messages.push(message);
// No tool call means the agent has its final answer.
if (!message.tool_calls?.length) {
return message.content;
}
/*
* Execute every tool requested by the AI.
*/
for (const toolCall of message.tool_calls) {
if (toolCall.function.name === "search_web") {
const { query } = JSON.parse(toolCall.function.arguments);
const results = await searchWeb(query);
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(results),
});
}
}
}
throw new Error("Agent reached the maximum number of tool calls.");
}
Como você pode ver, o usuário faz uma pergunta ao agente. O código então verifica se o modelo solicitou a ferramenta.
if (!message.tool_calls?.length) {
return message.content;
}
Nesse caso, extrai os argumentos da chamada da ferramenta.
const { query } =
JSON.parse(toolCall.function.arguments);
Em seguida, ele executa o search_web() função e envia os resultados de volta ao modelo.
const results = await searchWeb(query);
E por fim, adiciona a resposta da ferramenta à conversa.
messages.push({
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(results),
});
Pergunte novamente ao LLM e ele solicitará outra chamada de ferramenta ou fornecerá sua resposta final. E é assim que funciona o loop do agente.
Isso mapeia quase exatamente o fluxo documentado de chamada de ferramenta em três etapas do OpenRouter e seu loop de agente simples.
Execute o agente
Adicione o seguinte trecho de código para responder a uma pergunta na linha de comando e executar o agente.
/*
* Run the agent.
*/
// eg. "What are the latest JavaScript frameworks for building websites in 2026?"
const question = process.argv.slice(2).join(" ");
if (!question) {
console.error('Usage: node agent.js "your question"');
process.exit(1);
}
console.log(`n👤 User: ${question}`);
try {
const answer = await runAgent(question);
console.log("nn💬 Agent:n");
console.log(answer);
} catch (error) {
console.error("n❌ Error:");
console.error(error);
}
Agora, você pode executar o agente com uma pergunta como esta.
$ node agent.js "Who won the nobel prize in chemistry 2025?"
O fluxo de trabalho do agente ficará assim.
Da mesma forma, você pode fazer uma pergunta diferente. Por exemplo…
$ node agent.js "What are the best developer laptops available right now?"
E o agente pesquisará na web e fornecerá uma resposta com base nas informações mais recentes.
Se você quiser apenas ver o projeto em ação, confira o repositório GitHub. Faça um fork, adicione suas chaves de API OpenRouter e SearchApi no
.envarquivo e você está pronto para ir.
Por que este é um agente
Você pode estar se perguntando, “Amit! Isso não é apenas um LLM chamando uma API?”
Bem, não.
A principal diferença é que o que construímos aqui pode interpretar uma solicitação em linguagem natural, decidir se ela precisa de informações externas, selecionar uma ferramenta, gerar os argumentos da ferramenta, consumir o resultado da ferramenta e então produzir uma resposta final.
E o mais importante, não informamos quando pesquisar ou exatamente que consulta enviar. Demos a ele um recurso e deixamos o modelo decidir como usá-lo.
Levando o agente adiante
Para levar esse agente adiante, você pode, por exemplo, fazer com que o agente faça múltiplas pesquisas e combine os resultados para responder a uma pergunta.
Digamos que o usuário pergunte: “Compare Astro, Next.js e Nuxt para construir um site com muito conteúdo.” O agente poderia pesquisar cada tecnologia de forma independente e sintetizar os resultados.
Você também pode utilizar a oferta mais ampla de API do SearchApi, que oferece oportunidades de adicionar recursos especializados em coisas como compras, mapas, notícias, YouTube e outros mecanismos de pesquisa/fontes de dados.
Portanto, seu agente pode evoluir de:
em:
search_web()
search_news()
search_shopping()
search_maps()
search_youtube()
Isso tornaria seu agente mais capaz e versátil, permitindo responder a uma gama mais ampla de perguntas com informações em tempo real.
No encerramento
Construímos um agente de IA pequeno, mas funcional, sem uma estrutura de agente. O LLM decide quando precisa de informações, nosso aplicativo JavaScript executa a ferramenta solicitada, SearchApi recupera os resultados de pesquisa mais recentes e os resultados são realimentados no modelo.
A parte interessante não é a quantidade de código. É a arquitetura: um LLM se torna consideravelmente mais útil quando você fornece ferramentas que ele pode decidir usar.
A partir daqui, você pode adicionar mais ferramentas, oferecer suporte a múltiplas pesquisas, introduzir memória ou transformar a CLI em um aplicativo da web completo. As possibilidades são infinitas.






