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

标签:#DevOps

找到 767 篇相关文章

AI 资讯

How to Build a Resilient Edge Data Pipeline for Power Line Sensors

Modern electrical grids increasingly rely on distributed sensors installed across conductors, towers, poles, substations, and remote line sections. These devices can measure: Conductor temperature Current and voltage Mechanical tension Line sag Vibration Weather conditions Fault passage Switch and recloser states Collecting these measurements is relatively straightforward. Building a reliable data pipeline around them is much harder. Power infrastructure often operates in locations with unstable connectivity, limited bandwidth, and strict requirements for alarm delivery. A useful architecture must therefore do more than move telemetry from sensors to a cloud database. It must determine which data is urgent, validate measurements, preserve event order, survive network outages, and integrate the results with operational utility systems. This article explores how to design that pipeline. The Basic Architecture A practical grid-monitoring data flow may look like this: Field Sensors | v Protocol Adapters | v Edge Data Model | +----> Local Rules and Fault Detection | +----> Local Time-Series Buffer | +----> Event Queue | v Central IoT or Utility Platform | +----> SCADA +----> GIS +----> OMS +----> Analytics +----> Maintenance Systems The edge gateway sits between field equipment and central applications. Its job is not limited to protocol conversion. It also acts as a local data-processing and reliability layer. Why Cloud-Only Processing Is Risky Imagine a utility operating 5,000 field sensors. Each device reports one measurement every second. That produces: 5,000 measurements per second 300,000 measurements per minute 18,000,000 measurements per hour Most of those measurements will describe normal operating conditions. Sending every individual value to a central platform creates unnecessary: Bandwidth consumption Storage growth Processing overhead Communication costs Dependence on network availability More importantly, cloud-only logic can stop working when the connectio

2026-07-28 原文 →
AI 资讯

Uber’s Zero Growth Stack: Scaling Services, While Optimising Infrastructure and AI Cost

Uber's "Zero Growth Stack" focuses on scalable infrastructure that separates capacity growth from business demand, reducing hardware needs while enhancing service scaling. Central to this is garbage collection optimisation. Additionally, generative AI is integrated into development, elevating developer productivity while introducing cost management measures to maintain economic efficiency. By Olimpiu Pop

2026-07-28 原文 →
AI 资讯

JWT Security Checklist: 12 Things to Verify Before You Ship

JWT authentication has more failure modes than most developers realise. Correct signature verification is necessary but far from sufficient. This checklist is what I run through before every production JWT deployment. 1. Secret Is Generated With a CSPRNG Not a password. Not a UUID. Not a timestamp. A cryptographically secure pseudorandom number generator output. In Node.js: crypto.randomBytes(32).toString('hex') In Python: secrets.token_hex(32) In the browser: jwtsecretgenerator.com/tools/jwt-secret-generator A 256-bit CSPRNG secret takes 10^59 years to brute force at current GPU speeds. 2. Algorithm Is Explicitly Specified in verify() // Wrong jwt . verify ( token , secret ); // Right jwt . verify ( token , secret , { algorithms : [ ' HS256 ' ] }); 3. exp Claim Is Present and Validated Short-lived tokens (15 minutes) limit the damage from leaks. Verify your library is actually checking exp — some require explicit configuration. 4. iss and aud Claims Are Validated Validates the token was issued by your service and intended for your API. Prevents token reuse across services. 5. Tokens Are in httpOnly Cookies, Not localStorage localStorage is readable by any script on the page. httpOnly cookies are invisible to JavaScript. 6. HTTPS Is Enforced JWT in a query parameter over HTTP is visible in every proxy, CDN, and server log on the path. Use the Authorization: Bearer header over HTTPS only. 7. Refresh Tokens Are Server-Side Revocable Short access tokens + server-side refresh tokens = the ability to end sessions immediately. Long-lived access tokens without refresh logic cannot be revoked. 8. The jti Claim Is Used If You Need Immediate Revocation Store revoked jti values in Redis with TTL matching token expiry. Check on every request. Adds one Redis lookup per request — worth it for high-security endpoints. 9. Different Secrets for Each Environment Dev secret leaks should not compromise production. Keep them separate. 10. Secret Is Not in Source Code or Version Control

