13 years in, AI nearly left me behind. So I stopped fighting it and started building.
13 years in, AI nearly left me behind. So I stopped fighting it and started building.
从业 13 年,AI 差点让我被时代抛弃。于是我不再抗拒,转而开始构建。
13 years in, AI nearly left me behind. So I stopped fighting it and started building. I’ve been writing code for thirteen years. I mention that not to flex, but because it’s exactly why the last couple of years rattled me. When AI coding tools started getting genuinely good, I felt something I hadn’t felt since I was a junior: behind. Thirteen years of hard-won instinct, and suddenly a chatbot could scaffold in thirty seconds what used to take me an afternoon. You tell yourself it’s hype. Then you watch a feature ship in a day that would’ve taken a week, and the floor shifts a little under you. So I did what a lot of us did. I started dabbling. 从业 13 年,AI 差点让我被时代抛弃。于是我不再抗拒,转而开始构建。我写代码已经十三年了。我提到这一点并非为了炫耀,而是因为这正是过去几年让我感到不安的原因。当 AI 编程工具变得真正好用时,我感受到了一种自初级程序员以来从未有过的感觉:落后。十三年辛苦磨练出的直觉,突然间,一个聊天机器人能在 30 秒内搭建出我过去需要一下午才能完成的框架。你告诉自己这只是炒作。然后你眼睁睁看着一个原本需要一周才能完成的功能在一天内上线,脚下的地基似乎动摇了。于是,我做了我们许多人都会做的事:我开始尝试接触它。
The dabbling phase
尝试阶段
At first it was small, low-stakes stuff. Summarising things. Turning a wall of server logs into a readable incident report when a site fell over at 2am: paste the logs, one-line prompt, done. Little wins, low trust required. I wasn’t betting anything important on it. Then the wins got bigger, and so did my usage. I settled on Claude, in a browser tab that was basically always open. I’d describe a small problem, like a bit of functionality a site needed or a fiddly plugin to handle one specific thing, and download the artifact it produced. Copy, paste, tweak, ship. It became a real part of how I worked. But a browser tab has a ceiling. You’re forever copying things in and out, losing context, re-explaining your codebase every single session. 起初是一些小规模、低风险的事情。比如总结内容。当凌晨 2 点网站崩溃时,将一大堆服务器日志转化为可读的事故报告:粘贴日志,输入一行提示词,搞定。这些小小的胜利不需要太高的信任度。我并没有在上面押注任何重要的东西。后来,胜利变得越来越大,我的使用频率也随之增加。我最终选择了 Claude,它的标签页基本上一直开着。我会描述一个小问题,比如网站需要的一个小功能,或者处理特定任务的复杂插件,然后下载它生成的产物。复制、粘贴、微调、发布。它成了我工作流程中真正的一部分。但浏览器标签页是有上限的。你必须不断地复制粘贴,丢失上下文,并且在每次会话中都要重新解释你的代码库。
Down the rabbit hole
深入兔子洞
So I went into the terminal properly. Learning MCP servers, wiring the AI into my actual environment, my actual files, my actual tools. It was not a weekend project. It was a long, frustrating slog of making AI work the way I needed it to, rather than the way the demos pretended it already did. And somewhere in there, I hit the wall I think every serious developer using AI eventually hits: The time you save prompting, you lose reviewing. Because AI is confidently wrong in very specific, very repeatable ways. After enough hours you start to recognise the tells: It calls a method that doesn’t exist, a function the library never had, written so plausibly you almost don’t check. It imports a package you never installed, or invents a config option that was never in the docs. It reaches for a deprecated pattern from three years ago, because that’s what the training data was thick with. It “helpfully” refactors code you didn’t ask it to touch, and quietly reintroduces a bug you fixed last week. And the one that started to genuinely worry me: it leaves user input unsanitised, logs things it shouldn’t, hardcodes a secret right there in the source, because it’s optimising for works, not safe. I found myself spending nearly as many hours auditing AI output as I used to spend writing the code myself. I couldn’t find the balance between prompting and policing. And in an industry this competitive, “slower but I trust it” and “faster but I’m anxious about it” are both losing positions. That security thread turned out to be the loose end that unravelled everything else. 于是我正式进入了终端。学习 MCP 服务器,将 AI 接入我实际的环境、文件和工具中。这不是一个周末就能完成的项目。这是一个漫长且令人沮丧的过程,目的是让 AI 按照我的需求工作,而不是像演示中那样“假装”它已经完美了。在这个过程中,我撞上了我认为每个使用 AI 的严肃开发者最终都会撞上的那堵墙:你在提示词上节省的时间,全花在审查上了。因为 AI 总能以非常具体、非常可重复的方式“自信地胡说八道”。经过足够多的时间,你开始识别出它的破绽:它调用一个不存在的方法,或者库里从未有过的函数,写得如此逼真,以至于你差点就不去检查了。它导入一个你从未安装过的包,或者发明一个文档里从未有过的配置选项。它会使用三年前的弃用模式,因为训练数据里充斥着这些内容。它会“好心”地重构你没要求它改动的代码,并悄悄地重新引入你上周才修复的 Bug。最让我真正担心的是:它留下了未经过滤的用户输入,记录了不该记录的内容,直接在源码中硬编码了密钥,因为它优化的是“能运行”,而不是“安全性”。我发现自己花在审计 AI 输出上的时间,几乎和我以前自己写代码的时间一样多。我无法在提示和监管之间找到平衡。在这个竞争激烈的行业里,“慢但可信”和“快但焦虑”都是失败的策略。而那个安全隐患,最终成了导致一切崩塌的导火索。
How Ghostables was born
Ghostables 是如何诞生的
A client raised their hand and asked the question I’d been quietly dreading: “If you’re using AI to build our software, how do we know our data is safe?” Fair question. And I didn’t have a clean answer. So I went and built one. That became Ghostables, a way to make the data a project holds genuinely defensible, so that “we used AI” and “your customers’ data is protected” can both be true at once. I won’t go deep here; the point is it wasn’t a startup idea on a whiteboard. It was a real problem a real client had, and I built the thing that solved it. But solving it exposed something bigger about how we were working. 一位客户提出了我一直默默担心的问题:“如果你使用 AI 来构建我们的软件,我们怎么知道数据是安全的?”这是一个公平的问题。但我没有一个完美的答案。于是我动手做了一个。这就是 Ghostables 的由来,它让项目中的数据变得真正可防御,从而让“我们使用了 AI”和“客户数据受到保护”这两点能够同时成立。我在这里就不深入展开了;重点是,这并不是白板上的创业构想。这是一个真实客户遇到的真实问题,而我构建了解决它的方案。但解决这个问题揭示了我们工作方式中更大的问题。
The problem that became Snagger
演变成 Snagger 的问题
The agency I was at delivered projects… backwards. Feedback lived in screenshots with red circles scrawled on them. Client changes arrived as “the button on the about page, the second one, not that one.” Sign-off was a verbal “yeah, that’s fine” that evaporated the second a dispute started. Nothing was tracked. Everyone re-explained everything five times. If you’ve ever sent a developer a screenshot with a red circle and the note “this bit looks off”, you already know the exact problem I’m describing. 我所在的代理公司交付项目的方式……是倒退的。反馈存在于涂满红圈的截图中。客户的修改意见是“关于页面上的那个按钮,第二个,不是那个”。验收确认只是口头上的“嗯,行”,一旦发生纠纷,这句话就烟消云散了。没有任何记录。每个人都要把事情重复解释五遍。如果你曾经给开发者发过一张带有红圈并附注“这块看起来不对劲”的截图,你就明白我所描述的正是那个问题。
I genuinely tried not to build this
我真的尝试过不去开发这个产品
Before I wrote a line of code, I did the responsible thing and went looking for the tool that already did the job. I didn’t want to build a product; I wanted to use one. So I tried a lot of them. The visual-feedback tools are good at what they do. BugHerd, Marker.io, Usersnap, Pastel, Ruttl and the rest all do their job well. But they nearly all work one of two ways: either you install a script or widget on the site, or they freeze the page into a static screenshot you annotate on top of. The first needs developer cooperation and falls over the moment you’re reviewing a client’s existing site you don’t control, a staging build behind auth, or anything with a strict security policy that throws the snippet straight out. The second hands you a dead image: the menus don’t open, the forms don’t submit, the JavaScript doesn’t run, and you’ve lost the exact behaviour you were trying to give feedback on. The thing I most needed to review was usually the thing I either couldn’t install on, or couldn’t afford to flatten into a screenshot. And even when they worked, they only ever solved one slice of the project: the bug list. The feedback lived in BugHerd, but the design review lived in Figma comments, the sitemap lived in Slickplan or FlowMapp, the wireframes lived in Balsamiq or back in Figma, the tasks lived in Trello or ClickUp, and the client approval lived… nowhere, really, beyond an email that said “looks good.” Five or six subscriptions, none of them talking to each other, and the context dying every time it crossed a boundary. The part that finally pushed me over the edge was sign-off. Not one of them gave me a clean, formal “the client approved this page, on this date, at this viewport”, the kind of record that ends a dispute. 在写下一行代码之前,我做了负责任的事:去寻找现有的工具。我不想开发产品,我只想使用现有的。所以我试了很多。视觉反馈工具在它们擅长的领域做得很好。BugHerd、Marker.io、Usersnap、Pastel、Ruttl 等等,它们都做得不错。但它们几乎都以两种方式工作:要么你在网站上安装脚本或小部件,要么它们将页面冻结为静态截图,让你在上面标注。前者需要开发者的配合,一旦你审查的是你无法控制的客户现有网站、受身份验证保护的测试环境,或者任何有严格安全策略(会直接拦截代码片段)的网站,它就失效了。后者给你的是一张死图:菜单打不开,表单提交不了,JavaScript 无法运行,你丢失了试图反馈的那个具体行为。我最需要审查的东西,通常要么无法安装插件,要么不能被压扁成一张截图。即使它们能用,也只能解决项目的一小部分:Bug 列表。反馈在 BugHerd 里,设计评审在 Figma 评论里,网站地图在 Slickplan 或 FlowMapp 里,线框图在 Balsamiq 或 Figma 里,任务在 Trello 或 ClickUp 里,而客户的验收确认……实际上哪里都没有,除了那封写着“看起来不错”的邮件。五六个订阅服务,彼此互不相通,上下文在跨越边界时不断丢失。最终让我下定决心的是验收确认环节。没有一个工具能给我提供一个清晰、正式的“客户在某年某月某日、在某个视口下批准了此页面”的记录,而这正是终结纠纷所需要的证据。