博客

你的技术方案为什么总被否

上个月,一个技术朋友跟我吐槽。

他的团队花了两周设计了一套重构方案,要把跑了五年的单体应用拆成微服务。架构设计很扎实,领域划分清晰,接口定义规范,甚至连服务间通信方案都做了三版对比。

评审会上,他讲了45分钟,从领域驱动设计讲到CAP定理,从服务网格讲到可观测性。CTO听完,问了一个问题:"这个事做了之后,下个季度的大促能少出几次故障?"

他愣了一下,说:"理论上会改善。"

CTO说:"你们再想想。"

没有然后了。

这不是段子。我见过太多类似的场景,包括我自己。一个技术方案,技术上无懈可击,但就是过不了决策者那关。大部分技术Leader的第一反应是:他不懂技术。但如果你仔细复盘,问题往往不在技术本身。

决策者到底在听什么

技术方案被否,十有八九不是技术有问题,而是呈现方式和决策者真正关心的东西之间有错位。

技术Leader做方案评审,通常的逻辑是:先讲现状有什么问题,再讲对比了几种方案,最后讲为什么选这个。这个逻辑没毛病,但讲着讲着就容易变成技术展览——架构怎么拆、数据怎么迁移、性能数据有多好看。30分钟里25分钟在讲HOW,5分钟讲WHY,而且这个WHY还是技术视角的WHY。

Agent好不好用,怎么评

上个月,一个团队的朋友跟我说,他们在内部做了一次 Agent 能力评估。方式是让 Agent 跑 50 个真实的客服场景,然后让人工逐条打分。

结果出来之后,所有人都在争论一个问题:82% 的通过率,到底算好还是不好?

没人能回答。因为"好"没有标准。

这件事让我意识到一个问题:我们在疯狂地往生产环境里塞 Agent,但我们几乎没有一套可靠的方法来评价它到底干得怎么样。传统软件测试的那套方法论——单元测试、集成测试、端到端测试——在 Agent 面前,几乎全部失效。

传统测试为什么失效了

传统测试建立在一个核心假设之上:确定性。给定输入 A,系统必须输出 B。如果输出了 C,那就是 bug。

Agent 天然不满足这个假设。同一个用户问题,Agent 可能走完全不同的推理路径,给出不同的回答——而且两个回答可能都是"对的"。你怎么写断言?你没法写 assertEqual(agent.answer, expected_answer),因为 expected_answer 本身就不唯一。

这还只是最表面的问题。更深层的麻烦在于:

代码太多,审查不够

上周跟一个带前端团队的朋友聊天,他说了一句话让我印象很深:"现在最痛苦的不是写代码,是看代码。"

他的团队半年前全面推了 AI 编码助手。效率确实上来了——以前一周的活,现在两天就能干完。但代码审查(Code Review)的压力也跟着翻了三倍。以前每天审查两三百行,现在动辄上千行。审查者的时间没变,代码量却暴增了。

更麻烦的是,AI 生成的代码有一个特点:看着都对,但你不一定知道它为什么这么写。

这不是个案。我最近跟几个做技术管理的朋友聊过,发现一个共同的焦虑——AI 在加速代码生产,但质量把关的那道门,还是靠人肉。这道门正在被冲垮。

审查的瓶颈不是态度,是带宽

过去十几年,代码审查是软件工程里最被推崇的实践之一。它有效的核心前提是:代码作者能解释自己的思路,审查者通过提问和质疑来发现潜在问题。这是一场人与人的对话,有来有回。

AI 生成的代码打破了这个前提。

审查者面对的不再是一个能解释"我为什么这么写"的同事,而是一堆看起来合理但没人能完全解释意图的代码。你问 AI 为什么这么实现,它可以给你一个事后合理化的解释,但那个解释未必反映真实的决策过程——因为它根本没有"决策过程",它只是在做概率预测。

同步不再将就

上个月,一个朋友在群里吐槽:他们的在线文档产品要加多人协作功能,技术负责人评估了一下,给了个方案——用 WebSocket 广播所有编辑操作,冲突了就提示用户"文档已被他人修改,请刷新后重试"。

我问他,你们打算让用户刷新多少次才能写完一段话?

