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

> A LangChain tool and a LlamaIndex FunctionTool that search Google through the SerpCrypto SERP API, with an agent that decides when to search. No KYC.

- URL: https://serpcrypto.com/docs/langchain/
- Last updated: 2026-10-22
- Publisher: SerpCrypto (https://serpcrypto.com)

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.

**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*

```python
"""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."
```

## How do I let an agent decide when to search?

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*

```python
"""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*

```python
"""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](https://serpcrypto.com/docs/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.

---

SerpCrypto: SerpCrypto is a SERP API for developers and AI agents that returns Google and Bing results as JSON, paid in crypto with no ID upload. Prepaid search credits from $0.30/1K searches never expire. No KYC — no ID, no selfie, no documents. Pay in crypto.