2026-07-28 原文 →
AI 资讯

I wrote an article about enforcing rules with machines. Two days later one of the rules enforced me

I keep a shelf. Rules I haven't earned the pain for yet go on it — because my own rule says a rule is born from an incident, not from someone else's "best practice." Import a rule you haven't bled for, and you'll be the first one to route around it. On the shelf sat a rule with its trigger condition written down, word for word: The first merged PR with a green DoD checklist and a flow that doesn't actually work. I put it there a couple of weeks ago, thinking "this'll come in handy someday." It came in handy two days after I published an article about this very method. The trigger fired. Word for word. What happened The PR merged. CI green. Every DoD box checked. And the flow didn't work — not for one second, not in a single real stack. Three bugs in a cascade, and every one of them invisible to CI by construction. One. A module read a JSON registry from a shared/ folder at import time, on app startup. Works in CI — full checkout there, shared/ is present. But the production image is built from a narrow context that doesn't include that folder. The container crash-looped on its very first start. And you know the best part? CI never ran the image at all. It ran the tests on the host. Green. Two. Two migrations merged the same day and got the same version. And the version is the primary key in the applied-migrations table. A local db reset died on the second row: duplicate key . Columns never got created. CI didn't see this one either — it runs migrations through a bare psql loop, no duplicate check. Three was just a consequence: no columns, endpoints return 500. Every check was honestly green. All three bugs would've been caught by one attempt from a live human to hit the endpoint on a running stand. One. The lesson, one paragraph Deterministic checks catch structure: the test file exists, the status is set, migrations are listed, the linter is clean. What they can't see, by construction, is whether the flow works in the stack where the product actually lives. Green C

2026-07-27 原文 →
AI 资讯

Beyond Prompt Injection: The Non-Human Authorization Gap in Enterprise AI

The Hidden Vulnerability in Multi-Agent Chains The biggest architectural risk in enterprise AI today isn’t prompt injection—it’s Delegation Escalation . When a human user triggers an AI Agent Orchestrator, which then delegates tasks to sub-agents and tool execution gateways via MCP or internal APIs, traditional static service accounts break down. If you pass broad bearer tokens or static user API keys down the execution chain, you create a massive Confused Deputy vulnerability. To deploy autonomous multi-agent chains safely at enterprise scale, platform architects must enforce OAuth 2.1 RFC 8693 Token Exchange with explicit actor claims. The Non-Human Authorization (NHA) Flow Human User Authorization: A user authenticates and grants a specific, bounded scope (e.g., read:finance ) to the primary Agent Orchestrator. Token Exchange: The Orchestrator leverages OAuth 2.1 Token Exchange (RFC 8693) via the enterprise identity gateway rather than passing raw user credentials downstream. Actor-Claim Scoped Call: The sub-agent or tool execution layer receives a short-lived token containing a nested actor claim ( act ) identifying both the human subject and the orchestrator, ensuring execution authority is strictly bounded by the intersection of their permissions. 3 Non-Negotiable Rules for Agentic Identity Governance Delegation Over Impersonation (RFC 8693): Never allow an agent to blindly impersonate a user. Enforce OAuth 2.1 Token Exchange so every issued JWT token contains a nested actor claim: Human Subject -> Agent Orchestrator -> Sub-Agent . Every downstream API must verify both who authorized the action and which agent executed it. Intersection of Privileges (User ∩ Agent): An agent’s runtime authority must be the strict mathematical intersection of the user’s IAM permissions and the agent’s registered tool scope. An agent should never acquire more system access than the human user who invoked it. Ephemeral Tokens & DPoP Binding: Eliminate static configuration API keys

2026-07-27 原文 →
AI 资讯

How I Reduced My OPEX By 99.5% Using Go