这不是段子。在我见过的技术选型里,"广播 + 冲突提示"仍然是很多团队处理实时协作的第一反应。理由很简单——实现成本低,逻辑好理解。但这条路的尽头,是一个永远填不完的坑。

冲突不是边缘情况

想象一个场景:两个人同时编辑同一份文档的同一行。A 把"用户协议"改成了"服务条款",B 在同一位置加了个逗号。两个操作几乎同时发生,网络延迟让它们到达服务器的顺序不确定。

传统做法要么让 A 的修改覆盖 B 的(后到的覆盖先到的),要么把文档锁住让 B 等 A 改完。前者丢数据,后者体验差。

CRDT(Conflict-free Replicated Data Type,无冲突复制数据类型)提供了第三条路:从数学上保证,只要操作满足交换律和结合律,无论网络传输顺序如何、延迟多长,所有客户端最终都会收敛到同一份数据。不需要中心服务器仲裁,不需要锁,不需要用户手动解决冲突。每个操作本身就是一个独立的、可传播的、可合并的单元。

从论文到产品的距离

你的AI在想什么

上个月,一个朋友的公司上线了一个 AI 客服助手。上线第一周,用户满意度从 72% 飙升到 89%。所有人都觉得这是一次成功的技术落地。

第二周,满意度掉到了 61%。

没人知道为什么。日志里没有任何报错,API 响应时间正常,模型推理延迟也没变。客服主管说"AI 开始胡说了",但没人能说清楚它从什么时候开始胡说、为什么胡说、胡说频率有多高。

这不是一个孤例。我最近跟好几个团队聊过,发现一个共同的痛点:AI Agent 跑起来之后,团队对系统的理解能力反而在下降。

传统监控的三个假设,全被 AI 打破了

过去十几年,可观测性领域建立了三大支柱:日志(Logs)、指标(Metrics)、链路追踪(Traces)。这套体系运转得非常好,但它建立在三个隐含假设之上。

第一个假设:系统的行为是确定性的。 给定相同的输入,系统会产生相同的输出。你可以通过阅读代码来理解系统的行为边界。但 AI Agent 不是这样。同样的用户问题,Agent 可能给出完全不同的回答,取决于上下文窗口的状态、之前的对话历史、甚至 prompt 里某个词的微妙变化。代码审计?你审的只是调用框架,真正的决策逻辑在模型的权重里,而那个黑箱你是看不到的。

别急着加机房

博客分类: 

上个月参加一个架构评审会,有个团队提出要在新加坡加一个机房。理由很充分——东南亚用户访问我们的服务,延迟大概在 250 毫秒左右,体验不够好。加一个区域,理论上能降到 30 毫秒以内。

方案看起来很完美,PPT 里的数据也很漂亮。但我问了一个问题:你们拆解过这 250 毫秒里,有多少是真的花在网络传输上的吗?

没人答得上来。

这件事让我想到一个越来越普遍的现象:很多团队在做多区域部署决策的时候,把"加机房"当成了万能解。延迟高?加机房。用户远?加机房。容灾不够?加机房。但很少有人认真算过,加一个区域的真实成本是什么,以及——有没有更便宜的方案能达到同样的效果。

250 毫秒里,真正的网络传输只占一半

这是很多人不愿意相信的事实:用户感受到的端到端延迟,有接近一半跟地理距离无关。

一个请求从用户手机出发,经过 DNS 解析、TLS 握手、TCP 连接建立,到达服务器后被处理,再把结果返回。这整个链路里,真正受光速限制、必须靠物理距离来解决的,只有网络传播那一段。其他部分——DNS 查询、TLS 协商、连接池等待、服务间调用链、数据库查询、应用层序列化——这些都可以通过架构优化来解决,不需要搬家。

谁在用你的数据库

上周参加一个内部技术评审,有人提了一个看起来不太起眼的问题:我们的Agent在执行复杂任务时,数据库连接池经常被打爆,为什么?

排查下来发现原因很直接——Agent在做多步推理时,每一步都可能触发数据库查询。而且它的查询模式完全不符合人类开发者的习惯:没有预编译的SQL模板,没有合理的分页,没有批量查询优化。Agent就像一个不知疲倦的实习生,一条一条地查,一步一步地追,直到把数据拼完整。

