今日精选
HOT最新资讯
共 25396 篇I No Longer Feel Like a Developer — And I Don't Know How to Fix That
Last week I sat in my parked car for fifteen minutes before going inside. Not because of...
Part 1 — Container hoá app & chạy trong Kubernetes local
Bạn sẽ học gì Sau bài này, bạn sẽ tự tay đưa một app từ số 0 (một thư mục trống) đến chạy được bên trong một cluster Kubernetes chạy trên máy của bạn . Cụ thể: Viết một app Todo API nhỏ bằng Node.js + Express. Đóng gói (container hoá) nó thành một Docker image. Tạo một cluster Kubernetes local bằng kind . Deploy app bằng file YAML "thật" (không dùng lệnh tắt) để hiểu Kubernetes vận hành thế nào. Truy cập app đang chạy trong cluster từ máy của bạn. Đây là Part 1 trong series "DevOps 101 — Học K8s, Helm, ArgoCD từ số 0" . Cả series dùng chung một app tên todo-ops , các part sau sẽ xây tiếp lên nền này (thêm database, config, ingress, Helm, GitOps với ArgoCD). Điều kiện tiên quyết Docker (hoặc Docker Desktop / OrbStack) — đang chạy. kind — công cụ tạo cluster Kubernetes trong Docker. kubectl — CLI để nói chuyện với Kubernetes. Node.js 20+ và npm — để chạy thử app local. git — để quản lý mã nguồn. Cài đặt Chọn theo hệ điều hành của bạn. macOS (dùng Homebrew — nếu chưa có, cài trước): # Cài Homebrew (bỏ qua nếu đã có) /bin/bash -c " $( curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh ) " # Docker Desktop (hoặc OrbStack: brew install --cask orbstack) brew install --cask docker # Các CLI còn lại brew install kind kubectl node git Sau khi cài xong, mở Docker Desktop (hoặc OrbStack) và chờ nó báo Running trước khi chạy tiếp. Linux (Ubuntu/Debian): # Docker Engine curl -fsSL https://get.docker.com | sh sudo usermod -aG docker " $USER " # cho phép chạy docker không cần sudo (đăng xuất/đăng nhập lại để có hiệu lực) # kubectl curl -LO "https://dl.k8s.io/release/ $( curl -Ls https://dl.k8s.io/release/stable.txt ) /bin/linux/amd64/kubectl" sudo install -m 0755 kubectl /usr/local/bin/kubectl && rm kubectl # kind curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 sudo install -m 0755 kind /usr/local/bin/kind && rm kind # Node.js 20 (qua NodeSource) + git curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt-get insta
I added nested CSV to JSON support to a free browser-based converter
I built JSON Utility Kit as a small browser-based toolkit for everyday JSON tasks. The CSV to JSON converter recently got an update for nested JSON structures. For example, headers like user.name, user.email, order.id can be converted into nested objects instead of flat keys. What it supports: CSV to JSON conversion Nested object output from dot notation headers Browser-side processing No signup JSON formatting and validation tools nearby Tool: https://jsonutilitykit.com/tools/csv-to-json/ GitHub: https://github.com/kejie1/json_utility_kit
Testing In-App Chat and Customer Support Flows in Delivery Apps
The help button is the most important button in your delivery app that your QA team almost never...
一个任务的奇幻漂流:同一个Agent任务,在FROST和FROST-SOP中分别长什么样?
一个任务的奇幻漂流:同一个Agent任务,在FROST和FROST-SOP中分别长什么样? 作者 :神通说 日期 :2026-07-08 主题 :双项目联动 | 周三轮换 阅读时间 :8分钟 一个问题 你可能听过这样的故事: "这个框架很好,但我不知道怎么用到真实项目里。" FROST 社区里也收到过类似的反馈—— "500行代码确实让我理解了Agent的本质,但理解完之后呢?怎么从'看懂'到'会用'?" 今天这篇文章,就用 同一个真实任务 ,分别展示它在 FROST 和 FROST-SOP 中的样子。你会发现:它们不是两个不同的东西,而是 同一个东西的不同分辨率 。 今天的任务:自动写日报 假设你是一个独立开发者,想让Agent每天自动帮你写工作日报。需求很简单: 收集今天完成的任务 用LLM生成日报摘要 发送邮件给自己 就这么三步。让我们看看它在两个项目中分别怎么实现。 第一站:FROST——用最少的代码理解本质 FROST 的哲学是: 先用500行代码告诉你Agent的底层逻辑,剩下的你自然就会了。 在FROST中,一个Agent的运作只需要四个原子: from core import Store , Agent , skill_set , skill_get # 1. 创建记忆容器 store = Store () # 2. 定义能力(Skill = 纯函数) def collect_tasks ( context ): """ 收集今日任务 """ tasks = [ " 完成FROST v5.0文档 " , " 修复Skill测试用例 " , " 写推广文章 " ] context [ " tasks " ] = tasks return context def generate_summary ( context ): """ 生成日报摘要(简化版,实际调用LLM) """ tasks = context . get ( " tasks " , []) context [ " summary " ] = f " 今日完成 { len ( tasks ) } 项任务: " + " 、 " . join ( tasks ) return context def send_report ( context ): """ 发送日报 """ context [ " sent " ] = True print ( f " [日报已发送] { context [ ' summary ' ] } " ) return context # 3. 组装Agent agent = Agent ( " daily_reporter " , store , skills = { " collect " : collect_tasks , " summarize " : generate_summary , " send " : send_report }) # 4. 用SOP编排执行顺序 result = agent . run ( sop_steps = [ " collect " , " summarize " , " send " ], initial_context = {} ) # 输出:[日报已发送] 今日完成3项任务:完成FROST v5.0文档、修复Skill测试用例、写推广文章 这段代码做了什么? Store 是记忆——Agent的工作空间,所有中间结果存在这里 Agent 是细胞——拥有记忆和能力的最小执行单元 sop_steps 是宪法——定义执行顺序,Agent不会自作主张改变流程 就这么简单。没有配置文件,没有YAML,没有复杂的初始化。 30行Python代码,一个完整的Agent就跑起来了。 这就是FROST的价值——它不帮你"做"什么,它帮你 看懂 Agent到底是什么。 问题来了 上面的代码能跑,但如果你真的想把它用在生产环境,你会遇到一堆问题: 发邮件的能力怎么写? FROST不管——它只告诉你Skill是纯函数,具体实现你自己来 LLM调用怎么复用? 每次写日报都要调LLM,总不能每次都重写一遍 任务失败了怎么办? 发邮件失败了,要不要重试?重试几次? 执行日志在哪? 老板问"今天日报发了吗",你怎么知道发没发? 多个Agent协作呢? 一个人有好几个项目,每个项目一个Agent,怎么协调? FROST对这些问题的回答是: 这些问题不是我该回答的。 但它的兄弟——FROST-SOP——就是专门回答这些问题的。 第二站:FROST-SOP——让同一个任务跑在生产环境 FROST-SOP 的哲学是: 把FROST教你的每一个概念,都变成生产级的工程组件。 同样的"自动写日报"任务,在FROST-SOP中长
The Turborepo + Bun + Biome stack behind a 40-package monorepo
Forty packages, one maintainer, and no ESLint config anywhere in the repo. That is not a boast - it is the direct result of a decision made early: every tool in the toolchain has to earn its place by governing all forty packages from one config file, not forty. The repo is flare-engine , a modular 2D engine for React Native + Web (animation, gamification, interactive UI, with games as showcases - not a game engine, not a Unity or Godot competitor). The stack behind it is Turborepo Bun Biome , and this post is the actual setup: the real turbo.json , the real biome.json , the real CI guardrail, straight from the repo (trimmed only where a config is long, and I say so where I trim), not a starter template's idealized version. Four binaries, four root configs - turbo.json , biome.json , tsconfig.base.json , and the Changesets config - each governing all forty packages at once (Bun's own "config" is just the workspaces array in the root package.json ). Plus a CI step that fails the build the moment a package imports something it shouldn't. That is the whole story, and I want to show you the files, not describe them. Four binaries, not twelve config files The thesis is narrow: a solo maintainer can keep forty packages honest only if there is exactly one config of each kind, and every package extends it rather than declaring its own variant. Twelve packages each with a slightly different ESLint config is not a monorepo, it is twelve monorepos wearing a workspace file as a costume. Here is the root package.json that runs all of it - Bun workspaces (not pnpm; that distinction matters and I will say it again below), the script table every package leans on, and the pinned package manager: // C:\_PROG\flare-engine-workspace\flare-engine\package.json { "name" : "flare-engine" , "version" : "0.0.0" , "private" : true , "workspaces" : [ "packages/*" , "benchmarks" , "apps/*" ], "scripts" : { "build" : "turbo build" , "test" : "turbo test" , "lint" : "turbo lint" , "typecheck" : "t
An MCP Context Contract for Android Automation Drafts
When teams ask Codex or Claude to help with Android automation, the request usually starts as ordinary language. "Open the app, sign in, check the result, save a screenshot, and stop if the expected text is missing." That kind of instruction is useful, but it is not enough to generate a workflow that should run on a real device. The missing piece is a context contract. By context contract, I mean the minimum set of facts an AI assistant must read before it drafts an Android automation profile: the target environment, connected devices, app package, current screen, node schema, available visual assets, evidence policy, save policy, and stop boundaries. Without that contract, the assistant has to guess. In mobile automation, guessing is where many bad workflows begin. The LaiCai source article, Codex and Claude MCP for Android Automation with LaiCai Flow , describes this pattern from the LaiCai Flow side: Codex or Claude can draft from MCP context, but LaiCai Flow remains the graph, debugging, screen, log, and execution layer. Why a context contract matters Android automation has a lot of runtime detail. A model may know what "login" means, but it does not know whether the app is a staging build, production build, emulator build, or private test build unless the system tells it. It may know that OCR can confirm text, but it does not know which OCR region is stable unless the current screen and layout are available. It may know that a tap can press a button, but it should not choose a coordinate when a UI-tree target or visual check is safer. This is why Model Context Protocol is important for AI-assisted workflow generation. MCP gives the assistant a way to ask the local system for tools and structured context. A good LaiCai MCP workflow should make generation context, node schema, assets, profiles, devices, packages, screenshots, UI tree data, and recent run state available before draft generation. The goal is not to give the model unlimited power. The goal is to red
You don't own your reading list. You rent it.
Here is an uncomfortable one: you do not own your reading list. You rent it. Every "follow" button you have pressed in the last decade put your reading relationship inside a company's database, where it can be ranked, throttled, or ended the day the business model changes. You did not sign anything. You just stopped owning it. It was not always like this. Feeds were the quiet machinery that kept the web interoperable. RSS and Atom meant a site, a reader, and a robot could all agree on the same stream without asking anyone's permission. You published once, and anything could read it: whatever app, whatever order, no algorithm in the middle. Then it eroded. Plenty of sites ship no feed at all now, and "follow us" quietly became "create an account on someone else's platform." The reason is not mysterious. Platforms had every incentive to close the loop, because a feed lets you leave, and an account does not. So the industry swapped "here is my stream, read it however you like" for "log in to see updates," and a generation of sites simply stopped publishing feeds, because the platform was where the audience was. That is the trade you made without noticing. The open format that asked nothing of you got replaced by a login that asks for everything. Your reading list used to live in your reader and survive a company changing its mind, its ranking, or its whole business. Now it lives in their database and survives exactly as long as they allow. Getting it back is not nostalgia. It is infrastructure for independence: tooling that treats feeds as a first-class citizen, aggregates the sources you actually choose, and keeps that stream under your control instead of a platform's. The full case for why this is worth fixing, and what feed-first tooling looks like, is here: https://mederic.me/blog/open-web-feeds So, honestly: how many of the people and sites you follow could you still read tomorrow if the platform in the middle disappeared tonight?
AI Security Audit Checklist: 15 Vulnerabilities Claude Found in Production Code
Most web applications contain at least one vulnerability from the OWASP Top 10. A typical security audit takes 2-3 weeks and costs upward of $10,000. An LLM can compress the initial audit down to a few hours because it scans code for patterns rather than specific CVEs. Below are 15 vulnerabilities found while auditing production code with Claude. Each includes the vulnerable code, the fixed version, and a prompt to reproduce the finding. Classification follows OWASP Top 10 (2021). Order reflects frequency of occurrence: most common first. Methodology: how to run an AI security audit The audit consists of three passes. First, a broad scan: the LLM receives the entire project and looks for vulnerability patterns. Second, deep analysis: each identified pattern is verified in context (middleware, ORM, framework). Third, verification: manual review of every finding, because LLMs produce false positives. Prompt for the broad scan: Perform a security audit of this code. For each finding, include: 1. CWE ID and name 2. OWASP Top 10 category 3. Severity (Critical/High/Medium/Low) 4. The vulnerable code snippet 5. Attack vector -- exactly how an attacker would exploit this 6. Fixed code Ignore stylistic comments. Focus on security only. Start with injection attacks, then broken access control, then the rest. This prompt works because it defines the output structure and prioritizes categories. Without explicit instructions, the LLM mixes critical vulnerabilities with remarks about email validation. More on structured AI code review: AI Code Review Checklist . A03:2021 -- Injection 1. SQL Injection via string concatenation The most common finding. Shows up even in projects using an ORM, because developers switch to raw queries for complex filters. Vulnerable code: // API endpoint for user search app . get ( ' /api/users ' , async ( req , res ) => { const { search , sortBy } = req . query ; const query = ` SELECT id, name, email FROM users WHERE name LIKE '% ${ search } %' ORDER
Article. Learning FlashAttention the hard way. When a loop is secretly associative?
I'm writing a short series of tutorials on FlashAttention, the algorithm that largely powers modern LLMs. The core idea is to spot the associative structure hiding in the loop. Once you see it, you get two things: you can fuse the passes (in the case of attention, it is huge, because it avoids ever materializing the score matrix) and split and recombine the work across GPU threads or any parallel processor. This post is about recognizing that structure. The stable softmax operation on a vector x (part of the attention kernel) is computed as follows: m = max_j x_j softmax(x)_i = exp(x_i - m) / Σ_j exp(x_j - m) Naively, you would write something like: # pass 1 — running max m = -inf for j in 0..N: m = max(m, x[j]) # pass 2 — denominator, needs the final m d = 0 for j in 0..N: d += exp(x[j] - m) # pass 3 — normalize for j in 0..N: y[j] = exp(x[j] - m) / d The trick is not to wait for the final max before accumulating the denominator. Carry both in a small state (m, d) and rescale d whenever the max moves. Here is what the online version of the algorithm above looks like: # one pass — carry (m, d) together m, d = -inf, 0 for j in 0..N: m_new = max(m, x[j]) d = d * exp(m - m_new) + exp(x[j] - m_new) # rescale, then add m = m_new # normalize (unchanged) for j in 0..N: y[j] = exp(x[j] - m) / d It turns out this is not a one-off trick. There is a whole class of "secretly associative" loops that you can parallelize by introducing the right carrier state. The tutorial goes into detail, shows a few examples of secretly associative operations, provides the algebraic formulation for those, and gives some tools to help you recognize secretly associative loops. Overview: Safe softmax, Welford's variance, and FlashAttention belong to the same class of secretly-associative operations The twisted monoid via transport of structure, why the max-rescale coupling doesn't break associativity Third Homomorphism Theorem as a test for whether any loop is secretly associative Numerical analys
Bigger Context Windows Didn't Make Our RAG Smarter
We stopped measuring retrieval quality by how many tokens we could fit into the prompt. When...
Ask HN: Best Podcasts of 2026 [So Far]
Trying to diversify what I listen to and interested to hear what everyone else is enjoying this year!