惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
N
News and Events Feed by Topic
量子位
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
Hugging Face - Blog
Hugging Face - Blog
S
Security Affairs
J
Java Code Geeks
Schneier on Security
Schneier on Security
Google Online Security Blog
Google Online Security Blog
TaoSecurity Blog
TaoSecurity Blog
小众软件
小众软件
S
SegmentFault 最新的问题
www.infosecurity-magazine.com
www.infosecurity-magazine.com
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Privacy International News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
博客园 - 聂微东
T
Tor Project blog
博客园 - Franky
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
罗磊的独立博客
博客园_首页
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
腾讯CDC
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
博客园 - 【当耐特】
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
AWS News Blog
AWS News Blog
WordPress大学
WordPress大学
Jina AI
Jina AI
G
GRAHAM CLULEY
V
V2EX
L
LINUX DO - 最新话题
H
Heimdal Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
IT之家
IT之家

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
I Built an AI Agent to Do My Pre-Refinement. It Turned Into a Mirror of How We Wrote Tickets.
Olexandr Uva · 2026-04-28 · via DEV Community

1 hour. Seven hours. Same ticket, same prompt, two days apart.

The agent wasn't broken. It was showing me what my team had been doing silently for years.

But I'm getting ahead of myself.

The setup

Most teams I've worked on have a stage between "product writes a ticket" and "the team estimates it" — pre-refinement, grooming, technical intake, different names for the same homework. A developer reads the ticket before the team meeting, opens the design tool, searches the repos for similar components, and leaves a technical comment: what already exists, what needs to be built, files involved, an hour estimate, open questions. Then the team meets and estimates.

Without that homework, the meeting becomes the homework. Fifteen minutes stretches to forty-five.

That homework cost me about a day and a half per sprint. Not glamorous. Not particularly hard. Mostly reading, searching, context-switching, and a lot of "I swear we built something like this six months ago, where is it."

Perfect thing to hand to an AI agent.

The first version

The setup was intentionally boring. Nothing exotic under the hood — an LLM with tool access to our ticket system, the design tool, and both repositories, plus a prompt that said read these sources, produce this output, post it back as a comment. That's it.

What the agent was supposed to produce, per ticket:

  • What parts of the feature already exist in code
  • What needs to be built from scratch
  • A short plan with files involved
  • An hour estimate
  • Open questions

I ran it across the backlog. Comments appeared. Plans looked reasonable. I moved on, happy to have my afternoons back.

Then I started actually reading what it produced.

Discovery one: the agent was blind to what we already had

The agent kept confidently recommending we build things we'd already built.

A typical shape: a ticket would describe a feature — say, a section that displays a list of items with specific formatting, calculations, and localization rules. The agent would read it, search the code, and recommend building it from scratch. Meanwhile the exact calculation lived in another component, built months ago for a different flow. The agent missed it because the component name didn't match the language of the ticket, and because we have hundreds of components with similar-sounding names.

This wasn't the agent being dumb. This was me asking it to navigate our codebase the way a new hire does on day one — by keyword search and guesswork.

Why this matters more than it sounds

Our system is split across two repositories — a frontend one, and a CMS-style one. The frontend holds the actual UI components. The CMS-style repo holds configurable blocks that reference those components, and it's where product writes tickets from — picking blocks from a list, configuring their content, wiring them into flows.

The problem isn't that components are missing. They're there. Both in the frontend and registered in the CMS. The problem is that there are a lot of them, built over years, and nobody remembers all of them. Someone writing a ticket for a new section rarely scrolls through the full list of existing blocks to check. They describe what they want in their own words, and the ticket enters the backlog as "new feature" — even though the block they want already exists three dropdowns away.

The fix: give the agent institutional memory

The agent needed a map of what already existed. Not the code itself — the vocabulary of it. A living document listing our section types, screen types, their variants, and what each one actually does, in plain language.

So I wrote a second, smaller command: a sync script. It scans the frontend repo, pulls all the component schemas, and maintains a markdown file — something like component-patterns.md — that describes what exists, grouped by category, with short plain-language notes on what each component does. The main agent reads that file before doing anything else. Before searching. Before planning. Before estimating.

That single change turned the agent from "a confident outsider" into "someone who's at least read the team wiki." It started flagging overlaps it used to miss — tickets where the real answer wasn't "build this," but "most of this already exists, we just need to extract it and reuse it."

