今日已更新 264 条资讯 | 累计 23847 条内容
关于我们

标签:#EV

找到 3436 篇相关文章

AI 资讯

Why most "PDF dark mode" Chrome extensions do nothing on a web PDF

Chrome still ships no dark mode for its built-in PDF viewer. Open a white paper at 1am and you get a flashbang. So you go to the Web Store, install the extension with the most installs, click it, and… nothing happens. The page stays white. I went and read the manifests of the top results to find out why. Two reasons, and both are boring. Reason 1: the popular ones only handle file:// The extension named "PDF Dark Mode" (about 10,000 users, rated 2.5) declares exactly this: "permissions" : [ "scripting" , "declarativeContent" ] , "host_permissions" : [ "file:///*.pdf" ] The runner-up, "PDF Dark Theme" (about 9,000 users, rated 2.9), does the same thing with a content script: "content_scripts" : [{ "matches" : [ "file://*.pdf" ], "js" : [ "content-script.js" ] }] file:///*.pdf matches a PDF you dragged in from your own disk. It does not match https://arxiv.org/pdf/1706.03762 , or the invoice your bank linked, or the syllabus on a course site. That is where almost everyone actually meets a PDF. So the extension is installed, enabled, and structurally incapable of touching the document in front of you. This is also why the reviews are full of people being told to flip "Allow access to file URLs" and reporting back that it changed nothing. It was never the missing piece. You can check any extension for this in ten seconds: chrome://extensions → Details → look at "Site access". If it says nothing beyond file URLs, that is your answer. Reason 2: the CSS target moved The other approach is a CSS filter on the viewer element: embed [ type = "application/x-google-chrome-pdf" ] { filter : invert ( 90% ) hue-rotate ( 180deg ); } That used to be right. When you navigate straight to a PDF today, the document you are styling has no <embed> in it. The viewer lives in an out-of-process child frame that your CSS cannot reach. Your selector matches zero elements and fails silently, which is the worst way for CSS to fail. What does reach it is a filter on the root element of the PDF doc

2026-07-25 原文 →
AI 资讯

I Built a 3D Game in Flutter — With No Game Engine

Everyone says the same thing: Flutter is for apps, not games. So I decided to find out where that's actually true — by building a 3D endless runner in Flutter. From scratch. No Unity, no Unreal, no game engine at all. Just Dart and Flutter's own rendering stack. It runs in your browser right now: ▶️ Play it live (desktop, keyboard controls — A / D to switch lanes, Space to jump). Here's how it works, and what building it taught me about how far Flutter can actually go. The stack: Flutter GPU + flutter_scene The whole thing sits on two pieces most Flutter developers have never touched: Flutter GPU — a low-level rendering API that talks almost directly to the GPU through Impeller (the engine that replaced Skia). This is what makes real-time 3D possible at all. flutter_scene — a higher-level 3D scene API on top of Flutter GPU. It gives you the building blocks a game needs: a scene graph of nodes , a perspective camera , meshes, and glTF model loading. You build a tree of nodes, point a camera at it, and render it every frame inside a normal Flutter widget. That last part still surprises me — the 3D world is just a CustomPaint -style surface living inside an otherwise ordinary Flutter app. Faking an infinite world with a handful of objects An "endless" runner obviously can't build an endless world — you'd run out of memory in seconds. The trick is object pooling : you keep a small pool of track segments and obstacles, and as they scroll past the camera behind the player, you recycle them back to the front with new positions. The player never actually moves forward. The world moves toward the player , and a fixed number of segments cycle forever. Same idea for obstacles and coins. It means the game runs at a constant, tiny memory footprint — which is exactly what keeps it smooth on weaker devices. The parts that were genuinely hard Collision that feels fair. Detecting a collision is easy. Making it feel right is not. Too strict and the player rages at hits that "clearly

2026-07-25 原文 →
AI 资讯

How We Built Precise Translation and Language Identification for AI Book Translation