这件事让我开始认真想一个问题:当Agent成为数据库的主要使用者,而不是人类开发者时,数据库的设计范式是不是该变了?

传统数据库的隐含假设

过去几十年,数据库的设计和优化都围绕一个核心假设:使用者是人类开发者,通过应用程序发出可预测的查询。

SQL语法是为人类设计的。索引策略是基于已知的查询模式来优化的。连接池的大小是基于人类用户的并发行为来估算的。ORM框架把数据库操作封装成对象方法,本质上也是在替人类开发者降低心智负担。

这整套体系运转得很好——因为人类的行为是可预测的。一个电商系统的商品详情页,99%的情况下会命中那几个固定的查询路径。一个金融产品的持仓页面,查询模式在产品上线那天就已经确定了。

但Agent打破了这个假设。

Agent的访问模式完全不同

Agent跑起来了,但安全没跟上

最近看到一件事,越想越觉得不对劲。

一个AI Agent在生产环境里调用了一个外部API。这个API本身有鉴权,Agent也有合法凭证,请求参数也符合格式。从系统日志看,一切正常。但Agent拿到的数据里包含了一批不该被它看到的客户信息。

从基础设施的视角看,这次访问没有任何问题。但从安全的视角看,它问题很大。

这件事指向了一个我正在认真思考的方向:AI时代的安全,已经不是传统安全模型能覆盖的了。而大部分团队还没有意识到这一点。

AI的安全和传统安全,根本不是一回事

过去十几年,安全行业建立了一套相对成熟的防御体系。身份认证、权限控制、网络隔离、加密传输、审计日志。这套体系的核心假设是:人是操作者,系统是被操作的对象。

AI Agent打破了这个假设。

Agent不是工具,它是一个有一定自主决策能力的执行者。它会自己判断调用什么工具、访问什么数据、以什么顺序执行任务。而且它的行为模式不是预设的,是基于上下文动态生成的。

这意味着,传统安全模型里基于"角色-权限"的RBAC,只能管住"能不能做",管不住"该不该做"。传统网络策略可以限制Agent能访问哪些服务,但没法判断Agent在特定上下文中的行为是否合理。

AI学走手艺,师傅怎么办

前两天看到一条资讯,说的是某制造企业把老师傅十五年的质检经验,通过一套录制系统喂给了AI模型。三个月后,新来的实习生拿着平板对着工件拍张照,AI就能给出和老师傅几乎一致的判断——有没有裂纹、公差是否超标、能不能放行。

效率提升是真的。培训周期从两年压缩到两周也是真的。

但没人问过老师傅的感受。

一个在某个领域泡了十五年才沉淀出来的判断力,现在被一个录制按钮和三个月的实习期就复现了。这件事在技术圈被当成"AI赋能传统行业"的成功案例来讲,但如果你换一个角度看,它指向了一个更深层的问题:当经验可以被一键提取,"教会徒弟"这件事的底层逻辑变了。

被压缩的不是知识,是积累过程

过去,专家的价值不只在于"知道答案",而在于"知道为什么"。一个资深工程师看一眼日志就能定位问题,不是因为背过所有错误码,而是因为他踩过足够多的坑,知道什么条件下会出什么问题。这种判断力很难通过文档传递,只能在实战中一点一点磨出来。

这就是所谓的隐性知识——说不清道不明,但在关键时刻值千金。

AI改变了这个传递路径。不需要师徒制,不需要十年磨一剑,只要给模型足够多的决策记录,它就能在极短时间内提取出模式。而且它不吃饭、不离职、不需要情绪管理。

你的WiFi在看着你

你有没有过这种感觉——走进一个房间,抬头就看到一个黑色的小圆球对着你。

家里的智能摄像头、公司的安防系统、小区门口的人脸识别,它们无处不在。不管你怎么说服自己"又没做什么亏心事",那个镜头始终让你不太舒服。

我也一样。所以当我上周在 GitHub 上看到一个叫 RuView 的项目时,愣了好一阵。

这个项目做的事情很简单也很颠覆:用普通 WiFi 信号来感知你的存在、呼吸频率、心率,甚至能做姿态估计和跌倒检测。不需要摄像头,不需要穿戴任何设备,一颗 9 美元的 ESP32 芯片就够了。

WiFi 怎么"看"人