A small but consistent pattern appeared after that: two to five tickets per sprint would collapse. Not get simpler — the scope itself would change, from "build a new section" to "reuse the existing one with minor tweaks." Work that, measured honestly, shouldn't have existed.

That was the first uncomfortable finding. The slow part of pre-refinement wasn't reading the ticket. It was the institutional forgetfulness around what we'd already built.

Discovery two: the estimates drifted

Once the agent had a map of the codebase, the plans got better. But the estimates started doing something weird.

I ran the same ticket through the agent on two different days. No changes to the ticket. No changes to the prompt. First run: one hour. Second run: seven hours.

I read both outputs carefully. In one run, the agent had quietly assumed mobile wasn't in scope, the text was hardcoded, and the amounts didn't need locale-specific formatting. In the other run it had assumed all three. The ticket didn't specify any of them — so the agent filled the gaps differently each time. Gaps are gaps.

Then came the uncomfortable thought: this is exactly what humans on my team had been doing, too. Silently. Each person filling the same blanks with their own assumptions, and the aggregate came out looking like "team judgement" at the refinement meeting.

When estimates disagree in a room of people, we call it a discussion. When estimates disagree between two runs of the same model, it's glaringly obvious they're both guesses. The agent wasn't adding noise. It was surfacing noise we had been absorbing without noticing.

Discovery three: the same word meant different things

The same drift showed up in language, not just numbers.

A ticket uses the word "static." Everyone nods. Nobody stops to check: static in what sense? No animation? No saved user state? No editable copy in the CMS? Three different questions, one word.

The agent would hit tickets like that and — because it has no social cost for asking — just ask. "You wrote 'static.' Do you mean not animated, not interactive, or not editable? The design shows a button, which suggests interactivity, so I'm unsure."

Sometimes the PM meant one thing, the designer meant another, and whoever eventually built it would have read it as a third. Without the agent, those disagreements surfaced halfway through implementation. The ticket bounced around chat for a day, the developer rewrote the screen, everyone moved on. With the agent, they surfaced before anyone started coding. Same question. Vastly cheaper to ask.

The part I got wrong

My first instinct, after seeing these drifts, was to tune the agent harder. Add constraints. Force it to flag missing context instead of guessing. Make it more deterministic.

It helped a little. It didn't fix the root issue.

Because the agent was being asked to produce a technical plan from a ticket that wasn't ready to be turned into one. You can't tune your way out of that. You're asking the wrong question of the wrong document.

The weak link wasn't the agent. It was the input. And the input came from a different person — a product manager — who needed a different kind of feedback than the technical agent was producing. Files, gap analyses, hour estimates — useful to a developer. A PM reads that and has nowhere to hook in. They wrote requirements; they didn't write code. A technical review doesn't give them anything they can fix.

If I wanted the ticket to reach the technical agent in usable shape, I needed a different review — aimed at the ticket itself, written in the language of requirements.

Same access, opposite voice

So I built a second agent. A task quality reviewer.

Its plumbing is almost identical to the first one. Same ticket system access. Same repository search. Same design tool integration. Same component-patterns map.

The personality is the opposite. The system prompt has a hard rule near the top — roughly:

You have full access to both codebases. Use it internally to understand
what already exists and what's feasible.

STRICTLY FORBIDDEN in your output:
- File paths, code, schemas, APIs
- Technical jargon (component, props, endpoint, schema)
- Implementation details or options
- "How to build" anything
- Architecture suggestions

Your job is NOT to plan implementation.
Your job is to ask clarifying questions about REQUIREMENTS.

Transform technical findings into requirement questions.

Enter fullscreen mode Exit fullscreen mode

And a translation table that turns things the agent finds in the code into questions a PM can answer:

What the agent finds What it actually asks
The CMS can't store this text "Do editors need to change this wording, or is it fixed?"
A similar feature already exists elsewhere "Should this behave the same way as that one, or differently?"
No error state is shown in the design "What should the user see if something goes wrong?"
No mobile design exists "Does this need to work on phones? Same layout, or a different one?"
A timing behavior isn't specified "If the user has spent five minutes on the previous screen, does this start fresh or pick up where they left off?"

