●FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtask●LIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its own●MCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS●PLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callback●SONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15●IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October●FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtask●LIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its own●MCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS●PLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callback●SONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15●IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Building a Search-Augmented AI Assistant with Claude API: Web Search × Dynamic Filtering × Citations
Learn how to combine Claude API's Web Search Tool, Dynamic Filtering, and Citations API to build a production-grade search-augmented AI assistant that returns accurate, source-backed answers.
As large language model (LLM) adoption scales up in production systems, information freshness and answer accuracy remain the two most critical challenges. In March 2026, Anthropic promoted the Web Search Tool and Programmatic Tool Calling to general availability (GA) and introduced Dynamic Filtering — a powerful feature that uses code execution to filter search results before they enter the context window.
This guide covers how to combine Web Search Tool, Dynamic Filtering, and Citations API to build a search-augmented AI assistant that returns accurate, source-backed answers in production. We'll walk through architecture design, complete code implementation, cost optimization strategies, and resilient error handling patterns.
While traditional RAG (Retrieval-Augmented Generation) requires maintaining your own vector database, the Web Search Tool lets you use the entire internet as your knowledge base. By layering Dynamic Filtering on top, you eliminate noise from search results, optimize token consumption, and achieve higher-quality answers.
The search-augmented AI assistant architecture consists of three layers.
Search Layer (Web Search Tool): Executes real-time web searches based on user queries and collects relevant sources. The web_search_20260209 version supports domain filtering and user location settings.
Filtering Layer (Dynamic Filtering + Code Execution): Programmatically filters search results using a sandboxed code execution environment, removing irrelevant results before they consume context window tokens. This layer is the key to simultaneously improving both token efficiency and answer accuracy.
Answer Generation Layer (Citations API): Generates answers based on filtered information and automatically attaches source citations to each claim.
This design creates an end-to-end pipeline: user query → web search → dynamic filtering → cited answer generation.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦A design that cuts input tokens 40–60% with Dynamic Filtering while improving answer accuracy
✦An implementation that scores overall reliability from citation density, unique sources, and trusted-domain ratio
✦A multi-layer fallback that degrades from filtered search to basic search to model-only knowledge
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Web Search Tool Production Configuration — GA Version Parameter Reference
The Web Search Tool graduated from beta to general availability (GA) in March 2026, removing the need for beta headers. Here's how to configure it for maximum effectiveness in production.
Dynamic Filtering allows Claude to use a sandboxed code execution environment to programmatically filter search results. This removes noise before it enters the context window, achieving both token savings and improved answer accuracy simultaneously.
When Dynamic Filtering is enabled, Claude internally executes code in a sandbox environment to perform relevance scoring and deduplication of search results. Crucially, code execution is free when combined with Web Search — a significant cost advantage.
Domain Strategy Design
In production, your domain strategy should align with your use case.
Technical documentation search: Restrict to official documentation sites to eliminate outdated information and community misinformation.
News collection: Allowlist news sites while excluding social media and forums.
General search: Skip domain restrictions and let Dynamic Filtering assess result quality through code execution.
Dynamic Filtering in Practice — Maximizing Search Accuracy with Code Execution
Dynamic Filtering is one of the most powerful features of the Web Search Tool. Claude automatically executes code against search results to remove irrelevant items before they enter the context window.
How It Works
Claude executes a web search and retrieves multiple results
JavaScript/Python code is automatically executed in a sandbox
Each result is scored for relevance, reliability, and freshness
Low-scoring results are filtered out, keeping only top results
The answer is generated from filtered results only
Custom Filtering Logic
For more granular control, you can use Programmatic Tool Calling to customize filtering logic.
import Anthropic from "@anthropic-ai/sdk";const client = new Anthropic();async function advancedSearchWithFiltering(query: string) { // Step 1: Execute Web Search const searchResponse = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 4096, tools: [ { type: "web_search_20260209", name: "web_search", dynamic_filtering: { enabled: true }, }, ], messages: [ { role: "user", content: `Search for the latest information on: ${query}`, }, ], }); // Step 2: Extract source information from results const sources = extractSources(searchResponse); // Step 3: Apply custom filtering const filteredSources = sources.filter((source) => { // Prioritize articles from the last 24 hours const isRecent = Date.now() - new Date(source.publishedDate).getTime() < 24 * 60 * 60 * 1000; // Reliability score threshold const isReliable = source.reliabilityScore > 0.7; return isRecent || isReliable; }); // Step 4: Generate answer with filtered sources + Citations const finalResponse = await client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 8096, citations: { enabled: true }, messages: [ { role: "user", content: [ { type: "text", text: `Based on the following sources, answer "${query}". Always cite your sources.`, }, // Pass filtered sources as documents ...filteredSources.map((source) => ({ type: "document" as const, source: { type: "url" as const, url: source.url, }, title: source.title, })), ], }, ], }); return finalResponse;}// Source extraction helperfunction extractSources(response: Anthropic.Message) { const sources: Array<{ url: string; title: string; publishedDate: string; reliabilityScore: number; }> = []; for (const block of response.content) { if (block.type === "web_search_tool_result") { for (const result of block.content) { if (result.type === "web_search_result") { sources.push({ url: result.url, title: result.title, publishedDate: result.page_age || new Date().toISOString(), reliabilityScore: calculateReliability(result.url), }); } } } } return sources;}// Domain-based reliability scoringfunction calculateReliability(url: string): number { const trustedDomains: Record<string, number> = { "docs.anthropic.com": 1.0, "platform.claude.com": 1.0, "www.anthropic.com": 0.95, "github.com": 0.9, "developer.mozilla.org": 0.9, }; for (const [domain, score] of Object.entries(trustedDomains)) { if (url.includes(domain)) return score; } return 0.5; // Default score}
Measuring Filtering Effectiveness
To quantitatively assess Dynamic Filtering's impact, track these metrics.
// Filtering effectiveness metricsinterface FilteringMetrics { totalSearchResults: number; filteredResults: number; tokensBeforeFiltering: number; tokensAfterFiltering: number; filteringRatio: number; tokenSavings: number;}function measureFilteringEffect( before: number, after: number): FilteringMetrics { return { totalSearchResults: before, filteredResults: after, tokensBeforeFiltering: before * 500, // ~500 tokens per result tokensAfterFiltering: after * 500, filteringRatio: 1 - after / before, tokenSavings: 1 - after / before, };}// Expected results:// - Filtering ratio: 40-60% (removing over half of irrelevant results)// - Token savings: 40-60% (significant input token cost reduction)// - Answer accuracy: 15-25% improvement (less noise = less confusion)
Citations API Integration — Ensuring Trustworthy Answers with Source Attribution
The Citations feature structurally embeds source information into Claude's answers. It's a powerful tool against hallucination and essential for any search-augmented assistant.
Build an internal bot for development teams that returns accurate answers sourced exclusively from official documentation.
const techDocBot = new SearchAugmentedAssistant({ model: "claude-sonnet-4-6", systemPrompt: `You are a technical support bot for the development team.Always cite official documentation as your source.If the information is not found in official docs, say "Not found in official documentation."`, domainStrategy: "techDocs", reliabilityThreshold: 0.7,});// Usageconst answer = await techDocBot.answer( "How do I configure Extended Thinking in the Claude API?");// → Accurate answer based on official docs + source URLs
Use Case 2: Real-Time News Analysis
Collect and analyze the latest news into structured reports.
const newsAnalyst = new SearchAugmentedAssistant({ model: "claude-sonnet-4-6", systemPrompt: `You are an AI industry news analyst.Search for the latest news and create analysis reports in this format:1. Summary (3 lines max)2. Key takeaways3. Impact analysis4. Source list`, domainStrategy: "news", reliabilityThreshold: 0.5,});const report = await newsAnalyst.answer( "Analyze this week's latest Anthropic and Claude-related news");
What the Official Docs Don't Tell You — Notes From Actually Running This
Maintaining my own apps as an indie developer, I kept running into small questions — "is this still the current way to call the SDK?", "did last week's update change this behavior?" — and I'd bounce between the official docs and the release notes every time. The same friction showed up when I needed to check whether an AdMob SDK update had shifted anything on the app side. So I wired up the search-augmented assistant from this article as a tiny personal fact-checking bot and pointed it at exactly those questions. A few things surfaced that the docs never mention.
Dynamic Filtering's effectiveness depends heavily on how specific the question is. For a concrete question like "list the parameters of the Claude API web_search tool," the results surviving the filter dropped to well under half and input tokens fell noticeably. For a vague question like "recent trends in AI," the filter barely narrowed anything and the token savings were marginal. Filtering pays off most when the question gives it a clear basis for narrowing.
A single reliability threshold across every use case eventually breaks. For technical-doc lookups I set reliabilityThreshold high at 0.7 and only returned an answer when the citations leaned on official domains — false certainty dropped clearly. For news summaries, 0.7 triggered too many re-searches and stretched latency, so I lowered it to 0.5. Trying to cover every use case with one number always strains somewhere.
Multi-layer fallback earns its keep by degrading quietly. When search fails, instead of returning an error, answer from the model's own knowledge but add "this may not be current." That one line kept the bot trustworthy. What matters isn't never failing — it's how the system behaves when it's about to.
Summary
By combining Claude API's Web Search Tool, Dynamic Filtering, and Citations API, you can build a search-augmented AI assistant that returns accurate, source-backed answers — a critical capability for production AI applications. With GA availability bringing improved stability and free code execution for Dynamic Filtering, the barriers to production deployment have dropped significantly.
The key takeaways are: use Dynamic Filtering to reduce token consumption by 40–60% while improving search accuracy; leverage Citations API to structurally ensure answer trustworthiness; combine with Prompt Caching for additional cost savings; and implement multi-layer fallback strategies for production reliability.
Start from the minimal setup with dynamic_filtering and citations enabled, and measure what reliability scores your own common questions produce. Tune the threshold and domain strategy from those measured values — that turns out to be the shortest path. I hope this helps with your implementation, and thank you for reading.
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.