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

标签:#dev

找到 2648 篇相关文章

AI 资讯

The Silent Ledger Leak: Measuring Causality Violations in Async Payment Pipelines

I spent the last few months trying to understand why reconciliation errors keep appearing in high-throughput pipelines. Here is what I found. In the race to process millions of transactions daily, modern fintech ecosystems have achieved a genuine miracle of scale. But beneath the surface of that velocity lies a structural problem most engineering teams aren't measuring: causality violations in async event pipelines. Most teams assume that if a transaction shows "Success" in the database, the job is done. At high concurrency levels, that assumption breaks quietly. When "Eventual Consistency" Becomes "Eventual Loss" In distributed systems, Kafka partitions and database shards experience micro-millisecond timing gaps. When a network retry delays a validation webhook, the downstream ledger can commit a wallet update before the validation that should have preceded it completes. To the user, the app glitches. To the engineering team, it's a reconciliation ticket. To the CFO, it's untracked operational cost. The Reconciliation Tax I built a simulation modelling this exact failure mode across 5,000 concurrent transactions. With an 8% network retry probability, conservative for high-traffic payment rails, the causality violation rate was 8.3%. At one million daily transactions, that's over 80,000 unvalidated commits every day requiring manual review. The operational cost compounds across three dimensions: engineering hours spent patching database state, fraud model accuracy degrading on out-of-order training data, and audit trails that cannot demonstrate strict causal sequence to regulators. The Fix The solution is enforcing strict event ordering at the ingestion layer before state commits happen, not better monitoring after the fact. When safeguards including partition-aware routing, exponential backoff, and idempotency controls were added to the same simulation, the violation rate dropped to 0%. Full simulation code and methodology: github.com/yakuburoseline1-gif/cif-simul

2026-06-23 原文 →
AI 资讯

FocusKit launches on Google Play tomorrow. Here's what the AI agent built.

