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

标签:#AI

找到 4786 篇相关文章

AI 资讯

What to Put in Your CLAUDE.md (and What to Leave Out)

A great CLAUDE.md is not the longest one. It is the one where every line changes what Claude does. The whole skill is knowing what belongs in it — and, just as importantly, what does not. The sections that earn their place Start with a one or two line project description and your stack, with version numbers. Claude infers a lot from your code, but it will not guess that you are on Next.js 15 instead of 14, or which ORM you chose. Then a directory map — not every file, just the top-level layout with a note on what each part holds. After that: the build and test commands, the conventions a formatter does not enforce, and critically, the things not to touch. # Project: Acme Dashboard Next.js 15 (App Router), TypeScript, Drizzle ORM, Vitest. ## Structure src/app/ # routes and pages src/lib/ # shared utilities, db client db/migrations/ # generated - never hand-edit ## Commands Build: npm run build Test: npm run test ## Conventions - API routes return { data, error } - never throw to client - Server components by default ## Do not touch - db/migrations/ is generated. Never edit by hand. Every line in that file would cause a mistake if removed. That is the bar. What to leave out This is where most files go wrong. Two kinds of content waste your budget: Personality instructions. "Act as a senior engineer," "think step by step," "be thorough." These feel productive but change nothing — Claude already does them. General advice that does not prevent a specific mistake is pure noise. Rules a tool already enforces. If you have a formatter or linter, do not restate what it enforces. Wire it into a hook instead, and keep CLAUDE.md for what tools cannot enforce. The one-line test For every line, ask: "If I remove this, will Claude make a mistake?" If yes, keep it. If no, delete it. This single question, applied ruthlessly, is the difference between a file Claude follows and one it ignores. A bloated file buries the rules that matter in noise, so Claude cannot tell which line is the

2026-06-21 原文 →
AI 资讯

What Is CLAUDE.md? A Practical Guide to Configuring Claude Code

If you use Claude Code, there is one file that quietly shapes every session: CLAUDE.md. Most developers either do not have one or have one that works against them. Here is what it actually is, in plain terms. The file Claude reads every session CLAUDE.md is a markdown file that Claude Code reads at the start of every conversation. Think of it as your project's constitution — the source of truth for how your specific repository works. Because Claude reads it every time, you stop re-explaining your stack, your conventions, and your commands on every task. Why it exists Without a CLAUDE.md, every session starts cold. Claude can read your code, but it cannot infer the things that live outside the code: that you are on Next.js 15 and not 14, that a directory is generated and must never be edited, that your team has a particular commit style. You end up explaining these again and again, slightly differently each time, so the output drifts. CLAUDE.md captures that knowledge once, somewhere Claude always sees it. Where it lives, and how to start Put CLAUDE.md in the root of your project. You do not have to write it from a blank page — the /init command analyses your codebase and generates a starter, detecting your build tools, test framework, and existing patterns: $ claude > /init Treat the result as a foundation, not a finished product. The real value comes from refining it as you learn what Claude gets wrong without guidance. What belongs in it A good CLAUDE.md is short and specific: A one-line stack description, with versions — Claude will not guess Next.js 15 over 14 A directory map — the top-level layout and what each part holds The build and test commands The conventions a newcomer could not infer from the code A "do not touch" section — generated files, migrations, protected paths Here is a compact example: # Project: Acme Dashboard Next.js 15 (App Router), TypeScript, Drizzle ORM, Vitest. ## Structure src/app/ # routes and pages db/migrations/ # generated - never h

2026-06-21 原文 →
AI 资讯

The Real Reason Everyone's Fighting About Tailwind CSS v4