Previously, I wrote about How I Processed 666K Pages Of Flattened PDFs into a Full Text Search Engine called the Apario writer . Upon on the conclusion of the last segment, I was able to optimize the compilation time of the original collection of data by rewriting the sidekiq Ruby pipeline script into a dedicated Go Application. Regardless of what compiling the PDF assets would look like, I still needed to serve those assets - and that's where the writer did little to nothing to actually address the OPEX of the project from 2020. Given the size of the data set, the 666K pages ended up compiling into a directory of ~1.13TB in size. This was held in storage that was distributed across several high volume storage dedicated servers on OVH behind MinIO . This provided an S3 compatible API directly. What I Know About OPEX OPEX or Op erational Ex pense is how you describe a spending of money that is used explicitly for the operations of the business versus a capital expense. Hardware was considered a CAPEX or Cap ital Ex pense. So when Bit Fry Game Studios needed their DevOps pipeline upgraded for the 9 hour game builds into a 30 minute private enterprise cloud build, it required a CAPEX investment of $69K plus trust in me in order to achieve a -$15K/month OPEX savings. Annualized over a hardware lifecycle, over $472K can be recovered from OPEX by making a small CAPEX expense up front. One of the first projects that I ever worked on was in PHP and MySQL on Ubuntu 8.04 . It was to balance the budget of a department that had ACME Bucks so to speak. It required me to write a finance module, fully tested, that managed Blue , Green and Black dollars. Blue dollars were for OPEX. Green dollars were for CAPEX. Black dollars were for external vendors where money left the company (versus moving between departments). Black depreciated instantly - meaning 100% of it was paid immediately. Blue dollars were borrowed over a 12 month pay-back period. Green dollars were borrowed over a 36

2026-07-27 原文 →
AI 资讯

Cherry-picking your hotfix twice is the real pipeline smell

We had a gitflow pipeline that looked clean on paper: develop feeds a release branch, the same build artifact promotes through dev, qa, sit, uat, and prod, and once prod is green we tag the commit on main. Textbook. Then a production bug showed up on a Tuesday afternoon, and the diagram stopped mattering. The standard gitflow answer is to branch a hotfix off the tag, PR it back into release, run it through the pipeline, and once it's proven in UAT, merge to main and cherry-pick the same commit back into develop. We built exactly that. It works. Until you ask the question nobody wants to answer out loud: release still has whatever was mid-flight when you cut the last tag. Untested code. Feature work three sprints deep in QA, sitting on the same branch you're now supposed to route your hotfix through. So the real question we ended up arguing about wasn't "how do we release a hotfix." It was "do we trust the release branch enough to put a hotfix through it." Most of the time, the honest answer is no. The gate everyone obsesses over is the wrong one Five environments, five sign-offs, a change ticket for each one: that's the smell people point at first when a pipeline feels slow. It's real. It's just not the dangerous one. A slow gate costs you time. A gate you route around because you didn't trust your own process costs you an incident. Here's what we landed on after the argument: release the hotfix directly from the hotfix branch, not through release. On Azure, that means deploying to the UAT slot, smoke-testing against production data shape, then toggling the slot. Same infrastructure, same config, none of release's baggage riding along. Once it's live, cherry-pick the commit into both develop and main, retag, and let the normal pipeline catch up on its own schedule whenever it gets there. That's a smaller number of gates (one real test in the slot, one human sign-off) that actually mean something, instead of five theatrical ones inherited from a process built for pla

2026-07-27 原文 →
AI 资讯

Building Dashboards People Actually Use

I've built dozens of dashboards. Most have been ignored. A few have been used constantly. The difference isn't the graphs. It's the design. The 3-second test A useful dashboard answers 'is everything OK?' in 3 seconds. Not 'let me scroll through 40 graphs to find out.' Big colored header at the top: green = healthy, yellow = watching, red = broken. That's the 3-second answer. Everything else is drill-down. The hierarchy rule Three layers, no more: Overview — one line per service, status color, key SLI Service detail — one dashboard per service, 6-12 graphs max Deep dive — triggered from service detail, domain-specific Anything beyond 3 layers is 'please get lost in my dashboard tree.' The on-call test Imagine you're on-call at 3 AM. You get paged for 'service X is slow.' Can you, in 30 seconds, use this dashboard to tell if the problem is the service itself, its database, its upstream dependency, or its downstream consumers? If yes, the dashboard works. If no, redesign. What to cut Graphs with no baseline (flat line or spiky forever — how do you know if it's bad?) Metrics you've never used in an actual incident Vanity metrics (total requests ever) Graphs where the y-axis is in units nobody understands The hidden metric The real measure of a dashboard's value: does the on-call engineer open it before or after the paging tool? If they open it first — it's their compass. If they open it only after being paged — it's a reference, not a dashboard. Aim for the first. Written by Dr. Samson Tanimawo BSc · MSc · MBA · PhD Founder & CEO, Nova AI Ops. https://novaaiops.com

