摔断了我的手迫使我用 AI 编写了 2 个月的所有代码。我再也回不去了。
图 1 对使用 AI 编码“竖起大拇指”
(所有意见均为我自己的,不是我雇主的意见)
几个月前,我在骑自行车去旧金山上班时摔断了手,只能用左手打字。通过结合使用语音转文本和 Claude,我在 Anthropic 的工作中仍然能够编写大量代码,包括一周我写了 3,000 多行(诚然,样板重boilerplate-heavy)代码!
所有这一切的一线希望是:它迫使我生活在我们人类很少编写自己的代码的未来。老实说,我喜欢AI。
我的设置
我以前曾使用过 Copilot 等工具生成 AI 代码,但在事故发生之前,我主要还是自己编写代码。我也使用过语音转文本,但主要用于手机上的文本消息,从未在我的计算机上进行过。
幸运的是,Mac 内置的语音控制对于自然语言来说非常好,但遗憾的是,在任何与代码相关的事情上都很糟糕;符号和词汇太不合时宜了。“Eval(评估)”?你的意思一定是“Evil(邪恶)”。
图 2 我使用语音控制的典型松弛消息。
有像 Talon 这样出色的特定于代码的语音转文本系统,但对代码生成感到非常兴奋,我认为这是我们自己产品的借口!
Copilot Autocomplete 现在对我来说太慢了,因为它需要我写出半行代码。我的总体目标比开始编写代码本身要容易得多。
我将大部分代码库复制并粘贴到 Claude AI 中,并发出语音命令来转换它。例如,我会说“重构 ABC 函数以接受输入 XYZ”或“为这些新函数 ABC 编写单元测试,并查看 XYZ 的示例测试”。
它并不总是在第一次尝试时就成功,但 Claude 愿意接受后续指示和调整。我感觉就像在结对编程(编者:我常说,人机结对编程是未来常态),而其他人在驱动键盘!
如何使用 Claude
被迫像这样写代码,我很快就弄清楚了哪些有效、哪些无效。有时这很神奇,但有时我想把我的电脑扔出窗外。我不得不断地在我的 IDE 和 Claude 之间复制粘贴,并手动将因 Claude 的输出长度限制而截断的代码片段拼接在一起。有好几次,我都因为忘记了我之前的指示而对Claude大声指责。
图 3 使用语音控制时,对计算机生气会更令人满意。
举例说明
如果你给出一个基本的请求,LLM 会给你一个中间的通用答案,这可能不适用于你的特定代码库。
如果你给出非常明确的指令(instructions),说明你期望什么输入和输出、使用什么库,等等,你就会得到更好的结果。我运气最好,将我的指令放在输入数据和上下文的开头和结尾。
更好的是提供代码库中的示例进行模拟。这对于样板代码(boilerplate code)非常有效,例如编写单元测试或任何模板化(templatized)的东西,但也有助于向模型展示如何使用代码库中的内部实用程序函数。
迁移和重构就是这方面的完美案例。我会手动迁移一个实例,然后以此为例,让 Claude 转换其余的输入。通过遵循这种格式,我能够非常快速地重构大约 3,000 行代码。
把Claude放在驾驶座上(而不是副驾驶)
图 4 我朋友做的遥控机器人!
大多数人把 LLM 作为 StackOverflow 的替代品:他们会向LLM问路,但车还是他们自己在开。我要翻转过来——让LLM开车。如果你能给 Claude 正确的构建块,它通常可以一次尝试 “单次” 完成全部内容。
在我和我的朋友 Survy 的一个周末机器人项目中,我们给了 Claude 代码片段来控制单个电机并读取我们的蓝牙操纵杆。有了这些构建块,Claude 能够一次尝试编写所有代码来远程控制机器人,为我们节省了大量时间和繁琐的数据管道(data plumbing)!
令人惊讶的是,这与通常的建议相反,即一次提示 LLM 做一件事!在我不熟悉的环境中,Claude 经常擅长分解任务。过于具体的请求是可行的,但就像将人类建议限制在一个狭隘的问题中而不给出整体背景和目标一样,可能会导致你陷入兔子洞!
RTFM == Read This For Me
图 5 100 页的数据表和用户手册...
我们的电机控制器有一个 100 页的数据表,非常密集! 但将其上传到 Claude,然后我们只要提出问题,Claude就可以快速解决其中一个问题!而以前,这可能需要几个小时的仔细阅读和查找相关术语和教程。
机械的同情心
“你不必成为工程师才能成为赛车手,但你必须有机械的同情心(Mechanical Sympathy)”
——Jackie Stewart, 3次一级方程式世界冠军
我开始建立一种非常好的直觉,知道Claude可以做什么样的事情,以及我自己应该做什么。知道这种区别让我在两个方向上都避免了很多挫败感。
我学会了在哪里可以偷工减料:
“我正在使用一个名为 pygame 的 Python 库,然后......” 变为只是 “在 pygame 中......”
“当我运行代码时,我收到了此错误消息......你认为我现在应该怎么做” 变成了“在堆栈跟踪中复制。
我了解到,转换或重构大块代码效果很好; 例如,在每行之间添加定时仪表( timing instrumentation)。
另一方面,我了解到,如果 LLM 不能在两次尝试中修复一个错误,那么它永远不会。是时候深入挖掘自己了。
我也非常清楚Claude会犯什么样的错误。有一次,Claude 给了我们代码,该代码循环了 motor1、motor2、motor2、motor4,但丢失了motor3。我的朋友注意到了这一点,并说“哦,这一定是幻觉!” 但我只能感觉到“Claude不可能犯这个错误”,果然,当我们检查输入时,那个错误也存在于我们放入Claude的原始代码中。
为自己打造一次性工具
在带着我们的机器人在后院转了一圈后,它吐出了一个包含GPS坐标和其他数据的CSV文件。我们想检查实际现场运行的准确性,但我没有很好的方法来查看或检查它。
以前,弄清楚如何查看和分析这些 GPS 坐标可能需要一个小时。我们甚至可能不得不手动检查手机上的 GPS 坐标,并尝试用肉眼比较这些数字。
现在取而代之的是,我给了 Claude CSV的前两行,它为我们生成了一个网络应用程序,用于在卫星图像之上呈现上传的GPS坐标CSV!
图 6 Claude 在一个提示中创建的 GPS 可视化 Web 应用程序
拥有我需要的完美调试工具,而不是依赖打印语句或预构建的可视化工具,这完全改变了游戏规则。软件变得如此便宜,以至于它是一次性的!
总的来说,这些实践经验使我在使用 AI 编写代码方面变得更快!回到非 AI 工具,感觉就像放弃编译器并手动编写 Assembly。
这是怎么回事?
图 7 这一切将何去何从?
在过去的几年里,AI在软件工程中的最大用途是 Github Copilot,用于在 IDE 中自动完成,以及 ChatGPT用于回答过去需要 StackOverflow 的编程问题。早期的“智能体” 演示可以在没有人工监督的情况下一次操作多个步骤,但没有什么是实用的。
今年,这三个领域都在发生转变。Zed、Cursor 和各种 VSCode 扩展等 IDE 更深入地集成了 LLM,以提供更好的上下文并处理更大的代码生成块。Claude 的 Artifacts 和 ChatGPT 的 Data Analyst 已成为快速原型和一次性代码的首选解决方案,而不是 Jupyter 笔记本。最后,像 Cognition、Factory 和 CodeGen 这样的一大批智能体初创公司正在端到端地自动化工程工作流程的某些部分。
就我个人而言,我认为这三个区域可以融合成一个产品——“AI 工程师”。这将是一个可以在自主模式和同步模式之间的连续体中工作的单一系统:
用于明确任务的自主模式:人工智能将完全独立工作,能够编写和运行代码、使用外部工具、在网上搜索信息、访问内部文档以及从过去的错误中吸取教训。它将继续迭代任务,直到任务完成或卡住。这将针对 80% 的工作完成。
用于最困难任务的结对编程模式:人类将在高层次上指导AI,而AI则处理低层次的实现细节。交互将是高度多模态的,人类和AI在文本描述、视觉图表、口头讨论之间流畅切换,并直接操纵彼此的代码。我们可以共享屏幕并让 AI 跟随并为我们提供建议,或者AI可能会在我们提供编程指导时共享其屏幕!
AI 工程师将拥有我们所拥有的所有上下文和知识的完全访问权限:无论是自主操作还是与人类结对工作,AI将连接到公司知识库,可以访问设计文件和客户访谈记录,并将根据需要无缝提取这些信息以做出决策。AI将是积极主动的,而不是讳莫如深的:如果你提出一个设计,它可能会显示一个用户访谈记录,暗示一个更好的想法。
自主员工将派遣更便宜的子智能体(sub-agents)来完成其工作的简单和可预测的部分,主要是为了降低计算成本和延迟,就像我们可以浏览日志文件而不实际阅读每个单词一样。
虽然很难预测未来的模型将如何表现,但我认为“AI工程师”在特定事情上会比大多数人类工程师更聪明,但偶尔缺乏常识或需要重新关注和指导。老实说,这与今天经理和项目经理与工程师合作的方式没有太大区别!
我们还需要工程师吗?
在计算器发明之前,会计师将大部分时间花在进行计算上。计算器并没有让他们失业,只是让他们在更高的抽象层次上思考。会计师仍然需要知道如何做数学运算和理解计算,但计算器和电子表格等工具使他们能够提供比以前更多的价值!
我确实认为AI将降低任何人创建软件的门槛,就像任何人都可以使用Excel进行自己的个人会计一样。这是一件好事!学生将在宿舍里启动完整的应用程序和业务;夫妻店将创建专为他们量身定制的软件工具。我希望生活在这样一个世界里,人们的创造力是他们创造的唯一瓶颈。
图 8 我希望未来是什么样子
人类工程师不会消失。我们仍然需要推动高层次的优先级排序,了解问题的整体架构和范围,并审AI的工作,特别是随着系统变得越来越大。但是,我们会花更多的时间思考要构建什么,而较少的时间花在重复的“如何”构建上。我们最终将实现梦想——只处理问题的“固有复杂性”,而不是系统实施的“偶然复杂性”。
我已经不在表演了,再次用双手打字,但 Claude 仍在编写我的大部分代码。总的来说,我已经弄清楚了如何充分利用这些新的AI工具,我对这个行业的发展方向非常乐观!