# Pesquisa na web em LangChain e LlamaIndex: uma ferramenta e um retriever

> Pesquisa na web para LangChain e LlamaIndex: uma ferramenta search_web e um retriever que retorna um Document por página. Sem KYC, cripto.

- URL: https://llmwebsearch.com/pt/docs/langchain/
- Última atualização: 2026-10-22
- Editor: LLMWebSearch (https://llmwebsearch.com)

Duas formas cobrem a maioria dos frameworks. Uma ferramenta permite que o agente decida quando pesquisar. Um retriever conecta a web ao vivo a uma cadeia de recuperação, em que cada página lida se torna um documento com sua URL nos metadados.

**Resposta rápida — Como adiciono pesquisa na web ao vivo ao LangChain ou ao LlamaIndex?**

Envolva a chamada `/search` do **LLMWebSearch** em um `@tool` do LangChain, um retriever do LangChain ou um `FunctionTool` do LlamaIndex. Cada um retorna fontes classificadas com as 3 principais páginas em Markdown e suas URLs, prontas para citações. Nenhum pacote nosso para instalar: o código abaixo é a integração. Uma pesquisa custa 1 crédito, a partir de US$ 1,20/1K pesquisas em outubro de 2026. Sem KYC; pague com cripto.

## Para que serve cada wrapper

| Atributo | Valor |
| --- | --- |
| Ferramenta LangChain | Um agente chama `search_web` quando decide que precisa da web |
| Retriever LangChain | Uma cadeia busca documentos atualizados para cada pergunta, sem perguntar |
| FunctionTool LlamaIndex | A mesma função `search_web`, para agentes LlamaIndex |
| Pacotes | `langchain-core` ou `llama-index-core`, mais `requests` |
| Chave | `LLMWEBSEARCH_API_KEY` no ambiente |
| Cobrança | Um crédito paga uma pesquisa: até 20 resultados classificados, com as páginas dos 3 primeiros lidas e devolvidas em Markdown. Ler de 4 a 10 páginas custa 2 créditos. Uma chamada que termina em erro não custa nada |

## Como construo uma ferramenta de pesquisa para um agente LangChain?

Decore uma função com `@tool` de `langchain_core.tools`. O LangChain lê o nome, os argumentos tipados e a docstring para descrever a ferramenta ao modelo, então mantenha a docstring curta e precisa. A função retorna uma string com as fontes numeradas, o que funciona com todo modelo de chat e mantém as URLs junto ao texto.

Chame diretamente com `.invoke()` para testar, depois passe na lista de tools do seu agente.

*Ferramenta LangChain: search_web*

```python
import os

import requests
from langchain_core.tools import tool

API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}


@tool
def search_web(query: str, read: int = 3) -> str:
    """Search the live web. Returns numbered sources with URLs; the first `read` include page text."""
    body = {"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000}
    resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


print(search_web.invoke({"query": "postgres connection pool size"})[:500])

```

## Como uso a web ao vivo como retriever?

Crie uma subclasse de `BaseRetriever` e retorne um `Document` por página lida. O texto da página vai em `page_content`; a URL, o título, o rank e a data vão em `metadata`, onde as cadeias que citam suas fontes os procuram. Resultados sem conteúdo são ignorados, porque um retriever deve entregar texto que o modelo possa citar.

Um retriever roda a cada pergunta. Isso é correto para uma cadeia de perguntas e respostas sobre temas atuais, e desperdício para um chat em que a maioria dos turnos não precisa de pesquisa; nesse caso, use a ferramenta.

*Retriever LangChain: LLMWebSearchRetriever*

```python
import os
from typing import List

import requests
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever


class LLMWebSearchRetriever(BaseRetriever):
    """Live web search results as Documents, one per page that was read."""

    max_results: int = 5
    read: int = 3
    max_chars: int = 6000

    def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
        resp = requests.post(
            "https://llmwebsearch.com/api/v1/search",
            headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
            json={"q": query, "max_results": self.max_results, "read": self.read, "max_chars": self.max_chars},
            timeout=60,
        )
        resp.raise_for_status()
        docs = []
        for r in resp.json()["results"]:
            if r["content_status"] != "ok":
                continue
            meta = {"source": r["url"], "title": r["title"], "position": r["position"], "published_at": r.get("published_at")}
            docs.append(Document(page_content=r["content"], metadata=meta))
        return docs


retriever = LLMWebSearchRetriever(read=3)
for doc in retriever.invoke("pgbouncer transaction mode limitations"):
    print(doc.metadata["position"], doc.metadata["source"], len(doc.page_content))

```

## Como dou a mesma pesquisa a um agente LlamaIndex?

Escreva uma função simples e envolva-a com `FunctionTool.from_defaults` de `llama_index.core.tools`. O LlamaIndex monta o nome e a descrição da ferramenta a partir do nome, da assinatura e da docstring da função. Chamar a ferramenta retorna um `ToolOutput` cujo `content` é o texto que o agente vai ler.

A função é a mesma do LangChain, então uma equipe que usa os dois frameworks pode compartilhá-la.

*LlamaIndex: FunctionTool*

```python
import os

import requests
from llama_index.core.tools import FunctionTool


def search_web(query: str, read: int = 3) -> str:
    """Search the live web and return numbered sources; the first `read` include their page text."""
    resp = requests.post(
        "https://llmwebsearch.com/api/v1/search",
        headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
        json={"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000},
        timeout=60,
    )
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


search_tool = FunctionTool.from_defaults(fn=search_web)
print(search_tool.metadata.name)
print(search_tool.call(query="postgres connection pool size").content[:300])

```

## Como mantenho a janela de contexto sob controle?

Defina `max_chars` na chamada da API em vez de aparar depois: menos dados trafegam e o framework nunca guarda a versão longa. 5.000 caracteres por página e 3 páginas dão cerca de 4.000 tokens, confortável para a maioria dos modelos.

Para chains de retrieval que combinam a web ao vivo com os seus próprios documentos, dê um peso menor aos documentos da web ou uma seção de prompt separada. Páginas web mudam e podem estar erradas; os seus próprios documentos geralmente são a referência.

## Posso armazenar o que o retriever retorna em um banco de dados vetorial?

Sim, no que depender de nós. Não treinamos nenhum modelo com as suas consultas ou com o que a API retorna, e não adicionamos nenhuma regra própria contra armazenar resultados; os direitos dos sites cujas páginas você lê continuam valendo. Armazene a URL e `published_at` com cada chunk, para que o agente possa citar a página e você possa descartar chunks que envelhecem.

A maioria das equipes faz cache dos resultados da web de perguntas frequentes por um dia ou uma semana. Isso reduz pesquisas repetidas, e cada pesquisa evitada é um crédito economizado.

## LangChain e LlamaIndex: perguntas comuns

### Existe um pacote langchain-llmwebsearch?

Não. Não publicamos nenhum pacote. O código desta página é curto o bastante para ser seu: copie, altere os padrões e mantenha no seu repositório.

### Posso tornar a ferramenta async?

Sim. Substitua `requests` por `httpx.AsyncClient` e defina a função com `async def`. O `@tool` do LangChain decora funções async diretamente; no LlamaIndex, passe a versão async para `FunctionTool.from_defaults` como `async_fn`.

### Como leio uma página que o agente encontrou em outro lugar?

Adicione uma segunda ferramenta que envia URLs para `https://llmwebsearch.com/api/v1/extract`. Ler páginas cujas URLs você já tem custa 1 crédito por cada grupo iniciado de 3 páginas devolvidas com conteúdo, até 20 URLs por chamada; URLs recusadas ou com falha não são contadas. A [referência de extract](https://llmwebsearch.com/pt/docs/extract/) mostra a requisição.

---

LLMWebSearch: O LLMWebSearch é uma API de pesquisa na web para agentes de IA que retorna resultados classificados com o conteúdo das principais páginas em Markdown, pago com cripto sem envio de documentos. Os créditos pré-pagos a partir de US$ 1,20/1K pesquisas nunca expiram. Sem KYC — sem documento, sem selfie, sem comprovantes. Pague com cripto.