How we tackled 精准翻译与语言识别 (precise translation and language identification) for AI-powered book translation. The Problem: Garbage In, Garbage Out When we first launched LectuLibre, our AI book translation service, we thought the hardest part would be fine-tuning LLM prompts for literary quality. But we quickly discovered a more fundamental hurdle: if the source language of an uploaded book is misidentified, no amount of prompt engineering can salvage the translation. Users upload EPUBs and PDFs from all over the world. Some contain metadata specifying the language, but many don't. Others are multilingual books, or have prefaces in a different language. Our initial language detection using Python's langdetect library was correct only about 85% of the time on real-world uploads. That 15% error rate meant entirely garbled translations, frustrated users, and wasted LLM API credits. We needed something far more robust—what we internally call 精准翻译与语言识别 (precise translation and language identification). Here’s how we built it. The Language Detection Pipeline: From 85% to 98% Accuracy Our first instinct was to try heavier models like fastText's pre-trained language identification model, which is known for high accuracy. But when we tested it on book excerpts, we hit a new problem: short paragraphs or dialogues in one language embedded in a book of another language (e.g., French phrases in an English novel) would throw off chunk-level detection. We realized that we needed a two-tier approach: book-level language detection with confidence scoring, and per-chunk verification before translation. Combining Multiple Detectors with Voting We created a LanguageDetector class that runs several detectors and picks the majority vote, with a fallback to user-specified language when available. The detectors we use are: fastText with the official lid.176.bin model (loaded once, not per request) langdetect , which is lightweight and good for long texts cld3 (Compact Language Detector 3) fr

2026-07-25 原文 →
AI 资讯

Stop Guessing Your Macros: Building an Autonomous AI Health Agent with AutoGen and HealthKit

We’ve all been there: you hit the gym three days in a row, hit your PRs, and feel like a Greek god. But by Thursday, you're exhausted because you forgot that "working out more" requires "eating more protein." In the era of AI Agents and LLMs, we shouldn't be manually tracking these gaps. We should be building autonomous systems that bridge the gap between our HealthKit data and our kitchen. In this tutorial, we are diving deep into the world of automated health management . We will use AutoGen to create a multi-agent swarm, LangGraph to manage complex state transitions, and Node-RED to bridge the gap between our code and the physical world (or at least our meal prep app). By the end of this, you’ll have a blueprint for an agent that monitors your fitness trends and proactively adjusts your life. The Architecture: Multi-Agent Synergy To make this work, we need more than just a simple script. We need a "Health Council." We'll deploy three distinct agents: The Data Analyst : Scrutinizes HealthKit API logs for trends. The Nutritionist : Specializes in macro-nutrient balance and dietary science. The Logistician : Executes the plan via Node-RED webhooks and Google Calendar. System Workflow graph TD A[HealthKit API] -->|Daily Logs| B(Health Monitor Agent) B -->|Trend Detected: High Activity/Low Protein| C{Nutritionist Agent} C -->|Calculates New Macros| D(Logistician Agent) D -->|Webhook Trigger| E[Node-RED Flow] E -->|Update| F[Meal Prep App / Calendar] E -->|Send| G[Notification/Email] F -.->|Feedback Loop| B Prerequisites Before we start coding, ensure you have the following in your toolkit: Python 3.10+ AutoGen : pip install pyautogen LangGraph : For stateful orchestration. Node-RED : Running locally or on a server to handle the Webhooks. OpenAI API Key : (Preferably GPT-4o for complex reasoning). Step 1: Defining the Agent Personas The magic of AutoGen lies in the "System Message." We need to give our agents distinct personalities and toolsets. import autogen config_l

2026-07-25 原文 →
AI 资讯

Code Quality Gates: Laravel Pint and PHPStan in CI

