No KYC — no ID, no selfie, no documents. Pay in crypto: BTC, USDT, USDC, ETH, SOL, LTC
Language: English
Get an API key

Docs · LangChain · LlamaIndex · Python

LangChain web search tool on a SERP API, plus a LlamaIndex version

Wrap one HTTPS call in a tool, describe it well, and let the agent decide when to search. The code below works with LangChain 1.0 or later and with LlamaIndex; no SerpCrypto package is needed.

Last updated: · 4 min read

Quick answer

How do I give a LangChain agent a web search tool?

Decorate a Python function with @tool from langchain_core.tools, make it call https://serpcrypto.com/api/v1/search and return short text, then pass it in tools=[...] when you create the agent. With SerpCrypto, each search the agent runs costs 1 credit, from $0.30/1K searches, and failed calls are free. Credits are paid in crypto, with no KYC.

How do I write the search tool?

A LangChain tool is a typed function with a docstring. The decorator turns the signature into the argument schema and the docstring into the description the model reads, so both deserve care. Name the arguments the way the model should think about them: a query, a country, a language.

Return text, not the whole JSON. Five results with title, link and snippet give the model enough to answer and cite, at a fraction of the tokens of the raw answer. Return a short message on errors instead of raising, so the agent can explain or try again.

search_tool.py
"""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."

Pass the tool to create_agent, available from LangChain 1.0. The model reads the description and calls the tool when the question needs fresh facts. Set AGENT_MODEL to a model string your account supports, such as openai: or anthropic: followed by a model name; any chat model with tool calling works.

The system prompt matters as much as the code. Asking the agent to search only for information newer than its training data, and to cite links, keeps answers grounded and limits the number of paid searches.

agent.py
"""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)

How do I do the same with LlamaIndex?

Write a plain function with type hints and a docstring, then wrap it with FunctionTool.from_defaults. LlamaIndex reads the name, the hints and the docstring to build the tool schema, as LangChain does. Add the tool to any LlamaIndex agent that accepts a list of tools.

LlamaIndex FunctionTool
"""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.

Should the tool return JSON or text?

Text, in most cases. Models read short, labelled text well, and it costs fewer tokens than nested JSON. Return JSON only when a later step of your chain parses it, for example to store rankings.

Keep the links in the output. They let the model cite its sources, and they let you check afterwards which pages an answer relied on.

How do I control search costs in an agent?

Every tool call that succeeds is one credit. Three habits keep the count low: tell the model in the system prompt when not to search, cap the number of tool calls per run in your agent loop, and cache answers for repeated questions in your own code.

A pack of 100,000 searches costs $56.25, and Prepaid search credits never expire: unused searches stay on your account until you use them, so a quiet month does not waste anything.

LangChain questions

Is this an official LangChain integration?

No. It is a small custom tool built on LangChain's public @tool decorator. Because it is your code, you can change the output format, add parameters such as location or engine, or add a second tool for Google News.

Can the tool search a specific city?

Yes. Add a location argument and pass it in params, written City, Region, Country. See locations for the format and examples.

Does the agent pay for failed searches?

No. 1 credit = 1 successful search request, which returns one page of results on any supported engine. A request that fails is not charged. A tool call that hits a timeout or a temporary error uses no credit.

Which models can use this tool?

Any chat model that supports tool calling in LangChain or LlamaIndex. The tool itself only sends an HTTPS request, so it does not depend on the model provider.

From $0.30/1K searches · no KYC

Get an API key