Blog

Add Live Web Search to a LangChain Agent

By Kartey R

Founder of Serpex

Updated 7 min read
Technology

Wrap the serpex Python SDK in a LangChain @tool, hand that tool to create_agent, and your agent can run a live web search whenever it decides it needs one. Turn on include_content in the same tool and you also get each result's page back as markdown, so a second fetch step disappears. Below is the whole pattern: install, tool, agent, and a RAG-ready variant that returns page content instead of just snippets.

A lot of agents need two calls to get anything useful from the web: one to search, one to go fetch the pages that looked promising. It's not hard, it's just extra code and an extra round trip your agent has to reason through. Folding both into one tool call removes a whole class of glue code, and that's the version we're showing here. Serpex, a web search API built for AI agents, does both in one call: up to 10 results plus the top pages as Markdown, with 200 free credits to start and no card.

What do you need before you start?

  • Python 3.10+ (current LangChain needs it)
  • pip install serpex langchain
  • A Serpex API key from app.serpex.dev. New accounts get 200 free credits, no card required.
  • The key stored in an environment variable, SERPEX_API_KEY, never hardcoded in the script.

How do you wrap Serpex as a LangChain tool?

The serpex package exports SerpexClient. Its search() method takes a dict (or a SearchParams object) and returns a SearchResponse with a results list and a metadata object. Each SearchResult has title, url, snippet, position, and engine.

python
import os
from langchain.tools import tool
from serpex import SerpexClient
client = SerpexClient(os.environ["SERPEX_API_KEY"])
@tool
def web_search(query: str) -> str:
"""Search the live web and return titles, URLs, and snippets for a query."""
response = client.search({"q": query})
if not response.results:
return "No results found."
lines = [f"{r.title}\n{r.url}\n{r.snippet}" for r in response.results]
return "\n\n".join(lines)

The docstring on web_search is doing real work here. LangChain reads it as the tool's description, and it's how the model decides when to reach for it. Keep it plain and specific.

How do you plug the tool into an agent?

create_agent from langchain.agents is the current way to build a tool-calling agent in LangChain. Give it a model, a list of tools, and a system prompt.

python
from langchain.agents import create_agent
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[web_search],
system_prompt=(
"You are a research assistant. Use web_search whenever the user "
"asks about something current or something you're not sure about."
),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "What changed in the latest LangGraph release?"}]}
)
print(result["messages"][-1].content)

That's the whole loop. The agent decides whether to call web_search, gets the results back as a tool message, and folds them into its answer. No manual routing, no separate "did the model ask for a tool" check.

How do you get page content back for RAG?

Plain search gives you snippets, which are fine for a quick answer but thin for anything that needs grounding. Set include_content on the same search() call and Serpex fetches the page for each top result and returns it as markdown in that result's content field. A result that couldn't be fetched carries content_error instead (content and content_error never both appear on the same result). This is best-effort: content comes back for roughly 70% of the results you ask for, so plan for a few misses.

python
import os
from langchain.tools import tool
from serpex import SerpexClient
client = SerpexClient(os.environ["SERPEX_API_KEY"])
@tool
def web_search_with_content(query: str) -> str:
"""Search the live web and return page content as markdown for the top
results, ready to chunk and pass to a retriever."""
response = client.search(
{
"q": query,
"include_content": True,
"content_results": 5,
}
)
chunks = []
for r in response.results:
if r.content:
chunks.append(f"# {r.title}\n{r.url}\n\n{r.content}")
elif r.content_error:
chunks.append(f"# {r.title}\n{r.url}\n(content unavailable: {r.content_error})")
return "\n\n---\n\n".join(chunks)

Swap this tool in for web_search in the create_agent call above and the agent now has full page text to reason over, not just a one-line snippet. That's the shape you want for RAG: chunk the returned markdown per result and index it, or hand it straight to the model if the query is narrow enough.

What does this cost per call?