The Tailwind CSS4 debate is everywhere right now. And honestly? Most people are arguing about the wrong thing. The real question isn't "inline styles vs. utility classes" — it's about where your styling decisions live and who pays the cognitive cost. Let me break down what's actually happening, with real code, real trade-offs, and a clear take at the end. What Changed in Tailwind CSS v4 Tailwind CSS v4 introduced a major shift: CSS-first configuration. Instead of a tailwind.config.js , you define everything in your CSS file using @theme : /* Before (v3) - tailwind.config.js */ module .exports = { theme : { extend : { colors : { brand : '#6366f1' , } , spacing : { 18: '4.5rem', } } } } /* After (v4) - main.css */ @import "tailwindcss" ; @theme { --color-brand : #6366f1 ; --spacing-18 : 4.5rem ; } This is cleaner for many workflows. But it's not what's causing the drama. The Real Flashpoint: Utility Density in JSX What's actually triggering the discourse is how v4 accelerates a pattern that was already polarizing — components that look like this: // The "inline styles but make it Tailwind" pattern function AlertBanner ({ type , message }) { return ( < div className = { ` flex items-center gap-3 px-4 py-3 rounded-lg border ${ type === ' error ' ? ' bg-red-50 border-red-200 text-red-800 ' : ' bg-blue-50 border-blue-200 text-blue-800 ' } ` } > < span className = "text-sm font-medium" > { message } </ span > </ div > ); } vs. the @apply approach many teams prefer: /* alert.css */ .alert { @apply flex items-center gap-3 px-4 py-3 rounded-lg border; } .alert--error { @apply bg-red-50 border-red-200 text-red-800; } .alert--info { @apply bg-blue-50 border-blue-200 text-blue-800; } // Cleaner component function AlertBanner ({ type , message }) { return ( < div className = { `alert alert-- ${ type } ` } > < span className = "text-sm font-medium" > { message } </ span > </ div > ); } Both work. Neither is objectively wrong. But they encode very different philosophies. The Philos

2026-06-21 原文 →
AI 资讯

Why Claude Code Ignores Your CLAUDE.md (And How to Fix It)

You wrote a detailed CLAUDE.md, and Claude Code still gets things wrong — wrong convention, touches files it should not, ignores rules you clearly wrote down. The cause is almost never that the rules are missing. It is that they are buried. The over-specified file problem CLAUDE.md loads into Claude's context every single session, and performance degrades as that context fills. When the file grows too long, something counterintuitive happens: Claude starts ignoring parts of it. The important rules get lost in the noise, and the genuinely critical instructions sit too deep to reliably influence output. A bloated file does not just waste tokens. It actively makes Claude less reliable, because it cannot tell which of your hundred lines is the one that matters. The trap of good intentions It always starts reasonably: "let me put everything relevant in here." But relevant is a low bar. The file grows until it is impossible to scan, full of duplication, and so noisy that the truly important rules carry no weight. More content felt like more control. It was the opposite. The fix: prune ruthlessly Run every line through one question: "If I remove this, will Claude make a mistake?" If the answer is no, the line is noise — delete it. And if something only matters in a specific situation rather than always, it does not belong in the always-loaded file at all. That is what skills and subdirectory CLAUDE.md files are for — they load on demand, only when relevant. Let Claude fetch what it needs Instead of embedding everything, tell Claude how to pull context when it needs it. Rather than pasting an entire API guide into the file: # Wasteful - embeds the whole file every session: @docs/api-guide.md # Better - Claude reads it only when relevant: For Stripe integration work, read docs/stripe-guide.md The second form costs almost nothing until the moment it is needed. The result A pruned CLAUDE.md is often a third of the length and many times more effective. The rules that matter are

2026-06-21 原文 →
AI 资讯

I Fixed the "AI Commit Messages" Problem in 20 Lines of Python

You've probably seen that trending post — "I Asked AI to Write My Commit Messages and It Was Embarrassing." Same. But instead of accepting embarrassing output, I fixed it. Here's the thing: the problem isn't AI writing commit messages. The problem is how you ask it. One clear system prompt + the actual diff = surprisingly good results. The Setup No new packages. No API key. If you have Claude Code , you're already set. #!/usr/bin/env python3 import subprocess SYSTEM = ( " You are a git commit message generator. " " Output ONLY the commit message — no explanation, no markdown, no quotes. " " Follow Conventional Commits: type(scope): subject. " " Types: feat, fix, docs, style, refactor, test, chore. " " Subject: imperative, lowercase, max 72 chars. " ) diff = subprocess . check_output ([ " git " , " diff " , " --staged " ], text = True ) if not diff . strip (): print ( " Nothing staged. Run `git add` first. " ) raise SystemExit ( 1 ) msg = subprocess . check_output ( [ " claude " , " -p " , SYSTEM + " \n\n " + diff ], text = True , ). strip () print ( msg ) That's it. 20 lines. Uses the claude CLI under the hood — no API key, no config, just your existing Claude Code OAuth session. Why It Works The system prompt does the heavy lifting. Three constraints: Output ONLY the commit message — no preamble, no explanation Follow Conventional Commits — feat , fix , chore , etc. max 72 chars — keeps it readable in git log The diff is the context. You're not asking "write a commit message". You're asking "given these exact changes, what happened?" That's a much more answerable question. Usage # No setup needed if you have Claude Code. Just: git add . python /path/to/git_commit.py # → feat(server): add AI commit message generator via Claude CLI Or wire it into a git alias: git config --global alias.ai '!python /path/to/git_commit.py' # git ai The Results Before: update stuff fix bug WIP added the thing After: feat(api): add generate_commit_message tool to MCP server fix(auth): ha

