0
异步视界/agentic-coding-classics/armin-agents-are-hard
· AGENTIC-CODING-CLASSICS · 2026.05.06 · 13 MIN ·

Armin Ronacher《Agent Design Is Still Hard》:半年实战后的勘误表

Flask 作者在做了半年 agent 后写下的反思。给前面四篇的回信:每个具体设计决策都还在迭代,你今天用的 SDK 三个月后就会过时。精读 + 译者点评。 · by fancyoung
AI · HERO seed:4520260506 Flask 作者在做了半年 agent 后写下的反思。给前面四篇的回信:每个具体设计决策都还在迭代,你今天用的 SDK 三个月后就会过时。精读 + 译者点评。
FIG.00 — cover · ai-generated · placeholder

Agent Design Is Still Hard - social card

原文:lucumr.pocoo.org/2025/11/21/agents-are-hard/ 作者:Armin Ronacher —— Flask、Jinja2、Click、Werkzeug 作者;独立工程师,Sentry 早期员工,现 Earendil(coding agent 平台)联合创始人 发布:2025-11-21

🔥 影响力卡片

  • Hacker News 头条(item id 46013935),热烈讨论
  • Simon Willison 当周专文转译总结(2025-11-23 《Notes on agent design is still hard》)
  • 作者本身权威:Flask、Jinja2、Click 这三个 Python 库的造物主 —— 没有他就没有现代 Python web 生态
  • 这篇与他 2025-06 的《Agentic Coding Recommendations》、2025-07 的《Agentic Coding Things That Didn’t Work》、2025-12 的《A Year of Vibes》、2026-01 的《Agent Psychosis》构成一个 “半年一次的反思系列” —— 已是行业里最被引用的”实战派编年史”

🎯 为什么必读

这篇是前面四篇的”反应堆”

Karpathy 给宏大叙事,Anthropic 给 5 种模式,Dex Horthy 给 12 条原则,Geoffrey Huntley 给暴力美学 —— 然后 Armin 出现,用半年的实战疮疤告诉你:每一个具体决策都还没收敛

它的特别之处:

  1. 作者权威性极高且无利益绑定 —— Armin 不卖 SDK、不开课,他只是写自己的真实经验
  2. 诚实到极点 —— 公开”我之前那篇推荐的方案,半年后我改主意了”
  3. 聚焦工程细节 —— 不谈哲学,只谈”我今天构建一个 agent 会做什么决定”
  4. 它是当前 SOTA 的一份”今天怎么做”的对账单

读完你会获得一份”已被时间过滤过的具体实践清单”,以及一种警惕”已收敛”幻觉的免疫力

一句话总结

建 agent 还是一团乱。SDK 抽象在真实工具调用面前会断裂。强化(reinforcement)做的活比预期多得多。

💎 金句墙

“Building agents is still messy.” “造 agent 还是一团乱。” —— 这是这篇的 TL;DR 第一句,也是 Armin 给整个领域定的调。

“SDK abstractions break once you hit real tool use.”SDK 的抽象一碰到真实的工具调用就会断裂。—— 这一句让无数 LangChain/Vercel AI SDK 的用户点头如捣蒜。

“I’ve fully come around and now vastly prefer explicit cache management.” “我已经彻底转变立场,现在远远更偏好显式管理缓存。” —— 注意”fully come around”的修辞:Armin 在公开承认自己半年前的观点错了。这种坦诚在技术圈不多见。

“Reinforcement ends up doing more heavy lifting than expected.” “强化(信息注入)最后干的活比预期多得多。” —— 整篇文章最被低估的一句。它意味着 prompt 工程的重心在转移:从”系统提示”转向”循环中的提醒”。

“A dead end is where a task can only continue executing within the sub-tool that you built.” “所谓死胡同,就是任务只能在你建的那个子工具里继续往下走(出不来)。” —— 一句话讲清了为什么 agent 框架往往把任务卡死。

“A better tool caller will do the job in fewer tokens.”更好的工具调用者用更少的 token 干完活。—— Armin 的模型评判金标准:不是基准分,是 token 效率。

“Amp, similar to Claude Code, really feels like a product built by people who also use their own tool.” “Amp 跟 Claude Code 一样,真的感觉是被那些自己也用这个工具的人造出来的。” —— “做自己产品用户”是 Armin 反复强调的工程美德。

📋 核心精读

1. SDK 选择 —— 不要用高层抽象

Armin 直白:

我们没找到任何一个 SDK 把 agent 抽象得对。

具体含义:

  • 不要用 Vercel AI SDK 那种统一抽象,跨模型差异已经大到无法假装它们等价
  • 直接用 OpenAI / Anthropic 官方 SDK 自己写 agent loop
  • 高层抽象在 demo 阶段省时间,但在生产阶段你会反向工程框架才能做优化 —— 总成本反而更高

🟢 译者点评:这是与 Dex Horthy 12-Factor “Own your control flow” 完全一致的立场。两个独立观察者(一个访谈 100+ 创业者,一个亲自造产品)得出同一结论 —— 这个领域里,SDK 抽象暂时是负价值的

2. 缓存管理 —— 公开认错

Armin 半年前的立场:自动缓存就够了,不用想太多。 Armin 现在的立场:显式管理缓存,你的所有事都会变简单。

具体策略:

  • 系统提示后放一个缓存断点
  • 对话开头放两个
  • 最后一个跟着对话尾巴移动
  • Anthropic 的”付费缓存”模式被低估,实际上更便宜更可控

