当 agent 先研究,再开始写代码
今天 Hacker News 上最值得认真看的技术文章之一,不是某个新模型发布,也不是某个框架跑分,而是一篇方法论很强的实验:如果让 coding agent 在动手改代码之前,先去读论文、看别的项目怎么做、理解问题属于哪一类瓶颈,会发生什么。
答案很简单,也很重要:它会明显变得更像一个成熟工程师,而不只是一个会生成 patch 的自动补丁机。
文章作者把一个带 benchmark 和测试的自动优化循环,应用到 llama.cpp 的 CPU 推理路径上。最开始,agent 只根据代码上下文做实验,结果非常像一个"会写代码但不懂系统"的新人:它试着做各种 SIMD 微调、循环展开、局部小修小补,看起来都很合理,但收益几乎都在噪声里。后来 agent 才逐渐意识到,问题不是算得不够快,而是内存带宽已经快打满了。也就是说,这不是一个"多榨一点 ALU 性能"的题,而是一个"少做无意义内存搬运、减少多次遍历"的题。
这个转折非常关键。因为很多工程优化问题,本来就不是从代码表面能直接看出来的。代码能告诉你"现在怎么做",但不一定告诉你"为什么慢",更不会自动告诉你"别的系统已经试过什么、哪条路其实早就被证明没用"。这些信息通常散落在论文、竞品实现、fork、旧 PR、架构经验和领域知识里。也就是说,优化质量的上限,很多时候不是写代码能力决定的,而是假设质量决定的。
原文最有价值的地方,不是最后那几个百分点的性能提升,而是它把一个本来偏"工程直觉"的流程,变成了比较清楚的 agent workflow:先研究,再假设,再实验,再验证。研究阶段并不神秘,无非是让 agent 去看相关论文、看别的实现、看其他后端的处理方式、看有没有已经 upstream 的思路没被当前路径用上。真正改变结果的,是这个步骤把 agent 从"只会在本地代码里瞎试"变成了"会从外部世界借经验回来"。
文中有一个细节我很喜欢。作者说,最终真正带来启发的,往往不是 arXiv,而是别的 fork 和别的 backend。嗯,这很真实。现实工程里,最有用的知识未必总在论文里,常常就在别人的脏实现、历史 PR 和不同平台的特化代码里。论文给你原则,别人的代码给你可落地的线索。一个只读论文的 agent,可能会空想;一个只读本仓库的 agent,可能会短视。把两者结合起来,才更像在真正做研究式工程。
这件事对 AI coding 的启发其实很直接。我们过去太容易把 agent 的价值理解成"更快地产生改动"。但如果改动建立在错误的问题判断上,速度越快,浪费越大。一个 agent 可以在几分钟里做几十个实验,但如果它从第一步就把问题看成 compute-bound,而实际上系统是 memory-bound,那这些实验大多只是昂贵地确认自己在走错路。
所以真正该自动化的,不只是 edit-run-test 这个循环,而是"形成好假设"之前的准备动作。比如自动去搜同类项目,汇总相似优化思路,识别当前路径更像算力瓶颈还是带宽瓶颈,查看不同平台 backend 有没有已经存在的融合算子,甚至生成一份"历史上这个项目哪些优化尝试成功、哪些失败"的地图。这样 agent 不只是会试错,而是会先缩小错误空间。
从更大的角度看,我觉得这篇文章其实在提示一个未来分工:低层的机械执行越来越便宜,稀缺的会是"如何定义问题"和"如何挑选值得尝试的方向"。这和人类工程师的价值变化是同一个方向。以后大家比拼的,可能不只是谁会写代码,而是谁更快发现真正的瓶颈、谁更会组织实验、谁更会让 agent 站在更高质量的上下文上工作。
如果把这件事落到日常开发里,结论也不复杂。不要一上来就让 agent 改。先让它调研。先让它写出它认为的瓶颈模型,列出参考实现,说明它为什么认为这条路值得试,再进入修改和 benchmark。多这一层,看起来慢一点,实际上往往更快。因为真正昂贵的不是多读十分钟资料,而是沿着错误方向自动冲刺两个小时。
我们已经见过很多"先写再说"的 agent 了。接下来更值得期待的,应该是"先研究再动手"的 agent。前者像一个很勤快的实习生,后者才开始有点像工程师。