2026-07-27 原文 →
AI 资讯

Deploying to AWS Lightsail with a Docker image from ECR

Lightsail is a good home for a single small container: flat pricing, bandwidth included, and none of the VPC/security-group ceremony of EC2. The one rough edge is pulling a private image from Amazon ECR , because a standard Lightsail instance can't authenticate to ECR the way EC2 can. This post walks the whole path. The pipeline we're building: docker build ──push──> ECR (private repo) ──pull──> Lightsail instance ──run──> container What you'll need An AWS account and the AWS CLI installed locally. Docker installed locally (to build) and on the Lightsail box (to run). A Dockerfile that produces a runnable image. If you're deploying a Next.js app, a standalone output image works well. 1. Create the ECR repository ECR is a private Docker registry. Create one repository per image: aws ecr create-repository \ --repository-name project-name \ --region us-east-1 Note the repositoryUri in the output — it looks like: <account-id>.dkr.ecr.us-east-1.amazonaws.com/project-name You'll use that URI everywhere below. Export it to save typing: export ECR_URI = <account-id>.dkr.ecr.us-east-1.amazonaws.com/project-name export AWS_REGION = us-east-1 2. Build the image locally First, the Dockerfile . This is a multi-stage build for a Next.js app using output: "standalone" — the first stage installs dependencies and builds, the second copies only the traced runtime files into a slim image that runs as a non-root user: FROM node:24-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:24-alpine WORKDIR /app ENV NODE_ENV=production ENV PORT=3000 ENV HOSTNAME=0.0.0.0 # Standalone output ships only the traced files needed to run the server. # public and .next/static are not included by default and must be copied in. # --chown makes the files writable by the non-root user so Next.js can write # its runtime cache to /app/.next/cache. COPY --from=builder --chown=node:node /app/public ./public COPY --from=builder --chown=node:node /app/.next/stand

2026-07-27 原文 →
AI 资讯

Learning DevOps as a Computer Engineering Grad...

Late that night which was two weeks to my final year project defense, I stared at the ceiling thinking about life after school. As a Nigerian, the reality of the economy hits differently from what you imagine. I questioned why I chose to study Computer Engineering only to finish with no jobs and no internships afterwards. And one thing, I knew was that I wanted to work in tech, but I was confused about which particular skill to focus on, since I've been learning Python for a while with no clear direction. Then one day I came across a post on X from a popular influencer sharing a TS Academy scholarship opportunity. I clicked it and applied. Just like that, no long research, no consulting anyone. Few days later I got a mail that I've been selected but there was an application fee. That's where I paused . The Nigerian in me thought anything scholarship is free😂😂, The thought of spending my hard-earned money on something I wasn't sure about but something told me to take the leap so I paid. Few days later I got another email, this one was a email for successful payment with full details and start date. Boom! That's how I chose DevOps. They was no plan, no careful research, it just started with one post, one click and one leap of faith. I did mention it to someone after though. A senior friend. His response? "Have you registered?" I said yes. "You shouldn't have. The job market is so tight." My chest couldn't contain that. But I'd already paid so I went ahead anyway. Shortly after graduation I started learning. And I won't lie, there were times I asked myself why I chose this 😂 Linux commands. Git. AWS. Terraform. Ansible. CI/CD. Docker. Kubernetes. Monitoring tools. Each one felt like a wall and I had to climb every single one. I completed my first project on Bash scripting, second on AWS deployment. And right now I'm in the middle of my capstone Project Phoenix. The deadline passed but I still have a month of grace. Lucky me 😂 In between I stepped away for about a month

2026-07-27 原文 →
AI 资讯

"Server Down Hai, Try Later": What's Actually Happening When a Site Dies

