我的 AI 采纳之旅【译】

本文原文地址,使用claude进行了翻译,作者是HashiCorp的创始人Mitchell Hashimoto。 作者:Mitchell Hashimoto | 原文日期:2026年2月5日 我在采纳任何一款有价值的工具时,通常都会经历三个阶段:(1)低效期、(2)适应期,最终才到达(3)彻底改变工作流程乃至生活方式的顿悟期。 大多数情况下,我必须强迫自己熬过第一阶段和第二阶段——因为我通常已经有一套令自己满意且顺手的工作流程。引入新工具意味着额外的付出,我实在不想花这份力气,但出于对所在领域的全面性追求,我通常还是会去尝试。 这篇文章记录了我如何在 AI 工具链中找到真正价值的历程,以及我正在探索的下一步方向。在一片夸大其词、充斥炒作的声浪中,我希望这篇文章能呈现一种更细腻、更审慎的视角,如实反映我对 AI 的看法是如何随着时间推移而演变的。 本文完全由我亲手写就,字字出自本人之口。这句话放在这里本不必要,但鉴于文章的主题特殊,我想明确声明。 第一步:放弃聊天机器人 立即停止通过聊天机器人(如 ChatGPT、Gemini 网页版等)完成有实质意义的工作。聊天机器人确实有其价值,也是我日常 AI 工作流程的一部分,但在编程场景下,其效用极为有限——因为你基本上是寄希望于模型凭借预训练知识碰巧给出正确答案,而纠错则需要人工(即你本人)反复告知它哪里错了,效率极低。 我认为,几乎所有人与 AI 的第一次接触都是聊天界面。同样,几乎所有人第一次尝试用 AI 辅助编程,也都是向聊天界面输入需求、让它生成代码。 在我还是个坚定的 AI 怀疑论者时,我第一次发出"哇哦"的感叹,是将 Zed 命令面板的截图粘贴给 Gemini,让它用 SwiftUI 复现出来——它的表现之出色令我真正震惊。如今 Ghostty macOS 版中内置的命令面板,正是在 Gemini 几秒内为我生成的代码基础上,仅做了极少量改动后发布的。 但当我试图将这种成功经验复制到其他任务时,却屡屡失望。在存量代码库(brownfield project)的上下文中,聊天界面产出的结果往往很差,我发现自己在代码和命令输出的复制粘贴上来回折腾,效率明显低于亲自动手。 要真正发掘价值,你必须使用智能体(Agent)。智能体是业界公认的术语,指能够在对话循环中调用外部能力的大型语言模型(LLM)1。至少,该智能体必须具备以下能力:读取文件、执行程序,以及发起 HTTP 请求。 第二步:用智能体重现自己的工作 在探索历程的下一阶段,我尝试了 Claude Code。直说吧:最初我并不买账。每次会话产出的结果都不尽如人意,几乎每次都需要大量的后期修改,这比自己动手还要耗时。我读了不少博客文章、看了不少视频,但依然兴趣寥寥。 没有放弃,我强迫自己用智能体重做所有原本手动完成的提交(commit)。我字面意义上把每件事做了两遍:先手动完成,再与智能体较量,迫使它在质量与功能上达到相同水准(当然,不让它看到我的手动方案)。 这个过程极其痛苦,因为它妨碍了"把事情做完"这一最直接的目标。但我与非 AI 工具打交道的经验足够丰富,深知摩擦阻力是一种自然现象,不把精力耗尽就无法得出坚实可靠的结论。 然而,专业认知在磨砺中逐渐成形。我从第一性原理出发,很快就亲身验证了别人已有的发现——而正因为是自己发现的,底层理解也更为深刻: 将会话拆分为若干清晰、可执行的独立任务,切勿试图在一次超长会话中"一步画完猫头鹰"。 对于模糊的需求,应将工作分拆为独立的规划会话与执行会话,分步推进。 若为智能体提供校验其工作成果的手段,它在大多数情况下能够自主纠错,并有效防止功能退化(regression)。 更宏观地看,我也摸清了当时智能体的能力边界——它们擅长什么、不擅长什么,以及对于它们擅长的任务,如何获得满意的输出。 这一切带来了显著的效率提升——我开始自然而然地使用智能体,感觉不比自己亲手做更慢(尽管也没感觉更快,因为我大部分时间仍在充当"监工")。 这里有一个值得反复强调的"负空间":效率提升的一部分,恰恰来自于清楚地知道何时不该使用智能体。让智能体去尝试它很可能失败的任务,显然是巨大的时间浪费;而掌握这种判断力、主动规避,本身就是一种节省2。 第三步:下班前的智能体任务 为了进一步挖掘效率空间,我开始尝试一种新的工作模式:每天预留最后 30 分钟,用于启动一个或多个智能体任务。我的假设是:如果智能体能够在我无法工作的时间里取得实质进展,或许就能在时间之外创造时间。也就是说:与其在现有的工作时间内多做事,不如在原本"空置"的时间里多做事。 和之前一样,起初我觉得这既无效又令人烦躁。但我很快又梳理出了几类真正奏效的工作: 深度研究型会话:让智能体梳理某个领域,例如找出某种语言中采用特定许可证的所有库,并为每个库生成多页摘要,涵盖优缺点、开发活跃度、社区口碑等维度。 并行探索模糊构想:同时启动多个智能体,分别尝试我还没时间着手的不同想法。我并不指望它们产出可上线的成果,但希望它们能帮我在第二天真正着手时,提前发现一些"未知的未知"。 Issue 与 PR 的分类梳理:智能体善用 gh(GitHub CLI),我编写了一个简单脚本来并行启动多个智能体做 Issue 分类。我不允许智能体直接回复,只需要隔天早上看到报告,帮助我识别高价值或低难度的任务。 需要说明的是,我没有像某些人那样,让智能体整夜不停地循环运行。大多数情况下,任务在半小时内就会完成。但工作日下午的后半段,我通常已经精力耗尽、离开心流状态,个人效率大打折扣——将这段精力转移到启动智能体任务上,让我第二天早上能够"热启动",比以往更快进入工作状态。...

我和AI讨论的一些C#话题

很久没有用C#,最近需要使用。下面是跟AI问的一些C#的问题,未作整理。 基础 Span类型 c# Span的应用场景及具体例子 Span是一种新的引用类型,它允许存储和操作连续的内存块。它特别适用于那些需要高效处理内存块的应用场景,例如字符串处理、IO操作和序列化/反序列化。 下面是一些具体的例子: 字符串处理:Span可以用于快速地操作字符串,例如从字符串中截取子串、替换子串、查找子串等。下面是一个例子: string str = "hello world"; Span<char> span = str.AsSpan(6, 5); // 从第6个字符开始,截取长度为5的子串 IO操作:Span可以用于将IO操作映射到内存中,以提高性能。下面是一个例子: using (FileStream stream = File.OpenRead("file.txt")) { byte[] buffer = new byte[1024 * 1024]; while (stream.Read(buffer) > 0) { Span<byte> span = buffer.AsSpan(); // 将字节数组映射为Span // 处理Span } } 序列化/反序列化:Span可以用于快速地序列化和反序列化数据,尤其是在网络传输等场景中。下面是一个例子: public static void Serialize<T>(T value, Span<byte> buffer) where T : struct { unsafe { fixed (byte* ptr = buffer) { *(T*)ptr = value; // 将值拷贝到Span中 } } } public static T Deserialize<T>(Span<byte> buffer) where T : struct { unsafe { fixed (byte* ptr = buffer) { return *(T*)ptr; // 从Span中读取值 } } } 异步 c# SynchronizationContext的使用场景及例子...