Pricing Software Projects in the AI Era 人天报价为什么不够用了

最近在给一个需求做报价——一个多语言文档批量 QA 校验工具,需求分析花了好几轮问答才敲定范围,接下来要报价的时候,我在想一个问题:这活基本是 AI 辅助写完的,按传统的人天/人月去算,好像已经不太对了。 问题:人天为什么在 AI 辅助场景下失灵 人天报价能成立,前提是"1 人天 ≈ 一定量的产出"这个换算关系大致稳定。AI 辅助开发把这个关系打破了: 产出和投入的人天数脱钩。同样的功能,AI 辅助下可能几小时就写完测试都带上了,人天数骤降,但功能本身的价值(能不能用、值多少钱)并没有跟着降。继续按人天报价,要么报太低把自己的溢价空间搭进去,要么硬凑人天数撑报价,两边都别扭。 计时计费本身有激励错位。如果按小时/人天计费,乙方反而有动机把项目拖久一点——多算的工时里,有多少是"AI 生成代码但按人类费率计费",这跟"用 AI 提效"的初衷是反的。这个问题不是我一个人瞎想的,查了一圈资料,行业里已经在明确讨论这一点(见文末参考链接)。 顺带想到的:按 token 成本定价,行不行 报价的时候,我最初想的是一个"看起来很公平"的方案:按这次任务实际花的 token 成本 × 一个系数,再加上需求分析、架构、管理费这些固定项。想清楚之后放弃了,原因: token 成本和交付价值脱节。这次需求如果全靠 AI 辅助实现,token 花费可能就几十到一百多美元,但业务价值(省下的人工审校时间、给客户的报价空间)可能是这个数字的几十倍。按 token 成本定价会严重低估真正值钱的部分——需求澄清、边界判断、架构决策、验收测试,这些环节 token 消耗很少,但最耗专业判断。 和计时计费一样的激励错位。按 token 成本加成收费,等于鼓励自己多跑几轮、多重试、多探索——消耗越多赚得越多,这跟"用 AI 提高效率、把省下来的时间还给客户"的初衷正好相反。 不可审计、不稳定。token 单价随模型和厂商定价经常变,客户也很难验证实际花了多少 token,容易从"怎么定价"变成"信任问题"。 token 成本定价比较适用的场景,是那种极度机械、高重复量、判断空间很小的活(批量格式转换),成本约等于工作量。判断空间大的定制开发不属于这一类。 常见的软件项目报价模式 整理下来,常见的几种模式: | 模式 | 说明 | 适合场景 | |—————————–|————————————– –|————————–| | 固定价(Fixed price) | 范围定死后报一口价,风险在乙方 | 需求已经问清楚、边界明确的项目 | | 人天/人月(Time & Materials) | 按实际投入时间 × 日费率结算,风险在甲方 | 需求会持续演进、探索性强的项目 | | 里程碑付款 | 固定价拆成几个阶段验收付款 | 周期较长、双方都想控风险的项目 | | 价值定价(Value-based) | 按项目给客户带来的业务价值定价,不看成本 | 能算清 ROI 的项目 | | 结果导向(Outcome-based) | 只在结果达成时收费(比如按处理成功的记录数) | 高度可量化、重复度高的流程 | | 订阅/维护费 | 功能上线后按月收运维/迭代费 | 长期合作、持续迭代的项目 | ...

Created 29296-07-29 · Updated 29296-07-29 · 1 min · 206 words · -

Why the Blog Looked Quiet 一次构建失败导致的「假性停更」

本文是一条故障记录。 最近两天 wiloon.com 看起来像是“停更”,停在6月28号。但其实 blog 仓库是有更新的,也提交了,只是没能发布出来——博客有大约两天卡在一次构建失败上,而我自己一直不知道。 不是停更,是没发布出去 现象很简单:本地写好、git push 之后,wiloon.com 上看不到新内容。一开始我以为是 CDN 缓存或者部署延迟,没太在意。后来才发现是构建一直在失败——新提交根本没被发布出去。 怎么坏的 原因是文章标题里的一个冒号。 博客用 Hugo,文章开头的 front matter 是一段 YAML。我有几篇 Java/Spring 的文章标题是英中混写的,里面带了「冒号 + 空格」,比如: # breaks the build: ": " makes YAML parse it as a mapping title: Spring WebFlux: 响应式 Web 框架 在 YAML 里,: (冒号加空格)是 key/value 的分隔符。没加引号时,解析器会把这一行当成一个嵌套映射来读,于是报错、Hugo 构建中止。一篇的 front matter 解析失败,整站就一个页面都不生成。 修复其实只要把整个标题值用引号包起来: # fixed: quote the whole value so the colon is just text title: "Spring WebFlux: 响应式 Web 框架" 加上引号之后,构建立刻就恢复了。 ...