先别急着觉得这是科幻。

WiFi 信号本质上是一种射频电磁波。它在房间里传播时,会被人体吸收、反射和散射。你站在 WiFi 路由器和接收器之间,信号就会产生可测量的变化。通过分析这些变化——技术上叫 CSI(信道状态信息)——可以推断出空间里正在发生什么。

这个方向学术界已经研究了十几年。2015 年 MIT 的 RF-Capture 就展示过用 WiFi 信号追踪人体姿态;后来的 DensePose、MultiFormer 不断刷新精度。WiFi 感知在学术圈不算新鲜事。

代码越写越快,但谁来审?

最近几个月,一个趋势在我身边越来越明显:团队里用 Cursor、Copilot、Claude Code 的人越来越多,但大家聊的不再是"AI 生成的代码有多好",而是"review AI 代码有多累"。

一个同事上周跟我吐槽:以前 review 同事的代码,至少能理解他的思路,知道为什么这么写。现在 review AI 生成的代码,逻辑上没毛病,但总觉得哪里不对——命名风格不统一,错误处理过度防御,有些地方用了团队从没用过的设计模式,还有些地方莫名其妙地绕了一圈。

他说了一句让我印象很深的话:"我感觉自己不是在 review 代码,是在面试一个永远不累的实习生。"

这句话点破了一个很多人还没意识到的事情:AI 编码工具正在把工程师的核心工作从"写代码"变成"审代码",而大部分团队还没有为这个转变做好准备。

代码审查量在暴增,但审查能力没跟上

先说一个最直观的数据。Cursor 官方说他们的用户已经有超过 50% 的代码是 AI 生成的。我自己团队的感受也差不多——一个中等复杂度的需求,以前可能写两天,现在用 AI 辅助,大半天就能出初稿。

但"出初稿"和"能上线"之间,隔着一道巨大的鸿沟。

登录一次就信任一天?

一个真实场景

某个周一早上,安全团队收到告警:一个客服账号在周末两天内导出了5000条客户记录。排查下来,这个客服在9:00正常登录系统,角色权限允许查看客户信息。到10:00,他已经批量导出了大量数据;10:15,这些文件被转发到了他的个人邮箱。

安全团队的结论是:"用户具有相应权限。"

这句话才是问题所在。客服确实有查看客户记录的权限,但他的正常工作模式是一天处理20个工单,每次查看一两条记录。两天导出5000条数据,完全不在正常行为范围内。这个偏差,本应在操作发生的那一刻就被系统捕捉到,而不是等到事后审计。

登录时的授权为什么不够用

大部分系统的授权模型是这样的:用户登录时验证身份,根据角色分配权限,之后在会话期间的所有操作,都默认信任那次登录的授权结果。

这个模型在过去是够用的。系统部署在内网,用户在公司电脑上操作,数据访问模式相对固定。但在云环境下,这套逻辑开始松动。

原因很直接:登录时的授权只解决了"能不能做"的问题,没有回答"该不该做"。

微前端落地两年,我们开始往回收了

上个月,我们默默地把三个微前端子应用合并回了两个。没有发公告,没有写技术复盘,就是安安静静地把代码挪了回去,删掉了两个仓库,关掉了四条CI流水线。

如果有人在半年前问我"微前端到底好不好",我大概率会给他列一堆优点:独立部署、技术栈无关、团队自治。但现在我的回答变了:看你的团队到底有没有拆的必要。

这个判断听起来像废话,但我见过太多团队在这件事上栽跟头,包括我自己。

拆的时候有多爽,合的时候就有多痛

故事的开始总是相似的。一个大型前端项目,十几个开发者在同一个仓库里撞来撞去,merge冲突是家常便饭,发版节奏互相牵制。有人提了微前端,方案评审会上大家眼睛都亮了——每个团队自己的子应用、自己的发布节奏、自己的技术栈,互不干扰,多美好。

我们也是这么想的。2024年初,基于qiankun把主应用拆成了五个子应用,按业务域划分。前半年确实爽:团队A改了代码不用等团队B review,团队C想用新版本的React自己升,团队D甚至单独搞了一套构建流程。

问题是从第二年开始集中爆发的。

谷歌A2UI:AI终于不用写代码了

博客分类: 

