第 1 期:三层判断,以及为什么选 LangGraph 而不是自研循环
《笨办法学 Agent》上册用三十二个练习、不靠任何框架,亲手写出了一个 agent harness 的每一层。 读过的话,这一册会不断指回那些练习;没读过也不影响往下走。这一册从另一头开始: 公司里来了一个需求,要“做个 agent“。先别打开编辑器。第一件事是判断这个需求到底是不是 agent。
这一期没有图,只有一张判断清单和一个选择的理由。末尾有一个自检脚本, 把后面十四期要用的环境跑通。
三个档位
企业里的模型应用,形态就三种。
单 prompt。 输入进去,模型算一遍,结果出来,事情就完了,中间没有第二轮。 留言分类、字段抽取、通话摘要、翻译,都是这一档。加一步检索的也算:员工问报销限额, 程序去文档库捞出那条政策,拼进 prompt,模型照着文档措辞回答。检索、拼接、生成, 一条直线跑到底,每一步都是代码提前写死的。
预定义流程。 步骤不止一步,中间有分支,但每一步是什么、分支怎么走,写代码的时候 就画得出来。客服工单先分类,A 类查订单系统,B 类查物流,查完再生成回复。模型出现在 某几个节点里做判断或生成,路线图是你画的。
agent。 模型在循环里自己决定下一步:要不要查、查哪个、查完看结果再定方向。 哪一步调哪个工具,代码里没有写死,写死的只有可用的工具和结束条件。
界线只有一条:模型有没有在循环里自己决定下一步。 跟用没用检索、prompt 复不复杂、有几个步骤都没关系。上册前言引过 Anthropic 的定义,这里再用一次:agent 是模型 在循环里根据环境反馈使用工具。前两档里模型是流水线上的一环,在填空。
为什么要分这么清
agent 比前两档多一层循环控制,多一套工具接入,多一份出错处理。调试和评估的难度跟着 跳一个台阶:同一个输入,两次跑出来的路线可能不一样,出了错你要先弄清楚它这次走了哪条路。
本来一次调用能稳定解决的事,包一层 agent 上去,账单更贵,bug 更难查,能力一点没多。
反过来也成立。输入能枚举,流程就画得出来;画得出来,就该写成代码。确定、可测、 出错能定位到某一行,这些性质在生产环境里都是钱。企业场景的输入通常是可枚举的: 问题类型有限,工单状态有限,订单能做的操作有限。所以企业里大多数需求的正确答案是 第二档,一条写死的流程。
一个真实的对照:我们上过生产的六个模型应用里,落在 agent 这一档的只有一个, 处理多轮对话的那个客服。其余五个是单 prompt 或者预定义流程,把它们做成单 prompt 和流程, 不算委屈了需求,需求本来就该这么做。
四问清单
拿到需求,按顺序问四个问题。
一、任务能不能用单一 prompt 完成?
能 → 单 prompt
不能 → 下一问
二、任务流程能不能提前定义?
能 → 预定义流程(推荐)
不能 → 下一问
三、是否需要模型动态规划、自主决策?
是 → agent
否 → 回去重新评估需求
四、任务的开放性多高?
低 / 中 → 预定义流程 + 条件分支
高 → agent
第二问后面那个“推荐“,和第四问把“开放性低和中“推回第二档,是同一个意思说了两遍: 大多数需求的答案是流程。
“开放性“这个词具体说是两个问题。这次请求的输入能不能提前枚举成有限几类? 下一步能不能在写代码时画出来?两个都能,是流程。输入能枚举但下一步要综合判断, 是流程加条件分支。连输入都没法枚举,才是 agent。
清单里没有检索这一项。检索是一种能力,不算档位,三档都可以带。“我们做的是 RAG, 所以不用考虑流程编排”,是最常见的一个误判。
三个场景走一遍
拿三个真实上过生产的需求走一遍四问。
跨语言客服翻译。 客服用中文写,系统翻成客人的语言发出去。第一问:单一 prompt 能不能完成?能。术语表和几个示例塞进 prompt 就够了。停在第一档。这个需求当时也有人 提议做成 agent,让模型自己决定要不要查术语库。查术语库每一次都要做,没有 “决定“的余地,做成 agent 只是给一条直线硬加了一个循环。
商品咨询答案草稿。 客人问某个商品能不能改期,系统起草一份答案给客服过目。 第一问:不能,要先查商品政策。第二问:流程能不能提前定义?能。识别问的是哪个商品、 哪类问题,查对应的政策条目,拼进 prompt 生成草稿。第二档,预定义流程,带检索。
多轮对话客服。 客人在对话里陈述问题,系统要在几轮之内搞清楚他要什么,查订单, 给方案,必要时转人工。第一问:不能。第二问:流程能不能提前定义?不能。客人第三句话 可能推翻前两句,要不要再问一句、先查订单还是先查政策,每一轮都要看上一轮的结果。 第三问:需要模型自主决策。第四问:开放性高。第三档,agent。
三个需求,三个档位。第三个是这个系列后面要做的。第二档也不会被落下, 下一节会讲它为什么也能从这个框架里得到好处。
为什么用框架
上册花了三十二个练习不用框架,为的是看懂。这一册用框架,为的是上线。两者不矛盾, 但你有权利问一句:既然循环只有几十行,为什么不自己写?
因为循环只占了两章。 回头翻上册的目录。循环本身是练习 3 和练习 5,之后二十几章 全是围着它补的:工具注册、权限、会话持久化、上下文压缩、规则文件、记忆、skill、 子 agent、MCP、沙箱、后台任务。框架卖的不是那个循环,是这二十几章。
因为上线的要求和本地跑不一样。 你本机跑的 agent 挂了重启就行。给别人用的 agent, 要多用户互不干扰,要中途停下来等人批准再接着跑,要进程重启后从断的地方续上, 要流式输出。这些自研都能做,每一样都是一周的活,而且每家公司各写一套,谁也不认识谁的。
因为你的 AI 也要写这份代码。 这个系列的前提是任何人都可以写 agent,因为 AI 会替你写。 AI 见过的主流框架代码,远多于你自造的循环。让它在 LangGraph 上改,比让它在你的私有 结构上改稳得多。你自己看得懂的代码,和 AI 改得对的代码,是两个不同的标准。
上册练到的每一样,在 LangGraph 里都能找到对应的机制。这张表是这个系列的主线, 后面每一期都会回来指一次。
| 上册练习 | 你亲手写的 | LangGraph 里的 |
|---|---|---|
| 练习 3、5 | messages 数组加 for 循环 | StateGraph,节点和边 |
| 练习 5、6 | 工具注册表,模型选工具 | ToolNode,条件边 |
| 练习 9、10 | 权限闸门,删除前停下来问 | interrupt,Command(resume) |
| 练习 11 到 13 | 会话文件,上下文压缩 | checkpointer,thread_id |
| 练习 15 | MEMORY.md 跨会话记忆 | Store |
| 练习 19 到 21 | subagent,并行扇出 | 子图,Send |
| 练习 24 | 常驻对话界面 | 流式接口,外面包一层 FastAPI |
为什么是 LangGraph
市面上的 agent 框架不止这一个。选它,三个理由,一个代价。
它的核心概念是图。 很多框架的核心概念是 agent 对象:你定义几个角色, 框架替你跑循环。LangGraph 的核心概念是状态图:节点、边、共享状态。agent 循环只是其中的 一种图。这意味着第二档的预定义流程也能用它,条件分支就是条件边,人工确认就是一次中断。 四问清单里落在“流程加条件分支“那一档的需求,正是它最省事的地方。
顺带说清楚同一家的 deepagents。 LangChain 官方还有一个包叫 deepagents,一行
create_deep_agent() 给你一个带 skill、子 agent、文件系统、人工审批的完整 agent,底下也是
一张 LangGraph 图,只是画法固定:模型和工具来回一个循环,每一步走哪由模型决定。两者的取舍
很直接。deepagents 的优势是开发快:标配都齐了,写一段提示词、给几个工具就能跑。LangGraph
本体的优势是确定性和成本:流程里哪一步调模型、哪一步跑代码由你定,能用代码定的步骤就不花
模型的钱、不等模型的时间、结果也不会变。四问清单落在第二档的需求,这个差别最明显;落在
第三档、要的正好是那几样标配的,deepagents 更省事。
上线要的机制它自带。 checkpointer、interrupt、Store 都是图运行时自带的, 用不着另装插件。断点续跑和人工确认是同一个机制的两面:图在某个节点停下,状态落盘, 之后从那里继续。
它是目前最主流的一个。 这一条听起来功利,但对“让 AI 替你写“这个前提来说最要紧。
代价也要讲清楚。状态图这套抽象有学习成本,一个三步的流程写成图会显得啰嗦。版本变得快, 这个系列锁定的版本半年后可能就有新写法。出问题的时候要读框架源码,上册存在的意义 就是让你读得懂那份源码。
还有一条这一期就要说清楚。LangGraph 本身是 MIT 许可,但它官方的部署服务器不是。 那个服务器叫 Agent Server,自托管跑生产要企业授权。这个系列第 12 到 14 期教你用 FastAPI 自己包一层,就是因为这条路上没有许可证。
跑起来
后面十四期共用一个环境,现在把它装好。需要 Python 3.11 以上和 uv。
git clone https://github.com/Leihb/langgraph-in-action
cd langgraph-in-action/code
uv sync
cp .env.example .env
.env 里三个变量:模型端点、密钥、模型名。任何兼容 OpenAI 协议的端点都行。
填好之后跑自检:
uv run python -m common.check
你应该看到什么
端点没配对的时候,它会告诉你版本对了、连接失败:
python 3.13.3
langgraph 1.2.11 ok
langchain 1.3.18 ok
endpoint http://localhost:4477/v1
model chat-default
langfuse off (未配置,不上报)
model call failed: OpenAIConnectionError: Connection error.
端点配对了,最后一行变成模型的回复:
endpoint https://api.deepseek.com/v1
model deepseek-v4-flash
langfuse off (未配置,不上报)
model call ok -> '收到'
看到这一行,环境就通了。Langfuse 那行是 off 没关系,第 11 期才配。
常见问题
没读过上册,能直接看这一册吗? 能。正文里每处指回上册练习的地方,都会顺带交代 那个练习解决的是什么问题,跳过“上册练习 X“这半句话不影响理解。想搞懂 LangGraph 的 某个机制底层在做什么,上册对应的练习是最直接的路径——不必现在补,用到的时候再回去看也来得及。
上册不是说不用框架吗? 上册说的是先不用框架,把每一层亲手写一遍才看得懂。看懂之后, 用框架是为了少写那二十几章,把力气花在场景上。这不代表你必须先做完那三十二个练习才能翻开 这一册——只是如果你两本都读,会更清楚框架替你省掉的到底是什么。
我的需求落在第二档,还要往下看吗? 要。LangGraph 的图天生就是预定义流程, 条件边就是你的分支。第 2、3、5 期讲的内容第二档全用得上,第 10 期的子图和 agent 循环 才是第三档专属。
小项目也要这一套吗? 一个 prompt 就能解决的需求,一个 prompt 就够了,别装任何框架。 第二档起步再考虑。
为什么不是 CrewAI、AutoGen 或者 OpenAI 的 Agents SDK? 它们的核心抽象是 agent 对象和角色,适合“几个 agent 商量着干活“这类场景。企业里大多数需求拆开来是一条有分支的 流程,加一两个需要模型拿主意的节点,用图描述比用角色贴切。它们不差,只是优化的方向不一样。
加分练习
- 拿你手上正在立项的那个需求,四问走一遍,写下落在哪一档。写下来,别只在脑子里过。
- 把上册练习 31 的代码打开,列出里面每一个独立的机制。对照上面那张表,猜一猜哪些在 LangGraph 里有对应的机制、哪些没有。答案就在上面那张表里,表外的那几样后面各期会一一碰到。
- 找一个你见过的“做成了 agent 的需求“,用第一问和第二问重新判一次。