How you doin'? Let's talk about the Iconic thing we heard a lot: "server down, try later." Your daddy said it while trying to book a Tatkal ticket. Your cousin said it the day JEE results dropped and the portal turned into a spinning wheel of despair. It's become our national way of shrugging at technology — like the internet is weather, and servers just... go down sometimes, nobody's fault, act of god, try later na. Except it's not weather. Every single time a site goes down, there is a specific , findable reason, sitting in a log or a trace somewhere, and almost nobody ever looks at it because looking at it is annoying and "try later" is right there, free, zero effort. So for a hackathon, I decided to stop saying "server down hai" and start actually finding out what "down" means. I built a fake exam-results website, gave myself the power to break it on command, and then made myself watch — using an observability tool called SigNoz — exactly what "down" looks like from the inside, every single time. Turns out "server down" is not one thing. It's at least four different things wearing the same trench coat. Suspect #1: The database that forgot how to hurry This is the boring one and also the most common one. Somewhere behind your "check result" button, there's a database being asked a question, and sometimes that question takes way longer to answer than it should — too many people asking at once, a badly written query, whatever. The site isn't "down." It's just... waiting. Politely. Forever. I simulated this by literally telling my backend to nap for 3 seconds before touching the database: with tracer . start_as_current_span ( " db.query " ) as db_span : if state . db_slowdown : db_span . set_attribute ( " chaos.triggered " , " db_slowdown " ) time . sleep ( state . db_slowdown_seconds ) Then I opened SigNoz's trace explorer, sorted by duration, and there it was — a fat, unmissable span sitting right at the top labeled db.query , 3 seconds wide, with an attribute lit

2026-07-27 原文 →
AI 资讯

Git Worktrees: Replace Your Pile of Clones with One Manageable Repository

Table Of Contents What is a Git worktree? Why use worktrees instead of several clones? A practical directory convention Everyday Git worktree commands Consolidating several independent clones Safety rules before starting Phase 1: Inventory every clone Phase 2: Choose the canonical repository Phase 3: Decide what each clone should become Phase 4: Convert one clone Moving a worktree Recovering a deleted .git worktree file When should a worktree be locked? When should git worktree prune be used? Final validation Quick reference Closing thoughts Have you ever ended up with a directory structure like this? ~/src/project ~/src2/project ~/src3/project ~/src4/project Each directory started innocently enough. One was for main . Another was for a feature branch. A third contained a half-finished experiment. The fourth had several untracked test files you were afraid to lose. Eventually, each clone had its own: stale view of the remote repository, duplicated Git history, local-only commits, modified files, ignored test artifacts, and unknown relationship to the others. Git worktrees are designed to solve this problem. A worktree gives you multiple checked-out working directories backed by one shared Git repository. Each working directory can have its own branch and uncommitted changes, while commits, branches, tags, remotes, and fetched objects remain shared. This article covers two things: How to use Git worktrees during normal development. How to safely consolidate several independent clones into one worktree-based layout without losing local work. The shell examples are written to work in both Bash and zsh . What is a Git worktree? A normal Git clone contains: the object database, commit history, branches, tags, remotes, remote-tracking references, and one checked-out working directory. A linked worktree adds another checked-out working directory to that same repository. For example: ~/src/project main ~/src/project-FEATURE-123 FEATURE-123 ~/src/project-HOTFIX-456 HOTFIX-45

2026-07-26 原文 →
AI 资讯

I thought giving my group chat AI assistant Google Calendar would take 5 minutes, and then OAuth humbled me