Created 30306-06-30 · Updated 30306-06-30 · 2 min · 233 words · -

裁员之后,我的一些探索 (2026)

上一份工作在一家外企。公司近期裁员,我的 last day 是 2026 年 4 月 24 日。公司给了数月赔偿,算是接下来一段时间的生活缓冲。 公司曾宣布全球裁员约 4000 人;大连这一轮是老板加员工、整个项目分批裁,我认识的就有 20 多人;其它组、其它部门也有裁员,具体人数不详。 裁员之后,我计划着继续或者回归远程工作这条路线。四年前就想找一个远程职位,但当时有朋友推荐,进了本地的这家外企;公司推行混合办公,每周有 N 天可以在家远程,也算一定程度体验过远程工作。 最近偶尔有朋友推荐大连本地职位,我也投了几家——理想的 offer 还没落定。 一个问题 早上跑完步,在回家的路上,想到一个问题: 裁员之后,下一个理想的 offer 还没落定——我是不是应该趁这段缓冲期,测试一下:我自己加上 AI,能不能创造出一些价值(赚到钱)? 不一定默认回到「找工作 / 打工」这种状态。 为什么叫 Exploration 回到家,我打开 TickTick(一个待办应用),新建了一个"倒数日"——从 last day 起,记录这段日子过去了多少天。 给这个"倒数日"取名时,直觉想填「失业」——字面上没错,指的就是「裁员到下一个 offer 之间」这段日子;但是看起来有点奇怪:它只描述 失去什么,不描述 要做什么。 后来选了 Exploration。每天打开 TickTick,能看到日期的累加;这个词中性一些,也更贴近我接下来想做的事——不是停在「没了什么」,而是试着看看「我 + AI」能做出什么。 实验要回答什么问题 我能不能在真实场景里创造价值?(不只是写 demo,而是有人愿意用、能省时间、能复用。) 这种价值能不能部分转化成收入?(工具、咨询、小产品、开源项目的可持续性等。) 若答案偏 yes,是否足够支撑日常开销? 如果几个月后数据不好看,再去找工作也不迟。 已有的小实践 帮一位朋友开发了一个文档格式和内容的批量校验工具——过去同类文档的人工核对要花几小时,现在批量跑一遍只要几秒,后续项目也可以复用。 这事说明: 几小时级别的投入,可以节省别人未来 N 个小时的时间; 场景是真实的、可交付的,不是玩具; AI 在这里是搭档,负责生成和迭代,我负责需求、验收和边界。 这是这段探索里第一个可以写进笔记的点。 接下来的方向 缓冲期有限,我会按「可演示、可复用、能记账」来排优先级,而不是散点学技术。 贴近真实需求、容易形成复用 继续找真实需求里规则清晰、重复劳动多的环节(校验、一致性检查、格式处理等),做类似「几小时 → 几秒」、可复用的小工具。 自己的长期项目 开源项目:ENX 等 —— 在 runway 内推进到能讲清「对谁有什么用」。 若干私有仓库里的想法 —— 验证能否形成稳定用法,或小规模地「创造价值」。 每周复盘 这周创造了什么?(钱、省下的时间、可演示的功能、开源进展都算,但要写实。) 哪件事离「可重复」最近? 下周只押注一件事是什么? 和「找工作」之间的关系 若这几个月能证明「自己 + AI」可以持续交付价值,甚至覆盖一部分生活成本,就多一条值得走的路线;若证明不了,履历和作品集也会更清晰,回去职场同样是加分项。 ...

Created 22226-05-22 · Updated 25256-06-25 · 1 min · 118 words · -

车联网平台第三方数据推送集成:Kafka + Go 实现记录(2020)