2026-06-21 原文 →
开发者

Why I Redesigned StrictBlock to Make Focus Feel Easier

I rebuilt StrictBlock (my app) from the ground up. StrictBlock is an iPhone app blocker and focus app designed to help people stop procrastinating, protect deep work, and build better focus habits. For this relaunch, I did not want to just “refresh the UI.” I wanted to redesign the full product experience around one question: How can I make starting a focus session feel simple, strict, and useful? The new version focuses on reducing friction. Users can create focus profiles for study, work, sleep, deep work, or Pomodoro sessions, then start blocking distracting apps and websites with less setup. I also redesigned the app around accountability. StrictBlock now includes streaks, trophies, weekly reports, widgets, session journaling, and consequences for ending sessions early. As a developer, this redesign was a good reminder that productivity apps are not only about features. They are about behavior. The UI, the flow, the defaults, and the friction all shape whether someone actually stays focused. StrictBlock is now live with a complete redesign. Would love feedback from other builders, iOS devs, and product engineers. Try it here: Download strictblock on appstore

2026-06-21 原文 →
AI 资讯

Evaluating Kimi 2.5 vs Kimi 2.6: What happens to agent skills when the model gets smarter?

When a stronger model ships, there are two questions every skill author should want answered, and evals are the only honest way to answer either: Which skills just got absorbed? A model that now knows how to do X natively does not need a skill telling it to do X. Fewer skills to maintain, leaner context, lower cost. Which skills still matter? Behaviour-level guidance (conventions, preferences, project-specific workflows) is not something pretraining will fill in for you. Those skills should keep paying. Moonshot gave us early access to Kimi K2.6. We ran the Tessl agent skill evaluation harness on the same 21 skills and 100 paired scenarios against three solvers: Kimi K2.5, Kimi K2.6, and Claude Sonnet 4.5. A solver is the model whose output the grader scores; a paired scenario is the same task run twice per solver, once without the skill installed and once with it. These are early signals from one pre-release on one skill set. A deeper cross-model analysis with clean baselines across the board is in progress and will be its own piece. What does our setup look like? Scenarios and rubrics are held fixed across the two Moonshot runs. The only variable is the solver. Solver A: Kimi K2.5 Solver B: Kimi K2.6 Scenario generator: Claude Sonnet 4.5, up to 5 scenarios per skill, derived from each skill's SKILL.md Grader: Claude Sonnet 4.5, weighted-checklist rubric derived from the same SKILL.md Per skill × per solver: every scenario solved twice, baseline (no skill installed) and with-skill Per-skill n=5 is noisy; the aggregate over 100 scenarios is where the signal lives. Three findings: Kimi 2.6 is a better model than K2.5: Without skills, K2.6 sits ~2 pp (percentage points) above K2.5 in aggregate, with double-digit moves on specific skills. Kimi 2.6 holds its own against Sonnet 4.5. We picked Sonnet 4.5 as a competitive baseline, and found in this evaluation set that the K2.6 performed better both in the with/without skill scenario by around ~8 p.p . Skills remain a dura

2026-06-21 原文 →
AI 资讯

Goal In, DAG Out: How Open-Multi-Agent Turns a Goal into a Task DAG

