13_不用框架怎么实现一个Agent 13 · 不用框架怎么实现一个 Agent我失业在家做求职作品集第四周的任务是「做一个 Agent」。打开教程前十篇里有九篇告诉你用 LangChain / LangGraph / LlamaIndex三行代码接上完事。我没用。不是洁癖是三个很具体的理由。这篇文章写我怎么手写的以及——更重要的——什么时候你还是该用框架。一、为什么不用三个理由1. 我要证明的是「我会做」不是「我会调」简历上写「熟练使用 LangChain」面试官心里想的是「那换个人也能」。手写一遍我能说清楚每一步为什么这么写为什么解析要做三态、为什么熔断设 2 次而不是 1 次、为什么观察要截断。这些是判断不是配置。框架把判断藏起来了 —— 你调create_react_agent()它跑起来了但你不知道它在哪一步做了什么取舍。2. 框架的版本和抽象会吃掉我的调试时间LangChain 那套抽象chain / runnable / agent executor本身就要学。而我只有六周其中一周要做 Agent MCP 可观测。我要的是「Agent 的原理」不是「某个框架的 API」。这两件事花的时间差不多但前者可迁移后者可能下个版本就变了。3. 最实际的一条不用框架可观测才好做这条是我做完才想明白的。框架的 Agent 跑起来你想看每一步发生了什么得先学会它的回调体系、它的 trace 格式。而我自己写的循环事件是我自己发的——想在哪埋点就在哪埋点格式我自己定。后来我接 trace 的时候Agent 代码改了 0 行。就这一条省下的时间够我再写两个模块。二、怎么实现一个纯文本协议的 ReAct核心决定完全不传tools/tool_choice给模型。# app/react.pyrun_react(...)# 不传 tools不传 tool_choice模型用纯文本表达意图思考我需要先查一下天气。 行动get_weather 参数{city: 北京}我的代码负责解析 → 执行 → 把结果回灌 → 让模型继续。为什么不走原生 function calling因为它依赖服务端支持。如果我降级到某家免费模型、而它恰好不支持整个 Agent 就废了。纯文本协议是最差的模型也能跑的那条路。代价是格式全靠约定模型随时可能不守约。所以有了下面这些设计。设计一解析做三态不是二值{kind:action}# 要调工具{kind:final}# 给出最终答案{kind:unknown}# 没解析出有效标记unknown这一态是关键。二值解析遇到格式不对只能抛异常或者当 final——前者让整个任务崩掉后者会让用户收到一个莫名其妙的答案。我的处理unknown当成一次观察结果回灌给模型附一段格式示范让它自己改。设计二给两次机会然后熔断MAX_UNKNOWN_IN_A_ROW2# app/react.py:76设 2 而不是 1给模型一次「照着格式重来」的机会。设 1 太苛刻一次口误就崩设 3 太浪费改不对的格式改三次也改不对。设计三三个终止出口且绝不编造出口 1 模型给出「最终答案」 —— 正常结束 出口 2 步数到 max_steps默认 6 —— 安全结束由我控制 出口 3 连续 2 次格式不明 —— 安全结束后两个返回okFalse空答案。这点我想了很久。熔断的目标是「不烧钱 不骗人」不是「一定要有个答案」。让模型在不知道的情况下硬编一个比空手而归糟糕得多。设计四观察回灌要截断而且要说明截断了OBSERVATION_MAX_CHARS1500# app/react.py:79截断会丢信息所以必须标注「已截断原长 N 字。如需完整结果请缩小查询范围」。不标注会怎样模型会以为它看到的就是全部然后基于残缺信息下结论。告诉模型它的视野有边界它才有可能自己缩小查询范围。三、踩的坑一个差点让我误判的 bug做完之后我接了可观测把事件流翻成 span 树画瀑布图。跑起来一看step 1: 651ms step 2: 640ms step 3: 620ms step 4: 590ms ---------------- 合计: 244% ← 比整次任务还长一倍多四步加起来 244%我第一反应是「系统变慢了」。实际是我的 ReAct 事件词汇里有step_start没有step_end。没有结束信号每一步就只能靠下一个step_start来推断结束最后一步更是要等到根 span 兜底关闭才结束。于是每一步的耗时都变成了「从它开始到全程结束」。尺子坏了我却在怀疑被测的东西。修法下一个step_start/final/stop到来时关闭上一步。修完我加了条测试专门钉死这个行为——这类 bug 特别容易在改事件词汇时复发。这个坑给我的教训跟第三周一模一样你没法优化一个你测不准的东西。先修尺子。四、框架我装了但主代码不用项目里装着 LangGraph但主代码不用。我把它做成了对照脚本python scripts/langgraph_compare.py --with-langgraph这样我既保住了「未依赖框架」这个卖点又能说清楚两种实现差异在哪——而且我知道 LangGraph 的 checkpointer 适合什么场景。「我评估过然后选择了不用」和「我不会」在面试官耳朵里是两回事。五、什么时候你还是该用框架诚实说下面这些情况别手写场景为什么生产环境要长期维护手写意味着所有边界情况你自己扛。框架踩过的坑比你多需要复杂的分支 / 循环 / 并行图LangGraph 的状态图 条件边是真好用手写状态机是自虐需要持久化、断点续跑checkpointer 这类基础设施别自己造团队协作框架是公共词汇。你手写的协议只有你自己看得懂我自己这个项目的结论也一样生产更该用 workflow确定性流程agent 只作展示和面试素材。Anthropic 那篇《Building Effective Agents》给了三个「不该用 agent」的判据我照着对了一遍路径可预测 → 用 workflow一次调用能完成 → 直接调 LLM别套 agent错误成本高且不可恢复 → workflow 人工检查点根本原因就一句agent 的错误会累积errors compound。十步里每步 95% 正确端到端只剩 60%。六、一句话手写一遍 Agent最大的收获不是那个 Agent是我知道它在哪一步会出错。这份清单我写进了docs/Agent失败模式与兜底方案.md十二类每类都有真实触发场景和兜底手段。框架能帮你跑起来但不会告诉你它会怎么坏。