Resposta rápida
Como dou uma tool de pesquisa web a um agente LangChain?
Decore uma função Python com @tool de langchain_core.tools, faça ela chamar https://serpcrypto.com/api/v1/search e retornar texto curto, depois passe-a em tools=[...] ao criar o agente. Com o SerpCrypto, cada pesquisa que o agente faz custa 1 crédito, a partir de US$ 0,30/1K pesquisas, e chamadas com falha são gratuitas. Os créditos são pagos com cripto, sem KYC.
Como escrevo a tool de pesquisa?
Uma tool do LangChain é uma função tipada com docstring. O decorator transforma a assinatura no schema de argumentos e a docstring na descrição que o modelo lê, então vale cuidar dos dois. Nomeie os argumentos como o modelo deveria pensá-los: uma consulta, um país, um idioma.
Retorne texto, não o JSON inteiro. Cinco resultados com título, link e snippet dão ao modelo o suficiente para responder e citar, por uma fração dos tokens da resposta bruta. Retorne uma mensagem curta em caso de erro em vez de lançar exceção, para o agente poder explicar ou tentar de novo.
"""A LangChain tool that searches Google through the SerpCrypto SERP API."""
import os
import requests
from langchain_core.tools import tool
API_URL = "https://serpcrypto.com/api/v1/search"
@tool
def google_search(query: str, gl: str = "us", hl: str = "en") -> str:
"""Search Google for current information. Returns the top results with title, link and snippet.
Args:
query: the search query, as a person would type it.
gl: two-letter country code of the results, for example us, gb or de.
hl: language code, for example en, de or pt-BR.
"""
r = requests.get(
API_URL,
params={"q": query, "gl": gl, "hl": hl},
headers={"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]},
timeout=90,
)
if r.status_code != 200:
return f"Search failed with HTTP {r.status_code}."
results = r.json().get("organic_results", [])[:5]
return "\n\n".join(f"{x['title']}\n{x['link']}\n{x.get('snippet', '')}" for x in results) or "No results."Como deixo o agente decidir quando pesquisar?
Passe a tool para create_agent, disponível a partir do LangChain 1.0. O modelo lê a descrição e chama a tool quando a pergunta precisa de fatos novos. Defina AGENT_MODEL com uma string de modelo que sua conta aceita, como openai: ou anthropic: seguido do nome do modelo; qualquer chat model com tool calling funciona.
O system prompt importa tanto quanto o código. Pedir ao agente que pesquise só por informações mais novas que seus dados de treino, e que cite links, mantém as respostas fundamentadas e limita o número de pesquisas pagas.
"""An agent that decides when to search (LangChain 1.0 or later)."""
import os
from langchain.agents import create_agent
from search_tool import google_search
agent = create_agent(
model=os.environ["AGENT_MODEL"], # a provider:model string, such as one of your OpenAI or Anthropic models
tools=[google_search],
system_prompt="Answer with current facts. Use google_search when you need information newer than your training data, and cite the links you used.",
)
result = agent.invoke({"messages": [{"role": "user", "content": "What changed in Google's search results pages this year?"}]})
print(result["messages"][-1].content)Como faço o mesmo com o LlamaIndex?
Escreva uma função simples com type hints e docstring, depois envolva-a com FunctionTool.from_defaults. O LlamaIndex lê o nome, os hints e a docstring para montar o schema da tool, como o LangChain. Adicione a tool a qualquer agente LlamaIndex que aceite uma lista de tools.
"""The same search as a LlamaIndex FunctionTool."""
import os
import requests
from llama_index.core.tools import FunctionTool
def google_search(query: str, gl: str = "us", hl: str = "en") -> str:
"""Search Google for current information and return the top results with title, link and snippet."""
r = requests.get(
"https://serpcrypto.com/api/v1/search",
params={"q": query, "gl": gl, "hl": hl},
headers={"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]},
timeout=90,
)
r.raise_for_status()
results = r.json().get("organic_results", [])[:5]
return "\n\n".join(f"{x['title']}\n{x['link']}\n{x.get('snippet', '')}" for x in results)
search_tool = FunctionTool.from_defaults(fn=google_search)
# Pass search_tool in the tools list of your LlamaIndex agent.A tool deve retornar JSON ou texto?
Texto, na maioria dos casos. Os modelos leem bem texto curto e rotulado, e ele custa menos tokens que JSON aninhado. Retorne JSON só quando uma etapa seguinte do seu fluxo for analisá-lo, por exemplo para armazenar os rankings.
Mantenha os links na saída. Eles permitem que o modelo cite as fontes e que você confira depois em quais páginas uma resposta se baseou.
Como controlo os custos de pesquisa em um agente?
Cada chamada de tool que dá certo é um crédito. Três hábitos mantêm a contagem baixa: dizer ao modelo no system prompt quando não pesquisar, limitar o número de chamadas de tool por execução no seu loop do agente e cachear respostas para perguntas repetidas no seu próprio código.
Um pack de 100.000 pesquisas custam US$ 56,25, e Os créditos de pesquisa pré-pagos nunca expiram: as pesquisas não utilizadas ficam na sua conta até você usá-las, então um mês parado não desperdiça nada.
Perguntas sobre LangChain
Esta é uma integração oficial do LangChain?
Não. É uma tool customizada pequena, construída sobre o decorator público @tool do LangChain. Como é o seu código, você pode mudar o formato de saída, adicionar parâmetros como location ou engine, ou adicionar uma segunda tool para o Google News.
A tool consegue pesquisar em uma cidade específica?
Sim. Adicione um argumento location e passe-o em params, escrito City, Region, Country. Veja locations para o formato e exemplos.
O agente paga por pesquisas com falha?
Não. 1 crédito = 1 solicitação de pesquisa bem-sucedida, que retorna uma página de resultados em qualquer engine compatível. Uma solicitação que falha não é cobrada. Uma chamada de tool que atinge um timeout ou um erro temporário não usa crédito.
Quais modelos podem usar esta tool?
Qualquer chat model que suporte tool calling no LangChain ou no LlamaIndex. A tool em si só envia uma requisição HTTPS, então não depende do provedor do modelo.