AI 资讯
Stop Vibe Coding. Start Spec-Driven Development with N45.AI
AI coding tools are changing how software gets built. Claude Code, Cursor, GitHub Copilot, Windsurf and other tools can generate code incredibly fast. For small tasks, they are already useful: write a component, explain a function, scaffold an endpoint, create a test, refactor a file. But after using AI in real projects, one thing becomes obvious: The problem is no longer code generation. The problem is engineering control. Most AI coding workflows still look like this: text idea -> prompt -> code -> fix -> prompt again -> more code -> lost context -> start over It feels fast at the beginning. Then the project grows. Requirements change. Architecture decisions disappear inside chat history. The AI forgets previous context. You start acting as product manager, architect, reviewer, QA, DevOps, and prompt engineer at the same time. That is not software engineering. That is vibe coding. ## Vibe coding works until it doesn't Direct AI coding is great when the task is isolated. Ask for a React component. Ask for a SQL query. Ask for a utility function. Ask for a unit test. No problem. But real software is not a collection of isolated snippets. Real software has: - business rules - architectural constraints - existing patterns - security concerns - database impact - deployment requirements - edge cases - regression risk - long-term maintenance When AI jumps directly from prompt to code, it often skips the thinking that should happen before implementation. The result may compile. But does it fit the architecture? Does it respect the domain? Does it create hidden technical debt? Does it solve the right problem? That is the gap we are trying to close with N45.AI. ## What is N45.AI? N45.AI is a framework that turns AI coding tools into a structured engineering workflow. It works with the tools developers already use, including Claude Code, Cursor, GitHub Copilot, and Windsurf. The idea is simple: Instead of treating AI as one generic assistant, N45.AI organizes the work like a
AI 资讯
I just launched 𝗙𝗮𝗰𝗲 𝗦𝗼𝗿𝘁 𝗦𝘁𝘂𝗱𝗶𝗼! 📸🤖
It is a privacy-first, local-first photo organizer powered by deep learning face recognition. It detects, embeds, and groups faces to organize your photos automatically—all 100% offline. 🔥 Highlight Features: ✅ 100% Local: No cloud APIs, no telemetry, no leaks. ✅ Deep Learning: Driven by OpenCV DNN (YuNet + SFace ONNX models). ✅ Smart Automation: Copies matches, partial matches, and individual profiles into organized folders, complete with ZIP archives and JSON reports. ✅ Standalone EXE: Run it on Windows instantly with zero dependencies. ✅ Dynamic UI: Fully responsive Tailwind dashboard with Dark/Light modes. Check out the repository, download the EXE, or contribute: 👉 https://github.com/Shaan-alpha/face-sort-studio Let me know what you think! ⭐ machinelearning #computervision #python #localfirst #privacy #developers #opensource #ai Internet access on first launch only (to fetch the AI models ~40-50mb)
AI 资讯
How I Ship 10x Faster with Claude Code: The 5-Layer Workflow System
After 8 months of daily Claude Code use, I've distilled my workflow into a 5-layer system. Each layer builds on the previous one. Skip one, and the whole thing falls apart. The Problem with Most Claude Code Users Most people use Claude Code like ChatGPT — open terminal, ask a question, close, repeat. The next day, they explain their project from scratch. Again. The symptom: 20% of every session is wasted on context re-establishment. The root cause: No project memory, no workflow discipline. Here's the system that fixed it for me. Layer 1: CLAUDE.md — Your Project's Memory Anchor This is the foundation. Without it, nothing else works. CLAUDE.md is a file at your project root. Claude reads it automatically at the start of every session. It tells Claude: What this project is (one sentence) The tech stack (specific technologies, not "Python web framework") The architecture (the big picture you'd need 3 files to understand) Unique conventions (not generic advice like "write tests") Quality priorities Bad CLAUDE.md (you've probably written this): # My Project A web application built with Python and FastAPI. ## Development - Write clean code - Add unit tests - Use Git This tells Claude nothing it doesn't already know. Good CLAUDE.md: # CLAUDE.md ## Project Overview Internal RAG knowledge base serving 500+ employees. ## Tech Stack FastAPI + LangChain + Milvus + PostgreSQL + Redis ## Commands - Start: `uvicorn app.main:app --reload --port 8080` - Test: `pytest -x --cov=app --cov-report=term-missing` ## Architecture Request flow: router → service → retriever → Milvus → generator → LLM API Key directories: - app/router/ - API layer - app/service/ - Business logic orchestration - app/retriever/ - Retrieval strategies (vector/BM25/hybrid) - app/generator/ - LLM calls and prompt management ## Key Conventions - All APIs return `{"data": ..., "error": null}` - Retrieval results MUST include source field - Milvus collection naming: `{env}_{doc_type}` The rule: Only write what's uniq
AI 资讯
How to Use Primitive Types in TypeScript: string, number, and boolean
TLDR TypeScript has 7 primitive types: string , number , boolean , null , undefined , bigint , and symbol . You use them to tell TypeScript what kind of value a variable holds. You write them in lowercase. TypeScript can often figure out the type for you. But knowing how each one works is key to writing safe and clear code. What Are Primitive Types? Primitive types are the simplest building blocks in TypeScript. Every piece of data in your program starts with one. They hold a single value. They are not objects. You cannot add methods or properties to them directly. TypeScript has 7 primitive types in total: Type What It Holds string Text like names, messages, or IDs number Any number: integers, decimals, negatives boolean Only true or false null An intentional empty value undefined A value that was never assigned bigint Very large whole numbers symbol A unique identifier value This article covers all 7. You will use string , number , and boolean the most in everyday TypeScript code. How to Use the string Type A string holds text. Use it for names, messages, emails, URLs, and any other text data. Basic string annotation let firstName : string = " Alice " ; let greeting : string = " Hello, world! " ; let empty : string = "" ; Three ways to write strings TypeScript supports the same three string styles as JavaScript: let single : string = ' Single quotes work fine ' ; let double : string = " Double quotes work too " ; let template : string = `Template literals with ${ firstName } ` ; Template literals (backticks) let you insert values inside a string with ${} . TypeScript checks the types of those inserted values too. let age : number = 30 ; let message : string = `I am ${ age } years old` ; // TypeScript checks that 'age' is compatible here What TypeScript catches with strings let name : string = " Alice " ; name = 42 ; // Error: Type 'number' is not assignable to type 'string'. name = true ; // Error: Type 'boolean' is not assignable to type 'string'. Once a variable
开发者
JEP 401 being merged into JDK 28?
submitted by /u/davidalayachew [link] [留言]
开发者
C# 14: The `field` Keyword — Cleaner Properties, Zero Boilerplate
C# 14: The field Keyword — Cleaner Properties, Zero Boilerplate Every C# developer has been there. You start with a clean auto-property, then requirements change and you need to add a tiny bit of validation. Suddenly that one-liner explodes into six lines of boilerplate — a private backing field, a getter that just returns it, a setter that assigns it. The logic is two words. The ceremony is everything else. C# 14 fixes this with the field keyword: a contextual keyword that refers to the compiler-synthesized backing field of a property, letting you write custom accessor logic without ever declaring an explicit field. The Problem: Boilerplate Tax on Simple Properties Auto-properties are one of C#'s best quality-of-life features. This is clean: public string Username { get ; set ; } But the moment you need to trim whitespace on assignment, that cleanness evaporates: private string _username = string . Empty ; public string Username { get => _username ; set => _username = value . Trim (); } You now have six lines — and four of them exist only to hold the shape of the pattern together. The backing field _username is not carrying any meaningful design weight. Its only job is to be a storage slot that Username uses privately. You already know the compiler creates one for auto-properties. You are just forced to make it visible so you can reference it. This is the boilerplate tax. You pay it every time you add even the smallest piece of logic to a property. Why field Exists The C# language team has discussed this friction for years. The challenge was finding syntax that is: Unambiguous — no conflict with existing identifiers Familiar — consistent with how value works in setters Scoped — only meaningful inside a property accessor The solution landed in C# 14: the contextual keyword field . Just like value refers to the incoming assignment in a setter, field refers to the hidden backing storage the compiler manages for the property. It is contextual, which means it only acts
AI 资讯
Your Agent Returns 200 and Lies. Verify Before You Trust
A success gate verifies an AI agent's claimed success before your system accepts it. SuccessGate runs three read-only checks — schema/contract, claim-vs-evidence against the actual tool-call trace, and an optional post-condition probe — and turns a silent 200 into an explicit REJECTED with reasons. It's stdlib Python, needs no API key, moves nothing, and ships with a self-test you run in one command. Here's the failure that started this for me. An agent in a CRM workflow reported {"status": "sent", ...} for an invoice. Clean run. Green dashboard. 200 OK. The invoice went to a customer id that wasn't on our allow-list — a near-miss hallucination the model was completely sure about. Nothing crashed. No exception, no stack trace. We found it days later, downstream, the expensive way. That's not a rare bug. It's the default failure mode of agents in production, and it has a name now: silent-success drift . Cycles' writeup put it bluntly — "200 OK Is the Most Dangerous Response in Production" : "The most dangerous failures look like success." And the measurements back it up. The Berkeley Function-Calling Leaderboard (BFCL v3) puts frontier-model structurally invalid tool calls at 2–5% even on clean benchmark prompts — higher in noisy production ( via Future AGI ). The arXiv paper Agent Behavioral Contracts reports that across 1,980 sessions , contracted agents caught 5.2–6.8 soft violations per session that uncontracted baselines missed entirely. So the question is not how do I see failures sooner . It's how do I stop accepting a success the agent never actually achieved. TL;DR A 200 and a "status": "done" are claims, not proof. Agents return both while doing the wrong thing — or nothing. Observability is tracking : it tells you a call happened. It can't tell you the result was correct. That's a control problem. verify() runs three checks before you accept success: (1) schema/contract (shape, types, enums/allow-list), (2) claim-vs-evidence (did the agent actually call th
AI 资讯
C3 0.8.1 released: Raiding the stdlib for bugs
submitted by /u/Nuoji [link] [留言]
开发者
The unwritten laws of software engineering
submitted by /u/fagnerbrack [link] [留言]
AI 资讯
‘AI-pilled’ firms spend $7,500 per employee each month on AI
The most AI-obsessed firms are spending roughly $7,500 monthly per employee on AI, per Ramp AI Index. That's not more than an engineer's salary — yet.
AI 资讯
You can just tell the Instagram algorithm what you want now
Instagram is going to let you tweak what its algorithm shows you on your main feed. With the Your Algorithm feature, "you can now see the topics we think you're interested in, and change them, across all the major parts of Instagram," according to Instagram boss Adam Mosseri. Right now, the feature will only surface […]
AI 资讯
You Don't Need Another Agent. You Need a Linter.
In my last post I complained — a lot — about product managers and how they made my life hell with vibe code. PS: apologies, manager, if you're reading this — but it's true. Now, I'm not here just to complain. There were a lot of learning opportunities too, like how to handle legacy / vibe code. Because at the end of the day, both are the same: no one knows how they work, but somehow they keep working. Touching them is like defusing a bomb — you never know how your change might cascade and break the core logic. The good news is that vibe code is much simpler than legacy. AI, in all its glory, tries to write perfect-looking code — proper function names, comments, the works — not like legacy code where a single function runs 500 lines, with spaghetti names all over that make no sense and comments that are out of date. And that makes it something I can actually handle. I still don't have a perfect, step-by-step playbook — but I've got pieces. The first one. The cheapest and the oldest one. The one the industry solved decades ago and the whole "AI built my app in a day" crowd somehow forgot exists. A linter. Yes, you heard me right. A linter. ESLint. Most people who've been in this industry already know it. It's the most boring, reliable tool in the box. But in an era where the answer to every problem is "add another AI," it's worth saying out loud why the boring tool still wins. What a linter actually is If you vibe-coded your way into this world, or you're new to web dev in general and have never heard the word "lint", here's the honest version. A linter is a set of rules you add to your repo. It reads your code without running it, checks it against those rules, and flags everything that's broken, sloppy, or about to bite you in production. The detail people get wrong: it's not a grep for bad words. A real linter parses your code into a syntax tree and actually reasons about its structure — what's imported, what's called, what's reachable, what types flow where. That's
AI 资讯
CLI over MCP: a small Chrome DevTools experiment in Copilot CLI
I ran the same browser smoke task through two paths: direct Chrome DevTools MCP and a custom CLI skill around mcp2cli . In GitHub Copilot CLI with gpt-5.3-codex-medium , direct Chrome DevTools MCP added about 5k tokens of upfront context before the agent did any work. The runtime table is too small and too noisy to rank the tools. The useful question is where the agent pays to discover the browser-control surface. mcp2cli README says it can “Save 96-99% of the tokens wasted on tool schemas every turn.” That is a strong claim and frankly I didn't no expect that sort of numbers... It's just the CLI part resonates with me - (a) there's no system prompt pollution with CLI, (b) if you choose between gh CLI and GitHub MCP the former would be better due to the fact that model already knows the tool and there's less tokens wasted on JSON schemas and tool calls. I used Chrome DevTools MCP a lot and I have chosen this MCP as a test bed to try mcp2cli . This came handy cause I started my experiments with the minimal pi coding agent and it doesn't bundle any MCP integration, just the basic bash tool, I was very much happy not to bloat my instal with a dedicated MCP plugin. Although in this cases I cmpared MCP vs CLI using a fully fledged GitHub CLI. Tool discovery is part of the experiment. Native MCP gives the agent a tool surface by loading schemas into context. A CLI wrapper makes the agent discover the surface the way it discovers any other command-line tool: list, search, ask for help, run a small probe, write down what worked. That changes where the discovery cost lands. The Setup I ran this in GitHub Copilot CLI using gpt-5.3-codex-medium : Copilot stock MCP servers were disabled. The app under test was a private Pythobn/Streamlit codebase. The browser task was the same 9-step smoke test in both variants. One variant used direct Chrome DevTools MCP. Another variant used a custom skill that wraps Chrome DevTools MCP via mcp2cli . The custom skill itself started as an ad-h
AI 资讯
# I Just Published My First npm Package — Here's Everything I Did
A complete walkthrough of publishing Cartlify — a React e-commerce UI kit — to npm for the first time. The Milestone Yesterday I published Cartlify to npm. npm install cartlify It sounds simple. But getting to that one line took more decisions, more configuration, and more trial and error than I expected. This article covers everything — from setting up the build config to the actual publish command — so you don't have to figure it out the hard way. What Is Cartlify? Cartlify is a production-ready React + TypeScript + Tailwind CSS component library focused on e-commerce UI. 4 components that every e-commerce project needs: ProductCard — 3 layout variants, image gallery, wishlist, sale badges, skeleton loading CartDrawer — animated slide-in, focus trap, ESC dismiss, quantity stepper CheckoutStepper — horizontal/vertical, animated connectors, keyboard navigation PageLoader — 4 animation styles, 3 position modes Plus 3 utility hooks, 11 tree-shakeable icons, 40+ CSS design tokens, full dark mode, and 141 Jest + React Testing Library tests. Built so freelance developers and indie makers can skip the painful e-commerce UI layer and ship faster. Why Publish to npm? Before npm, Cartlify was only available on Gumroad as a paid download. That's fine — but npm adds something Gumroad can't: Developer sees Cartlify → runs npm install cartlify → evaluates the compiled output → trusts the quality → buys the full source on Gumroad npm is a credibility and discovery channel — not just a distribution method. A package on npm signals that something is real, maintained, and production-ready. Also: npmjs.com gets millions of developer searches every month. That's free traffic you can't get from Gumroad alone. The Build Setup — tsup The most important decision before publishing is how you bundle your library. I chose tsup — a zero-config TypeScript bundler built on esbuild. Here's why: Tool Config needed Speed Output Rollup Lots Medium ESM + CJS Webpack Heavy Slow CJS only Vite lib mode
AI 资讯
Generation-Side Tooling Outpaces Validation-Side Tooling
The generation side is shipping fast (TileGym, AutoKernel, KernelEvolve). The validation-side surface for “what the kernel actually did at runtime” has not kept pace. TL;DR In the past nine months, three significant releases have landed for auto-generation of CUDA kernels: NVIDIA TileGym , RightNow AutoKernel, and Meta’s KernelEvolve. Each ships training infrastructure for kernel generation. Validation infrastructure (what the generated kernel actually did at runtime, on a real workload, in a production-shaped environment) has not kept the same pace. eBPF traces are the ground-truth layer that closes the gap. What “validation” means at the kernel level Two distinct validation surfaces: Pre-launch: the generated CUDA C compiles, the PTX assembles, the kernel passes a numerical-equivalence test against a reference. Standard compiler / unit-test territory. Generation frameworks ship this themselves. Post-launch: the kernel ran, returned, took N microseconds, used M registers per thread, hit X cache miss rate, and did or did not serialize the rest of the stream behind it. This is the layer that an eBPF trace plus standard CUDA driver counters can answer for any kernel, generated or hand-written. Auto-generation pipelines do not by default close the post-launch loop. They demonstrate “the kernel works in our test setup”. They do not demonstrate “the kernel does not regress p99 latency on production inference traffic”. What an eBPF trace adds to a generated kernel Once a generated kernel is in a real workload, the same trace surface used for any CUDA kernel applies: launch latency from cudaLaunchKernel , sync stalls from cudaStreamSynchronize , host-side overhead from the dispatcher, host scheduling preemption while the GPU is busy. None of those signals are visible to a generation framework that evaluates kernels in isolation. -- post-launch validation: did the new generated kernel regress p99? SELECT kernel_name , COUNT ( * ) AS launches , AVG ( duration_ns ) / 1 e3 AS
开发者
A Fun & Absurd Introduction to Vector Databases • Alexander Chatzizacharias
submitted by /u/goto-con [link] [留言]
开发者
ReactJS Syntax For Web Components
Im investigating an idea i had about JSX for webcomponents after some experience with Lit. I am sharing this here because it might be interesting/educational for someone, if it isnt, let me know and i'll remove the post. Lit is a nice lightweight UI framework, but i didnt like that it was using class-based components. Vue has a nice approach but i prefer working with the syntax that React uses. I find it more intuitive for debugging and deterministic rendering. I wondered if with webcomponents, i could create a UI framework that didnt need to be transpiled. Read the docs Checkout the code Storybook demo (My intentions with this framework is to get to a reasonable level of stability, to then replace React on some of my existing projects.) IMPORTANT: Im not trying to promote "yet another ui framework", this is an investigation to see what is possible. You should not use this framework in your own code. It is not production-ready. It is not on NPM. Im not looking for another framework to replace React (im trying to create it). This framework is intended for myself on my own projects. This project is far from finished. Feel free to reach out for clarity if you have any questions. submitted by /u/Accurate-Screen8774 [link] [留言]
AI 资讯
Thinking in Graphs: A Cypher Crash Course for SQL Engineers | by Aayush Ostwal | Jun, 2026
I've written SQL for over a decade. Joins, subqueries, recursive CTEs – the whole deal. Then I tried a graph database (Neo4j). And my relational muscle memory kept getting in the way. I kept trying to "map foreign keys" instead of just… traversing edges. So I built myself a side‑by‑side cheat sheet: SQL → Cypher for everything from basic SELECTs to variable‑length paths that would require recursive CTEs in PG/SQL Server. Turns out, queries like "users who bought this also bought…" go from 30 lines of self‑joins to 6 lines of zig‑zag pattern matching. If you've ever felt frustrated with: multi‑hop join performance LIKE '%...%' on string scans or just the sheer noise of mapping join tables for many‑to‑many …give this 5‑min read a shot. The mental shift alone (relationships as physical edges, not ID matching) changed how I model data – even when I go back to SQL. submitted by /u/ostwal [link] [留言]
AI 资讯
Built my first proper agentic AI project
Over the last few weeks, while learning LangGraph and agentic systems, I ended up building Co-Founder Memory . It's a stateful AI assistant with: • long-term memory • planning loops • self-correcting RAG • web search fallback • automated timeline summaries • project and preference tracking Nothing revolutionary — many ideas already exist. The goal wasn't to reinvent memory, but to understand how these systems work by actually building one. A lot of concepts only started making sense once I had to connect them together: graph-based workflows with LangGraph memory extraction and storage retrieval and validation loops routing and planning nodes maintaining context across sessions Building it taught me far more than watching tutorials ever did. Repo: https://github.com/Somay-kousis/Co-Founder-Memory I'm currently entering my 3rd year at IIITM Gwalior and looking for ML / GenAI internships . If you're building interesting things around LLMs, agents, RAG, or AI products, I'd love to connect. Always happy to chat with fellow builders as well 🚀 AI #GenerativeAI #LangGraph #RAG #LLM #MachineLearning #Internship
AI 资讯
Why I Stopped Using reset() and end() in PHP (And What I Use Now)
If you have been writing PHP for a year or two, you have almost certainly written something like this: $items = getFilteredOrders (); $first = reset ( $items ); $last = end ( $items ); It works. It runs. It looks fine in code review. And it contains a subtle bug waiting to happen. The problem with reset() and end() Both functions move PHP's internal array pointer as a side effect. PHP arrays have a hidden cursor that tracks "the current position" in the array. Functions like current() , next() , prev() , and each() depend on where that cursor sits. reset() moves it to the first element. end() moves it to the last. This is harmless in an isolated script. But in a real application, the same array often passes through multiple functions — and any function that relies on the cursor position after your call will get unexpected results. Here is a concrete example: function getFirstActiveOrder ( array $orders ): ?array { // Moves the pointer to the first element $first = reset ( $orders ); foreach ( $orders as $order ) { if ( $order [ 'status' ] === 'active' ) { return $order ; } } return null ; } At first glance this looks fine. But foreach in PHP actually resets the pointer to the beginning before iterating — so in this simple case you get lucky. The bug shows up in less obvious situations: when you call reset() inside a function that the caller is already iterating with current() / next() , or when you use end() to peek at the last item while a foreach is in progress on the same array reference. The deeper issue: reset() and end() return false on an empty array. But false might also be a legitimate value stored in your array: $flags = [ true , false , true ]; $last = end ( $flags ); // returns false — but is this "empty array" or "the value false"? You have to write: if ( $flags === [] || end ( $flags ) === false ) { ... } Which is already awkward. And it still mutates the pointer. The modern solution: array_key_first() and array_key_last() PHP 7.3 introduced two functi