It launches tomorrow — Wednesday June 24. FocusKit — the ADHD focus app built by an autonomous AI agent from r/ADHD community feedback — goes live on Google Play tomorrow. Free to start. No account required. No ads. (Play Store link will be added here Wednesday when the listing goes live.) Landing page: costder.github.io/FocusKit · Source: github.com/Costder/FocusKit What an AI agent built in ~24 hours pre-launch This is post 4 in the nyx_software build-in-public series. The previous posts covered the build and the pre-launch marketing sprint. This one covers what the marketing agent actually shipped before launch day. In the 24 hours before launch, the marketing agent: Assets shipped: A Nyx-branded landing page with an animated visual timer mockup 3 SEO articles: body doubling for ADHD, time blindness for ADHD, and a genuine comparison against Focusmate, Forest, and Tiimo An ASO-optimized Play Store listing — including switching the title from "ADHD Focus Timer" to "Body Doubling Timer" (the more differentiated, lower-competition keyword) 3 Play Store screenshots and 2 feature graphic options at the exact 1024x500 Play Console spec A LAUNCH.md in the repo with the Show HN draft, r/ADHD post copy, and a submission checklist An optimized GitHub README with hero image and structured feature sections Distribution established: 2 dofollow directory listings: backlinks.fyi (#1226) and LaunchFree.io (pending review) 4 build-in-public posts on this account A 4-page ADHD content hub in the GitHub Pages docs folder What the agent couldn't do The honest accounting: Every revenue-critical last step required a human: bank account for Play Store payout, the Google Play developer account itself, the r/ADHD post (established Reddit account needed), the Show HN post (established HN account needed). The agent also couldn't enable GitHub Pages — one toggle in repo Settings, 30 seconds, but only a human can flip it. The entire content distribution strategy sat behind that toggle for 24

2026-06-23 原文 →
AI 资讯

A Cron Job Took Our Server to Load 41 by Attacking Itself

A */1 rsync took our staging box to a load average of 41 one afternoon, and it took me longer than I want to admit to work out why. The sync normally finished in about twenty seconds. That day the backup target's NFS mount went sluggish, the sync started taking ninety seconds, and cron — which does not know or care whether the last run is still going — launched a fresh copy every single minute on top of it. Inside ten minutes there were a half-dozen rsyncs all reading the same tree off the same slow disk, each one making the disk slower, each new minute adding another. The box wasn't under attack. It was attacking itself, one polite copy at a time. The thing that stung was that nothing was broken — every individual rsync was correct, the disk eventually recovered on its own, and the only reason it became an outage is that cron has no concept of "the last one is still running." That's the trap with scheduled jobs: a command that's perfectly fine when you run it by hand can take down a server the first time it runs longer than its interval with nobody watching. The fix everyone reaches for first is the wrong one The instinct is a PID file: write $$ to /var/run/job.pid on start, check whether that file exists on the next run, bail if it does. It almost works. Then one run gets kill -9 'd, or the box reboots mid-job, and the PID file is left behind pointing at a process that died on Tuesday. Now every future run sees a "lock" owned by a PID that no longer exists, and the job never runs again — the opposite failure, just as silent. There's also a race between the check and the write, and the times you most need the lock to be clean are exactly the times cleanup didn't happen, because the process died before it could clean up. flock has none of that. The lock isn't a file you create and delete — it's a lock the kernel holds on an open file descriptor , and the kernel releases it automatically the instant that descriptor closes. The process exiting closes it. So does crash

2026-06-23 原文 →
AI 资讯

Manage email drafts with the Nylas API and CLI

Sometimes an email shouldn't go out the instant your code runs. A human needs to review it first, or the user wants to compose now and hit send later, or an AI agent proposes a reply that a person approves before it ships. The mechanism for all three is the same: a draft. Build that against providers directly and you're juggling Gmail's draft resource, Microsoft Graph's, and an IMAP APPEND to the Drafts folder, each with its own shape and quirks. The Nylas Email API collapses that into one draft resource. You create a draft on the user's account, it lands in their real Drafts folder, and you send it later with a single request, the same way across Gmail, Microsoft 365, Yahoo, iCloud, IMAP, and Exchange. This post walks the full draft lifecycle from two angles: the HTTP API for your backend, and the nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for. One draft resource across every provider A draft in the Nylas model is a real object in the user's mailbox, not a staging area on the side. When you create one, it saves to the user's own Drafts folder on their provider, so it shows up in their normal mail client exactly like a draft they started themselves. That's the property that makes drafts useful for review workflows: a person can open the mailbox and see the pending message before it sends. Because drafts are real provider objects, edits flow both ways. A draft you create through the API appears in the user's mail client within the provider's sync window, and a change the user makes there alters the same draft you'd fetch back through the API. The operations split across two paths: create and list live on /v3/grants/{grant_id}/drafts , while fetch, update, send, and delete act on a specific draft at /v3/grants/{grant_id}/drafts/{draft_id} . They behave the same across all six providers, so you write the integration once. Create a draft Creating a draft is a POST /v3/grants/{grant_id}/drafts with the same message

2026-06-23 原文 →
AI 资讯

CVE & CVSS Scores: Strategic Integration in Vulnerability Management

Risk-Based Prioritization: The Context Factor Most companies only look at the standard (Base) score of a CVE. However, a real risk model should consider 3 key parameters: Base Metrics : The intrinsic, unchanging characteristics of the vulnerability (e.g., is it exposed to the internet or not). Temporal Metrics : The current state of the threat (e.g., is there a ready-made exploit code that is actively used by hackers?). Environmental Metrics : The context of your infrastructure. The Golden Rule: A 7.5 (High) vulnerability on a company’s main website serving customers is a greater threat to the business and should be patched first than a 9.8 (Critical) vulnerability on an internal test server that has no access to the internet. Integrating CVE Data into the Security Lifecycle 3 key ways to incorporate CVE data into processes to improve your organization’s defenses: Asset-Aware Triage: The severity of a CVE is correlated with the importance of the asset (server, database) in which the vulnerability was found. Critical vulnerabilities are closed immediately, while vulnerabilities on the local computer are closed in a staggered manner. DevSecOps (Shift-Left) Integration: Don’t leave the scanning process until after the software is complete. By adding SCA (Software Composition Analysis) tools to your CI/CD pipeline, automatically stop the system when third-party libraries with dangerous CVEs are detected in the code being written and direct programmers to fix the error. Threat Intelligence Alignment: Compare your internal scan reports with live cyber-threat data (e.g., CISA’s catalog of actively exploited vulnerabilities). If you find that hacking groups or ransomware are actively exploiting any Medium CVE, immediately raise the status of that vulnerability to "Urgent". Conclusion Proper use of CVE and CVSS is a matter of context, not quantity. When you align universal vulnerability information with your business assets and the real-world threat landscape, you can focus

2026-06-23 原文 →
AI 资讯

I built a fully local AI assistant at 16 — no cloud, no API keys, runs on your GPU

I'm 16, from Pune, India. For the past couple of years I've been building O-AI — a fully local AI desktop assistant. No cloud. No API keys. No data leaving your machine. Everything runs on your own GPU. Why I built it Every AI assistant I tried sent data somewhere. ChatGPT, Copilot, Gemini — all cloud. I wanted something that felt like JARVIS from Iron Man: smart, fast, personal, and private. So I built it from scratch. What O-AI can do Core engine: Runs LLMs fully on-device via llama.cpp / Ollama (zero internet required) Self-learning core — extracts facts from every conversation and stores them permanently Fine-tuning pipeline — train the model on your own data, locally Voice & language: Voice control in English, Hindi, and Marathi via Whisper (running locally) Responds in whatever language you speak Modes: JARVIS mode — arc-reactor HUD, 4 reactive states, British-male voice, "sir" persona Take Over PC mode — full desktop automation Animated floating desktop pet (4 types, draggable, reacts to voice) 30+ automation fast-paths: open apps, search the web, control media, screen vision, run code, edit files, cursor control, social media steps, clipboard ops... Multi-step agent system: plan → execute → verify loop with 14+ step types (web_search, fetch_url, read_screen, run_code, edit_file, open_social, and more) Stack Backend: Python (Flask IPC + agent core) Frontend: Electron + vanilla JS LLM: llama.cpp / Ollama Voice: Whisper (local) + Edge TTS / neural voice Vision: PIL + screen capture The hardest bugs "Says done but isn't" — Early versions reported success even when an agent step failed. Fixed by building a proper outcome verifier that reads the actual result, not the plan. The "opens a random video" bug — Asking the agent to play something would open random YouTube videos. Root cause: the plan validator wasn't catching placeholder URLs like [video_url] . Fixed with a universal content guard on all plans. GPU offloading on Windows — Getting all 32 layers onto the

2026-06-23 原文 →
开发者

Ever had a renamed column quietly break a CSV export? csv-pipe makes it a compile error, reads and writes both ways, and parses several times faster than papaparse. Live playground in the post to try your own data.

csv-pipe: read and write CSV in TypeScript, several times faster than papaparse Myroslav Martsin Myroslav Martsin Myroslav Martsin Follow Jun 22 csv-pipe: read and write CSV in TypeScript, several times faster than papaparse # javascript # typescript # webdev # node 1 reaction Add Comment 2 min read

2026-06-23 原文 →
开发者

Sentry vs OpenTelemetry: You Don’t Need to Pick One

TL;DR — If your backend already uses OpenTelemetry, you can send traces and logs to Sentry by changing a few environment variables. No SDK swap, no instrumentation rewrite. Point your OTLP exporter at Sentry’s endpoint, add the Sentry SDK on the frontend for browser context, and you get one connected trace from click to backend span. You already instrumented the backend with OpenTelemetry. Your services emit spans. Your teams know the OTel APIs. Maybe you already run a Collector. So when you start evaluating Sentry, the obvious question is: Do you need to replace your OpenTelemetry setup with the Sentry SDK? No. The practical answer is usually: keep OpenTelemetry where it already works, add the Sentry SDK where it gives you more application context, and send OpenTelemetry Protocol (OTLP) events to Sentry. For a web app, that often means using the Sentry SDK on the frontend for browser tracing, errors, logs , Session Replay , and source maps, while keeping OpenTelemetry on the backend for existing service instrumentation. One scope note: OTLP can carry traces, logs, and metrics. At this moment, Sentry’s OTLP ingest supports logs and traces, not metrics. We’re considering adding support for them in the future. The important part is separating two decisions that often get lumped together: How traces stay connected across frontend and backend. How backend OTLP events are exported to Sentry. Once you separate those, the architecture gets a lot easier to reason about. Sentry vs OpenTelemetry is the wrong question The first decision is trace linking. If a user clicks a button in your React app and that click triggers a backend request, the frontend and backend need to agree on the same distributed trace context. In this example, the Sentry frontend SDK sends W3C traceparent headers (configurable through the propagateTraceparent option), and the OpenTelemetry backend continues the trace. That linking is handled by the frontend SDK configuration: Sentry . init ({ integration

2026-06-23 原文 →
开发者

10 Things Nobody Tells You About process.env

10 Things Nobody Tells You About process.env I've burned myself on most of these so you don't have to. Here's what I wish someone had told me early on. 1. Keys are case-sensitive on Linux, case-insensitive on Windows process . env . PORT = " 3000 " console . log ( process . env . port ) // undefined on Linux, "3000" on Windows This one got me during a "works on my machine" incident. My Windows dev box ran fine. The Linux CI server crashed because a teammate typed env.port instead of env.PORT . Your CI runs Linux. Your dev box probably runs macOS or Windows. Case-sensitivity differences will bite you. How to handle it : Use a validation layer that throws on missing keys. A simple getEnv("PORT") will catch typos at startup. 2. Values are always strings console . log ( typeof process . env . PORT ) // "string" even if you set PORT=3000 Number(process.env.PORT) can return NaN without throwing. Boolean values like "false" are truthy strings. How to handle it : Always parse. If you use a schema library like CtroEnv, it coerces types and throws on invalid input. 3. process.env is NOT the same as .env This confused me for way too long. process.env is whatever the shell gave the process. A .env file is just a text file dotenv reads to populate process.env . Node doesn't touch .env files on its own. // This won't read .env automatically console . log ( process . env . MY_VAR ) // undefined How to handle it : Call dotenv.config() at entry, or use @ctroenv/node which loads .env files automatically. 4. You can set env vars per-command PORT = 4000 node app.js This sets PORT only for that single process. It doesn't pollute your shell session. Super useful for one-off runs or testing different configurations without editing files. console . log ( process . env . PORT ) // "4000" 5. process.env is mutable at runtime process . env . DATABASE_URL = " postgres://hacker:gotme@evil.com/db " I've seen code that modifies process.env to "fix" config at runtime. Don't do this. If something i

2026-06-23 原文 →
AI 资讯

The First Text Message Said Merry Christmas

The first text message ever sent was not a love note, a meeting reminder, or a meme. It was a Christmas greeting. On December 3, 1992, a 22-year-old engineer named Neil Papworth sat at a desktop computer, typed two words, and sent the world's first SMS to a mobile phone: "Merry Christmas." More than thirty years later, that humble two-word message has grown into one of the most quietly important protocols in connected technology, and it still shows up in the IoT devices we build today. The engineer who sent the first SMS Neil Papworth was working for the Anglo-French firm Sema Group Telecoms, part of a team building a Short Message Service Centre (SMSC) for the British carrier Vodafone. The SMSC was the piece of infrastructure that would store and forward text messages across the cellular network. To prove it worked, Papworth sent a test message from a computer terminal to the Orbitel 901 handset of Richard Jarvis, a Vodafone director who was at a company Christmas party. The message arrived. Jarvis read it. But he could not reply, because mobile phones at the time had no way to compose a text. There was no keypad-driven messaging app, no T9, no touchscreen. SMS started life as a one-way novelty riding on a spare slice of the network's signalling channel, and almost nobody involved thought it would matter very much. Why SMS was designed the way it was The technical detail that makes this story relevant to anyone building connected hardware is how SMS was engineered. Text messages were squeezed into the control channel that phones already used to talk to cell towers, the same channel that handles things like call setup. That is why a single SMS is capped at 160 characters: it had to fit inside a small, fixed-size signalling packet. This constraint turned out to be a feature. SMS is lightweight, store-and-forward, and works even when a data connection is weak or absent. The message waits in the SMSC until the device is reachable, then gets delivered. No persistent con

2026-06-23 原文 →
AI 资讯

Most AI agent memory never pays for itself

Built a small tool for Claude Code that tracks whether “agent memory” rules actually pay for themselves in token usage. The idea is simple: every persistent instruction should justify itself by reducing future token cost. If it doesn’t, it gets flagged for removal. Over time, a surprising amount of memory ends up being neutral or negative ROI once measured. Check it out, would mean a lot :) Repo: https://github.com/vukkt/token-warden

2026-06-23 原文 →
AI 资讯

Give your AI agent its own calendar to book meetings

An AI agent that can email but can't hold a calendar slot is only half useful. The moment a conversation turns into "let's meet Thursday at 2," the agent needs a real calendar — one that sends invitations people accept in Google Calendar or Outlook, receives invites at its own address, and RSVPs back so the organizer sees a real response next to everyone else's. Bolting a scheduling library onto a shared mailbox doesn't get you there; the agent needs a calendar identity of its own. An Agent Account ships with exactly that. Every account gets a primary calendar that hosts events, accepts invitations over standard iCalendar, and RSVPs with yes, no, or maybe. To a participant, the agent is just another attendee on the invite. This post walks through using that calendar from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for. The calendar an Agent Account comes with When Nylas provisions an Agent Account, it creates a primary calendar that belongs to the account. You reach it through the same Calendars and Events endpoints at /v3/grants/{grant_id}/... that any other grant uses, so calendar code you've written for a connected Google or Microsoft account works here unchanged. Each account gets: A primary calendar , provisioned automatically. It can't be deleted while other calendars exist on the account. Additional calendars , up to your plan's cap, for separating concerns — a sales-calls calendar and an internal one on the same agent. Free/busy queries , so the agent can check its own availability before proposing a time. Event webhooks — event.created , event.updated , and event.deleted fire on every change, whether it came from the agent or from someone responding to an invitation. List the calendars from the terminal with nylas calendar list , or over the API with GET /v3/grants/{grant_id}/calendars . Both return the primary calendar plus any you've added. List what'

2026-06-23 原文 →
AI 资讯

Keep your AI agent's email replies in the right thread

An AI agent sends an email, a reply lands three hours later, and the agent has to answer two questions before it can do anything useful: which conversation is this, and what did I last say? Get the first one wrong and the agent's reply shows up in the recipient's inbox as a brand-new message instead of slotting into the existing thread. To the person on the other end, that looks broken — like the agent forgot the conversation it started. Threading is the part of agent email that's easy to get almost right and quietly wrong. The fix lives in a few email headers most developers never touch, and in the Threads API that groups messages into conversations for you. This post walks through both, from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal. I work on the CLI, so the terminal commands below are the ones I reach for when I'm testing a reply loop. The three headers that make threading work Threading runs on three email headers, not on subject lines. Every message carries a Message-ID — a globally unique identifier the sending server stamps on it. When someone replies, their mail client adds In-Reply-To (the Message-ID of the message being answered) and References (the full chain of Message-ID values, oldest to newest). Those two headers are how every mail client decides which messages belong together. Here's what the chain looks like across one exchange. The agent's first message gets a Message-ID ; the reply points back at it; the agent's follow-up references both: # The agent's outbound message Message-ID : <abc123@agents.yourcompany.com> Subject : Following up on your demo request # The recipient's reply Message-ID: <def456@gmail.com> In-Reply-To: <abc123@agents.yourcompany.com> References: <abc123@agents.yourcompany.com> Subject: Re: Following up on your demo request # The agent's follow-up Message-ID: <ghi789@agents.yourcompany.com> In-Reply-To: <def456@gmail.com> References: <abc123@agents.yourcompany.com> <def456@gmail.com> The Ref

2026-06-23 原文 →
AI 资讯

Give your AI agent a real email address on your own domain

Most "AI agent that emails for you" demos point a language model at a human's Gmail inbox over OAuth. That works until the agent needs its own identity: an address people reply to, a calendar that accepts invites, a mailbox your application owns end to end. Borrowing a human's inbox means inheriting their OAuth scopes, their rate limits, and the awkwardness of an agent sending mail as a person who didn't write it. A Nylas Agent Account flips that around. It's a real name@yourcompany.com mailbox that you create and control entirely through the API — it sends, receives, hosts calendar events, and RSVPs, and it's indistinguishable from a human-operated account to anyone on the other end. Under the hood it's just a grant , so the grant_id you get back works with the same grant-scoped endpoints — Messages, Threads, Folders, Drafts, Attachments, Contacts, Calendars, and Events — you've already used for connected accounts, plus the standard webhook triggers. This post is a working tour of provisioning one, from two angles: the HTTP API for your backend, and the Nylas CLI for the terminal and quick experiments. I work on the CLI, so the terminal commands below are the exact ones I reach for. Why an Agent Account beats borrowing a human inbox An Agent Account is a first-class sender, not a delegated one. When the agent owns support@yourcompany.com , people reply to it directly, calendars invite it as a normal participant, and its mail authenticates as coming from you. A few concrete differences from pointing an agent at someone's existing mailbox: No OAuth flow to babysit. Creation needs only an email address on a domain you've registered — there's no refresh token to store or rotate, and the grant rarely expires because there's no OAuth token to refresh. Its own reputation. The account sends on your domain, and a new domain establishes its sender reputation over roughly four weeks of gradual sending. That reputation is yours to protect, not a shared corporate inbox's. Per-t

2026-06-23 原文 →
AI 资讯

SQL Formatter: a data tool that earns its tab

Developers inheriting sprawling SQL codebases or revisiting queries from weeks earlier know the frustration: a dense, unformatted block that obscures joins, filters, and logical flow. Readable SQL isn’t cosmetic — it directly affects debugging speed, peer review accuracy, and long-term maintainability. What it is SQL Formatter restructures raw SQL into clear, conventionally formatted code, running entirely in the browser. It applies consistent indentation, capitalisation of keywords, and logical line breaks — all without altering the query’s semantics. The formatter understands the syntax of all major database engines, including PostgreSQL, MySQL, SQL Server, and Oracle, so it preserves dialect-specific functions and operators rather than flattening them into a generic style. The tool is one of 200+ free browser utilities on DevTools. It processes all input entirely on your machine — no data ever leaves the browser, no account is required, and no analytics track your usage. That privacy-first design means you can safely format queries that contain proprietary business logic embedded in production SQL. The engine handles the full spectrum of SQL complexity: basic SELECT statements, multi-table joins, Common Table Expressions (CTEs), correlated subqueries, window functions, and DML operations like INSERT or UPDATE . Because it parses the input rather than applying regular expressions, deeply nested constructs retain their hierarchy, with each subquery or CTE level indented to show ownership. How to use it Paste any SQL fragment into the left-hand editor and the formatted result appears instantly in the output panel. A live preview updates as you switch formatting options, so you can tune the output without re-pasting. The primary configuration controls help you match your team’s conventions or personal preference: Dialect : selecting a specific database ensures that functions such as PostgreSQL’s STRING_AGG or MySQL’s GROUP_CONCAT are not inadvertently mangled, and th

2026-06-23 原文 →
AI 资讯

Tired of Searching for Different Base64 Tools? I Built One Place for Everything

As developers, we've all been there. Q: Need to decode a Base64 string? Open one website. Q: Need to convert an image to Base64? Open another website. Q: Need to validate a Base64 string? Search Google again. Q: Need to compare two Base64 values? Yet another tool. I found myself repeatedly switching between different websites, browser tabs, and terminal commands just to perform simple Base64-related tasks. So I decided to build something that solved this problem for me. The Goal Keep every commonly used Base64 utility in one place and make it work directly in the browser. No installations. No command-line knowledge required. No account creation. Just open the website and use the tool What You'll Find Instead of only providing an encoder and decoder, I wanted to cover the complete Base64 workflow. Some of the available tools include: Base64 Encode / Decode Image to Base64 Audio to Base64 Video to Base64 Base64 Validator Base64 Detector Base64 Compare Base64 Repair Base64 URL Encode Base64 File Decoder CSS Data URI Converter And more are being added regularly. Why I Built It Honestly, this started as a personal productivity project. I was using different Base64 tools almost every week and got tired of bookmarking multiple websites for related tasks. Having everything in one place turned out to be surprisingly useful, so I decided to make it public. Give It a Try https://base64converters.com I'm continuously improving it and would love feedback from fellow developers. Are there any Base64-related tools or workflows you use frequently that should be included?

2026-06-23 原文 →
AI 资讯

How I Cut My LLM API Bill by 80% With a Simple Router

No fancy infrastructure. Just a 50-line Python function that picks the right model for the right query. Last month my LLM API bill hit $340. This month: $67. Same traffic. Same product. The only change was adding a simple router that stops sending every request to Claude Sonnet when GPT-4o mini can handle it just as well. Here's exactly how it works. The Problem When you prototype, you pick one model and hardcode it everywhere. Usually something capable like GPT-4o or Claude Sonnet, because you want good results fast. Then you ship, traffic grows, and you get a bill that makes you question your life choices. The thing is — not all queries need a flagship model. In a typical RAG app: "What is the return policy?" → GPT-4o mini handles this fine "Summarize these 5 conflicting documents and identify the key disagreement" → needs Sonnet You're paying Sonnet prices for return policy questions. That's the bug. The Fix: A Complexity Router import anthropic from openai import OpenAI openai_client = OpenAI() anthropic_client = anthropic.Anthropic() def classify_complexity(query: str) -> str: """Returns 'simple' or 'complex'.""" simple_indicators = [ len(query.split()) < 15, query.endswith("?") and query.count("?") == 1, not any(w in query.lower() for w in [ "compare", "analyze", "summarize", "explain why", "difference between", "pros and cons", "evaluate" ]) ] return "simple" if sum(simple_indicators) >= 2 else "complex" def route(query: str, context: str = "") -> str: complexity = classify_complexity(query) if complexity == "simple": # $0.15/M input — GPT-4o mini response = openai_client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": context}, {"role": "user", "content": query} ] ) return response.choices[0].message.content else: # $3.00/M input — Claude Sonnet (only when needed) response = anthropic_client.messages.create( model="claude-sonnet-4-6", max_tokens=1024, system=context, messages=[{"role": "user", "content": query}] ) retur

2026-06-22 原文 →
AI 资讯

React Server Components in 2026: Patterns, Pitfalls, and When to Actually Use Them

React Server Components in 2026: Patterns, Pitfalls, and When to Actually Use Them Most React Server Components problems stem from teams treating them like regular components with a new rendering location. The architecture shift is deeper than that. RSC fundamentally changes where code executes, what data can cross boundaries, and how developers reason about state. Teams that ignore these constraints burn weeks debugging serialization errors and performance regressions. The pattern that production teams overlook is the server/client boundary itself. Understanding where computation happens, what props can serialize, and when to break out of server rendering determines whether RSC improves or destroys your application's performance. Core Concepts: How RSC Actually Works Under the Hood React Server Components execute on the server and send rendered output to the client. No JavaScript bundle ships for these components. The client receives a serialized tree describing what to render, along with holes for client components to fill. The execution model works like this: the server runs your component tree, fetches data directly, and serializes the result. When the payload reaches the browser, React reconstructs the UI without hydrating server component code. Only client components hydrate with their JavaScript bundles. RSC execution flow from server to client This distinction is critical. Server components cannot use hooks like useState or useEffect because they don't exist in the browser. They render once on the server per request. Client components ship JavaScript and can use the full React API. The implication here is that your component tree becomes a mix of server and client code. The boundary between them determines your bundle size, waterfall depth, and debugging complexity. Production-Ready Patterns: Streaming, Suspense, and Data Fetching The correct pattern for data fetching in server components eliminates the request waterfall. Fetch data directly in the component

2026-06-22 原文 →
AI 资讯

From Feature Delivery to Platform Engineering.

The Problem: Feature Velocity Was Creating Structural Debt The system originally started as a simple feature delivery backend: A Django API powering agricultural insights Celery workers handling asynchronous processing Independent endpoints for each new capability A growing set of Earth Observation computations (NDVI, NDWI, etc.) At first, it worked. But as more features were added, a pattern emerged: Each feature introduced its own pipeline logic Observability was inconsistent across services API contracts drifted between frontend and backend Debugging required tracing multiple disconnected systems We weren’t scaling functionality. We were scaling fragmentation. The Turning Point: Features vs Platforms The key realization was simple: Features solve user problems. Platforms solve system problems. We were repeatedly rebuilding: Authentication flows Data ingestion logic Processing pipelines API validation layers Monitoring hooks Each feature was solving its own version of these concerns. That is where platform engineering became necessary. The Shift: Introducing a Platform Layer We introduced a platform layer between feature delivery and infrastructure. Instead of building isolated pipelines, we standardized: 1. Unified API Surface All Earth Observation workflows (NDVI, NDWI, and future indices) were normalized into a consistent API contract. Shared request/response structure Versioned endpoints Schema validation through serializers Central routing logic This eliminated endpoint fragmentation. 2. Standardized Processing Pipeline Celery tasks were refactored into a reusable pipeline pattern: Ingestion Validation Computation Storage Publishing Instead of feature-specific workers, we moved toward composable tasks. This allowed new indices or processing logic to plug into the same execution flow. 3. Observability as a First-Class Layer One of the biggest failures in the original system was visibility. We introduced: Structured logging across all services Traceable job IDs

2026-06-22 原文 →