You wrote the graph by hand. Then the requirements changed. Most TypeScript agent frameworks make you draw the graph yourself. You declare the nodes, wire the edges, decide what runs after what, where it branches, where it joins. It works, right up until the goal shifts and you are back in the graph editor re-wiring a pipeline you already built once. There is another way to model this: describe the goal, and let a coordinator build the graph for you. That is what runTeam() does in open-multi-agent. You hand it a team and a sentence. It hands back a result. In between, a coordinator agent decomposes the goal into a task DAG, assigns the tasks to your agents, runs the independent ones in parallel, and synthesizes the final answer. There are no edges to wire. This post is about what happens in that "in between," because the mechanism is the whole point. The one call import { OpenMultiAgent } from ' @open-multi-agent/core ' const orchestrator = new OpenMultiAgent ({ defaultModel : ' deepseek-v4-flash ' , defaultProvider : ' deepseek ' , }) const team = orchestrator . createTeam ( ' research ' , { name : ' research ' , agents : [ { name : ' researcher ' , model : ' deepseek-v4-flash ' , provider : ' deepseek ' , systemPrompt : ' You research topics and gather concrete facts. ' }, { name : ' writer ' , model : ' deepseek-v4-flash ' , provider : ' deepseek ' , systemPrompt : ' You turn research notes into clear prose. ' }, ], sharedMemory : true , }) const result = await orchestrator . runTeam ( team , ' Research the tradeoffs of TypeScript decorators, covering the stage-3 standard ' + ' versus the legacy experimental implementation, runtime and bundle-size cost, and ' + ' current framework support, then write a clear 500-word explainer for a team ' + ' deciding whether to adopt them. ' , ) console . log ( result . agentResults . get ( ' coordinator ' )?. output ) Three things to notice before we go under the hood: You never declared a task graph. You wrote the goal in pla

2026-06-21 原文 →
AI 资讯

Your AI feels slow? Maybe it's not dumb—you're making it work one thing at a time

📖 Originally published on my blog . Part of a series on building with Claude Code. For a while I'd watch the AI work and quietly grumble: a fairly big task, and it would finish one module before starting the next, while I just sat there waiting for it to clear one before the other's turn came up. The work itself was fine—it was just slow. Slow because it was stuck in a queue. Then it clicked: a lot of these modules have nothing to do with each other, so why make them go one after another? Split them up, let several agents work at the same time, done. What I want, and where it stops What I want is simple: the same work, for roughly the same tokens, with the wall-clock time cut way down. But let me put the boundary up front— not every task can be split this way . This is just an approach I've worked out for myself; take what's useful. The prerequisite: a clean architecture For several agents to work at once without stepping on each other, the prerequisite isn't the AI—it's your architecture . That task of mine could be split because it was already several modules, talking to each other through interfaces, with internal implementations that don't affect one another—as long as each one honors the interface contract, it can be built independently. Loosely coupled, highly cohesive, in other words. And I'd nailed that design down together with opus before writing a line: opus helps me think it through and lays out options, but I'm the one who decides . You can't cut corners here. Forcing parallelism onto an architecture you haven't cleanly split is like cutting a tangle of yarn into a few pieces that are all still knotted together—it only gets messier. Who runs the show, who plans, who does the work With the design settled, it's time to assign roles. The split I tend to use: opus runs the show —holds the big picture, hands out work, does the final check; sonnet does the TDD planning —per the design, it lays out how each module gets tested and implemented; haiku writes the

2026-06-21 原文 →
AI 资讯

When an AI Agent Joins Your Yjs Room, Three Assumptions Break

Wiring an LLM as a first-class Yjs peer is architecturally sound — but it invalidates three silent assumptions your collaboration stack already makes about peer symmetry: throughput, undo ownership, and presence cadence. You've tuned a Yjs provider under real collaborative load. You know the feeling before you can name it — one heavy client starts lagging the room, presence updates stutter, and you end up adding a debounce somewhere and calling it done. Now imagine that client generates text at 3,000 words per minute, never goes offline, and has its own awareness cursor. That's not a sidebar feature. That's a new class of peer, and your collaboration architecture wasn't designed for it. The Demo Is Real — But It Skips the Hard Parts In April 2026, a working demo wired an LLM as a genuine server-side Yjs document peer — same transport as the human editors, same CRDT, its own awareness state. The implementation uses y-prosemirror and the standard awareness protocol directly. If you've shipped TipTap collaboration, you already have every dependency it needs. The architecture is correct. Making the agent a server-side peer — rather than a client-side bolt-on posting diffs over a REST endpoint — gives you one convergence model instead of two, real presence semantics for the agent, and a clean separation between the LLM streaming layer and the document state layer. But the demo establishes the peer model. It doesn't stress-test what happens to your existing assumptions once that peer is running. The Silent Assumption Every CRDT Implementation Makes Here it is — the assumption baked into the Yjs awareness protocol, the undo manager, and your backpressure strategy, the one nobody wrote down because it was always true until now: All peers produce operations at roughly human speed. Not identical speed. Human typists vary. But they land in the same order of magnitude. The entire design space — how often you broadcast awareness, how you scope undo history, whether you need per-

2026-06-21 原文 →
AI 资讯