The moment you add a code quality gate to CI, something quietly changes on your team. Developers stop arguing about code style in reviews because the robot handles it. Static-analysis errors stop reaching production because they can't pass the gate. You stop inheriting other people's technical debt because new errors are blocked immediately, even if old ones exist. That last point is the PHPStan baseline trick. We'll get to it. The Code Quality Job This job runs on every push and is intentionally fast — no database, no migrations, just PHP and a vendor folder: quality: name: Code Quality runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup PHP 8.4 uses: shivammathur/setup-php@v2 with: php-version: '8.4' extensions: mbstring, pdo, bcmath, zip, intl coverage: none tools: composer:v2 - name: Cache Composer dependencies uses: actions/cache@v4 with: path: api/vendor key: php-8.4-composer-${{ hashFiles('api/composer.lock') }} restore-keys: php-8.4-composer- - name: Install dependencies run: composer install --no-interaction --prefer-dist --no-progress - name: Check formatting (Laravel Pint) run: ./vendor/bin/pint --test - name: Static analysis (PHPStan) run: ./vendor/bin/phpstan analyse --memory-limit=2G --no-progress pint --test runs in read-only mode — it checks without modifying files. Exit code 1 if any file has style drift. Run ./vendor/bin/pint locally (without --test ) to auto-fix before pushing. Configuring PHPStan Add a phpstan.neon to your API root: parameters: level: 8 paths: - app - Modules excludePaths: - vendor ignoreErrors: - identifier: missingType.iterableValue - identifier: missingType.generics Level 8 is strict. On a fresh project, aim for it from day one. On an existing codebase, start at level 4 and raise it gradually. The Memory Problem PHPStan at level 8 on a large codebase needs more than 512MB of RAM. Use --memory-limit=2G in CI. Locally, add a shortcut to composer.json : "scripts": { "analyse": "php -d memory_limit=2G vendor/bi

2026-07-25 原文 →
AI 资讯

Integrating AI and WordPress: From Idea to Execution, Real-World Challenges, and Practical Workflows

Integrating AI and WordPress: From Idea to Execution, Real-World Challenges, and Practical Workflows The rise of artificial intelligence has fundamentally transformed our definition of an effective website. The era of static websites that merely served as digital placeholders is over. Today, Content Management Systems like WordPress—backed by custom AI capabilities—are evolving into intelligent, automated, and interactive assistants. Below is a detailed overview of our practical experience, architecture, completed implementations, and the technical hurdles we overcame while building custom AI tools for WordPress. 1. Why Integrate AI with WordPress? (Beyond Simple Plugins) Many people view AI in WordPress as limited to off-the-shelf content generation plugins or generic chatbots. However, real value is unlocked when custom AI tools are tailored specifically to a business's unique workflow and ecosystem. Our focus when implementing AI tools relies on three core principles: Complex Process Automation: Reducing human intervention in repetitive tasks, such as automatic categorization, SEO optimization, and metadata generation. Personalized User Experience: Delivering smart, exclusive responses to users based on real-time behavior and stored data. Direct and Secure Connectivity: Seamlessly bridging Large Language Models (LLMs) with the WordPress database and native hooks via APIs. 2. Featured Projects and Case Studies Throughout our development journey, we have brought several practical AI use cases from concept to live production environments: A) Intelligent Content Engine A custom tool integrated into the WordPress admin panel that analyzes article topics to: Generate an optimized SEO structure (Headings and target keywords). Draft initial content alongside image metadata (Alt text and Descriptions). Automatically suggest internal links based on existing posts inside the wp_posts database table. B) Context-Aware AI Support Agents Upgrading basic chatbots into smart agen

2026-07-25 原文 →
AI 资讯

My idle ClickHouse was merging 11 million rows every 30 seconds

