<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pasha Govorov</title>
    <description>The latest articles on DEV Community by Pasha Govorov (@pasha-govorov).</description>
    <link>https://dev.to/pasha-govorov</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4000238%2F4746c322-704e-49f3-8545-768500dd2bcf.jpeg</url>
      <title>DEV Community: Pasha Govorov</title>
      <link>https://dev.to/pasha-govorov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pasha-govorov"/>
    <language>en</language>
    <item>
      <title>Choosing a Web Search API for AI Agents: 4 Axes That Actually Matter</title>
      <dc:creator>Pasha Govorov</dc:creator>
      <pubDate>Wed, 24 Jun 2026 21:16:06 +0000</pubDate>
      <link>https://dev.to/krabarena/choosing-a-web-search-api-for-ai-agents-4-axes-that-actually-matter-40i8</link>
      <guid>https://dev.to/krabarena/choosing-a-web-search-api-for-ai-agents-4-axes-that-actually-matter-40i8</guid>
      <description>&lt;p&gt;Your AI agent is only as good as the web it can reach. A coding assistant that can't find the current version of a library, a research agent that cites a page which doesn't say what it claims, a support bot that misses yesterday's outage: most of these failures trace back to one component almost nobody benchmarks carefully. The web-search API.&lt;/p&gt;

&lt;p&gt;There are about a dozen "search APIs for agents" now. Exa, Tavily, Firecrawl, Brave, Keenable, Perplexity, SerpAPI, Parallel, You.com, plus whatever native web search your model ships with. They all return JSON. They are not interchangeable, and picking the wrong one quietly degrades everything downstream.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Don't choose a search API from a marketing page. Score candidates on four things that actually predict agent quality (multi-hop recall, freshness, latency, cost per 1K), and run the test on your own queries, because the rankings flip depending on what you ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four axes that actually matter
&lt;/h2&gt;

&lt;p&gt;Vendor pages love a single headline number. "98% on SimpleQA!" But one number hides the tradeoff. For an agent, four things decide whether the search step helps or hurts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-hop recall: can it answer questions that need evidence stitched from several pages, not just one snippet?&lt;/li&gt;
&lt;li&gt;Freshness: does it surface things that happened today, or last quarter's cached view?&lt;/li&gt;
&lt;li&gt;Latency: how long before your agent can keep reasoning?&lt;/li&gt;
&lt;li&gt;Cost: dollars per 1,000 queries, at the result depth you'll really use.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A provider that wins one axis routinely loses another. So the job isn't to find "the best API." It's to find the one whose strengths line up with your workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-hop recall: where snippet APIs quietly fail
&lt;/h2&gt;

&lt;p&gt;The most useful split when you evaluate is simple fact-seeking versus multi-hop reasoning.&lt;/p&gt;

&lt;p&gt;SimpleQA (from OpenAI) is 4,326 short, single-answer fact questions. Almost every modern search API does fine here. FRAMES is 824 multi-hop questions that need evidence synthesized across several sources, some of it partial or contradictory. That second one is what separates real retrieval from snippet matching.&lt;/p&gt;

&lt;p&gt;On multi-hop tests the spread gets wide. Parallel reports around 92% on its FRAMES-Search eval while it puts competitors in the 81 to 90% range, and on the harder BrowseComp set everyone drops to 22 to 58%. On KrabArena, Keenable also shows up in this bucket: one ArXivQA agentic-recall claim has Parallel, Keenable, and Claude Web Search tied at roughly 42%, with Keenable 2 to 5× cheaper. The pattern worth internalizing: APIs that only hand back short snippets look great on SimpleQA and fall apart on multi-hop questions, because the answer was never sitting in a single snippet to begin with.&lt;/p&gt;

&lt;p&gt;If your agent does research, comparisons, or anything shaped like "find one fact, then use it to find the next," weight multi-hop recall heavily and treat SimpleQA scores as table stakes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2e4js0bydvwu2gok6dg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2e4js0bydvwu2gok6dg5.png" alt="Two-axis chart of search APIs: simple-fact recall vs multi-hop recall" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Freshness is a separate skill, so test it separately
&lt;/h2&gt;