背景 2020 年前后,我在大连 R 公司负责车联网平台协议解析层的开发和维护。R 平台是一套部署在公有云上的 IoT 平台,接入大量在线车载设备,实时处理车辆上报的行车数据。 那时平台有一项新的合作需求:一家做共享汽车业务的公司(以下简称 M 公司)采购了 R 公司的车载设备,安装在共享汽车上,希望通过接口从 R 平台获取这些车辆的实时行车数据,再通过自己的 App 提供给用户查询车辆状态和行驶记录。 我负责这次集成的开发工作,包括改造行车数据服务的分流逻辑,以及独立开发一个面向 M 公司的数据推送服务。这也不是我第一次做类似的事,R 平台之前也有过给其他第三方提供数据接口的项目,但 M 公司是其中规模比较大的一家。 技术方案 行车数据服务本身改动不大。原来的逻辑是收到设备上报的数据后直接写入平台内部各个下游。这次只是加了一段分流逻辑:根据车辆底盘号(VIN)查询 Redis 中的客户映射关系,如果这辆车属于 M 公司,就把这条数据额外发送到一个专用的 Kafka topic。 Kafka topic 的另一侧是我新写的 Go Kafka consumer,消费消息后做数据格式转换,处理鉴权,再通过 HTTP POST 批量推送给 M 公司的接口。推送时有一个打包策略:收到 N 条数据就打包发出,或者超过一定时间没有新数据也把当前这批发出,每次 HTTP 请求可能包含多条记录。 VIN 到客户的映射关系存储在 Redis,由业务侧维护,数据服务只做读取。 工程细节 可观测性 对接第三方的接口,出问题时的排查成本比内部服务高很多——双方都需要对齐日志,搞清楚是哪一侧的问题。 我在这个服务里做了几件事: 每一批次数据带一个唯一的 trace ID,日志里记录发送时间、trace ID、完整 payload、M 公司 API 的响应时间和状态码。在调试阶段和试运行阶段,日志级别调到 debug,把 payload 全量打印出来,方便排查数据是否正确、格式是否符合对方预期。 除了日志,我还在服务里埋了监控指标,记录推送并发量和调用对方 API 的响应时间,接入 R 平台已有的 Grafana 看板,可以直观看到推送量和延迟的变化趋势。 ...

Created 17176-06-17 · Updated 17176-06-17 · 1 min · 100 words · -

物联网平台协议解析服务生产环境 OOM:MySQL 迁移 InfluxDB(2017)

背景 2017 年前后,我在大连 R 公司负责 R 平台协议解析层的开发和维护。R 平台是一套车联网平台,部署在 H 云上,用来接收和处理车载设备实时上报的数据。 协议解析层有十五个以上的服务,每个服务至少两个节点,负责解析车载设备上报的自定义 TCP 协议,网络通信与连接处理底层由 Netty 实现。平台共有 300 多台虚拟机,单个服务的规格通常不会拉很高,G4 所在的虚拟机配置是 2 CPU、4 GB 内存。 其中 G4 是协议解析层数据量最大的服务,负责解析行车数据,单条消息包含约两百个字段,涵盖车速、转速、门窗锁状态、发动机参数、各类液体温度、油量等实时车况信息。正常 QPS 约 700 条/秒,峰值超过 1000 条/秒,四个节点加起来总 QPS 在 5000 左右。 解析完成后,G4 把数据写入 Redis(实时数据)和 MySQL(行车历史数据,水平分片成 1024 个库),另外还有一些平台内部的 API 调用。MySQL 访问层是在 JDBI 基础上封装了一层。 协议解析层的数据来自上游接入层,接入层向协议解析层推送数据,同时用 RabbitMQ 做消息队列缓冲。 装车增长与早期告警 R 平台接入的设备数量持续增长,每个月有几千台新设备安装到实车上。随着在线行驶车辆增多,G4 的数据量也跟着涨。 大规模故障之前,G4 就开始在早高峰和晚高峰偶发内存告警,高峰过去后十几分钟会自行恢复。当时不清楚具体原因,尝试过把业务线程数从默认值增加到 16,改完之后等服务低峰期重启,观察下一次高峰是否有改善。效果不明确,可能有一定缓解,也可能影响有限,之后就转向其他方向排查,线程数就维持在 16 没有再改。 大规模 OOM 装车量继续增加,某天 G4 出现了大规模 OOM。现象是四个节点滚动离线:一个节点 OOM 重启,剩余节点压力上涨,接着下一个离线,重启后很快再 OOM,如此循环。 节点重启之后撑不了太久,因为上游 RabbitMQ 里已经积压了大量数据,积压时间估计有一两个小时。一个节点恢复,积压数据涌入,Netty 堆外内存里挤满了等待处理的业务数据,内存很快再次撑满。一个节点离线,剩余三个节点分摊的流量更大,内存涨得更快,形成连锁反应。节点之间的 OOM 间隔只有几分钟。 ...

Created 31316-05-31 · Updated 5056-06-05 · 2 min · 263 words · -