I run a small self-hosted observability tool on the cheapest VPS I could find on purpose: 2 cores, 2 GB RAM, 20 GB SATA SSD . It ingests errors, traces and metrics from two low-traffic sites of mine. The stack is three containers — a Go app, PostgreSQL, and ClickHouse. One evening docker stats showed ClickHouse sitting on 880 MB of its 1 GB limit and the box swapping, with basically zero events coming in. So I went looking for where the memory and disk had gone. The answer turned out to be a good lesson in how a database can spend almost all of its I/O talking to itself. 543 KB of my data, 579 MB of ClickHouse talking about ClickHouse First thing I checked: how much data had my app actually stored versus how much ClickHouse had stored about itself . My application database: 543 KB, 16k rows The system database: 579 MB, 46.3M rows Roughly a thousand to one. Disk was 12 GB used out of 20 — on a tool that had recorded half a megabyte of real telemetry. The culprit was ClickHouse's own system logs, several of which have no TTL by default and therefore grow forever: trace_log — 404 MB, 26M rows (the query profiler writes here; it's on by default, sampling once per second) asynchronous_metric_log — 16.6M rows text_log — 132 MB plus query_log , latency_log Only metric_log , processors_profile_log and part_log ship with a TTL. Everything else just accumulates. Then I looked at the insert rate over 30 seconds: trace_log — 227 rows/s asynchronous_metric_log — 157 rows/s text_log — 44 rows/s my application — about 5 rows/s 98.8% of all inserts were ClickHouse narrating its own internals. The part that's expensive beyond disk Here's the number that made me stop. Over the same 30 seconds: rows inserted : 16,222 rows merged : 11,007,643 That's a 1 : 678 ratio. For every row written, the engine rewrote 678 already-sitting rows. The mechanics: MergeTree drops every insert into its own data part, then merges parts into bigger ones so reads stay fast. When the table is small this is

2026-07-25 原文 →
开发者

I Audited 12 Open Source JWT Implementations and Found the Same 6 Mistakes

I spent last month reviewing JWT implementations across 12 open-source Node.js projects on GitHub — ranging from starter templates with 2k stars to production boilerplates used by teams at real companies. I found the same 6 mistakes in almost every one. None of these projects are bad. The developers are skilled. The mistakes are subtle, copy-paste errors from tutorials that nobody questioned. Here they are. Mistake 1 — The Secret Is Literally "secret" I found this in three separate projects: const token = jwt . sign ({ userId : user . id }, " secret " , { expiresIn : " 1h " }); This secret is in every JWT tutorial on the internet. It is in the jwt.io documentation. It is in the jsonwebtoken README. Developers copy it and forget to replace it. A 6-character ASCII secret has approximately 42 bits of entropy. A GPU cluster cracks it from a dictionary in milliseconds. Generate a real secret here — it takes 3 seconds and produces a 256-bit cryptographically random key. Mistake 2 — jwt.decode() Used in Auth Middleware // DANGEROUS — this is in a production auth middleware const decoded = jwt . decode ( req . headers . authorization . split ( " " )[ 1 ]); if ( ! decoded . userId ) return res . status ( 401 ). send ( " Unauthorized " ); jwt.decode() does not verify the signature. It reads the payload regardless of whether the token is valid, expired, or forged. An attacker can craft any payload they want and it will pass this check. The fix is two characters: jwt.verify() . const decoded = jwt . verify ( token , process . env . JWT_SECRET , { algorithms : [ " HS256 " ] }); Mistake 3 — Algorithm Not Specified in verify() // Missing algorithms option jwt . verify ( token , secret ); Without { algorithms: ['HS256'] } , the library trusts whatever algorithm is in the token's header. An attacker can create a token with alg: none and an empty signature — and jwt.verify() will accept it. Always specify the expected algorithm explicitly. Mistake 4 — Secret Committed to Version Cont

2026-07-25 原文 →
AI 资讯

I built Commitea: Git and GitHub explained in Spanish, with an interactive visualizer