最近有个趋势越来越明显:前端工程师看着 Copilot、Cursor 生成的 UI 代码,开始焦虑自己是不是要被替代了。

我觉得这个焦虑方向搞错了。真正值得关注的事情,不是 AI 写的代码比你好,而是 AI 可能根本不需要写代码了。

谷歌刚发布的 A2UI v0.9 就是这个方向上的一步。A2UI 全称 Agent-to-UI,是一套与框架无关的标准,让 AI 智能体声明 UI 意图,由 Web、移动端、桌面端原生渲染。关键词是"声明意图"——AI 不需要生成 HTML、CSS 或组件代码,它只需要说"我需要一个什么界面",平台自己搞定渲染。

这件事值得认真聊聊。

AI 生成代码的真正问题,不是代码质量

现在 AI 写前端代码的方式,本质上是"生成一堆代码,人来兜底"。Copilot 也好,Cursor 也好,甚至那些号称能生成完整页面的工具,都在解决同一个问题:怎么让生成的代码能跑起来。

但跑起来只是最低标准。在生产环境里,一段前端代码要真正"能用",得跟已有系统严丝合缝地集成:用团队的设计系统、符合品牌规范、支持无障碍访问、不超标性能预算、跟现有状态管理兼容、能扛住国际化。

AI Agent 一天烧掉 1.4 万美元,你的风控系统还在睡大觉

博客分类: 

上周看到一个案例,震得我好一阵没缓过来。

一家三个人的小公司,AWS 月费常年维持在十几美元的水平。某天早上,创始人打开邮箱,发现一封来自 AWS 的账单提醒——单日费用 1.4 万美元。不是月度,是单日。

排查的结果更让人窒息:一个 EC2 实例上的静态密钥不知道什么时候泄露了,攻击者拿着这个密钥大量调用 Bedrock 的 Claude 模型,跑了一整夜的推理任务。从安全角度看,这甚至不算什么高级攻击,就是一个最基础的凭证扫描 + 资源滥用。但从财务角度看,一家月支出十几美元的公司,在一夜之间欠下了一笔可能需要半年才能消化的债务。

这个案例之所以让我印象深刻,是因为它揭示了一个在 AI Agent 时代正在加速放大的系统性风险:算力消耗的速度,已经远远超过了传统风控系统的反应速度。

传统账单风控的三道防线,全部失灵

大多数公司的云成本风控,本质上就三道防线:

第一道:预算告警。 设置一个月度预算阈值,超过 80% 发邮件提醒。问题是,AI 算力的消耗速度是指数级的。一个大模型推理任务可能在几分钟内就烧掉几百美元,而告警系统的检测周期通常是小时级甚至天级的。等告警邮件送达,预算早就被打穿了。

你以为流很省内存,其实在背N份账

最近帮一个 Node.js 中间层排查 OOM。一个聚合接口,把三四个下游接口的数据拼一下吐给前端,单次请求的数据量也就两三 MB,看着毫无压力。但 Grafana 上常驻内存随 QPS 线性爬升,GC 触发得越来越频繁,终于在晚高峰把进程撑爆了。

翻代码,逻辑大致是这样:

```js
const responses = await Promise.all(
endpoints.map(url => fetch(url).then(r => r.json()))
)
return res.json(merge(responses))
```

看起来人畜无害。`fetch` 拿到的是流,`.json()` 一次性消费它,`merge` 拼好再 `res.json()` 序列化出去。整个链路里数据至少出现了三份:原始响应体、解析后的对象、合并后的对象。再加上序列化时的字符串缓冲,单请求峰值轻松到原始数据的四五倍。这还没算 V8 把这些短命对象塞进新生代、触发 Scavenge 的开销。

版本号说了谎:semver为什么管不住npm生态

博客分类: 

上周四晚上十点半,我收到一条告警:生产环境的理财持仓页白屏率从0.1%飙升到8%。排查了两小时,最后发现是一个间接依赖发布了"patch"更新,把一个工具函数的返回值从数组改成了迭代器。没有破坏性变更声明,没有 major 版本升级,就是一个小小的 1.2.3 到 1.2.4。

这种事在 Node.js 生态里不算新鲜。每个在前端或 BFF 层待过几年的工程师,大概率都经历过类似的"幽灵故障"——代码没动,依赖没升,线上突然就挂了。问题出在哪?出在我们把 semver 当成了契约,但它充其量只是一份君子协定。

 