AI Coding Agents Need a Control Layer

AI Coding Agents Need a Control Layer AI coding agents are getting good enough that the problem is changing. A year ago, the question was mostly: Can this thing write useful code? Now, for a lot of builders, the better question is: How do I supervise this thing once it is actually doing work? That shift feels important. Claude Code, Cursor, Codex, and similar tools are not just autocomplete anymore. They can plan, edit files, run commands, review code, and work across larger chunks of a project. That is powerful. It also gets messy fast. The bottleneck is moving The hard part is no longer just picking the best coding agent. It is figuring out how to manage agent work once multiple tools or sessions are active. Questions start showing up: What is each agent doing right now? What changed? What still needs human review? Where did approval happen? Which agent owns which task? Did two agents touch the same part of the codebase? What should be paused, redirected, or stopped? What happened while I was focused somewhere else? That is not really a prompting problem. It is a control problem. The current workflow is mostly duct tape A lot of agent workflows seem to rely on some combination of: terminal tabs tmux sessions git branches git worktrees editor diffs notes issue trackers rules files memory vibes That works for a while. But once agents become more autonomous, or once a builder runs more than one agent at a time, the workflow starts to need a real operating layer around it. Not because the agents are bad. Because the agents are getting useful enough to need supervision. The missing layer The layer I keep thinking about has a few jobs. State What is running? What is paused? What needs attention? Ownership Which agent owns which task, branch, file, or objective? Review What changed, and what still needs a human to look at it? Approval Where should the human say yes before work continues? Intervention When should a builder pause, redirect, compare, or stop an agent? Memor

2026-06-21 原文 →
AI 资讯

Why I'm betting on AI-curated directories when Google AI Overviews answer the same queries

The obvious counterargument to everything I'm building is this: Google already does it. You type "best AI tools for video editing" into Google and an AI Overview surfaces a curated list, synthesized from the same kind of data I maintain, without requiring a click. My three directory sites — Top AI Tools , Find Games Like , and Open Alternative To — are competing with a feature baked into the world's dominant search engine. I launched these sites on 2026-04-23, built on an architecture that runs at about $25/month . Traffic is essentially zero — the sites have been indexed for three weeks and organic crawling takes time. The question I keep returning to isn't whether Google will eventually index my pages. It's whether anyone will prefer clicking through to my site over reading the AI Overview box that already answered the same question. Here's my honest, falsifiable position. The bet, stated plainly By October 2026 — six months post-launch — at least one of the three sites will show organic click trends in Google Search Console indicating real query traffic to specific comparison or filtered-browse pages. I define that as: at least 200 non-homepage organic clicks per month, sustained for two consecutive months, from queries I didn't directly drive through social or newsletter posts. If that doesn't happen, I'll publish the Search Console screenshots and write a post explaining what I got wrong. I'm committing to that here. The counterargument I take seriously AI Overviews have gotten genuinely good at list-and-compare synthesis. If you search "open source alternative to Notion" today, Google often returns a four-item structured list with one-sentence descriptions directly in the Overview box. My Open Alternative To site covers that territory. The AI Overview absorbs the zero-click version of that query. The optimistic response is: "my site appears as a citation source." The pessimistic response is: "Google consumes your signal and stops sending clicks." The pessimist

2026-06-21 原文 →
AI 资讯

Precision Medicine RAG: Building a Clinical Trial Search Engine with Hybrid Search and BGE-M3

In the world of Generative AI, there is a massive difference between asking for a "pancake recipe" and asking for "eligibility criteria for phase III immunotherapy trials." In specialized fields like healthcare, a standard vector search often fails because medical terminology is dense, specific, and unforgiving. 🏥 Today, we are building a High-Precision Medical RAG (Retrieval-Augmented Generation) engine. We will move beyond simple semantic search by implementing Hybrid Search (Dense + Sparse vectors) using the powerhouse BGE-M3 model, storing it in Qdrant , and fine-tuning the results with FlashRank . This approach ensures that technical medical terms (like EGFR L858R mutation ) aren't lost in the "vibe" of a vector space. Keywords: Hybrid Search , Medical RAG , BGE-M3 Embeddings , Qdrant Vector Database , Clinical Trial Retrieval . The Architecture: Why Hybrid Search? Traditional RAG relies on "Dense Vectors" (semantic meaning). However, in clinical trials, keywords matter. A patient searching for "Pembrolizumab" needs that exact drug, not just "something related to cancer." By using BGE-M3 , we get the best of both worlds: Dense Retrieval : Captures the context and intent. Sparse Retrieval (Lexical) : Captures specific keywords and medical codes. Reranking : Re-evaluates the top hits to ensure the most clinically relevant document is on top. graph TD A[User Query: Medical Case] --> B{BGE-M3 Encoder} B -->|Dense Vector| C[Qdrant Collection] B -->|Sparse Vector| C C --> D[Hybrid Search Results] D --> E[FlashRank Reranker] E --> F[Top K Relevant Documents] F --> G[LLM: Final Synthesis] G --> H[Actionable Clinical Insight] Prerequisites 🛠️ Before we dive in, make sure you have your environment ready: Qdrant : Our high-performance vector database. BGE-M3 : A state-of-the-art embedding model that supports dense, sparse, and multi-vector retrieval. FlashRank : An ultra-fast, lightweight reranking library. LangChain : To orchestrate our RAG pipeline. pip install qdrant-c