A plain search is 1 credit. With include_content on, billing is based on how many pages actually came back, not how many you asked for: 3 credits when 1 to 5 pages are delivered, 6 credits when 6 to 10 are delivered, and if content delivery fails for every result in the request you're only charged the plain-search rate of 1 credit. Your own organization repeating the same query within about 5 minutes costs 0 credits either way. Full breakdown is in the Search API reference.

FAQ

Does this replace LangGraph entirely? No. create_agent is built on LangGraph under the hood, so you're still getting a graph-based agent loop, just without hand-wiring the nodes yourself.

Can I use the same tool with a different agent framework? Yes. SerpexClient and the tool function have nothing LangChain-specific in them beyond the @tool decorator, so the same client.search() call works in any Python agent setup.

What if a page fails to fetch? You get content_error on that result instead of content, with a reason like blocked, timeout, or robots_disallowed. The result still has its title, URL, and snippet, and a failed fetch alone is never billed.

Do I need to handle GET versus POST myself? No. SerpexClient.search() sends the request for you; you just pass a dict or a SearchParams object.

Try Serpex

Get an API key and you'll have 200 free credits to wire this up yourself, no card needed. The docs have the full install and setup steps in the quickstart, and pricing lists the pay-as-you-go rates, with credits that never expire.

Serpex Blog

Related Articles

More content you might be interested in

Oct 24, 2026 · 8 min read

Vibe Coding Web Search: Add a Search API With Cursor, Claude Code or Lovable

Add web search to an app you build with AI, no coding needed: get a key, give your agent the docs, keep the key server-side. Cursor, Claude Code, Lovable.

Technology
Read More
Oct 24, 2026 · 14 min read

Search APIs for Enterprise AI (2026): Security, Rate Limits and Cost at Scale

Questions to ask before signing a search API contract for enterprise AI: security, retention, SLAs, rate limits, billing, and cost at 1M-10M searches.

Technology
Read More
Oct 23, 2026 · 15 min read

PHP2Shell vs the Knowledge Cutoff: CVE-2026-109618, Tested Oct 2026

Only 3 of 36 top-3 search results for PHP2Shell came from the PHP project. We built a 91-line agent that checks CVE-2026-109618 against primary sources.

Technology
Read More
Oct 19, 2026 · 19 min read

Which Search API Is Cheapest at 100k, 1M and 10M Searches a Month? (Prices Checked October 2026)

Search API costs at 100k, 1M and 10M searches a month, checked Oct 23, 2026. Lowest list: $0.20/1k. Serpex: $0.50-$0.80, from $0.20 at 10M+.

Technology
Read More
Oct 19, 2026 · 8 min read

How to Add Web Search to an AI Workflow or RAG Pipeline (Python, 2026)

How to add web search to an AI workflow or RAG pipeline in Python (2026): one call returns pages as Markdown to chunk, rank and cite, with real monthly costs.

Technology
Read More
Oct 19, 2026 · 8 min read

Tavily Pricing in 2026: What 10k, 100k and 1M Searches Cost

Tavily pricing in 2026: $8 per 1,000 credits pay as you go, $5 on Growth. Monthly cost at 10k, 100k and 1M searches, advanced depth, Extract and alternatives.

Technology
Read More
Oct 19, 2026 · 8 min read

Serper vs Tavily (2026): Pricing, Output and Which to Use

Serper vs Tavily in 2026: Serper costs $0.30 to $1.00 per 1,000 searches, Tavily $5 to $8. Free tiers, output, page content, LangChain support and which to use.

Technology
Read More
Oct 19, 2026 · 8 min read

Google Custom Search API Is Closing: What to Use by January 1, 2027

The Google Custom Search JSON API is closed to new users and existing ones must move by January 1, 2027. Replacements and 2026 costs at 10k and 100k searches.

Technology
Read More
Oct 3, 2026 · 7 min read

Web Search in n8n: HTTP Request, AI Agent or Community Node

Add web search to an n8n workflow with the HTTP Request node, use it as an AI Agent tool with $fromAI(), or install the n8n-nodes-serpex community node.

Technology
Read More