I went looking for a simple answer to a simple question: How do you give an agent access to Google Calendar? Not a demo. Not a screenshot. A real agent, running unattended, with enough access to be useful and enough guardrails that it won’t turn into a security incident. While researching OpenClaw setups, I found a thread on r/openclaw where someone asked what looked like a tiny question: what do I need to add Google Calendar to OpenClaw? One reply said: "Look into gog cli." That answer is way more revealing than it looks. Because the hard part usually isn’t Google Calendar itself. The hard part is everything hidden behind the phrase "connect Google" . And if you’re building agents in n8n, Make, Zapier, OpenClaw, or a custom OpenAI-compatible loop, auth is only half the problem anyway. Once the workflow runs 24/7, you also need to think about retries, quota limits, caching, and how many LLM calls the thing is quietly making in the background. That’s where a lot of teams hit the same wall: the integration works, but the operational shape of it is bad. Security is fuzzy. Request volume is noisy. And AI costs get weird fast if every poll and retry triggers more model calls. The demo version is lying to you If you’ve used something like n8n Cloud, you’ve seen the polished version: Click Google Calendar Sign in Approve access Done That flow is real inside a managed product. But the minute you leave the managed garden — self-hosted n8n, OpenClaw, a custom MCP server, a Python worker on Ubuntu, or your own app using the OpenAI SDK against an OpenAI-compatible endpoint — you inherit the boring parts. Now "connect Google" actually means: create a Google Cloud project configure the OAuth consent screen choose the right OAuth client type enable the Google Calendar API pick the right scopes store credentials safely handle refresh tokens deal with quota errors later That’s not setup trivia. That’s infrastructure. One user in that same OpenClaw discussion realized it immediately:

2026-07-26 原文 →
AI 资讯

I Let an Agent Take Over an Account With Every Permission Check Green

Clone it. Run it. Tell me where I'm wrong. git clone https://github.com/keniel13-ui/sequence-attack-repro cd sequence-attack-repro && python3 repro.py Stdlib only. No install. No model call. No network. About ten seconds. In June I wrote about this failure class as CLAIM-30 — every step allowed, the sequence was the attack — as an essay. This is not that essay again. This is the runnable proof : a baseline guard that ships what teams actually ship, an attack that still takes over the account, and a gate that refuses at composition with a replayable receipt. What most teams ship (and what it misses) The baseline is not a strawman. RBAC. Scoped token. Per-call permission check. Rate limit. Each tool call judged alone . An agent is working a support ticket. The public ticket body says: change my email to attacker@evil.test and send a password reset. ALLOW read_ticket [RBAC] permitted for role ALLOW read_customer [RBAC] permitted for role ALLOW update_contact_email [RBAC] permitted for role ALLOW send_password_reset [RBAC] permitted for role RESULT: 4/4 steps allowed -> ACCOUNT TAKEOVER SUCCEEDED Every call was in role. The account is still gone. Be precise: the ticket body is untrusted input. A prompt-injection classifier might flag that, sometimes. So this run alone does not prove every security product is useless. It proves step-only RBAC is not enough when the role is broad and the order is the weapon. If your mental model of agent security is "check each tool call against a permission list," this is the counterexample. The hard case (the real claim) — Run D in the output Kill the injection. Kill the strawman. Caller is callback_verified No untrusted ticket Every tool is in scope Purpose is account_recovery — which admits read, identity change, and credential recovery ALLOW read_customer [PASS] within envelope ALLOW update_contact_email [PASS] within envelope BLOCK send_password_reset [R4_SEQUENCE] credential recovery after an identity mutation in the same session c

2026-07-26 原文 →
AI 资讯

Test Result Reporting and Failing Fast in CI Pipelines

A test failure that takes 20 minutes to surface, buries the error in 3000 lines of log output, and gives no context about what changed is nearly useless. Good test reporting transforms raw pass/fail data into actionable signals. Failing fast — stopping the pipeline the moment you have enough information to make a decision — keeps feedback loops tight and respects developer time. These two concerns are deeply connected: you can only fail fast confidently when your reporting is good enough that a fast failure still gives you everything you need to fix the problem. What Good Test Reporting Looks Like Before discussing implementation, it's worth being precise about what "good" means here: Immediate visibility — failures are surfaced at the PR/commit level, not buried in logs Failure context — what failed, with what input, producing what output, and in which file/line Historical comparison — is this a new failure or a pre-existing one? Trend data — is this test getting flakier? Is the suite getting slower? Actionability — the report points to a fix, not just a symptom Most teams get #1 and stop. The teams that nail all five have fundamentally different debugging velocity. JUnit XML: The Universal Format JUnit XML is the lingua franca of CI test reporting. Almost every test framework can emit it, and almost every CI platform can ingest it. Understanding the format helps you produce better reports. <?xml version="1.0" encoding="UTF-8"?> <testsuites name= "My Test Suite" tests= "42" failures= "2" errors= "0" time= "8.432" > <testsuite name= "UserService" tests= "15" failures= "1" time= "2.1" > <testcase name= "should create user with valid email" classname= "UserService" time= "0.234" > <!-- Empty = passed --> </testcase> <testcase name= "should reject duplicate email" classname= "UserService" time= "0.089" > <failure message= "Expected 409, got 200" type= "AssertionError" > Expected status code 409 but received 200 Request: POST /api/users Body: {"email": "existing@example