为什么显式优于自动?因为缓存命中 = 成本 + 延迟,而这两个变量你必须能预测。自动缓存让你看到的是”昨天命中率 73%,今天 41%“,但你完全不知道为什么

🟢 译者点评:Armin 这种”我半年前错了”的公开记录,是这篇的灵魂。这篇的真正价值不是”现在的最佳实践”,而是”已被时间筛过、半年内没变的最佳实践” —— 后者更接近真相。

3. 循环中的强化(Reinforcement)—— 这一节最重要

Armin 发现:比起调一个完美的系统提示,在每次工具调用之后注入一段强化信息,效果好得多。

什么是强化信息?

  • “你目前的目标是 X,你刚才做了 Y”
  • “上一步失败了,原因是 Z”
  • “时间已过去 N 步,还剩 M 步预算”

最妙的发现:Claude Code 的 todo 工具其实是个”自我强化”工具 —— 它本质就是把当前任务清单 echo 回去给 LLM,推它继续。

🟢 译者点评:这一节是这篇文章对实战派最大的礼物。如果你的 agent 跑着跑着开始忘记目标、原地打转、产生幻觉 —— 90% 的概率你需要的是循环中的强化机制,而不是更长的系统提示。

4. 失败隔离 —— 用子 agent 装可能失败的事

设计原则:任何”可能失败”的任务都应该委托给一个子 agent,主 agent 只看到”成功 / 失败 + 失败原因”。

为什么?LLM 的注意力是有限的资源,失败信息塞回主上下文等于让它中毒。

文章顺便提到 Anthropic 的”context editing”功能,认为它有潜力但会破坏缓存,目前权衡不明。

5. 子 Agent 与共享状态 —— 警惕”死胡同”

Armin 定义了一个工程概念:dead end —— 任务只能在你建的子工具里继续走,出不来。

解决方案:所有工具应该共享一个虚拟文件系统。Code、Inference、Image Generation 等不同类型的工具,通过读写同一个文件系统传递状态。

🟢 译者点评:这是给造 agent 平台的人最重要的一条架构指南。工具孤岛是 agent 的头号失败模式,共享文件系统是简单且强力的解药。

6. 输出工具 —— 小心”显式输出”陷阱

很多 agent 会引入一个”输出工具”让 LLM 调用,以便结构化产出。Armin 发现:

  • LLM 经常忘记调用这个工具
  • 即使调用,措辞和语气难以控制
  • 想用另一个 LLM 修措辞 → 延迟和质量都垮

他的解决方案:

  • 直接让 LLM 在普通对话里产出
  • 加一个”未调用就注入提醒”的机制做 fallback

7. 模型选择 —— 没有大变化

  • Haiku、Sonnet 仍是工具调用的最佳选择
  • Gemini 2.5 适合长 PDF/大文档分析
  • GPT 系列在 agent 主循环里表现一般(令人意外)
  • 评判标准:“better tool caller does the job in fewer tokens” —— 不是 benchmark 分,是 token 效率

8. 测试与评估 —— 没有解决方案

最坦诚的一节。Armin 直接说:

这是最难的问题,我没有满意的答案。

外部 eval 平台都解决不了,因为真实 agent 行为高度依赖部署环境(工具状态、外部 API、用户输入)。当前他能做的是基于可观测性数据的回看分析,但这是反应式的,不是主动式 eval。

🟢 译者点评:这一节是埋在文章里的定时炸弹。当前所有”agent eval 平台”创业公司都在攻这个山头。谁能解决,谁就能拿到下一轮独角兽估值。但截至 Armin 写作时,没人解决了

9. Coding Agent 现状 —— Amp 值得看

Armin 最近在用 Amp(类似 Claude Code 的工具),欣赏它的多子 agent 交互设计。 他的判断标准:这个产品是不是被它自己的造物主每天用? Amp 和 Claude Code 都通过这个测试,很多 SDK 框架不通过

🟢 译者总评

如果说前四篇是地图,这一篇是勘误表

它最大的价值不是”告诉你正确答案”,而是告诉你哪些半年前的”正确答案”已经过期。在一个迭代周期以季度计的领域,这种”勘误”比”答案”更值钱。

它对前四篇的隐含回应是这样的:

  • 对 Karpathy:你的 autonomy slider 思路对,但实现 slider 的 SDK 都还没就绪
  • 对 Anthropic:5 种 workflow pattern 抽象对,但具体到 caching / sub-agent 共享状态 / 强化机制,Anthropic 自己的 cookbook 也没标准答案
  • 对 12-Factor:你的 “own your control flow” / “own your context window” 是对的,而且你提到的痛苦,我在每一行代码里都遇到了
  • 对 Ralph:你的暴力循环有效,但只在你能容忍 “$297 替代 $50k 但 90% 完成度” 这个交易时有效;对真生产你需要的不止这些

如果你只从这篇带走 5 件东西:

  1. 不用高层 SDK,用官方 SDK 自己写 loop
  2. 显式管理缓存,不要让框架替你管
  3. 强化(reinforcement)在每次工具调用后注入,这是当前最大的杠杆
  4. 失败必须用子 agent 隔离,不要污染主 context
  5. eval 还没解决,不要相信任何”我们解决了 agent eval”的产品声明

这篇文章告诉你的最深一句话没明说但贯穿全文:

2025 年的”最佳实践”,2026 年还会再变一次。这个领域要再 2-3 年才会收敛到下一个稳定点。在那之前,你要做的不是押注,是做能让你跟上的事。

🔗 延伸阅读

🔗 调研来源(可校验)