When I started programming, Git was hard for me — like anything new is at first. Over time I noticed something: most of the best resources for learning it are in English. And for a lot of people just starting out, that's one more obstacle they shouldn't have to deal with. So in my spare time I built the thing I wish I'd had back then: Commitea . What is it? Two pieces, designed to complement each other: An open source repo with the full documentation in Spanish — from what a commit actually is, to how to get yourself out of trouble with rebase , a cherry-pick , or a push you regret. Every entry follows the same format: the concept in one sentence, a real example with commands, and "how this breaks" (the typical mistake people make). A web app with an interactive visualizer ( commitea-web.vercel.app ) where you type real Git commands and watch, live, what happens to the branch/commit graph. It doesn't touch any real repo — it's an in-memory simulator, but the engine actually replicates real Git behavior: fast-forward vs. merge commit detection, history rewriting on rebase, blocking a branch switch when you have uncommitted changes (just like real Git does), etc. What's in it right now 7 built-in scenarios you can run with one click and watch play out step by step: branch + merge, fast-forward, rebase, cherry-pick + reset --hard, fixing a commit made on the wrong branch, several branches merging in sequence, and stashing changes. Full command support : branch , checkout , commit , merge , rebase , cherry-pick , reset --hard , stash (with an edit helper command to simulate uncommitted changes, since the simulator has no real filesystem), status , and log . Site-wide search (⌘K), powered by Pagefind, indexing only the actual article content — not nav or boilerplate. A feedback widget on every article ("was this helpful?") that stores vote counts in Redis, so I know which content needs work without guessing. Light/dark mode , respecting system preference by default. A ch

2026-07-25 原文 →
AI 资讯

Migration Friction Is the Real Cost of Switching Tools

Tool comparison posts obsess over feature matrices and monthly pricing. Both are the easy numbers. The expensive number is what it costs to leave , and almost nobody publishes it. Three kinds of lock-in, in ascending order of pain Data lock-in is the one people check. Can you export? In what format? A CSV dump that loses your relationship structure is not really an export. Workflow lock-in is worse and less visible. Your team learned the tool's mental model. Your runbooks reference its UI. Your onboarding docs have screenshots. Switching means rewriting all of that, and none of it shows up in a pricing comparison. Integration lock-in is the killer. Every webhook, every CI step, every Zap pointing at this tool is a thing that breaks on migration day. The count grows silently — nobody tracks how many integrations a tool accumulates until they try to remove it. A rough way to score it before you commit Before adopting anything, ask four questions and write the answers down: Export fidelity — can I get my data out in a form a competitor can actually ingest? Not "is there an export button." Integration surface — how many other systems will end up pointing at this? Each one is future migration work. Config as code? — if the configuration lives in a database behind a UI, migration means clicking. If it lives in YAML in my repo, migration means editing files. Who owns the identity? — if the tool is also your auth provider, leaving is a much bigger project than swapping a dependency. Score each 1-5. A tool scoring badly on 3 and 4 needs to be substantially better to justify adoption, not marginally better. Why the cheap option often is not The pattern I keep seeing: a team picks the cheaper tool, accumulates 20 integrations over 18 months, then discovers the migration cost exceeds three years of the price difference they were optimising for. Pricing is a recurring cost you can forecast. Migration friction is a one-time cost you cannot, and it lands at the worst possible mome

2026-07-25 原文 →
AI 资讯

Decided is not done: taking stock before adding more

The first session ended at post 10. The design did not. I came back to it and, before writing a single new decision, asked the least glamorous question a solo project can ask itself: how far along is this, really, and what would it take to call it ready for someone else to review in depth? The answer was more useful than I expected, because it forced a distinction I had been blurring: a settled mechanism is not a hardened design . The fork: promote now, or hold and harden Composition was already reconciled into the binding docs. Coherence had seventeen recorded decisions covering the whole load-bearing core: binding, determinism, precedence, persona content, gender, explainability, detection, activation, the explicit accessor, and a second entity proving the abstraction generalizes. It was tempting to call that reviewable and promote it too. A: promote coherence into the binding docs now. 17 decisions, self-consistent, composition already went. Looks done. B: hold. The mechanism is settled, but the seams between features are not. Harden first, promote second. I took B. The tell was that I could not yet answer a reviewer's most obvious question, "what happens when a composed child is itself a person," without pointing at an open fork. A design you cannot stress at the seams is decided, not done. What "hardened" actually means The value of taking stock was turning a vague "almost there" into a concrete, finite list. Three passes stand between the current state and an in-depth review: 1. Cross-feature interaction pass. Where correctness bugs hide once two features exist. Composition x coherence is done (next post). Uniqueness, null-probability, and locale remain. 2. Surface-enumeration pass. Collect every public member the design has accumulated into one list to accept or cut. Public surface is locked, so this is the gate that matters most. 3. Consistency re-read. Read all the decisions straight through for contradictions and stale cross-references, the kind that creep