The reviewer reads the ticket, checks the design, searches the code to know what's feasible — and produces a list of human-language questions about what the ticket doesn't yet say. The PM gets a comment that feels like a thoughtful peer asking for clarification. They update the ticket. Run it again. In practice it's usually one cycle — one round of questions, one round of answers, done. Occasionally a second pass for edge cases, but rarely a long loop.

What actually fixed things: the gate between them

Having two agents didn't fix anything by itself. The fix was the order — and the rule that the second agent doesn't run on a ticket the first one hasn't cleared.

Here's the flow:

  PM writes ticket
        │
        ▼
  ┌──────────────────────┐
  │  Quality reviewer    │  ← same tools, PM-facing voice
  └──────────┬───────────┘
             │
     ┌───────┴───────┐
     │ Questions?    │
     └───────┬───────┘
    yes      │       no
    ◄────────┤
  PM updates │
  the ticket ▼
  ┌──────────────────────┐
  │  Technical agent     │  ← same tools, dev-facing voice
  └──────────┬───────────┘
             │
             ▼
    Team refinement
             │
             ▼
       Execute step

Enter fullscreen mode Exit fullscreen mode

Nothing clever in the sequence itself. It's just a gate. But without the gate, the system falls back to the old problem: the technical agent producing confident plans from under-specified tickets, and estimates that silently disagree.

The value turned out not to be in having more agents. The value was in preventing each one from running on an input the previous step was supposed to clean up.

What this actually changed

A few concrete things, after running this setup for a while:

  • Pre-refinement vanished from my calendar. The day and a half per sprint that used to go to reading tickets, opening the design tool, and grepping through repos is roughly zero now. I read the agent's comment on my way to the meeting; if something is unclear, the comment points me to the exact files where the relevant logic lives.
  • Refinement meetings got shorter. The team walks in with the write-up already done. Discussions focus on trade-offs and priorities instead of "what exactly does this ticket even mean."
  • 2–5 tickets per sprint stop being new work — they collapse to "reuse the existing component with minor tweaks" once the agent surfaces what's already there.
  • Estimates stopped drifting on the same ticket. Because the ticket arriving at the technical agent is now complete, the agent doesn't have gaps to fill with guesses.

Honestly, the agent's write-ups are more thorough than mine ever were, because it doesn't get tired halfway through the backlog.

One more step (with caveats)

Once the flow was stable, I added one more thing — not an agent, a small script. It reads the technical plan from the ticket comment, creates a branch in the right repo, and implements the ticket following local conventions.

Quality is rough — closer to "a junior following clear instructions" than a senior who's seen the problem before, and not always even that. Small, well-scoped tickets it closes fine. Anything more complex it struggles with. Real room to improve, and it's the next thing on my list.

But the reason the rough version works at all is that by the time a ticket reaches the execute step, the plan is already a plan. Requirements are in the ticket. The existing-code check has been done. The "is this actually new work" check has been done. The script isn't being asked to decide anything big — it's being asked to follow a document.

When it fails, it tends to fail in small, specific ways that point back to a gap one of the earlier steps missed. Even in its current rough shape, it ends up acting as a final validator of the work that came before.

Three takeaways

An AI agent isn't a model. It's an output contract for a specific reader. The same access, same data, same tools can drive two agents that produce completely different — and equally useful — artifacts, just because they're written for different people. Trying to fit two readers into one agent is a design problem, not a prompt-tuning problem.

Automation reveals process. If an automated step produces unstable output, before blaming the model, look at the step before it. Humans may have been quietly absorbing that instability for years. The agent does the same work without the silent patching — and suddenly the noise becomes visible. That's a diagnostic, not a failure.

A chain of agents isn't valuable because there are more agents in it. It's valuable because of the gates between them. The order matters. The refusal of the next step to run on unready input matters. Remove the gates and adding agents just compounds the same mess in more places.


If I had built the pre-refinement agent and stopped there, I'd have reclaimed my afternoons and convinced myself I'd automated a process. Instead I accidentally ran an audit of how we wrote tickets — and that turned out to be worth more than the hours the agent itself saved.

Which is maybe the most honest thing I can say about using LLMs inside a team workflow: the first thing a well-built agent usually shows you is what the team was actually doing before you automated it. Sometimes that's the real story.


This is the opening article in my AI Agents series. It builds on lessons from my earlier CSS in a Team series — the same principle of "make the system enforce itself" shows up here, just in a different medium.