semver 的承诺本身就是模糊的

 

semver 的规则看起来很简单:major 变更代表不兼容的 API 修改,minor 是向后兼容的功能新增,patch 是向后兼容的问题修复。三段式版本号,清晰明了。

越过山丘,勇立潮头:20年技术老兵的安泰"破壁"与"重构"

博客分类: 

在技术领域深耕近二十年,我先后跨越了通信、软件、互联网等多个行业,并在金融科技领域潜心笃行近十年。一路上,我经历了从后端到前端的技能迁移,也完成了从普通工程师到研发管理者的角色跃迁。我曾作为初创成员,从零开始搭建起一支高效的团队;也曾与伙伴们并肩作战,见证了核心业务突破万亿规模的高光时刻。

然而,当技术管理走到深水区,我逐渐感受到了那面无形的玻璃天花板——单纯的技术视角在面对复杂的商业战略、跨部门协同以及宏观市场变化时,常常显得力不从心。

为了突破认知瓶颈,重塑个人品牌,并构建更宽广的资源网络,我选择在职业生涯的黄金期主动求变。2026年,我顺利拿到了上海交通大学安泰MBA综合管理方向的拟录取通知。

这段备考之路,既是一次严苛的自我测试,也是一场关于"取舍"的修行。以下是我的一些实战经验,希望能为正在筹备考研的学弟学妹们提供一些落地、有价值的参考。

 

一、择校:谋定后动,选择最契合的土壤

 

对于在职备考的人来说,精力的分配是极其奢侈的,因此择校的精准度决定了备考的性价比。我选择交大安泰MBA,主要基于三个维度的考量:

写下第一行管理代码之前,没人告诉你的事

博客分类: 

上周和一个刚升 Tech Lead 的朋友吃饭,他半开玩笑说了句:"我以前觉得最焦虑的是线上故障,现在发现最焦虑的是打开 Slack 不知道该回哪条消息。"

他不是在抱怨工作量。他困惑的是一个更根本的问题——他不确定自己现在到底该干什么。

这位朋友技术能力没得说,组里最难的问题都是他啃下来的。升职之后,他给自己定的策略很简单:还是干最难的活,顺便把管理的事也带着做了。三个月下来,最难的技术活他还在干,管理的事全是"顺带"——顺带开个会,顺带审批个需求,顺带和产品对个方案。团队产出反而不如他一个人扛活的时候。

这个故事不新鲜。我见过太多优秀的工程师在走上管理岗之后经历类似的挣扎。不是能力问题,是角色切换的认知滞后——你以为只是多了一些职责,其实是在换一个职业。

 

升的是 Title,丢的是手感

 

工程师的身份建立在什么上面?解决问题的能力。一个 bug 搞定,一个功能交付,一个性能瓶颈突破——每一个都是明确的、可感知的成就。这种正反馈循环是工程师职业早期的核心驱动力。

防资损这道题,测试答不了

金融系统出bug和出资损,是两个完全不同的量级。功能写错了,改过来就是;页面丑了,迭代一轮就行;但钱算错了,那是客诉、是赔付、是监管约谈,严重的时候直接停业整改。

我观察到一个很普遍的反应模式:出了资损,先加测试用例;又出一次,加人肉对账;再出一次,加发版审批。每一步都在做加法,每一步都离根本原因更远。因为大部分人把资损当成了一种"严重的bug",用防bug的思路来防资损。这个认知偏差才是资损反复出现的根源。

 

资损不是bug的严重版

 

普通bug和资损的核心区别在于:bug是你功能做错了,资损是你的功能没做错,但钱错了。

一个理财产品页面,把年化收益率3.5%展示成3.8%,这是bug。但用户基于3.8%做了购买决策,实际到账按3.5%结算,用户体验上的落差就是资损——即使从功能角度看,展示模块和计算模块各自都"按逻辑运行"。

更典型的场景:用户申购一笔理财,网络超时,前端重试了一次,后端处理了两笔。这两笔处理的每一笔单独看都没"错"——接口接收请求、参数校验通过、数据库写入成功。但因为缺少幂等约束,结果就是资损。

页面