构建软件,构建用户
本文信息来源:dima
Vibe coding 让我们能够以惊人的速度构建软件,但同时也将软件质量的问题提升到了新的高度。什么才意味着软件是高质量的?是为所有可能的代码执行分支编写单元 / 集成 / E2E 测试吗?是衡量代码覆盖率吗?是拥有一整套全面的测试用例吗?那我们又该如何衡量测试的全面性?我们应该关注 happy path 还是负向校验?性能测试与压力测试?可访问性?在每一个 pull request 上运行所有可能的测试?安全测试?可用性?这样的清单还可以继续列下去。
测试类型确实很多。但即便我们把它们全都写完了,就能保证软件质量吗?实践表明答案是否定的。有一个 meme 把这一点诠释得淋漓尽致:
一名 QA 工程师走进一家酒吧,点了一杯啤酒。她点了 2 杯啤酒、0 杯啤酒、-1 杯啤酒。第一位顾客走进来,点了一杯啤酒。他们喝完之后,接着问洗手间在哪里。
酒吧爆炸了。
啤酒点单 Module 完美无瑕——它能够处理所有可能的啤酒点单方式。然而,酒吧还是爆炸了。
为什么酒吧会爆炸?
问题在于,建造这家酒吧的工程师并没有设身处地站在用户的角度思考。他们没有意识到,在酒吧点酒并喝啤酒的人,通常在喝了几品脱之后就需要去洗手间。如果他们更深入地研究目标用户,本可以知道这一点。我们不可能了解用户生活中的每一个方面。但现在我们有了 LLMs——它们几乎是在整个互联网的数据上训练的。LLMs 很可能比我们更清楚用户需要什么、想要什么。那么,为什么不直接对用户本身进行 vibe coding 呢?
Vibe coding 用户
这个想法很简单:选择你的目标用户,并对他们进行全面、深入的理解。你可以创建一个如下所示的文件夹结构:
/users
/group1
user.md
/happy-paths
requirement.flow.md
在这个例子中,group1 代表一组与我们软件交互的用户。user.md 包含用户个人资料——描述他们是谁、一天中做些什么,而我们的软件只是其生活中的一个环节。happy-paths 是一个文件夹,包含描述用户如何在我们软件中流转的文件。这些 happy path 可以像 agent skills 一样构建——根据流程所需的精确程度,使用自然语言、伪代码或实际代码。
工作流程
这个过程是迭代的:
Vibe code users → Vibe code software
^ |
| |
|____________________|
一步一步地,你会在让软件对用户更简单的同时,逐渐真正理解你的用户。
简约才是终极的精妙
在我看来,高质量的软件对用户而言应该看起来很简单。但要实现这种简单,需要深刻的理解——用户的工作流程、能力、背景知识,基本上是关于他们的一切,以及我们的软件如何融入他们的生活。我们可以将用户作为子代理运行,让他们在我们的软件中执行 happy paths 并提供反馈。如果我们对目标受众的理解足够深入,能够使用代理(如 Claude Code、Open Code、Cline 或 Copilot 这样的通用型代理)以较高的准确性模拟他们的行为,我们就能释放出几乎无限的潜力来简化我们的软件并提升其质量。我们可以将这一过程自动化——让代理在与模拟用户协商的过程中对应用程序进行 vibe 编程。在这种范式下,人类开发者只是另一个用户,向代理说明要构建什么。
它与用户画像和用户故事有什么不同?
这种方法与传统的用户画像(persona)和用户故事非常相似。关键区别在于,我们像进行“vibe coding”软件一样对用户画像进行“vibe coding”——先构建用户画像和用户故事,软件的构建放在第二位。用户画像及其故事会变成真正使用你软件的 LLM 代理——像真实用户一样点击按钮、阅读信息并满足自身需求。
它与测试有什么不同?
这种方法看起来与当前的软件测试实践相似,但有一个至关重要的区别:起点。通常,我们会先进行 vibe coding 来构建软件,然后再对其进行测试,试图用功能性和非功能性测试覆盖已经开发完成的特性。测试驱动开发(TDD)确实存在,但它面临一些根本性的问题:我们应该编写什么测试?我们如何知道这些测试或需求是合理的,并且真正验证或代表了软件应该做的事情?以及,从一开始,软件到底应该做什么?在实践中,TDD 在单元层面运行良好,因为函数的“用户”(通常是另一个函数)是被充分理解的。但在端到端(e2e)层面,一切都会变得更加困难,因为我们面对的是真实的人类用户——而我们很少对他们有足够深入的理解。
结论
关键在于首先理解用户。在构建软件本身之前,先构建一个代表你软件用户的 agent。然后进行迭代:创建一个 agentic user,构建软件,让用户(真实用户和 agentic 用户)与之交互,完善 agentic user,改进软件,并不断重复这一过程。通过这种方式,我们才能实现真正高质量的软件——在那些真正使用它的人眼中看来简单直观的软件。