2026-06-21 原文 →
AI 资讯

I Built an Afriex MCP Prompt Cookbook So Developers Never Have to Stare at a Blank Prompt Again

A few weeks ago, I started exploring the Afriex MCP server. The setup was surprisingly straightforward. Connect your MCP client. Configure your API key. Verify the connection. Done. But then I ran into a different problem. Not a technical problem. A prompt problem. The Blank Prompt Problem Once everything was connected, I found myself staring at an empty prompt box. What should I ask? Sure, I could retrieve balances. I could create customers. I could generate virtual accounts. But what were the most useful workflows? What were the prompts that would actually help developers build real products? This isn't a problem unique to Afriex. It's becoming a common challenge across the entire MCP ecosystem. The infrastructure exists. The tools work. But many developers don't know where to start. MCP Changes How We Build Traditionally, integrating a payment API looked something like this: Read documentation Find the endpoint Write HTTP requests Parse responses Build business logic With MCP, the workflow looks very different. You can simply tell your AI assistant what you want to build. For example: Create a customer onboarding flow that: - Collects customer details - Generates a virtual account - Displays payment instructions Build it using Next.js and TypeScript. Instead of manually stitching everything together, the AI can interact with infrastructure through the MCP server. That's incredibly powerful. But only if you know what to ask. The Idea That's what led me to build the: Afriex MCP Prompt Cookbook A collection of practical, production-oriented prompts designed specifically for developers building with Afriex MCP. The goal is simple: Copy. Paste. Build. Instead of starting from scratch every time. The cookbook is open source and available on GitHub: https://github.com/SonOfUri/afriex-mcp-cookbook Feel free to explore the prompts, use them in your own projects, and contribute new recipes. What's Inside The cookbook is organized around real-world use cases. Not API endpoi

2026-06-21 原文 →
AI 资讯

Stop reading to build a library. Start reading to solve a problem.

Most engineering reading lists are optimized for knowledge accumulation. Modern engineering rewards bottleneck elimination. Last week, a junior engineer showed me a "Top 10 Books Every Engineer Should Read" list. It looked almost identical to the lists I saw ten years ago. The same classics. The same process books. The same assumption: Read enough books and you'll become a better engineer. That's not how most high-performing teams learn. The best engineers I know don't build learning plans around books. They build learning plans around constraints. The Problem with standard reading lists Most reading lists assume that knowledge is universally valuable. In practice, engineering value is highly contextual. A backend engineer struggling with database contention does not need another chapter on Agile. A team spending thousands of dollars per month on LLM inference does not need a generic software craftsmanship book. A startup fighting latency issues does not need a leadership framework. They need solutions to the bottleneck directly in front of them. Reading lists rarely account for this. They optimize for completeness. Engineering rewards relevance. The Shift Most Engineers Miss The fundamentals still matter. Distributed systems matter. Databases matter. Networking matters. Operating systems matter. They are not obsolete. But they are no longer sufficient. Modern systems introduce constraints that barely existed a few years ago: AI inference costs Context window limitations Agent orchestration Evaluation pipelines Semantic caching Non-deterministic workflows Model routing Human-in-the-loop systems Many traditional reading lists never touch these problems. Yet these are exactly the problems teams are solving every day. The challenge is no longer simply writing correct software. The challenge is building reliable systems on top of components that are inherently probabilistic. What Changed For decades, engineers mostly worked with deterministic systems. Given the same inp

2026-06-21 原文 →