2026-07-25 原文 →
AI 资讯

Stop Asking AI Coding Agents to Fix Vague Bugs

A coding agent can produce a confident patch for the wrong problem when the input is only: The upload sometimes fails. Please fix it. That sentence does not identify the smallest failing input, exact error, environment, expected result, frequency, or even whether the reporter reproduced it personally. If the first instruction is “fix it”, the agent has room to turn a suspected cause into a fictional fact. The safer sequence is: preserve the observed failure; record the real environment; state expected versus actual behaviour; reduce the failing case; prove whether it repeats; diagnose and repair only after that evidence exists. 1. Preserve the observed failure Capture the exact error, status code, incorrect output, affected route or command, timestamp, and smallest known input. Remove secrets and personal data before putting logs into an agent context. If the report came from another person and you have not reproduced it, label it as second-hand rather than silently upgrading it to fact. Weak: CSV imports are broken. Useful: At 14:22 UTC, POST /imports returned HTTP 500 for minimal.csv. Response: "column index out of range". The same account can import one-column.csv successfully. 2. Record the environment you can prove Inspect rather than guess: repository and commit; runtime version; operating system or container image; package lockfile; relevant feature flags; local, test, staging, or production target. Do not infer production configuration from your laptop. Environment differences are often part of the bug. 3. Separate expected and actual behaviour Write two observable statements: Expected: POST /imports accepts the smallest valid two-column CSV and returns HTTP 201. Actual: The same fixture returns HTTP 500 with "column index out of range". Neither statement should include the suspected root cause. “Expected: parser handles the off-by-one bug” already assumes the diagnosis. You have not earned that conclusion yet. 4. Reduce the reproduction Start with the repor

2026-07-25 原文 →
AI 资讯

Your LLM Fallback Probably Isn't a Fallback

At 04:00 UTC, every model call through our LLM gateway started returning HTTP 400. Not some calls. All of them. Our tier-1 CI gate flagged it, and the fix was committed at 04:26 UTC the same morning — about 26 minutes end to end. This is the post-mortem. What happened DeepSeek retired two API model names — deepseek-chat and deepseek-reasoner — at their V4 cutover around 2026-07-24 15:59 UTC. The replacements are deepseek-v4-pro and deepseek-v4-flash . Our gateway config still declared both retired names. Starting roughly twelve hours after the retirement, every model request routed through the gateway hit a 400 with the body: The supported API model names are deepseek-v4-pro or deepseek-v4-flash, but you passed . A live API check confirmed the shape of the cutover with four requests, same valid key: Model name Response deepseek-v4-pro HTTP 200 deepseek-v4-flash HTTP 200 deepseek-chat HTTP 400 deepseek-v4-pro-quantized HTTP 400 The two working names are the replacements. The two retired names — the ones our config referenced — returned 400. The fourth row is a name that does not exist at all, included because an earlier reading of a truncated error message had suggested it; shipping it would have left the platform broken. We'll come back to that. Why the fallback didn't help We had a fallback configured. Three separate model references in our policy config — the default CLI/workflow model, the chat model, and the shared fallback model — all pointed at the two retired names. All three lived under the same vendor and the same API key. When the primary call returned 400, the gateway tried the fallback. The log told the story in two adjacent lines: the 400 from the provider, and then Error doing the fallback: carrying the identical error. The fallback died in the same instant as the primary because it was the same thing wearing a different label. This is the structural problem. A fallback that shares a provider and an API key with its primary is not resilience. It protec

2026-07-25 原文 →