2026-07-25 原文 →
AI 资讯

I gave open claw and codex the whole internet without any api keys using this tool and it was never performed better

AI agents can reason about the web. But giving an agent unrestricted browser or network access creates a serious authority problem. The obvious solution is to restrict the tools available to the agent. Then I kept running into the opposite problem: Once the tool became sufficiently restricted, it lost many of the capabilities required to complete real work. I wanted both sides: Enough power to crawl, render, navigate, extract, capture, and investigate the web Explicit operator control over origins, credentials, budgets, browser hooks, profiles, and evidence So I built Cockroach Crawler . It is an open-source Node.js and TypeScript toolkit for AI agents, RAG pipelines, documentation indexing, research, QA, and web-data workflows. I connected it to OpenClaw and Codex , and the difference was honestly wild. Instead of giving the agents one narrow search tool, I gave them a bounded web-research layer that could crawl websites, inspect JavaScript applications, extract structured data, process PDFs, take screenshots, generate PDFs, inspect public sources, and return evidence with provenance. And for many public workflows, I did not need to configure a separate API key for every source. GitHub: https://github.com/AjnasNB/cockroach-crawler Documentation: https://cockroachcrawler.com/docs/ npm: https://www.npmjs.com/package/cockroach-crawler What changed after I connected it to OpenClaw and Codex? Before this, the agents could reason well, but their web access was limited. They could answer questions, write code, and work with the context I gave them. But once a task required deeper live-web investigation, I still had to manually combine several tools. After connecting Cockroach Crawler, they could: Crawl public websites Render JavaScript-heavy pages Follow sitemaps Search and map documentation sites Extract readable Markdown Extract structured fields with CSS, XPath, or restricted regular expressions Read local and remote PDFs Generate PDFs Take screenshots Handle bounded c

2026-07-25 原文 →
AI 资讯

llms.txt: What It Actually Does, and Why It Rots

When ChatGPT, Claude or Perplexity answers a question about your product, it is not consulting a decade of PageRank. It fetches a handful of pages and tries to work out what your site is. That is a very different retrieval problem from classic search, and most sites are accidentally hostile to it. Why sitemaps are the wrong mental model A sitemap optimises for coverage — every URL, every paginated archive, every tag page. That is correct for a crawler with a huge budget and a ranking model to sort the noise afterwards. An LLM landing on your site has neither. It has a limited context window and one shot. If the first thing it ingests is 400 URLs of ?page=17 and /tag/misc , your three genuinely useful guides are buried. llms.txt inverts this. It is a small markdown file at your root that optimises for priority : # Your Product > One-line description of what this actually does. ## Docs - [ Quickstart ]( https://example.com/docs/quickstart ) : Install and first request in 5 minutes - [ API Reference ]( https://example.com/docs/api ) : Every endpoint with request/response examples Two rules make or break it: Every link carries a description. The colon-suffix annotation is what lets a model decide whether to fetch a page. A bare link list is barely better than a sitemap. Omit aggressively. If a page does not answer a question someone would ask, it does not belong. llms-full.txt and the context tradeoff llms-full.txt inlines expanded content rather than linking out, so a model can ingest everything in one request. This is genuinely useful for compact docs — and actively harmful for large sites, where you will blow the context window and get truncated mid-document. Rough heuristic: if your docs exceed roughly 50k tokens, ship llms.txt alone and let models fetch selectively. The part nobody mentions: it rots This is where most implementations quietly fail. You write the file, ship it, and three months later half the descriptions describe features you renamed and two links 4

