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

标签:#EV

找到 5228 篇相关文章

AI 资讯

7 MCP Tool-Schema Mistakes That Make AI Agents Less Reliable

AI agents can only use tools as reliably as those tools are described. That’s why I built ToolReady AI —a free tool that reviews MCP and AI-agent tool schemas, identifies reliability problems, and recommends specific fixes. A function might work perfectly when a developer calls it directly, yet still fail when an agent has to decide when to call it, which arguments to provide, and what values are safe. In many cases, the problem is not the underlying API. It is the tool schema placed between the API and the model. Here are seven issues worth checking before releasing an MCP or AI-agent tool. A description that is too vague Descriptions such as "Searches documents" do not give an agent enough routing context. The description should identify the supported content, expected result, important limits, and a clear use case. Better: «Search indexed support documents and return the most relevant text excerpts. Use this when answering questions about product setup or troubleshooting. Do not use it for account-specific or real-time billing information.» No boundary conditions A useful description should also explain when the tool should not be used. Exclusions help an agent distinguish similar tools and avoid calls that cannot succeed. Examples include: Do not use for personal account data. Do not use when the user requests current inventory. Do not use for destructive actions without confirmation. Undocumented inputs An input name such as "query", "id", or "limit" may seem obvious to its author, but the agent still has to guess the required meaning and format. Each property should explain: What the value represents The expected format A realistic example Any important constraints Missing required fields If the schema does not identify the minimum necessary inputs as required, an agent may send an empty or incomplete call that cannot produce a useful result. For example: { "type": "object", "properties": { "query": { "type": "string", "description": "Natural-language search q

2026-08-18 原文 →
AI 资讯

We Tested 4 Text-to-Speech Engines on 12,000 Live Healthcare Calls — Here's Which One Patients Actually Trust

Last quarter, we ran our production voice AI receptionist — Loquent — across four different TTS engines simultaneously, split-testing real patient calls at dental and healthcare clinics. The results surprised us: the most "natural sounding" engine in demos performed the worst with actual patients. Why We Ran This Test At Autor, we've been running Loquent in production for over a year now. It handles thousands of automated calls per month for healthcare and dental clinics across Canada — booking appointments, answering insurance questions, handling after-hours triage. The voice is the product. If patients don't trust the voice, they hang up, and the clinic loses a booking. When we first built Loquent, we picked our TTS engine the way most teams do: we generated a few sample clips, played them for ourselves, and went with the one that sounded best in a quiet office. That worked fine until we started digging into our call analytics and noticed something weird. Our completion rate — the percentage of calls where patients actually finished the full interaction instead of hanging up or asking for a human — was hovering around 74%. Good, but not great. We suspected the voice itself was part of the problem. So we designed a proper A/B test. Not a demo comparison. A production comparison on live calls. The Setup We tested four TTS engines across 12,247 calls over 8 weeks. Each engine handled roughly equal volume, randomly assigned at call start. All other variables stayed constant: same prompts, same Anthropic Claude backbone for conversation, same Twilio infrastructure, same clinics. The four engines: Engine A : ElevenLabs (Turbo v2.5) — our existing production engine Engine B : OpenAI TTS (tts-1-hd) — the model most teams default to Engine C : Deepgram Aura — optimized for real-time, low-latency use cases Engine D : A newer entrant we'd been evaluating (under NDA, so I can't name it) We measured five things: Completion rate — did the patient finish the full call flow? Time

2026-08-18 原文 →
AI 资讯

Building Fault-Tolerant, Event-Driven Kafka Pipelines in Go: Reliable Reprocessing & Dead Letter Queues

A practical guide to building reliable event-driven systems in Go using Apache Kafka. Learn how to implement tiered retry strategies with delayed reprocessing, route permanently failed messages to dead letter queues in Golang with Sarama. Prerequisites What do you need to follow along? Working knowledge of Golang. Go & Docker installed on your PC. What is an Event-Driven Architecture? An Event-Driven Architecture (EDA) is a design approach where services communicate by producing and responding to events. Each service operates independently, producing or reacting to events as they happen. What are Events? An event is a record of something that has happened in a system, typically representing a state change or a significant action. An event contains data (payload) describing what happened. An example of an event could be: A user signing up for a service. A user placing an order in your system. Components of an Event-Driven Architecture To understand how events flow through a system, we need to know three key players: Event Producers : They are the sources of events. They generate and publish events like signup events, order placed events, etc. Producers generate events and transmit them to the rest of the system. They do not know who is listening for or handling the events. Event Brokers : They sit between producers and consumers, decoupling them so neither needs a direct connection to the other. Brokers receive event messages, maintain their chronological order, make them available for consumption, and route them to the right consumers. Apache Kafka is an example of an event broker, and it's the one we'll use throughout this guide. Event Consumers : They handle the processing tasks. They listen on event channels and react when an event they are subscribed to is published, then they process the event, which can include making API calls, updating a database, triggering other events, or logging information. The Complete Flow With those three pieces in place, the flow of

2026-08-18 原文 →
AI 资讯

Your backup is not a backup until you have restored it

This is an English write-up of a post from my Japanese dev diary. Original: https://saas-diary.com/tech-log/backup-restore-drill-automation/ For over a year, my backup job has reported success every single night. Green check, every day, no exceptions. Then I asked myself one question and went cold: "How many times have I actually restored from it?" Zero. Not once. "It was backed up" and "it can be restored" are different states My setup has two paths. One mirrors all source to a private repo. The other packs the things I can never recreate — notes, config, and Android signing keys — into an encrypted bundle and ships it to a private channel every night. Both were green every day. But green only proved the upload finished . It never proved the contents were right, or that the archive could even be opened. Within one month, I had two failures that stayed green the whole time. Failure 1. The collector for signing keys used three hardcoded paths. I kept shipping new apps, so the number of keys kept growing — but the collector didn't. By the time I noticed, 7 of 10 keys were missing from the backup . Five of those apps were live on the store. If my machine had died, I could never have shipped an update for them again. The backup reported success every night through all of it. Failure 2. The mirror push failed 7 days in a row (a large binary hit the host's file-size limit). But the script printed "✅ done" and returned exit code 0 even when one half failed. A failure that isn't visible isn't a failure — it's a time bomb. So I automated a restore drill Once a month, a job now does this: Rebuild the encrypted bundle (without shipping it) Actually decrypt it with the stored passphrase Extract it and count what's inside Check the mirror is not stalled (latest commit timestamp via API) Delete the scratch folder and the generated bundle The encryption is openssl-compatible AES-256-CBC with PBKDF2 (SHA-256, 100k iterations). I deliberately avoided depending on the openssl binary,

2026-08-18 原文 →
AI 资讯

Architecting a Low-Power Geofencing Engine: Lessons from Battery Optimization on Android

Opening hook The silence in the room was absolute, save for the rhythmic scratching of pens against paper during a final exam. I was three rows back, feeling confident, until my phone decided to vibrate against the wooden desk. It wasn't a subtle hum; it was a rhythmic, aggressive buzz that echoed like a snare drum in a cathedral. Every single head turned in my direction. I scrambled to silence the device, but in my panic, I fumbled the power button. That moment of pure, unadulterated embarrassment was the catalyst for everything I have built since. The problem We live in an age where our devices are supposed to be smart, yet they consistently fail at the most basic context-aware tasks. We have high-end processors, sophisticated neural engines, and sophisticated sensor arrays, but we still have to manually toggle a 'silent' switch before entering a meeting, a lecture, or a mosque. The friction isn't just the act of flipping a switch; it is the cognitive load of remembering to do it and, more importantly, remembering to turn it back on afterward. I spent months living with the anxiety of a phone that might ring at the worst possible time. I tried existing automation tools, but they were either bloated, relied on cloud-based tracking that hammered my battery, or lacked the granular control I needed for specific locations. Most apps that promised location-based sound management were either imprecise or drained my battery by keeping the GPS radio active around the clock. I didn't want a heavy-duty tracking app; I wanted a silent, background-native utility that respected the hardware constraints of the Android platform while solving the specific problem of environmental sound management. The technical decision / implementation When I started building Muffle, my primary constraint was the battery. Android users are rightfully protective of their background processes, and if my app showed up as a primary battery consumer in settings, it was effectively useless. I had to de

2026-08-18 原文 →
开发者

Understanding chmod Without Memorizing Numbers

How Linux file permissions actually work under the hood, why symbolic mode is your best friend, and how to stop blindly typing chmod 777. Every Linux engineer has been there. You write a brand-new bash script, try to run it from your terminal, and hit an immediate roadblock: $ ./backup.sh bash: ./backup.sh: Permission denied You open your search engine or ask a chat assistant for help. Within seconds, you find an answer that tells you to run: chmod 777 backup.sh You run the command, hit enter, and the script runs. Problem solved, right? Not quite. In fact, you just opened the digital front door of that file to every single user and background service on the entire operating system. When I started managing Linux servers years ago, permissions felt like a strange puzzle of three-digit math problems. People kept throwing numbers around: 755 for scripts, 644 for web pages, 600 for SSH keys, and 777 whenever something broke and nobody knew why. I memorized those numbers like cheat codes in a video game. But whenever I had to handle a real permission problem, like giving a development team write access to a shared log folder without letting them delete each other's files, memorized numbers fell apart. Here is the secret: you do not need to do binary math or memorize three-digit codes to master Linux permissions. Linux has a built-in, human-readable permission syntax called symbolic mode . Once you understand how Linux looks at files, who owns them, and what actions each permission controls, chmod becomes one of the most intuitive tools in your terminal. Let's break down how it all works step by step. 1. What chmod Actually Does The name chmod stands for change mode . In Unix and Linux systems, every single file and directory has a "mode". That mode determines who is allowed to read it, write to it, or run it. When you run chmod , you are simply updating those access bits inside the Linux filesystem inode. To see the current mode of your files, open any terminal and run ls

2026-08-18 原文 →
AI 资讯

Você criou uma tabela de tokens pra proteger PDF. O Laravel já fazia isso.

O contrato do cliente tá numa URL que qualquer um adivinha A tarefa parecia simples: o cliente precisa baixar a nota fiscal dele. Você salvou em storage/app/public/notas/ , rodou php artisan storage:link , mandou o link e foi feliz. https://app.com/storage/notas/nota-1042.pdf . Semanas depois cai a ficha. Aquele arquivo está aberto na internet . Sem login, sem nada. E o nome é sequencial: quem baixou a nota-1042.pdf só precisa de curiosidade e cinco segundos pra tentar a 1041 . E a 1040 . Então você faz a coisa certa: tira do disco público e cria um sistema pra controlar acesso. Tabela download_tokens , model, geração de UUID, coluna expires_at , controller que valida, e um comando no scheduler pra limpar os vencidos. Sessenta linhas depois, funciona. E aí alguém comenta no PR: "por que você não usou uma URL assinada?" O sistema que você não precisava construir // ❌ migration + model + controller + command. tudo isso pra um PDF. Schema :: create ( 'download_tokens' , function ( Blueprint $table ) { $table -> id (); $table -> uuid ( 'token' ) -> unique (); $table -> string ( 'path' ); $table -> foreignId ( 'user_id' ); $table -> timestamp ( 'expires_at' ); $table -> timestamps (); }); public function gerarLink ( NotaFiscal $nota ): string { $token = DownloadToken :: create ([ 'token' => Str :: uuid (), 'path' => $nota -> arquivo_path , 'user_id' => auth () -> id (), 'expires_at' => now () -> addMinutes ( 10 ), ]); return route ( 'download' , $token -> token ); } Não tem nada de errado tecnicamente. O problema é o custo: mais uma tabela crescendo pra sempre, mais um comando no scheduler, mais um caminho pra testar. E você vai manter isso enquanto o projeto existir. O Laravel resolve o mesmo problema com uma assinatura criptográfica na própria URL. Sem estado, sem tabela, sem limpeza. Como uma URL assinada funciona A ideia é bonita de simples: o Laravel monta a URL com os parâmetros que você quer, calcula um hash disso tudo usando a APP_KEY e cola o hash no final. /not

2026-08-18 原文 →
AI 资讯

Seu log tem 40 mil linhas e nenhuma resposta

"Deu erro ao salvar, umas duas da tarde" É a única informação que você tem. O cliente não lembra o que clicou, não tirou print e já fechou a aba. Você abre o laravel.log . Quarenta mil linhas no dia. Faz um grep por "erro". Aparecem 1.200 ocorrências, e a maioria é isso: [2026-08-14 14:03:11] production.INFO: entrou [2026-08-14 14:03:11] production.INFO: erro aqui [2026-08-14 14:03:12] production.INFO: passou [2026-08-14 14:03:12] production.ERROR: Erro ao salvar Erro ao salvar o quê ? De qual usuário? Qual pedido? Qual valor? Aquele entrou da linha de cima é do mesmo request ou de outro cliente que estava usando o sistema no mesmo segundo? Você tem log. Você não tem informação. São coisas diferentes. O problema não é a falta de log. É o excesso de log inútil. public function emitir ( Pedido $pedido ) { Log :: info ( 'entrou no emitir' ); try { $nota = $this -> sefaz -> emitir ( $pedido ); Log :: info ( 'emitiu' ); } catch ( Throwable $e ) { // parabéns, você registrou que algo deu errado em algum lugar 🎉 Log :: error ( 'Erro ao emitir nota' ); return back () -> withErrors ( 'Falha na emissão' ); } } Repara no que esse catch jogou no lixo: a mensagem da exceção, o stack trace, o ID do pedido, o CNPJ, o retorno da SEFAZ. Tudo estava ali, na mão, e foi substituído por uma frase genérica. E os Log::info('entrou') espalhados? Aquilo foi debug que virou permanente. Hoje eles só servem pra empurrar as linhas úteis pra fora da tela. Duas perguntas que todo log precisa responder Um log serve pra duas plateias: você, com sono, às 3h da manhã — e uma máquina , filtrando milhões de linhas. As duas querem a mesma coisa: O que aconteceu , numa mensagem que não muda nunca. Com quem aconteceu , em dados separados da mensagem. Essa separação é o pulo do gato. Repare na diferença: // ❌ mensagem única pra cada pedido. impossível agrupar ou contar. Log :: error ( "Falha ao emitir nota do pedido { $pedido -> id } do cliente { $cliente -> nome } " ); // ✅ mensagem estável + contexto est

2026-08-18 原文 →
AI 资讯

Authentication done right: JWT, sessions, and OAuth explained — Like a Marvel superhero assembling the team

The Quest Begins (The "Why") I still remember the first time I tried to add login to a side‑project. I’d read a tutorial that said “just store a token in localStorage and you’re good,” slapped together a few fetch calls, and called it a day. A week later I got an email from a user: “Hey, I can’t log out, and someone else seems to be using my account.” My heart sank. I realized I’d bolted a flashy lock onto a screen door — it looked secure, but anyone with a screwdriver could walk right in. That moment kicked off a deep dive. I wanted to understand the trade‑offs between sessions , JSON Web Tokens (JWT) , and OAuth so I could pick the right tool for each job, not just the shiniest one. What followed felt like assembling a superhero squad: each member has a unique power, and knowing when to call on them makes the difference between saving the day and causing collateral damage. The Revelation (The Insight) Sessions – The Trusty Sidekick Sessions are the classic, server‑side approach. When a user logs in, the server creates a random identifier (the session ID), stores it in a database or cache (Redis, Memcached, etc.), and sends it back to the browser as an HttpOnly cookie. On every request, the browser automatically includes that cookie, the server looks up the ID, and pulls the associated user data. Why I love it: The secret never leaves the server, so stealing a cookie only gives an attacker a session ID that’s useless without the server’s store. Revoking a session is trivial — just delete the row from the store. Works great for traditional web apps where you control both front‑ and back‑end. Where it stumbles: Horizontal scaling requires a shared session store; otherwise each instance forgets who the user is. Every request does a database/lookup, which can add latency if the store isn’t fast enough. JWT – The Lone Wolf with a Signed Badge A JWT is a compact, URL‑safe string that contains claims (like sub , exp , roles ) and is cryptographically signed (HMAC or RSA).

2026-08-17 原文 →
AI 资讯

The Kitchen Doesn't Care About Your Excuses

There is a moment in every high-stakes environment when something goes completely, objectively wrong, and the only viable response is to keep working. In my case, it was a pantry clerk who walked into the dry storage room carrying a stack of boxes, clipped a fire sprinkler head, and discharged what I can only describe as an impressive quantity of initially greasy water across an active commercial kitchen. We were told to continue service. It took four hours for the sprinkler system technicians to arrive and resolve the situation. We dried our shoes afterward. I have thought about that shift many times since leaving commercial kitchens for the technology industry. Not because it was the strangest thing I witnessed. It wasn't. Not by a significant margin. However, because the response to it was so instinctively correct. Nobody called an all-hands. Nobody convened a retrospective on the water. We just kept swimming. It turns out that lesson travels extremely well. A few weeks ago I wrote about how a non-linear career isn't actually non-linear, that the industries change but the underlying questions stay remarkably consistent. I want to make that argument concrete. Here's what commercial kitchens specifically taught me about performing under pressure, and why none of it required translation when I showed up in technology. The Kitchen Never Lies I spent years in commercial kitchens before I spent years in technology. Western Culinary Institute. Private golf clubs. A Lebanese restaurant. Bulk production facilities turning out ten thousand pounds of macaroni and cheese a day, five days a week. Country clubs. A casino. Catering. Culinary competitions. The environments were different. The underlying dynamics were identical. High pressure. Constrained timelines. Mismatched team experience levels. Leadership of wildly variable quality and sobriety. Outcomes that mattered regardless of what had happened behind the scenes to produce them. Customers who neither knew nor cared abo

2026-08-17 原文 →
AI 资讯

Why I Built Unlockt: A Local-First Instagram Saved Archiver, Canvas Collage Studio & 9:16 Video Vault

Like many developers, designers, and digital marketers, my Instagram "Saved" collection had turned into a digital graveyard with over 5,000 bookmarked posts, reels, and carousels. The native Instagram web app offers virtually zero productivity tools: ❌ No full-text search across captions or hashtags ❌ No way to extract individual slides from carousel photo dumps ❌ No offline preservation (if a creator archives a post, it disappears forever) ❌ Existing web downloaders ask for account passwords, inject trackers, or bombard you with ads. So I spent the last few months developing Unlockt — a 100% free, MIT open-source, local-first Chromium extension and Node.js Express dashboard. --- ## 🏗️ Architecture & Engineering Highlights Here is how Unlockt is designed under the hood: ┌─────────────────────────────────┐ │ Chromium Extension (MV3) │ ──► Reads Instagram GraphQL via active session └────────────────┬────────────────┘ │ Local REST Sync ▼ ┌─────────────────────────────────┐ │ Express Backend (Port 3000) │ ──► SSRF-Hardened Proxy & HTTP 206 Video Streamer └────────────────┬────────────────┘ │ ┌────────┴────────┐ ▼ ▼ ┌──────────────┐ ┌───────────────────────────┐ │ data/saved. │ │ /thumbnails /videos │ │ json (DB) │ │ (Local High-DPI Storage) │ └──────────────┘ └───────────────────────────┘ 1. Zero-Password Session Scraping Rather than asking users for their credentials or running headless browser instances that trigger Meta account checkpoints, Unlockt operates as a Manifest V3 Chromium extension. It uses the cookies and CSRF tokens already present in your authenticated browser tab with randomized jitter delays (800ms - 2200ms) to respect rate limits. 2. 1-Click HTML5 Canvas Collage Studio One of my favorite features is the Carousel Studio . When you open a 10-slide photo dump, Unlockt extracts every slide and can render them onto an off-screen HTML5 <canvas> element to produce high-resolution moodboards ( 2x1 , 2x2 , 3x2 , 3x3 , and 5x2 ) with crisp 4px white margin div

2026-08-17 原文 →
AI 资讯

Network Devices Explained — The Foundation Every Cloud & DevOps Engineer Needs

🌐 Network Devices Explained The Foundation Every Cloud & DevOps Engineer Needs Series: Networking Fundamentals for Cloud & DevOps — Part 1 of 6 Before VPCs, subnets, route tables, and security groups make sense, you need to understand what's happening beneath them. This series builds that foundation — starting with the devices that make networks work. Why Networking Before Cloud? I hit a wall during my AWS VPC sessions. Route tables, subnets, gateways, NACLs — the concepts existed in isolation. I could follow steps in the console, but I couldn't reason about why traffic was or wasn't flowing. The fix wasn't more AWS documentation. It was going back to networking fundamentals. Once I understood what a router actually does — how it makes forwarding decisions, what a routing table really is — the AWS route table stopped being a mysterious config screen and became something I could think through. That's what this series is. Six posts covering the networking concepts that directly underpin Cloud and DevOps work. No exam prep framing, no CCNA depth. Just what you actually need. 1. What is a Host? A host is any device that participates in network communication by sending or receiving traffic. That's broader than most people assume. Examples: your laptop, your phone, an EC2 instance, a web server, a virtual machine. The word "host" doesn't imply a server — your laptop is a host just as much as a data center machine is. 2. Client vs Server — Roles, Not Hardware A client is a host that initiates a request. A server is a host that responds. The critical point: a server is not a special type of computer . It's just a computer running software that listens and responds. Your Browser (Client) │ │ HTTP Request ▼ Web Server (Server) │ │ HTTP Response ▼ Your Browser (Client) The same machine can be a client in one communication and a server in another. Your EC2 running a web app is a server to users hitting it — and a client when it queries RDS. 3. IP Address — The Network Identity

2026-08-17 原文 →
AI 资讯

Why I left Warehouse out of our Fabric deployment scope

title: Why I left Warehouse out of our Fabric deployment scope published: true tags: microsoftfabric, datawarehouse, cicd, devops Our Fabric deployment pipeline handles sixteen item types. Warehouse is not one of them, and that was deliberate. DEFAULT_ITEM_TYPES = [ " DataPipeline " , " Lakehouse " , " Notebook " , " SemanticModel " , # "Warehouse" is intentionally excluded. Warehouse schema deployment must # be handled separately to avoid schema reset risk during publish. " Environment " , " Eventhouse " , ... ] The reason Publishing a warehouse through this path can reset its schema. Not "might behave unexpectedly". The failure mode is that a deployment intended to be additive removes structure, and the thing that removes it is the same routine that successfully deploys the other sixteen types. The choice that follows Two options once you know that. Include it and hope nobody deploys a warehouse without reading the docs. The pipeline supports everything, and one day someone promotes a change on a Friday and finds out. Or exclude it, document why, and handle warehouse deployment as its own problem with its own tooling. I took the second. An automation that covers most cases and silently corrupts the rest is worse than one that covers most cases and refuses the rest. The refusal is visible. The corruption is not. Making the exclusion loud An exclusion is only useful if someone notices it. Three things help: The comment sits inside the list , not in a doc nobody opens. Anyone reading the item types sees the gap and the reason in the same glance. It is in the README under known limitations, next to the other things the framework does not do. There is a test. It asserts Warehouse is absent from the default scope: def test_warehouse_stays_excluded ( self ): """ Warehouse publish can reset schema, so it is handled separately. """ self . assertNotIn ( " Warehouse " , deploy . DEFAULT_ITEM_TYPES ) That test looks silly. It is asserting that a string is missing from a list.

2026-08-17 原文 →