LangChain Agent: Search the Web, Then Read the Page (Python)
Update, November 10, 2026. If you want hits and their page text in one payment instead of a search then extract loop, the direct API now has Search + Read at $0.015 (versus $0.029 a la carte). The two-step pattern in this post is still the right choice when you search free and only read one or two URLs.
Update Nov 9, 2026: paid calls now default to AgentSearch's direct x402 API on Base: search $0.008, extract $0.007, render $0.010 per call, settled only on success. The MCP server (1.6.0+), langchain-agentsearch (0.5.0+), n8n-nodes-agentsearch (0.5.0+), and crewai-agentsearch, llama-index-tools-agentsearch, openai-agents-agentsearch and @agentsearchhq/langchain (0.3.0+) use it by default with a wallet key; set
AGENTSEARCH_PAYMENT_ROUTE=pocketto keep the legacy Pocket Network route at $0.005 per call. Where this post quotes $0.005 or portal URLs, that is the Pocket route. Free search is unchanged.
A search result is a title, a URL and a two-line snippet. That's enough to pick a source, but not to answer from it. When your LangChain agent needs the actual changelog, pricing table or docs section, it has to read the page, not just find it.
This guide builds that loop in Python with one package, langchain-agentsearch:
- Search for candidate URLs. Free, no API key.
- Extract the best one or two results as clean markdown. $0.007 per page.
- Render a page in a headless browser only when Extract comes back thin, for JavaScript-heavy sites. $0.010 per call.
pip install -U langchain-agentsearch langchain langchain-openai
What we checked: langchain-agentsearch 0.2.0 and 0.2.1 (released November 9, 2026) with langchain 1.4.9 and langchain-core 1.7.6. We ran a live free search, the no-wallet Extract and Render messages, and the full create_agent loop with a scripted model (search, then extract). We also installed the [paid] extra (x402 2.27.0), and on 0.2.1 from PyPI checked that search stays on the free relay with a wallet key set. We didn't run a funded Extract from this package for this post.
Only need search? Start with how to add web search to a LangChain agent. Using LangGraph? See web search in a LangGraph agent.
Why snippets aren't enough
Ask an agent with search only "What changed in the latest LangChain release?" and it does the best it can with snippets: a sentence from the release page, a sentence from a blog that summarized it. Answers like that are vague, and the details are often wrong.
Splitting the work into separate tools fixes it, and keeps the cost visible:
| Step | Tool | Input | Returns | Cost |
|---|---|---|---|---|
| Find | agentsearch_search | a query | up to 5 results: title, url, content | Free (up to 25 searches/day per IP) |
| Read | agentsearch_extract | a URL | title, markdown or text, links, meta | $0.007 per call |
| Read JS pages | agentsearch_render | a URL | rendered markdown, text, HTML, links | $0.010 per call |
The model decides which URL is worth reading. You decide how much it may spend.
Step 1: free search, no key
from langchain_agentsearch import AgentSearchTool
search = AgentSearchTool(mode="free")
print(search.invoke({"query": "LangChain create_agent docs", "max_results": 3}))
The tool returns a JSON string. Trimmed, from our run:
{"query": "LangChain create_agent docs", "result_count": 3,
"results": [{"title": "Agents - Docs by LangChain",
"url": "https://docs.langchain.com/oss/python/langchain/agents",
"content": "create_agent is a highly configurable harness. ...",
"domain": "docs.langchain.com"}]}
Free search uses the AgentSearch relay: up to 25 searches per day per IP, subject to shared daily capacity, up to 5 results per search. No account, API key or wallet.
Step 2: the search-then-read agent
Give the agent all three tools and tell it when to use each one. The prompt matters more than the code here: it stops the model from extracting all five results when one or two will do.
# agent.py
from langchain.agents import create_agent
from langchain_agentsearch import AgentSearchTool, AgentSearchExtractTool, AgentSearchRenderTool
tools = [
AgentSearchTool(mode="free"), # search stays free, even after you add a wallet
AgentSearchExtractTool(), # read a URL as markdown
AgentSearchRenderTool(), # only for JavaScript-heavy pages
]
SYSTEM = """You answer questions from the live web.
1. Call agentsearch_search first to find candidate URLs.
2. Pick at most 2 results that look authoritative and call agentsearch_extract on them
with max_chars=8000. Do not extract every result.
3. If extract returns empty or very short content, call agentsearch_render on that URL once.
4. Answer from the page text and cite every URL you used.
5. If a tool returns an error, say what you could not read and answer from what you have."""
agent = create_agent(model="openai:gpt-4.1-mini", tools=tools, system_prompt=SYSTEM)
res = agent.invoke({"messages": [{"role": "user",
"content": "What changed in the latest LangChain release? Cite URLs."}]})
print(res["messages"][-1].content)
Any chat model with tool calling works. openai: needs OPENAI_API_KEY for the model; the AgentSearch tools need no key.
What happens before you add a wallet
Run it as-is and the loop already works: search is free, and Extract answers with a clear message instead of failing:
Error: agentsearch_extract is paid ($0.007 per call in USDC on Base via x402).
No wallet is configured, so no call was made. ...
Tools return "Error: ..." strings rather than raising, so the agent keeps going and answers from snippets, which rule 5 of the prompt covers. That lets you ship search now and switch reading on later without changing code.
Step 3: switch on page reading ($1 covers about 140 pages)
Extract and Render are paid per call over x402: the tool gets an HTTP 402 with the price, signs a USDC payment on Base from a wallet you give it, and retries. There's no account, subscription or API key, and no ETH needed for gas.
- Create a new wallet just for the agent. Any EVM wallet works. Don't reuse a wallet that holds anything else: treat it like a prepaid card.
- Put a little USDC on Base in it. $1 is plenty to start: at $0.007 per call that's about 140 page reads.
- Install the paid extra and set the key:
pip install -U "langchain-agentsearch[paid]"
export AGENTSEARCH_WALLET_PRIVATE_KEY=0x... # the new wallet's key
export AGENTSEARCH_MAX_TOTAL_ATOMIC=200000 # optional: $0.20 cap for this process
Run the same agent.py. Extract now returns the page as markdown, and each paid result includes a payment object with the amount and transaction.
Keep search free. From
langchain-agentsearch0.2.1, a wallet key alone keeps search free and only switches on page reads. In 0.2.0,AgentSearchTool()with nomodewent paid as soon as a key was set, so the example passesmode="free", which keeps search free in every version. Usemode="paid"only if you want search with no daily cap at $0.008 per call.
Spending limits, checked before anything is signed:
| Env var | Default | What it does |
|---|---|---|
| AGENTSEARCH_MAX_TOTAL_ATOMIC | 1000000 ($1.00) | Total spend per process, in USDC atomic units |
| AGENTSEARCH_MAX_PER_CALL_ATOMIC | 10000 ($0.010) on the direct route, 5000 on Pocket | Per-call ceiling; can only be lowered |
| AGENTSEARCH_TIMEOUT_MS | 30000 | Request timeout |
The key is only used to sign. It isn't included in tool output or error messages.
Step 4: JavaScript pages, Render only when needed
Extract is a fast HTTP fetch. It reads articles, docs and server-rendered pages well, but a single-page app can come back as an empty shell. You have two options:
- Let the model decide, as in the prompt above: if Extract looks thin, call
agentsearch_renderon the same URL. - Do it automatically: pass
render_fallback=Trueto the extract call, or setAGENTSEARCH_EXTRACT_RENDER_FALLBACK=1. When Extract returns under 200 characters of text, the tool renders the same URL and adds arender_fallbackobject to the result. That's a second call ($0.010).
from langchain_agentsearch import AgentSearchExtractTool
read = AgentSearchExtractTool()
print(read.invoke({"url": "https://example.com/app", "max_chars": 8000, "render_fallback": True}))
Render runs the page in headless Chromium, with a ~4.2 s render deadline. It also accepts wait_until, wait_for_selector and wait_ms for pages that load content late. More in reading JavaScript pages from an AI agent.
What a question costs
| Run | Calls | Cost | |---|---|---| | Search only | 1 search | $0 | | Search, then read 2 pages | 1 search + 2 extracts | $0.01 | | Same, one page needed Render | 1 search + 2 extracts + 1 render | $0.015 | | 20 questions like that a day | ~40–60 paid calls | about $0.20–$0.30 |
Non-2xx answers (bad input, rate limits, server errors) aren't charged. A delivered answer is charged even when the target site itself failed, and the result then carries an error object. The full table is on the pricing page.
When the free search limit hits
Past the free limit, the relay answers HTTP 429 and agentsearch_search returns an Error: string that says so. It resets daily. If your agent needs more searches than that, use AgentSearchTool(mode="paid") with the same wallet: $0.008 per search with no daily cap.
FAQ
Does langchain-agentsearch need an API key?
No. Search works with no key, account or wallet (up to 25 searches per day per IP). Extract and Render need a wallet key with a little USDC on Base, not an API key.
How much does it cost to read a web page from a LangChain agent?
$0.007 per Extract call, in USDC on Base via native x402 (langchain-agentsearch 0.5.0+). Rendering a JavaScript-heavy page is another $0.010. $1 covers about 140 extracts.
Will adding a wallet make my searches paid?
No, from langchain-agentsearch 0.2.1: a wallet key enables Extract and Render, and search stays free unless you pass mode="paid" or set AGENTSEARCH_MODE=paid. In 0.2.0 a key switched the default search tool to paid; AgentSearchTool(mode="free") keeps search free in every version.
What happens if the agent calls Extract without a wallet?
No request is made and nothing is charged. The tool returns an "Error: ..." string explaining how to enable it, and the agent can carry on with search snippets.
When should the agent use Render instead of Extract?
Use Extract first: it's faster and handles articles, docs and server-rendered pages. Use Render when Extract returns empty or very short content, which usually means a JavaScript app, or set render_fallback=True to do it automatically.
Does this work with LangGraph?
Yes. The tools are standard LangChain tools, so you can pass them to langgraph.prebuilt.create_react_agent or to your own ToolNode.
Is there a LangChain.js version?
Yes: npm install @agentsearchhq/langchain gives the same three tools for LangChain.js, and search stays free there unless you opt in to paid search.
More from the blog
- How to Add Web Search to a LangChain Agent in Python (No API Key)
- How to Read JavaScript-Rendered Pages from an AI Agent (When Extract Comes Back Empty)
- Search → Extract → Render: Three Web Tools for AI Agents, Not One Browse
Service pages: Web Search API · Web Extract API · Web Render API