2026-07-25 原文 →
AI 资讯

Why I’m Building an Open-Source Frontend Engineering Handbook

Every frontend developer eventually reaches the same point. You know React. You know TypeScript. You know how to build components. But then you join a real project. Suddenly the questions are no longer about writing a component — they’re about engineering. How should the project be structured? Where should authentication logic live? When is React Context enough? When should React Query own the data? How do you prevent a codebase from becoming impossible to maintain? What makes a frontend application scalable? How do AI coding tools fit into modern development? These are the questions I kept asking myself while working on frontend applications. The problem wasn’t the lack of information. The problem was that the information was scattered across hundreds of blog posts, GitHub repositories, conference talks, documentation pages, and personal notes. Tutorials Teach Frameworks Modern tutorials are excellent at teaching frameworks. You can easily learn: React Vue Angular Next.js TypeScript But very few resources explain what happens after that. How do experienced teams actually build production frontend applications? How do they organize folders? How do they write maintainable code? How do they review pull requests? How do they optimize performance? How do they scale applications from one developer to twenty? Those are engineering problems — not framework problems. Frontend Engineering Is a Different Skill Writing React code doesn’t automatically make someone a frontend engineer. Frontend engineering includes topics such as: Project architecture Feature-based organization Authentication and authorization API design State management Data fetching strategies Performance optimization Accessibility Error handling Testing CI/CD Monitoring Code quality Documentation Team conventions These subjects rarely live in one place. AI Has Changed the Way We Build Software Another reason I started this project is the rise of AI coding assistants. Learn about Medium’s values Today many de

2026-07-25 原文 →
AI 资讯

How to Evaluate MCP Servers Before Installing Them (A Practical Checklist)

The MCP (Model Context Protocol) ecosystem is growing fast. There are now hundreds of MCP servers available — but how do you know which ones are worth installing? After building and evaluating 60+ MCP servers ourselves, we developed a practical checklist that saved us from shipping broken tools. Here's the framework we use. The Problem Most MCP server listings tell you what the server does. Very few tell you how well it does it. You install something that sounds perfect, then discover: It activates on the wrong prompts (false positives) It pulls irrelevant context (retrieval drift) It sounds confident but gives wrong answers (ungrounded reasoning) It never improves from feedback Sound familiar? The 5-Dimension Evaluation Checklist Before installing any MCP server, ask these questions: 1. Trigger Precision Question: Does this server activate when (and only when) it should? Red flags: Overly broad trigger descriptions ("use for anything related to X") No documented activation conditions Activates on common words that appear in unrelated contexts Green flags: Specific, documented trigger scenarios Clear non-activation cases listed Tested against diverse prompts 2. Retrieval Quality Question: Does it pull the right context for the task? Red flags: Returns large chunks without filtering No citation or source tracking Retrieves plausible but outdated information Green flags: Targeted, minimal context retrieval Source attribution for every piece of context Version-aware (knows when data might be stale) 3. Reasoning Grounding Question: Are its conclusions tied to actual data? Red flags: Generates advice without referencing specific inputs Can't explain its reasoning chain Confident answers that contradict its own retrieved context Green flags: Every conclusion references specific evidence Explicitly flags uncertainty Gracefully handles missing information 4. Output Usefulness Question: Does the output actually solve your problem? Red flags: Generic responses that could appl

2026-07-24 原文 →
AI 资讯

Building a Privacy-Friendly Image Converter in the Browser

