AI 资讯
Presentation: Mitigating Geopolitical Risks with Local-First Software and atproto
Martin Kleppmann discusses the urgent need for technological sovereignty in modern infrastructure. Exploring the shifting landscape of global tech dependencies, he shares how engineering leaders can leverage multi-cloud architecture, de facto API standardization, the AT Protocol, and local-first development paradigms to reclaim user agency and build highly resilient systems. By Martin Kleppmann
AI 资讯
Give Your AI Agent Live Web Data with MCP
Key takeaways Give an AI agent live web data by connecting it to Crawlora's hosted MCP endpoint — it calls documented tools (search, maps, commerce, social, finance) and gets normalized JSON back, with no scraping code or proxies to run. MCP (Model Context Protocol) is an open standard: agents discover and call tools through one interface instead of a bespoke integration per data source. Connect over Streamable HTTP at https://mcp.crawlora.net/mcp with your API key — about three minutes in Claude, Cursor, Cline, Windsurf, or any MCP client. One connection exposes 319 tools across 33 platforms (393 REST endpoints underneath): Google/Bing/Brave search, Google Maps, Amazon, YouTube, TikTok, Yahoo Finance, CoinGecko, and more. You pay only on a successful (2xx) response — failed calls are free — and the free tier includes 2,000 credits a month with no card. Versus writing your own scrapers: no per-source glue code, normalized JSON instead of HTML, and proxy routing, rendering, and retries handled behind the endpoint. You can give an AI agent live web data by connecting it to a hosted MCP endpoint : your agent calls documented tools — search, maps, e-commerce, app stores, social, finance, and more — and gets back normalized JSON, with no scraping code to write or proxies to run. This guide explains what MCP is, what data you can pull, how to connect in about three minutes, and what a real tool call and its response look like. Most LLMs are frozen at their training cutoff and can't see the live web. The usual fix — writing a scraper per source, then maintaining proxies, headless browsers, and parsers — is exactly the work teams don't want to own. MCP plus a hosted data server removes it: the model gets a stable set of tools, and the fetching lives behind an endpoint. What is MCP, and why does it matter for agents? The Model Context Protocol (MCP) is an open standard that lets an AI agent call external tools through one consistent interface. Instead of wiring a bespoke int
AI 资讯
The Anti-Bot Detection Checklist I Use Before Every Scraping Project
The Anti-Bot Detection Checklist I Use Before Every Scraping Project Every scraping project I take on starts with this checklist. Not because I'm paranoid — but because I've learned the hard way that production scrapers fail silently. They return 200 OK with garbage data, or they get rate-limited so gradually you don't notice for days. This is the systematic approach I've refined over 50+ scraping projects. Pre-Scraping: Know Your Target 1. Identify the CDN and Protection Stack Before writing a single line of code, check what you're up against: # Check CDN and headers curl -I https://target-site.com # Look for these common protection headers: # X-Engine: akamai-html-protection # X-Served-By: DataDome # cf-ray: Cloudflare # X-Bot-Status: blocked Common protection platforms: Cloudflare → Look for cf-ray and __cfduid cookies DataDome → Look for datadome in headers or scripts PerimeterX → Look for _pxff cookies Akamai → Look for akamai-html-protection headers 2. Check Robots.txt Respectfully curl https://target-site.com/robots.txt | grep -v "^#" Don't take this as gospel — but it's a good signal. If they explicitly disallow your use case, that's a flag. 3. Map the Site's JavaScript Rendering Some sites are fully static (fast, easy). Others render everything with JavaScript (need Playwright/Puppeteer). Check: // Quick check - fetch raw HTML vs rendered content // If they differ significantly, you need JS rendering const https = require ( ' https ' ); const html = await fetch ( ' https://target.com ' ). then ( r => r . text ()); const hasAngularVueReact = /ng-app|vue|react|__NEXT_DATA__/i . test ( html ); console . log ( ' Needs JS rendering: ' , hasAngularVueReact ); Code-Time: Defensive Patterns 4. Rotate User Agents const USER_AGENTS = [ ' Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120 Safari ' , ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Edge/120 ' , ' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chro
AI 资讯
Multi-Model AI API Routing: Cut Costs Without Sacrificing Quality
Multi-Model AI API Routing: Cut Costs Without Sacrificing Quality Problem: You're building an AI-powered app, but relying on a single model (like GPT-4) for every request is burning through your budget. Simple tasks like summarization or classification don't need a heavyweight model, yet you're paying premium prices for them. Solution: Route requests intelligently to the cheapest model that can handle each task. This is multi-model AI API routing, and it can cut your costs by 60-80% while maintaining output quality. Prerequisites Python 3.8+ API keys for at least 2 AI providers (e.g., OpenAI, Anthropic, or NovaAPI) Basic understanding of async/await in Python Step 1: Define Your Routing Strategy First, create a routing configuration that maps task complexity to model tiers: # router_config.py ROUTING_CONFIG = { " simple " : { " models " : [ " nova-1-fast " , " gpt-3.5-turbo " ], " cost_per_token " : 0.0001 , " max_tokens " : 500 , " tasks " : [ " summarization " , " classification " , " entity_extraction " ] }, " medium " : { " models " : [ " nova-1-medium " , " gpt-4-mini " ], " cost_per_token " : 0.0005 , " max_tokens " : 2000 , " tasks " : [ " code_generation " , " translation " , " sentiment_analysis " ] }, " complex " : { " models " : [ " nova-1-pro " , " gpt-4 " ], " cost_per_token " : 0.002 , " max_tokens " : 4000 , " tasks " : [ " reasoning " , " creative_writing " , " complex_qa " ] } } Step 2: Build the Router Now implement the core routing logic with fallback capabilities: # ai_router.py import asyncio from typing import Dict , List , Optional import time class AIRouter : def __init__ ( self , config : Dict , api_keys : Dict [ str , str ]): self . config = config self . api_keys = api_keys self . metrics = { " cost " : 0 , " requests " : 0 , " failures " : 0 } async def route_request ( self , task : str , prompt : str ) -> str : """ Route request to appropriate model based on task complexity. """ tier = self . _classify_task ( task ) models = self . confi
AI 资讯
OpenAI-Compatible Gateway Control Plane Checklist
A lot of teams start their LLM stack with one model string in application code. That is fine for prototypes. It becomes painful once multiple products, customers, background jobs, and fallback paths all share the same AI budget. At that point, an OpenAI-compatible gateway should not just be a convenience proxy. It should become a control plane: the place where routing, quotas, cost attribution, keys, and failover are managed consistently. Here is the checklist I use when evaluating whether a gateway setup is production-ready. 1. Keep the SDK surface stable Your application should not need to know every provider-specific header, endpoint, or auth detail. A simple OpenAI-compatible client shape keeps provider changes out of the main code path: from openai import OpenAI import os client = OpenAI ( api_key = os . environ [ " AI_GATEWAY_API_KEY " ], base_url = os . environ . get ( " AI_GATEWAY_BASE_URL " ), ) The app should usually call a logical model or route. Provider-specific decisions should live in gateway configuration where they can be reviewed and changed safely. 2. Route by feature, not by vibes A global default model is easy to start with, but it hides important differences between workloads. A better routing table looks like this: Feature Default tier Fallback tier Budget sensitivity Classification low-cost fast model second low-cost model high Support summary low/mid model mid model high Customer chat mid/frontier model safe fallback medium Coding/analysis strongest reliable model reasoning model low/medium Background enrichment batch/cheap model skip/defer very high The goal is not always to use the cheapest model. The goal is to use the cheapest model that reliably clears the quality bar for that feature. 3. Enforce limits at the gateway boundary Do not rely only on scattered application code for cost control. A shared gateway should enforce: per-API-key quotas per-project or per-customer spend caps per-feature token limits provider and model allow-lists e
AI 资讯
Boosting Blog Post Visibility: Building an Automation System with the IndexNow API
I'm sure many of you have experienced the frustration of publishing a new blog post only to find it's not immediately visible in search engine results. I recently learned that search engines like Bing and Yandex offer a way to quickly notify them of new posts via the IndexNow API. So, I decided to integrate this feature into my blog. Attempts and Pitfalls Initially, I created helper functions in services/indexnow_service.py to call the IndexNow API when a post was published. I structured the code to use asyncio.create_task to send a ping asynchronously whenever the post status changed to 'published' in the BlogRepository.update_status method. # services/indexnow_service.py (partial) import asyncio import httpx async def ping_urls ( urls : list [ str ], api_key : str ): async with httpx . AsyncClient () as client : for url in urls : try : response = await client . post ( " https://api.indexnow.org/submit-url " , json = { " url " : url , " key " : api_key } ) response . raise_for_status () print ( f " Successfully pinged { url } " ) except httpx . HTTPStatusError as e : print ( f " Error pinging { url } : { e } " ) except Exception as e : print ( f " An unexpected error occurred for { url } : { e } " ) async def ping_blog_post ( post_url : str , api_key : str ): await ping_urls ([ post_url ], api_key ) # BlogRepository.update_status (partial) async def update_status ( self , post_id : int , new_status : str ): # ... existing logic ... if new_status == ' published ' and INDEXNOW_KEY : post = await self . get_post_by_id ( post_id ) # In reality, you'd get the URL from the post object asyncio . create_task ( ping_blog_post ( post . url , INDEXNOW_KEY )) # ... I also created an admin API endpoint to manually trigger pings. I set up the public/<KEY>.txt file and even configured middleware. But to my surprise, the pings just wouldn't go through, no matter what I tried. After about three hours of debugging, I discovered that the ownership verification file required by the In
AI 资讯
API Design as Value Imprinting
Every interface you create is a constraint on future behavior. Every abstraction emphasizes certain patterns and discourages others. You are not just building tools. You are shaping how people think about problems. I have been paying attention to how API design encodes values, not just technical decisions, but philosophical ones. What Your API Communicates Consider these design choices: Mutability vs Immutability. Do you encourage stateful modification or pure functions? This is not just about performance. It is a philosophy about side effects and reasoning. If your default is mutable state, you are telling users that local mutation is fine, that they can reason locally. If your default is immutability, you are telling them to think about data flow. Explicit vs Implicit. Do you make users specify parameters or infer from context? This trades convenience for transparency. I lean toward explicitness. Magic is convenient until you need to debug it. Fail Fast vs Fail Safe. Do you throw exceptions or return error codes? This encodes beliefs about who should handle errors and when. Fail-fast says "don't let bad state propagate." Fail-safe says "keep running if you can." Both are defensible, but they lead to very different code. My Design Values When I build libraries, I try to encode: Explicitness over magic. I would rather make users type more than hide behavior behind conventions they have to discover. Composition over inheritance. Small pieces that combine flexibly beat deep class hierarchies. Clarity over cleverness. Code should be obvious, not impressive. Safety by default. The easy path should be the safe path. Why This Matters Your API is a value statement. It says what you think is important, what you think is dangerous, and how you think about the problem domain. This is why I spend so long on interface design. The APIs we create shape future thought. They outlast the code that implements them, because the patterns they teach persist in the minds of the people wh
开发者
Why I started documenting everything I learn as a web developer
As a web developer, I've noticed that many beginners spend months watching tutorials but struggle when it's time to build something from scratch. That's one reason I started building WebCoDeveloper — a place where I can share practical web development knowledge, real coding examples, and solutions to problems I've faced while working on projects. My goal isn't to create another tutorial website. It's to build a resource that helps developers move from "I watched a video about it" to "I actually built it." I'm curious: What's the biggest challenge you faced while learning web development? Understanding JavaScript? React/Next.js concepts? Building projects? Finding quality learning resources? Getting your first developer job? I'd love to hear your experiences and learn what resources have helped you the most.
AI 资讯
Your Scraper Collected 50 Rows. There Were 4,000.
A scraper can pass every check you wrote and still be wrong about the one thing you actually care about: how much it collected. No exception. No 500. No broken row. Exit code 0, logs green, every field valid. And the set on disk is a quarter of what the site actually has. I have run scrapers in production enough times to stop trusting a green run on its own, and this is the failure that taught me to count. TL;DR A paginated source can serve fewer rows than it claims and never throw — page caps, hidden offset limits, infinite scroll that "ends" early. Your status check (200), schema check (valid row), and byte check (you got data) all pass. None of them counts records. The tell: declared total vs unique ids collected. Or, when there's no declared total, the page that quietly repeats an earlier page. Below is a 40-line probe you can run right now. On a source that caps at 1,500 of a declared 4,000, it returned VERDICT: INCOMPLETE (missing 2500 rows) . This is a completeness check, not a correctness check. Different layer, different bug. What actually goes wrong You write the loop everyone writes. Walk ?page=1 , ?page=2 , keep going until a page comes back empty. Stop. Save. Done. The source has other plans. It says it has 4,000 records — the count is right there in the envelope, or in a "Showing 4,000 results" line in the HTML. But it only ever hands out real data for the first 30 pages. Page 31 doesn't error. It doesn't return empty either. It returns page 1 again. Still HTTP 200. Still 50 valid rows. Your loop has no reason to stop, so it grinds on until its own page budget runs out, collects a pile of rows, and exits clean. You now have 5,000 rows in hand and feel great about it. Looks like plenty. The catch: only 1,500 are unique. The page cap fed you the same first page over and over, and those duplicates hid the shortfall behind a big-looking row count. That is the exact shape of "50 rows passed every check while 4,000 existed" — the scraper saw a lot of rows an
AI 资讯
How to Use Web Scraping Templates the Right Way (2026)
Most web scraping projects are not unique snowflakes. Track competitor prices. Enrich a list of leads. Audit a site for SEO. Pull training data for a model. It is the same handful of recipes, over and over. A web scraping template is one of those recipes, pre-wired: a ready-to-use JSON config that chains the right tools in the right order, so you copy it, point it at your targets, and run. CrawlForge ships 24 of them in the templates gallery . This guide is about using them well — not just copy-paste, but read, adapt, and cost them out before you scale. TL;DR: A CrawlForge template is a copy-paste JSON config that chains multiple MCP tools into one workflow (price monitoring, lead enrichment, SEO audits, market research, AI training data). There are 24 across 9 categories, each costing 3–19 credits per run. Run them from Claude/Cursor, the crawlforge CLI, or the REST API. Free tier = 1,000 credits, no credit card. Table of Contents What Is a Web Scraping Template? Templates Gallery vs the scrape_template Tool How to Use a Template the Right Way 8 Templates Worth Copying First The Other 16 Templates Customizing or Building Your Own FAQ What Is a Web Scraping Template? A template is a saved configuration that orchestrates two or three CrawlForge tools into one workflow with a business outcome attached. Instead of wiring search_web then scrape_structured then analyze_content yourself — and guessing every parameter — you copy a config that already does it. Each template in the gallery carries: A category — E-commerce, Research, Data Collection, Monitoring, AI & LLM, Sales, SEO, Content, or Advanced Scraping (nine in total). A difficulty — beginner, intermediate, or advanced. The tool chain it runs and a fixed credit cost per run (3–19 credits). A copy-paste JSON config with sensible default parameters. You run that config from any MCP client (Claude, Cursor, Windsurf), the crawlforge CLI, or the REST API. Same config, same shape of result. Templates Gallery vs the scrap
AI 资讯
FastAPI for AI Engineers - Part 3: Connecting to a database
In the previous article, we explored how to build our first CRUD API using FastAPI. While our API worked correctly, there was one major problem. We were storing data inside Python lists, which exist only in memory. If you've ever wondered how applications like Instagram, LinkedIn, or ChatGPT remember information even after a server restart, the answer is simple: databases. In this article, we'll solve the problem of in-memory storage by connecting our FastAPI application to SQLite using SQLAlchemy. If you haven't read the previous post, check it out: FastAPI for AI Engineers - Part 2: Building Your First CRUD API Ananya S Ananya S Ananya S Follow Jun 1 FastAPI for AI Engineers - Part 2: Building Your First CRUD API # ai # backend # fastapi # python 7 reactions Comments Add Comment 4 min read By the end of this article, you'll understand: Why in-memory storage is a problem What SQLite is What SQLAlchemy is How ORM works How to create database tables using Python classes How to perform CRUD operations using a real database The Problem with In-Memory Storage Previously, our application stored students inside a Python list. students = [ { " id " : 1 , " name " : " Ananya " , " department " : " CSE " , " cgpa " : 8.9 } ] This worked for learning CRUD operations. However, consider what happens when the server restarts: FastAPI Server Stops ↓ Python Memory Cleared ↓ All Student Data Lost This is unacceptable in real-world applications. We need a place where data can survive application restarts. This is where databases come in. What is SQLite? SQLite is a lightweight relational database. Unlike MySQL or PostgreSQL, SQLite doesn't require a separate database server. Instead, everything is stored inside a single file. students.db Advantages of SQLite: No installation required Lightweight Easy to learn Perfect for local development Great for small projects For this article, we'll use SQLite. What is SQLAlchemy? Before SQLAlchemy, developers often wrote raw SQL queries. Exampl
AI 资讯
Ideogram 4.0 is on 7 Platforms. Here's What It Actually Costs.
Ideogram 4.0 launched this week and within 48 hours it was available on seven platforms. That is unusual. Most model launches trickle onto one or two platforms over weeks. Ideogram went wide immediately, which suggests the open weights strategy is working as intended. Here is what you will pay depending on where you use it. fal.ai The cheapest API access. Turbo mode at three cents per megapixel. That is roughly three cents per 1K image. Balanced at six cents. Quality at ten cents. Pay-per-use, no minimums. If you are generating through an API, this is your starting point. Krea Included in all paid plans. Basic is $5.25 per month billed annually with 5,000 compute units. Pro is $21 per month with 20,000 CUs. The CU cost for Ideogram 4.0 specifically is not published yet, but Krea includes 150 plus models in their CU pool, so you are not paying extra for access. If you already use Krea for other models, Ideogram 4.0 is effectively free to try. ComfyUI Free if you have the GPU. The model is open weights at 9.3 billion parameters. Native ComfyUI support means you can download the weights and run it locally. No per-generation cost. No API calls. Just your electricity bill and GPU time. For volume generation or iteration, this is the cheapest path by far. Leonardo Announced as a day zero launch partner but the pricing page still lists Ideogram 3.0. Plans range from $12 to $60 per month with token allowances from 8,500 to 60,000. Third party models on Leonardo always consume tokens, no relaxed generation. Until they publish the 4.0 token cost, you are guessing. Assume it will be similar to their other premium models. Replicate The Ideogram 3.0 listing is live but 4.0 is not there yet. Replicate prices by hardware time rather than per-image, which can be cheaper or more expensive depending on your batch size and the GPU allocated. Worth checking when it lands. FLORA Available in FLORA. Pricing unclear. FLORA is primarily a creative platform, not an API provider, so you are
AI 资讯
What Is a SERP API and Why Do SEO and AI Teams Need One?
Search results look simple from the outside. You type a keyword into Google, Bing, or another search engine, and you get a page of links, snippets, ads, maps, news, images, videos, and sometimes AI-generated answers. But if you have ever tried to collect search results at scale, you know it gets messy quickly. A result page is not just a list of links. It changes by country, language, device, location, query intent, and search engine. The same keyword can show different rankings in New York, London, Singapore, or Berlin. A page may include organic results, paid ads, local packs, shopping results, People Also Ask, news results, images, videos, or other SERP features. For humans, that is just a search page. For SEO teams, AI teams, data teams, and developers, it is a data source. That is where a SERP API becomes useful. What is a SERP API? SERP stands for Search Engine Results Page . A SERP API is an API that lets you collect search engine results in a structured format, usually JSON and sometimes HTML. Instead of manually searching a keyword or building a scraper to parse search result pages, you send a request to a SERP API with parameters such as: keyword search engine country language location device type output format The API then returns structured search data. A simplified response might look like this: { "query" : "best project management software" , "organic_results" : [ { "position" : 1 , "title" : "Best Project Management Software Tools" , "link" : "https://example.com" , "snippet" : "Compare features, pricing, and reviews..." } ] } This is much easier to work with than raw HTML. You can store it in a database, send it to a dashboard, compare rankings over time, feed it into an AI workflow, or generate automated reports. Why not just scrape search results yourself? You can build your own scraper. For a small test, that may be enough. You can send a request, parse the HTML, extract titles and links, and save the data. The problem starts when the workflow bec
AI 资讯
How to test whether your web extraction API is lying to your agent
The dangerous part of web extraction is not the error. The dangerous part is a clean JSON response that looks correct and is not. If an AI agent uses that output, the mistake does not stay inside a scraper. It moves into a report, a lead list, a price alert, a CRM update, or an automated decision. So before you trust any web extraction API in an agent workflow, test whether it fails honestly. Here is the checklist I use. 1. Test a real page, not a demo page Demo pages are usually polite little museum exhibits. Use pages that behave like the actual internet: a JavaScript-heavy product page a search results page a page with missing fields a login-gated page a blocked or rate-limited page a thin page that has layout but little useful content If the tool only looks good on clean static pages, you have not learned much. 2. Check whether the API separates fetch success from extraction success A page can return HTTP 200 and still be useless. Common examples: the final page is a login screen the visible content is a bot challenge the useful data loads after hydration and never appeared in the fetch the page contains a generic country selector instead of the product the source has navigation text but no actual item data The extractor should not treat these as success just because the request completed. A better response says something like: { "status" : "failed" , "failure_type" : "login_required" , "extracted" : null , "next_step" : "Use a public URL, authorised access, or sample content." } That is boring. Boring is good here. Boring means the agent can stop safely. 3. Ask for fields that are not on the page This is the easiest lie detector. Ask the extractor for something impossible: Extract the product name, price, stock status, warranty length, CEO name, office address, and refund policy. If the page only contains product name and price, the API should say the other fields are missing or low confidence. It should not politely invent them because the schema asked nicely.
AI 资讯
OpenAI and Anthropic May Be Rivals, but Investors Aren’t Picking Sides
“Why wouldn’t you want to be in both Pepsi and Coke?” says one venture capitalist. “It’s the same here.”
AI 资讯
Introducing BulkSMSOnline: Global SMS API Built by a Small, Developer-First Team
We’re a tiny team of 2–9 engineers who believe business messaging should be simple, reliable, and accessible to everyone. Today we’re officially opening up BulkSMSOnline to the Dev.to community, and we’d love your feedback. What’s BulkSMSOnline? A global bulk SMS platform that lets you send campaigns, alerts, OTPs, and notifications via: A clean web portal A REST API An HTTP API It’s designed for developers who want reliable global delivery without fighting arcane telecom protocols or opaque pricing. Why We Built It We noticed a pattern: most SMS platforms either overcomplicate things with bloated SDKs or hide behind enterprise gatekeepers that don’t listen. We wanted something different a lean, transparent API backed by real people who actually care about your deliverability. So we built BulkSMSOnline around three principles: Reliability : Messages must arrive, every time. Radical simplicity : A clean API you can integrate in minutes. Transparency : Honest pricing, clear limits, no surprises. Quick Start: Send an SMS in Under 5 Minutes Here’s how simple it is with our REST API. For full docs, check out our developer portal . curl -X POST https://api.bulksmsonline.com/v1/sms \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+1234567890", "message": "Hello from BulkSMSOnline!", "sender": "MyApp" }' You’ll get a JSON response with a message ID and status. That’s it. No multi-page setup or carrier negotiations. What else can you do? Send bulk messages with a single API call Track delivery in real time via webhooks Pull reports programmatically Use our HTTP API for legacy systems Who’s Behind This? We’re a small, agile team (2–9 people). That means: No bureaucracy: Fixes and features ship fast. Direct access: When you email support, you reach the engineers who built the platform. Your feedback shapes our roadmap: Many of our recent features came from developer conversations. Tech stack we love: Python, Node.js, PostgreSQL, an
AI 资讯
AI API gateway fallback policy template for production apps
Fallback rules are where an AI API gateway becomes operationally valuable. The goal is not to blindly retry every failed LLM call. The goal is to choose the right backup model, provider, or budget path based on the workflow, customer tier, latency target, and risk of a lower-quality answer. A practical fallback policy should define: which failures are retryable; which workflows may downgrade models; which customers or API keys are allowed to use premium fallback routes; how budget caps change routing behavior; what metadata gets logged so the team can debug cost and quality later. 1. Classify traffic before routing Do not write one global fallback rule for every request. Start by classifying traffic: Critical user-facing : support chat, checkout assistance, customer-facing agent answers. Non-critical user-facing : summaries, title generation, enrichment, recommendations. Internal automation : triage, labeling, data cleanup, back-office agents. Batch jobs : long-running summarization, extraction, report generation. Experiments : tests, staging, evaluation, prompt tuning. Each class should have a different fallback budget and quality floor. 2. Decide what counts as a retryable failure Good retry candidates: upstream timeout; 429 rate limit; temporary 5xx provider error; network interruption; overloaded model endpoint; streaming connection drop before useful output. Poor retry candidates: invalid API key; malformed request payload; unsupported tool-call schema; content policy rejection; user quota exhausted; deterministic validation failure. Retrying non-retryable failures usually burns tokens and hides product bugs. 3. Example fallback policy matrix Traffic class Primary route First fallback Second fallback Hard stop Critical user-facing frontier model same-class model on second provider cheaper model with explicit uncertainty after 2 provider failures Non-critical user-facing balanced model cheaper model cached/default response after budget cap Internal automation lo
AI 资讯
Your memory, your data: read, edit, export, delete
Most AI memory features are a black box. The assistant remembers things about your users, but you...
AI 资讯
Cloudflare Turnstile in Playwright: Why Your Tests Stall and How to Solve It in 8 Lines
Cloudflare Turnstile in Playwright: Why Your Tests Stall and How to Solve It in 8 Lines If you're running Playwright or Selenium against any site behind Cloudflare, you've already met Turnstile. It's the new "managed challenge" widget Cloudflare started shipping in 2023, and it now appears in front of login flows, contact forms, signup pages, and increasingly the entire site root. Here's the part most teams miss: Turnstile doesn't always show a checkbox. A lot of the time it just sits invisible, runs its scoring loop, and either issues a token silently or stalls forever. Your test doesn't crash. It just times out at the next page.click("button[type=submit]") . The CI log says "element not interactable." Nobody knows why. I work on CaptchaAI. I'm going to show you exactly what's happening, then drop in 8 lines that fix it. The real scenario You have a Playwright suite that runs every PR. One day a test starts failing on the signup flow. You re-run it. It fails again. Locally on your laptop it passes. On CI it doesn't. What's actually happening: Cloudflare flagged your CI runner's IP block (GitHub Actions, GitLab runners, Hetzner, OVH, DO — all of them are on Cloudflare's "elevated risk" list). Turnstile decides to switch from invisible mode to "managed challenge" mode. Now there's a widget in the DOM that needs a real token before the form submit will accept. Your test never interacted with the widget because last week it didn't exist. Why retries don't help The instinct is to add a retry: 2 and move on. Don't. Cloudflare's scoring is per-IP-per-fingerprint, and each retry from the same runner makes the next challenge harder, not easier. After ~3 attempts you'll get full block pages instead of the widget. The right move is to solve the widget once, inject the token, and submit normally — exactly what a human user does, just faster. How Turnstile actually issues a token The widget renders an iframe pointing at challenges.cloudflare.com . Inside the iframe it runs a fi
AI 资讯
Alphabet’s record-breaking $85B raise for Google’s AI business is a helluva good signal
If Alphabet's record-breaking $85 billion stock sale signals investor appetite for AI-related offerings, we can see that investors are ready to chow.