Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 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、5messages 数组加 for 循环StateGraph,节点和边
练习 5、6工具注册表,模型选工具ToolNode,条件边
练习 9、10权限闸门,删除前停下来问interrupt,Command(resume)
练习 11 到 13会话文件,上下文压缩checkpointer,thread_id
练习 15MEMORY.md 跨会话记忆Store
练习 19 到 21subagent,并行扇出子图,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 商量着干活“这类场景。企业里大多数需求拆开来是一条有分支的 流程,加一两个需要模型拿主意的节点,用图描述比用角色贴切。它们不差,只是优化的方向不一样。

加分练习

  1. 拿你手上正在立项的那个需求,四问走一遍,写下落在哪一档。写下来,别只在脑子里过。
  2. 把上册练习 31 的代码打开,列出里面每一个独立的机制。对照上面那张表,猜一猜哪些在 LangGraph 里有对应的机制、哪些没有。答案就在上面那张表里,表外的那几样后面各期会一一碰到。
  3. 找一个你见过的“做成了 agent 的需求“,用第一问和第二问重新判一次。