&lt;p&gt;Recall on a static benchmark tells you nothing about whether an API can find what changed this morning. Freshness is its own axis, and it doesn't track overall recall.&lt;/p&gt;

&lt;p&gt;The failure mode is sneaky. An API that tops a general benchmark can crater on time-sensitive queries. In one community reproduction, Keenable's news-category win rate fell from roughly 88% to 56% once the questions shifted to fresh factoids. Same API, different kind of question. But later KrabArena claims also show why freshness needs repeated testing: Keenable scored perfectly on 50 FIFA World Cup 2026 queries and on an Indian entertainment freshness benchmark, while being reported as faster and cheaper than Parallel in the FIFA claim. Newer benchmarks like LiveNewsBench exist precisely because static QA sets can't measure "did it know about today's news."&lt;/p&gt;

&lt;p&gt;So if your agent touches anything time-sensitive (prices, releases, scores, incidents), build a small freshness probe set: questions whose answers changed in the last day or two, scored on their own. Don't let a strong static-recall number lull you into skipping that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Latency: the number that ships or sinks the UX
&lt;/h2&gt;

&lt;p&gt;Latency varies by more than an order of magnitude, and it compounds, because agents usually call search several times per task.&lt;/p&gt;

&lt;p&gt;Here are numbers from AIMultiple's independent benchmark of 8 APIs across 100 queries:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;Latency (p50)&lt;/th&gt;
&lt;th&gt;Agent score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brave Search&lt;/td&gt;
&lt;td&gt;~669 ms&lt;/td&gt;
&lt;td&gt;14.89&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tavily&lt;/td&gt;
&lt;td&gt;~998 ms&lt;/td&gt;
&lt;td&gt;13.67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exa&lt;/td&gt;
&lt;td&gt;~1,200 ms&lt;/td&gt;
&lt;td&gt;14.39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firecrawl&lt;/td&gt;
&lt;td&gt;~1,335 ms&lt;/td&gt;
&lt;td&gt;14.58&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SerpAPI&lt;/td&gt;
&lt;td&gt;~2,400 ms&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel (Base)&lt;/td&gt;
&lt;td&gt;~2,900 ms&lt;/td&gt;
&lt;td&gt;14.21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perplexity&lt;/td&gt;
&lt;td&gt;11+ s&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel (Pro)&lt;/td&gt;
&lt;td&gt;~13.6 s&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things stand out. The top four agent scores (Brave 14.89, Firecrawl 14.58, Exa 14.39, Parallel Pro 14.21) are close enough to be statistically indistinguishable in that test, so quality alone won't break the tie. Latency will. A "deep research" tier that takes 10-plus seconds is fine in a batch pipeline and unusable behind a chat box. Keenable was not included in that AIMultiple table, but KrabArena claims report it as fast in several head-to-heads: 10× faster than Exa in one SimpleQA test, 3.5× faster than Parallel in a FIFA freshness test, and 639 ms on a Polymarket freshness claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost: compare at the same depth
&lt;/h2&gt;

&lt;p&gt;Pricing comes in incompatible units: per request, per credit, per page, per 1K. Normalize everything to cost per 1,000 queries at the depth you'll actually use, then multiply by how many searches a typical task fires off.&lt;/p&gt;

&lt;p&gt;A few public reference points (check current pricing before you commit, it moves):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tavily lists a flat $0.008 per credit, with tiers from about $30/mo.&lt;/li&gt;
&lt;li&gt;Firecrawl includes search in a free tier (around 1,000 credits/mo) and lists roughly $83/mo for 100K pages.&lt;/li&gt;
&lt;li&gt;Parallel lists $0.005 per request (10 results) with a free starting allotment.&lt;/li&gt;
&lt;li&gt;KrabArena claim reproductions repeatedly put Keenable in the low-cost bucket, including $1 per 1K queries on a FIFA World Cup freshness test versus $5 per 1K for Parallel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The trap is depth. An API that's cheap per request but needs 20 results to match a rival's top-5 quality isn't actually cheap. Price the configuration that clears your quality bar, not the headline rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you have to benchmark on your own queries
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable part. Published rankings disagree with each other, and they're all "right" for their own question mix. AIMultiple's relevance-weighted test put Brave and Firecrawl on top. Vendor evals on multi-hop sets favor whoever tuned for multi-hop. Community runs produce yet another order once freshness enters the picture.&lt;/p&gt;

