
1. 当 DHH 说“手写代码时代落幕”他到底在说什么DHH 这个名字如果你写过 Rails大概率不会陌生。Ruby on Rails 的作者、Basecamp 的联合创始人、那个永远带着点“反潮流”气质的丹麦程序员最近又扔出了一颗炸弹——大意是手写代码的时代正在落幕Agent 正在重塑软件工程。这话一出来圈子里立刻炸了锅。有人拍手叫好有人嗤之以鼻更多的人是懵的Agent 到底是什么它凭什么能“重塑软件工程”我是不是该转行了先别慌。我做了十多年一线开发从最早手写 SQL 拼字符串到后来用 ORM再到 CI/CD 自动化每一次工具链的升级都伴随着“程序员要失业了”的论调。但这次不太一样。Agent 不是简单的代码补全也不是你按 Tab 就帮你写完一行的 Copilot。它是一个能自己规划、自己执行、自己验证、自己修正的闭环系统。你给它一个目标它会拆解任务、调用工具、读写文件、运行测试、根据报错调整策略直到把事办成。这跟以前那种“你写一行它补一行”的辅助工具完全是两个物种。那 DHH 说的“手写代码时代落幕”到底是什么意思我的理解是不是说不写代码了而是说“逐行手写业务逻辑”这件事正在从主流开发方式退化成一种底层能力。就像今天你开车不需要懂化油器原理但修车师傅得懂。未来大部分软件工程师的日常会从“写实现”转向“定义问题、设计约束、审查结果”。Agent 负责把意图翻译成可运行的代码人负责判断这个翻译对不对、好不好、安不安全。这篇文章我想聊透几件事Agent 到底怎么工作的它跟传统 CLI 工具、跟 Rails 这种“约定优于配置”的框架是什么关系实际落地时有哪些坑以及作为一个普通开发者你现在应该怎么上手。不吹不黑只讲我踩过的坑和验证过的路。2. Agent 不是魔法拆开看就是四件事2.1 从“补全”到“闭环”Agent 的核心差异很多人第一次接触 Agent会觉得它跟 Copilot 差不多都是 AI 帮你写代码。但用久了就会发现Copilot 是“你写它猜”Agent 是“你说它做”。这个差别看似微小实则决定了整个工作流的重构。Copilot 的工作模式是你正在编辑器里敲代码它根据上下文预测你接下来要写什么给你一个建议你按 Tab 接受或忽略。它的输入是你的光标位置和周围代码输出是一段文本。它不关心这段代码能不能跑通不关心项目结构不关心依赖版本。它就是一个超级智能的自动补全。Agent 的工作模式是你给它一个任务描述比如“给用户表加一个软删除字段并更新所有相关查询”。它会先理解这个任务然后规划步骤第一步找到用户表的定义文件第二步生成迁移脚本第三步找到所有查询用户表的地方第四步逐个修改查询条件第五步运行测试第六步如果测试失败分析报错并修正。整个过程它自己驱动自己验证自己迭代。这个闭环能力来自四个核心组件规划器、执行器、记忆、工具集。规划器负责把大任务拆成小步骤执行器负责调用工具去执行每一步记忆负责保存上下文和历史操作避免重复劳动和状态丢失工具集就是它能调用的外部能力比如读写文件、执行命令、访问网络、查询数据库。2.2 规划器Agent 的“大脑”怎么拆任务规划器是 Agent 最核心也最脆弱的部分。它决定了 Agent 能不能把一个模糊的人类指令翻译成一系列可执行的具体操作。我试过不少 Agent 框架发现规划器的好坏直接决定了 Agent 是“智能助手”还是“智障助手”。一个好的规划器首先得理解任务的边界。比如你说“优化首页加载速度”它得知道这不是一个单一操作而是一个需要先诊断、再定位、再修改、再验证的复合任务。它得能区分“哪些事我现在能做”比如读代码、跑性能分析哪些事需要人类介入比如决定要不要换 CDN 供应商。其次规划器得能处理不确定性。实际开发中你永远不知道下一步会遇到什么。可能你打开一个文件发现它跟你预想的完全不一样可能你跑一个命令报了一个从没见过的错。规划器不能死板地按预设步骤走它得能根据执行结果动态调整计划。我见过一些早期 Agent规划器写得太死遇到意外就卡住最后只能报错退出。这种体验还不如自己动手。最后规划器得知道什么时候停下来。这听起来简单其实很难。Agent 容易陷入两种极端一种是过早放弃遇到一点困难就说“我做不到”另一种是无限循环反复尝试同一个失败的操作。好的规划器会设置合理的重试上限和退出条件并且在卡住的时候主动向人类求助而不是自己瞎折腾。2.3 执行器与工具集Agent 的“手脚”怎么动执行器负责把规划器拆出来的步骤翻译成具体的工具调用。工具集就是 Agent 能用的“武器库”。这两者配合得好不好决定了 Agent 的实操能力上限。工具集的设计有个原则工具要原子化但语义要清晰。什么意思比如“读写文件”是一个原子工具“执行 shell 命令”是另一个原子工具。但你不能把“重构这个模块”当成一个工具因为那太复杂了执行器不知道怎么调。反过来工具的名字和参数要足够清晰让规划器一看就知道什么时候该用哪个。我见过一些框架工具命名很随意结果规划器经常选错工具效率极低。执行器还有个关键能力错误处理。Agent 执行命令时失败是常态。文件不存在、权限不够、依赖缺失、网络超时各种问题都会遇到。执行器不能一报错就崩它得能捕获错误、提取关键信息、反馈给规划器让规划器决定是重试、换方案还是放弃。这个反馈循环的质量直接决定了 Agent 的鲁棒性。2.4 记忆Agent 的“记性”为什么重要记忆系统经常被忽视但它其实是 Agent 能否处理复杂任务的关键。没有记忆的 Agent每次操作都是“失忆”状态它不知道刚才做了什么、为什么做、结果如何。这会导致两个问题一是重复劳动比如反复读同一个文件二是状态丢失比如改了一半的代码下一步忘了改了什么。记忆通常分短期和长期。短期记忆保存当前任务的上下文比如已经执行了哪些步骤、遇到了哪些错误、当前的文件状态。长期记忆保存跨任务的知识比如这个项目的代码规范、常用的命令、之前踩过的坑。短期记忆让 Agent 能连贯地完成一个任务长期记忆让 Agent 能越用越聪明。我实际用下来记忆系统的设计难点在于信噪比。保存太多上下文爆炸Agent 处理不过来保存太少关键信息丢失Agent 犯低级错误。好的记忆系统会做摘要和压缩只保留对当前决策有用的信息。这个度很难把握目前大部分框架还在摸索阶段。3. 从 Rails 到 CLIAgent 落地时绕不开的几个现实问题3.1 Rails 的“约定优于配置”为什么天然适合 AgentDHH 是 Rails 的作者他谈 Agent 重塑软件工程绕不开 Rails 这个背景。有意思的是Rails 的设计哲学跟 Agent 的工作方式有天然的契合点。Rails 最核心的理念是“约定优于配置”。这意味着项目结构是标准化的模型放app/models控制器放app/controllers视图放app/views迁移放db/migrate。路由有固定写法数据库表名默认是模型名的复数形式。这些约定对人类开发者来说是减少决策负担对 Agent 来说则是降低了探索成本。你想想如果一个项目的结构完全自由Agent 要找一个用户模型的定义可能得遍历整个代码库。但在 Rails 项目里它直接去app/models/user.rb就行了。这种可预测性让 Agent 的规划器能生成更确定的步骤执行器能更高效地定位文件整体成功率大幅提升。另一个契合点是 Rails 的“全栈一体化”。Rails 自带 ORM、路由、模板、测试框架所有组件都在一个体系内。Agent 不需要在多个工具之间切换它可以用统一的命令完成迁移、测试、启动服务等操作。这种一致性对 Agent 来说就是更少的工具调用、更短的反馈循环、更高的执行效率。当然这不意味着只有 Rails 适合 Agent。任何有清晰约定和标准结构的框架都会让 Agent 更好用。但 Rails 确实是这方面的典范DHH 的观察有他的道理。3.2 CLI 才是 Agent 的主战场不是 IDE很多人以为 Agent 会以 IDE 插件的形式存在毕竟 Copilot 就是这么做的。但实际用下来我发现CLI 才是 Agent 最自然的交互界面。为什么因为 Agent 的工作方式是“执行命令、观察结果、调整策略”。这跟 CLI 的交互模式完全一致。你在终端里输入一个命令看到输出再输入下一个命令。Agent 也是这么干的只不过它自己决定输入什么命令自己解析输出。IDE 插件的问题在于它被限制在编辑器的上下文里。它能读写文件但很难执行复杂的 shell 命令它能分析代码但很难启动服务、跑数据库迁移、管理进程。而 CLI Agent 没有这些限制它可以在一个真实的终端环境里像人类开发者一样操作整个系统。我实际用 Codex CLI 和 Claude Code 这类工具时最直观的感受就是它像一个坐在你旁边的同事你告诉它要做什么它就在终端里敲命令你看着它操作随时可以打断或纠正。这种体验比 IDE 里那种“它悄悄改你代码”的方式要透明得多也安全得多。CLI Agent 的另一个优势是可组合性。你可以把它嵌到 CI/CD 流程里让它自动处理一些重复性任务你可以用脚本调用它批量处理多个项目你可以把它跟 Git hooks 结合在提交前自动检查代码质量。这种灵活性是 IDE 插件很难做到的。3.3 Agent 的并发问题为什么“扛并发”是个伪命题热词里有个“ai agent 怎么扛并发”这个问题我一开始也觉得挺重要后来想明白了大部分 Agent 场景根本不需要扛并发因为 Agent 的工作模式是串行的。你想想一个 Agent 在执行任务时步骤之间是有依赖的。它得先读文件才能改文件先改文件才能跑测试先跑测试才能根据结果决定下一步。这种依赖关系决定了它很难并行化。你强行让它并发执行多个步骤反而容易导致状态冲突和数据不一致。那什么时候需要并发一种是多个独立任务同时执行比如同时处理多个项目的代码审查。这种场景下你需要的不是单个 Agent 扛并发而是多个 Agent 实例并行工作。每个实例处理一个独立任务互不干扰。另一种是 Agent 内部某些步骤可以并行比如同时读取多个文件。但这种并行通常由执行器内部处理不需要 Agent 层面操心。所以“Agent 怎么扛并发”这个问题本质上是个架构问题不是 Agent 本身的问题。你需要的是一个能调度多个 Agent 实例的任务队列而不是一个能同时干多件事的超级 Agent。想清楚这一点很多架构决策就清晰了。4. 实操从零搭一个能用的 Agent 工作流4.1 工具选型Codex CLI、Claude Code 还是自己搭市面上 Agent 工具不少我实际深度用过的主要是 Codex CLI 和 Claude Code也试过一些开源框架自己搭。选哪个取决于你的需求和动手能力。Codex CLI 的优势是跟 OpenAI 生态集成好安装简单开箱即用。它的命令设计比较直观适合快速上手。但它的定制能力有限你很难深度修改它的规划逻辑或工具集。如果你只是想体验一下 Agent 的工作方式或者做一些标准化的任务Codex CLI 够用了。Claude Code 的优势是上下文窗口大处理复杂任务时不容易丢信息。它的工具集也比较丰富支持文件操作、命令执行、网络访问等。但它的配置相对复杂需要你理解它的权限模型和安全机制。另外它在某些环境下的网络连接可能不太稳定需要提前测试。自己搭的话LangChain、AutoGPT 这些框架都可以用。优势是完全可控你可以按自己的需求设计规划器、工具集和记忆系统。劣势是工作量大而且很多坑得自己踩。如果你有明确的定制需求比如要接入内部系统、要遵循特定的代码规范自己搭是值得的。否则先用现成工具跑通流程再考虑定制。提示不管选哪个工具先在隔离环境里测试。Agent 会执行真实命令改真实文件跑真实测试。别一上来就在生产环境或重要项目上试。4.2 环境准备别小看这一步Agent 工具对环境的要求比普通 CLI 工具高。它需要能执行命令、读写文件、访问网络所以权限配置和安全隔离特别重要。第一步准备一个独立的开发环境。可以是 Docker 容器也可以是虚拟机或者至少是一个独立的用户账户。别用你的主账户跑 Agent万一它误删文件或执行危险命令后果很严重。第二步安装必要的运行时。大部分 Agent 工具需要 Python 或 Node.js 环境。以 Codex CLI 为例它需要 Node.js 18 以上版本。安装命令很简单# 安装 Node.js以 Ubuntu 为例 curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs # 验证安装 node --version npm --version第三步配置 Agent 工具本身。以 Codex CLI 为例安装命令是npm install -g openai/codex-cli安装完成后你需要配置 API 密钥。这个密钥决定了 Agent 能调用哪个模型也决定了你的使用成本。建议先用小额度测试确认工作流没问题再加大投入。第四步准备一个测试项目。别拿空目录试Agent 需要真实的代码上下文才能展示能力。可以克隆一个开源项目或者用 Rails 快速生成一个gem install rails rails new agent-test --databasepostgresql cd agent-test这个项目结构清晰有模型、控制器、测试适合用来测试 Agent 的各种能力。4.3 第一个任务让 Agent 帮你加一个功能环境准备好了来跑第一个真实任务。我选的是一个很典型的 Rails 需求给用户表加一个软删除功能。任务描述我写成这样给 User 模型添加软删除功能。要求1. 添加 deleted_at 字段2. 默认查询排除已删除用户3. 提供 soft_delete 和 restore 方法4. 更新相关测试。这个描述包含了目标、约束和验收标准Agent 能理解得更准确。如果只写“加软删除”它可能会漏掉某些要求或者用你不喜欢的方式实现。Agent 接到任务后通常会先探索项目结构。它会读app/models/user.rb看现有的模型定义读db/schema.rb看当前的表结构读test/models/user_test.rb看测试怎么写。然后它会生成一个计划大概是生成迁移文件、修改模型、更新测试、运行测试。执行过程中它会调用各种命令。比如生成迁移rails generate migration AddDeletedAtToUsers deleted_at:datetime然后修改迁移文件加上索引class AddDeletedAtToUsers ActiveRecord::Migration[7.0] def change add_column :users, :deleted_at, :datetime add_index :users, :deleted_at end end接着修改模型加上默认作用域和方法class User ApplicationRecord default_scope { where(deleted_at: nil) } def soft_delete update(deleted_at: Time.current) end def restore update(deleted_at: nil) end end最后跑测试看有没有问题。如果测试失败它会读报错信息分析原因然后修正代码。这个迭代过程可能重复几次直到测试通过。我实际跑下来这个任务 Agent 大概用了两分钟中间失败了一次默认作用域影响了测试里的计数它自己发现并修正了。整体体验比我预想的顺畅。4.4 关键配置让 Agent 更懂你的项目Agent 默认的行为可能不符合你的项目规范。比如它可能用Time.current而不是Time.zone.now可能不写测试可能不遵循你的代码风格。要让它更懂你的项目你需要提供额外的上下文。最直接的方式是写一个AGENTS.md文件放在项目根目录。这个文件告诉 Agent 你的项目有哪些约定、用什么命令、注意什么。比如# 项目约定 ## 代码风格 - 使用 RuboCop 检查代码风格 - 方法名用蛇形命名 - 避免使用 default_scope ## 测试 - 使用 RSpec不用 Minitest - 每个功能都要有对应的测试 - 测试文件放在 spec/ 目录下 ## 常用命令 - 跑测试bundle exec rspec - 代码检查bundle exec rubocop - 启动服务bin/dev这个文件相当于给 Agent 的一份“入职指南”。它会在规划任务时参考这些约定生成更符合你期望的代码。我试过加了这个文件之后Agent 生成的代码质量明显提升返工率大幅下降。另一个技巧是给 Agent 提供示例。如果你希望它用某种特定的方式实现某个功能可以在项目里放一个示例文件然后在AGENTS.md里指出来。Agent 会参考这个示例模仿它的风格和结构。5. 踩坑实录Agent 实际用起来有哪些坑5.1 常见报错与排查思路Agent 工具用起来报错是家常便饭。我整理了几个高频问题附上排查思路。报错信息可能原因排查方法unable to locate the codex cli binary安装不完整或 PATH 配置错误检查npm list -g是否安装成功确认 PATH 包含 npm 全局目录internetopenurl() failed网络连接问题或代理配置错误检查网络连通性确认 API 端点可访问agent execution terminated due to error任务执行中遇到未处理的异常查看详细日志定位具体失败步骤node_modules 与 Windows 版本不兼容Node.js 版本或系统架构不匹配确认 Node.js 版本检查是否用了正确的安装包codex无法发送消息API 密钥无效或额度耗尽检查密钥配置确认账户余额这些报错看起来吓人但排查思路都差不多先看日志定位失败的具体步骤再检查环境确认依赖和配置没问题最后简化任务排除是任务本身太复杂导致的。我遇到最多的问题是网络相关的。Agent 需要调用远程 API网络不稳定时容易超时或失败。解决办法是配置合理的超时时间并且在 Agent 卡住时能自动重试。有些工具支持配置重试策略记得打开。5.2 安全边界哪些事千万别让 Agent 干Agent 能执行真实命令这意味着它也能造成真实破坏。我踩过的最大的坑是让 Agent 在一个没有版本控制的项目上跑重构任务。它改了一堆文件跑测试失败然后试图“修复”问题结果越改越乱。最后我花了一个下午才恢复原状。从那以后我给自己定了几个规矩第一永远在版本控制下工作。Agent 改任何东西之前先确保代码已经提交。这样即使它改坏了你也能一键回滚。Git 是 Agent 时代最重要的安全网没有之一。第二限制 Agent 的权限。别给它 sudo 权限别让它访问生产数据库别让它执行rm -rf这类危险命令。大部分 Agent 工具支持配置允许的命令白名单一定要用起来。第三重要操作要人工确认。比如数据库迁移、部署、删除文件这些操作应该让 Agent 先给出计划你确认后再执行。有些工具支持“dry run”模式先模拟执行看看它会做什么确认无误再真正跑。第四定期审查 Agent 的操作日志。Agent 可能会做一些你意想不到的事比如修改了不该改的文件、安装了不必要的依赖、访问了外部服务。定期看日志能及时发现这些问题。注意Agent 的安全问题不是技术问题是流程问题。再好的工具如果你不给它设边界它就可能闯祸。把安全规则写进AGENTS.md让 Agent 自己遵守比事后补救有效得多。5.3 成本控制别让 Agent 烧光你的额度Agent 调用大模型 API 是按 token 计费的。一个复杂任务可能消耗几十万甚至上百万 token成本不低。我第一个月用下来账单比我预想的高了不少。控制成本有几个办法。一是限制上下文长度。Agent 每次调用模型时会把当前的任务状态、历史操作、文件内容都塞进上下文。如果上下文太长token 消耗就大。好的 Agent 工具会做上下文压缩只保留关键信息。你可以配置压缩策略比如只保留最近 N 步的操作记录。二是用更便宜的模型做简单任务。不是所有任务都需要最强的模型。读文件、跑命令、解析输出这些操作用便宜的小模型就够了。只有复杂的规划和决策才需要用大模型。有些框架支持模型路由根据任务类型自动选择模型能省不少钱。三是设置预算上限。大部分 API 平台支持设置月度预算超过就停止服务。这个一定要设防止意外情况导致账单爆炸。四是缓存重复操作。如果 Agent 反复读同一个文件、跑同一个命令可以缓存结果避免重复调用模型。这个需要框架支持自己搭的话可以加一层缓存。我现在的做法是日常开发用中等模型复杂重构用大模型简单查询用小模型。一个月下来成本控制在可接受范围内。6. 软件工程的新分工人负责什么Agent 负责什么6.1 从“写代码”到“定义问题”Agent 时代软件工程师的核心能力在转移。以前你花 80% 的时间写代码20% 的时间想需求。未来可能反过来你花 80% 的时间定义问题、设计约束、审查结果20% 的时间处理 Agent 搞不定的边角料。“定义问题”听起来简单其实很难。你得能把一个模糊的业务需求翻译成 Agent 能理解的清晰指令。你得知道哪些约束是必须的哪些可以放宽。你得预判 Agent 可能在哪里出错提前给它指路。这些能力本质上是对业务的理解和对技术的判断不是写代码能替代的。我实际用 Agent 做项目时最大的感受是写代码的时间确实少了但思考的时间多了。以前拿到需求就开始敲键盘现在得先想清楚这个需求的核心是什么有哪些边界条件用什么方案最合适Agent 可能会怎么实现我该怎么验证它做对了这些问题想清楚了Agent 执行起来就顺畅想不清楚Agent 就会给你一堆需要返工的代码。6.2 代码审查变成“结果审查”传统代码审查你看的是实现细节变量命名对不对、逻辑有没有漏洞、边界条件处理了没有。Agent 生成的代码你依然要看这些但重点会转移。因为 Agent 生成的代码风格通常是一致的低级错误也少。你更需要关注的是它有没有理解对需求有没有遗漏关键场景有没有引入不必要的复杂度这些问题看代码本身不一定能发现得结合需求文档和测试用例来判断。我现在的审查流程是先看 Agent 的任务计划确认它理解对了再看它改了哪些文件确认范围合理然后跑测试看功能是否正常最后抽查关键代码看实现是否优雅。这个流程比逐行审查快但要求你对业务和架构有更深的理解。另一个变化是测试变得更重要了。Agent 生成的代码你得有足够的测试来验证。测试写得好Agent 改完跑一遍就知道对不对测试写得差Agent 改完你还得手动验证效率反而低。所以未来软件工程师的一项核心技能是写出高质量的测试让 Agent 能自己验证结果。6.3 学习路线现在该学什么如果你还在学校或者刚入行面对 Agent 时代可能会焦虑我该学什么我的建议是基础要扎实工具要会用思维要转变。基础扎实指的是数据结构、算法、操作系统、网络、数据库这些底层知识依然重要。Agent 能帮你写代码但不能帮你理解为什么这么写。遇到复杂问题时你的基础决定了你能不能判断 Agent 的方案对不对。工具会用指的是熟练使用至少一种 Agent 工具理解它的工作原理知道怎么配置、怎么调试、怎么控制成本。这就像当年学 Git 一样不是可选项是必备技能。思维转变指的是从“我要写代码”变成“我要解决问题”。代码只是手段解决问题才是目的。Agent 能帮你更快地实现手段但定义问题、设计方案、验证结果这些还是得你来。我个人的学习路线是先用 Agent 做小任务熟悉它的能力和边界然后逐步加大任务复杂度观察它在哪些地方容易出错最后尝试定制 Agent让它更贴合自己的项目需求。这个过程不需要很久但需要你主动去试、去踩坑、去总结。7. 我个人的一些体会用 Agent 做开发这几个月我最大的感受是它没有让我变懒反而让我更勤快了。以前遇到重复性任务我会拖着不想做因为手动操作太烦。现在我会直接扔给 Agent自己去做更有意思的事。结果就是我做的事情更多了项目的推进速度也更快了。另一个感受是Agent 放大了你的能力也放大了你的问题。如果你对项目理解清晰、规范明确Agent 会帮你高效执行如果你自己都稀里糊涂、代码一团乱麻Agent 只会把混乱放大。所以用好 Agent 的前提是你自己得先想清楚。最后分享一个小技巧给 Agent 写任务描述时多用“验收标准”。比如“完成后所有测试通过RuboCop 无警告功能在浏览器里能正常使用”。这些标准让 Agent 知道什么时候算完成也让你知道怎么验证它做对了。我试过加了这个之后Agent 的返工率明显下降。这个领域变化很快今天好用的工具明天可能就被替代了。但底层的逻辑不会变理解问题、设计方案、验证结果这些能力永远有价值。Agent 只是让这些能力的杠杆更大了。