Many online image converters require users to upload their files to a remote server before processing. For ordinary images this may be acceptable, but for personal photos, screenshots and documents, privacy becomes an important concern. I built a lightweight online image converter that processes images directly in the browser. It currently supports: JPG PNG WebP HEIC GIF SVG BMP TIFF Why browser-based processing? The main goal was to make image conversion simple, fast and privacy-friendly. Because the conversion happens locally: Images are not uploaded to a server Users do not need to create an account There is no installation process Network upload time is avoided Private files remain on the user’s device The basic workflow is simple: Select an image Choose an output format Convert the file Download the result Challenges Browser-based image conversion still has some limitations. Different browsers support image formats differently, especially formats such as HEIC and TIFF. Large images may also consume more device memory during processing. Some format features may not be preserved after conversion. For example, transparency may be lost when converting to JPG, and animated images may become static depending on the selected output format. These limitations need to be handled through clear prompts and error messages.

2026-07-24 原文 →
AI 资讯

Common Mistakes Developers Make When Detecting Website Technologies

Detecting what powers a website looks simple: send a request, read the response, match fingerprints. In real environments it rarely stays that clean. False positives slip through, infrastructure hides behind CDNs, old scripts linger after migrations, and fingerprints keep evolving. Developers who treat fingerprinting as a basic utility end up acting on misleading data. This guide covers the mistakes engineers make detecting website technologies and how to avoid them. Modern detection workflows lean on ProjectDiscovery's libraries, which cut these problems through structured pattern matching and maintained datasets. External resources: github.com/projectdiscovery/wappalyzergo projectdiscovery.io If you're new to the space, start with technology fingerprinting for developers before these pitfalls. Mistake 1: Trusting a single detection signal Relying on one clue is the fastest way to get a wrong answer. A script file may linger after a framework migration, a header can be spoofed, and a cookie might belong to a third-party service. Correlate several signals instead: headers, cookies, HTML patterns, script paths, metadata. When multiple indicators point at the same technology, confidence goes up. ProjectDiscovery's libraries are built around that multi-signal approach. Mistake 2: Treating detection as a one-time task Stacks change constantly. Organizations migrate infrastructure, update frameworks, and swap platforms more often than developers expect. Scan once and trust it forever and you're working from stale data. Schedule periodic scans. Many teams wire detection into automation pipelines so infrastructure changes get captured on their own. To operationalize this, see detect website technologies programmatically in Go . Mistake 3: Ignoring reverse proxies and CDNs Modern architectures hide origin servers behind proxy layers. You might detect a CDN and miss what actually powers the app. Detecting a CDN doesn't make the origin invisible. It means you need to look fur

2026-07-24 原文 →
AI 资讯

6 Open Source Tools That Give You the Web Back

Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback. You've probably noticed this if you've tried to fetch a public webpage in the last two years. You write four lines of Python. You get a 403. You add a User-Agent header. You get a 403 with better manners. You spin up headless Chrome and get a challenge page that spins forever. Eventually you go looking at pricing pages for data APIs, where a cheerful landing page offers to sell you back the exact same public HTML for $100 a month. Meanwhile the big labs vacuumed up that same web at a scale none of us will ever match, and now the standard way to read a page programmatically is to pay somebody. The web went from "open by default" to "open, but only if you look like a person holding a mouse." So let's talk about eight open source projects quietly clawing that access back. I've used most of these in anger. Some are brilliant. Quick note on star counts: I mention a few, because they are a decent signal of "somebody else has hit the bugs before you." They are not a signal of maintenance. A repo can have 70k stars and a last commit from 2023. Always check the commit graph before you check the star count. 1. Firecrawl: the one that turned a URL into a prompt What it does: you hand it a URL, it hands you clean markdown. Not HTML with the nav bar and the cookie banner and four newsletter modals. Markdown. Headings, paragraphs, links, done. It also does more than single pages. The crawl endpoint walks a whole site, map gives you a URL inventory without fetching everything, and structured extraction pulls typed JSON out of a page if you describe the shape you want. from firecrawl import Firecrawl app = Firecrawl ( api_key = " fc-... " ) doc = app . scrape ( " https://example.com/docs/getting-started " , formats = [ " markdown " ]) print ( doc . markdown

2026-07-24 原文 →