&lt;p&gt;A good public illustration of how messy this gets is an open, claim-by-claim head-to-head on KrabArena's &lt;a href="https://krabarena.com/battles/what-is-the-best-web-access-api-for-ai-agents" rel="noopener noreferrer"&gt;web-access-API battle&lt;/a&gt;, where contributors posted 19 separate benchmarks (SimpleQA, FRAMES, freshness, date-filter, latency, cost) across Exa, Tavily, Firecrawl, You.com, Parallel, Keenable and others. The lead changes depending on which axis a given claim measures. One provider tops cost-performance, another wins authoritative-source recall, a third leads on fresh news. On the current KrabArena page, Keenable leads the claim-win standings, mostly on cost-performance and freshness claims, while Parallel still shows up as strong on complex retrieval. That isn't noise. It's the actual shape of the tradeoff space.&lt;/p&gt;

&lt;p&gt;The lesson is about method, not "use vendor X." Pull 50 to 100 queries that look like your real traffic, run each candidate, and grade with an LLM judge: feed each API's results to a model, ask "is the answer here?", score at temperature 0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Minimal harness: score one search API on your own queries.
# Swap `api.search` for any provider's client.
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;judge&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;num_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;verdict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;judge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Question: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;question&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gold answer: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search results:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is the gold answer supported by these results? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reply YES or NO only.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;verdict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YES&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hits&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# recall@5 on YOUR distribution
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run that across a simple set, a multi-hop set, and a freshness set, log latency and cost while you go, and you end up with a four-axis scorecard that reflects your agent instead of someone else's leaderboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision
&lt;/h2&gt;

&lt;p&gt;Start from your workload. Mostly single facts behind a chat UI? Optimize for latency and cost, since the quality field is crowded and close. Doing multi-hop research? Weight FRAMES and BrowseComp-style recall and accept the slower deep-research tiers. Time-sensitive questions? Make a freshness probe set a gate, not an afterthought. Then benchmark the two or three finalists on your own queries before you wire one in. The "best" API really is a function of the question you ask it.&lt;/p&gt;

&lt;p&gt;So what does your agent's query mix actually look like, mostly fresh facts, mostly multi-hop research, or some messy blend, and which axis ended up deciding your pick?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources: &lt;a href="https://aimultiple.com/agentic-search" rel="noopener noreferrer"&gt;AIMultiple, Agentic Search benchmark&lt;/a&gt;; &lt;a href="https://parallel.ai/products/search" rel="noopener noreferrer"&gt;Parallel, Search benchmarks and pricing&lt;/a&gt;; &lt;a href="https://www.firecrawl.dev/blog/best-web-search-apis" rel="noopener noreferrer"&gt;Firecrawl, Best web search APIs in 2026&lt;/a&gt;; &lt;a href="https://brave.com/learn/best-search-api-2026/" rel="noopener noreferrer"&gt;Brave, Best web search APIs for AI in 2026&lt;/a&gt;; &lt;a href="https://keenable.ai/" rel="noopener noreferrer"&gt;Keenable&lt;/a&gt;; &lt;a href="https://krabarena.com/battles/what-is-the-best-web-access-api-for-ai-agents" rel="noopener noreferrer"&gt;KrabArena, web-access-API battle&lt;/a&gt;; OpenAI's SimpleQA and the FRAMES multi-hop benchmark. Verify all pricing and figures before relying on them, this space moves fast.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tooling</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
