写在前面
如果有人问你「2026 年最该学的一门工程技能是什么」,Agent 开发大概率会出现在答案里。大模型已经足够会聊天,但真正改变产品形态的,是它开始「会做事」——能自己拆解任务、调用工具、检查结果、在失败后重来。从写代码、查资料到操作浏览器、编排多步流程,几乎每个方向都能看到 Agent 的身影。
这本书想解决的,正是从「会调一次模型」到「能交付一台可靠引擎」之间那段距离。它不试图成为某框架的用法手册,也不试图穷尽所有 Agent 架构。它想做的事更朴素:带你从「这是什么」一路走到「我在真实项目里能放心地用它做决定」。而这篇文章,是这趟旅程开始前的一段闲聊——聊聊这个转折意味着什么,为什么它比看起来更难,以及你该从哪里进入。
从「会聊天」到「会做事」
要理解 Agent 为什么值得专门学,先看清它和「聊天」差在哪里。一段对话里,模型只需要输出文字;而一个 Agent,要在输出之后真的去做点什么,再把做的结果拿回来继续判断。这一字之差,把工程复杂度抬高了一个量级。
| 维度 | 会聊天 | 会做事 |
|---|---|---|
| 输出 | 一段文本 | 一段文本 + 一组动作 |
| 状态 | 基本无状态,一问一答 | 多轮累积,历史决定下一步 |
| 失败 | 答得不好,重问即可 | 动作可能已经产生了真实副作用 |
| 成本 | 一次调用 | 一轮可能调用几十次 |
| 验证 | 读起来对不对 | 结果对不对、过程能不能复现 |
转折点在于动作。一旦模型开始调用工具,它就不再只是一个「生成器」,而是一个「执行器」——它要决定调哪个工具、传什么参数、拿到结果后怎么办。而真实世界里的动作往往不可逆:发出去的邮件收不回来,下出去的订单撤不干净。这就把「生成质量」问题,变成了「系统工程」问题。
为什么是现在
如果 Agent 这个概念并不新,为什么偏偏是现在值得专门学?因为它背后的三块拼图,最近才真正凑齐。
| 能力 | 过去 | 现在 | 对 Agent 意味着什么 |
|---|---|---|---|
| 工具调用 | 靠提示词「求」模型输出固定格式,再用正则抠 | 模型原生支持结构化工具调用 | 动作变得可靠,能接真实系统 |
| 上下文长度 | 几千 token,一长就忘 | 动辄十万级,长任务不丢线 | 多轮任务可以带着完整历史跑 |
| 推理成本 | 每轮都很贵,不敢多跑 | 单次成本持续下降 | 多轮循环在经济上变得可行 |
三块拼图里,最关键的是工具调用被原生化。以前要模型输出一段固定格式的文本、再靠字符串解析去抠,脆弱且难维护;现在模型直接吐出一个结构化的工具调用,你的代码负责执行、再把结果塞回消息。这条闭环一旦稳定,Agent 才从「实验」变成「工程」。
这解释了一个常见困惑:为什么网上很多「Agent 教程」看起来差不多,做出来的东西却差别很大。差别往往不在提示词写得多漂亮,而在工具调用闭环与循环控制这两件事做得扎不扎实——而这正是本书花最多篇幅的地方。
Agent 工程的四个真实难点
很多人第一次写 Agent,都停在「能跑通一个 demo」这一步:给模型接两个工具,让它转几圈,看着挺像那么回事。但从 demo 到能用,中间隔着四道坎。它们不是理论问题,而是你一定会撞上的工程问题。
| 难点 | 具体表现 | 本卷对应章节 |
|---|---|---|
| 可靠性 | 同一个输入,有时对有时错;循环停不下来或提前停 | 第 3、5、14 章 |
| 可观测 | 出了问题不知道它哪一步想错了、调了什么 | 第 7、15 章 |
| 成本 | 一轮任务调用几十次,token 与延迟悄悄失控 | 第 2、15 章 |
| 安全 | 参数被注入、越权调工具、副作用不可回滚 | 第 4、14 章 |
可靠性是第一个拦路虎。大模型本质上是概率系统,同样的输入可能给出不同的下一步;再加一个循环,不确定性会层层放大。你会发现 Agent 有时聪明得惊人,有时又在一个简单任务上绕圈——而这两种表现可能来自同一段代码。卷一的第 3 章先把循环写对、把停止条件立稳,第 5 章再讲几种让「想—做—看」更可控的推理模式。
可观测是第二个。传统程序出错,你有堆栈;Agent 出错,你只有一段对话历史,还说不清它是在哪一轮、基于什么信息做错了决定。没有可观测性,你连「它变好了还是变坏了」都判断不了。第 7 章把运行过程流成事件,第 15 章再把事件组织成可追踪、可核算的结构。
成本是第三个,也最容易被忽视。一次任务可能触发几十次模型调用,每次都消耗 token;如果不做预算与核算,账单会以一种「不知不觉」的方式涨上去。第 2 章讲 token 预算与截断,第 15 章讲用量与成本核算,都是为了把这件事变成可见、可控的数字。
安全是第四个,也是最危险的。当模型能真的调工具,它调错一个参数就可能造成真实损失;而工具入参里混入的恶意内容,可能诱导它做出越权操作。第 4 章的参数校验与执行隔离、第 14 章的幂等与副作用处理,是这一卷给出的最小防线。
这四个难点,构成了「会写 demo」和「能交付」之间那条真实的鸿沟。这本书的每一部分,几乎都能对应到其中某一两个。
一个真实的小对照
抽象地说「确定性很重要」很容易变成口号,不如看一个具体到不能再具体的例子。假设你想测「Agent 在拿到工具结果后会不会正确收尾」,最直觉的写法是直接调真实模型:
# 需要密钥、需要联网、每次结果都可能不同
resp = client.messages.create(model="claude-...", messages=history)
assert resp.stop_reason == "end_turn"
这段代码能跑,但它埋了几个坑:它依赖密钥与网络;同一个断言今天过、明天可能不过;而且它测的其实是「模型」,不是「你的循环逻辑」——模型换一版,你的测试就全废了。用假模型写同一个断言,是这样:
from dataclasses import dataclass, field
@dataclass
class Message:
role: str
content: str = ""
@dataclass
class ModelResponse:
message: Message
stop_reason: str = "end_turn"
usage: dict = field(default_factory=dict)
class FakeModel:
def __init__(self, script):
self.script = list(script)
self.calls = []
def complete(self, messages, tools=None):
self.calls.append((list(messages), list(tools or [])))
return self.script.pop(0)
m = FakeModel([
ModelResponse(Message("assistant", "我先查一下。"), stop_reason="tool_use"),
ModelResponse(Message("assistant", "查完了,答案是 42。"), stop_reason="end_turn"),
])
first = m.complete([Message("user", "帮我算一下")])
second = m.complete([Message("user", "帮我算一下"), first.message])
print(first.stop_reason, "->", second.message.content)
print("模型被调用了", len(m.calls), "次")
tool_use -> 查完了,答案是 42。
模型被调用了 2 次
差别不在于「谁更短」,而在于后者把一件事显式化了:测试的对象是「你的循环」,而不是「模型今天的心情」。假模型的行为完全由脚本决定,跑一百遍结果都一样;它还能记录每次调用的入参,让你断言「循环到底把什么喂给了模型」。这些正是本书要反复训练的东西——不是记住某个写法,而是知道一个写法在替你解决什么问题。
为什么不直接用框架
既然已经有成熟的 Agent 框架,为什么还要从零手写一遍?这是最常被问、也最值得认真回答的问题。
框架当然有用,而且用得好能省很多事。但它们有一个共同的特点:它们替你做了一堆决定,却没有告诉你为什么这么做。 一个 AgentExecutor 帮你管理循环、重试、工具调用,你确实少写了代码,但当它行为不符合预期时,你往往只能靠读文档、翻源码去猜。
这本书的立场是:先用二十行代码把循环写出来,再去理解框架替你省掉了哪二十行。 手写过一遍之后,你再看框架的 API,就能一眼看出它每个参数在控制什么、每个抽象在解决什么问题——这时候用框架,才是真的在用,而不是在被框架牵着走。
还有一个更现实的原因:框架会变,原理不会变。 今天流行的编排库,明年可能被另一种范式取代;但「消息协议、工具注册、循环停止条件、上下文预算」这些东西,换个语言、换个框架依然成立。卷一教的正是这些不变的部分。
需要说清楚的是,本书不反对用框架,只是把框架用法放到了卷三。卷一坚持不依赖任何 Agent 框架,是为了让你先把地基打牢。
为什么是「从零手写 + 假模型」
前面说了「从零手写」,再说「假模型」。这两件事是配套的,缺一不可。
从零手写给你的是「理解」。你能亲手定义 Message 长什么样、工具怎么注册、循环什么时候停。这些决定一旦由你做出,Agent 对你就不再是黑箱。
假模型给你的是「可复现」。Agent 最大的麻烦是不确定性,而假模型恰好把它消掉了:它的输出完全由脚本决定,不需要网络、不需要密钥、跑一万遍结果都一样。这意味着你可以像测普通函数一样测一个 Agent——给定一段脚本,断言它调了几轮、每轮发了什么、最后停在哪儿。
把这两件事合起来,你就得到了一台行为确定、结构透明、可以随时拆开看的引擎。这就是 minagent——本书全卷围绕它推进,从一个二十行的循环,长成涵盖消息、工具、记忆、编排、评测、服务的完整模块。
真实模型当然也要用,但用法不一样:本书把真实 API 放在全卷末尾第 18.2 节,作为可选的一次冒烟验证,并且需要你自己决定是否消耗额度。日常开发与测试,假模型是默认路径。
Agent 时代还需要系统学吗
这是当下绕不开的问题:既然框架和 AI 助手已经能替你写出一大段 Agent 代码,还有必要花几周时间从零手写一遍吗?
答案是:工具让「写出能跑的 Agent」变便宜了,但没有让「判断它可不可靠」变便宜。
一个 Agent 写出来能跑,和它能交付,是两件事。前者靠生成,后者靠判断——判断它为什么停不下来、判断某个工具该不该有副作用、判断这次改动到底有没有让效果变好。这些判断需要你理解引擎内部是怎么转的,而这正是从零手写能给你的东西。
换个角度看,框架与 AI 助手恰恰提高了系统知识的回报率。它们最擅长的场景,是在一个结构清晰、契约稳定、测试完备的代码库里补全实现;而在一个循环写错、状态混乱、没有测试的项目里,它们给出的建议同样混乱。你越懂 Agent 引擎,工具就越有用。
所以本书不会因为有了框架就降低对原理的要求。恰恰相反,正因为生成代码变得廉价,「知道什么是对的」才变得更值钱。
与站内 AI 专题的分工
本站已经积累了约 250 篇 AI 主题文章,覆盖了提示工程、检索增强、模型评测、MCP、LLMOps 等方向,其中与 Agent 直接相关的至少 25 篇。它们质量不低,但有一个共同的特点:每一篇都假设你已经理解 Agent 是什么,然后带你在某个单点上钻深。
这恰恰是它们对初学者不够友好的地方。一个连「循环为什么停」都还没想清的人,去读一篇讲多 Agent 拓扑对比的文章,收获会很有限——不是因为文章写得不好,而是因为缺了前置的那一层。这些专题文章串起来,像是一排深井,每口井都很深,但井与井之间没有路。
这本书要补的就是这条路:一条从零到能交付的递进路径。它从「消息协议是什么」开始,经过模型接口、工具调用、推理模式、记忆与检索、编排与协作,一路走到可观测、评测与服务化,最后用一个完整项目收尾。读完它,你再去读那些专题文章,才能真正读出味道来。两者是互补关系:本书负责「按顺序搭起一台引擎」,专题负责「就一个问题钻到底」。
本书的三个刻意取舍
在动笔之前,我为这本书定了三条规矩。它们决定了每一节的样貌,也决定了这本书不适合谁。
| 取舍 | 具体含义 | 为什么这样选 |
|---|---|---|
| 引擎优先,而非 API 清单 | 每节都围绕 minagent 的推进,概念服务于可运行代码 | 纯概念罗列学不会 Agent,只能背下来 |
| 假模型优先,而非真实调用 | 默认路径零凭据、零联网,输出确定可断言 | 不能复现的行为,就无法被验证与改进 |
| 广度优先,够用即止 | 并发深度、生产化加固、框架用法都留给后续卷 | 入门卷的价值是走通一条完整的路 |
第一,讲「引擎怎么转」,而不只是「怎么调」。 比如讲到工具调用,重点不是背下某个框架的注册语法,而是理解「模型输出一段结构化参数、你的代码负责执行并把结果塞回消息」这个闭环。理解了闭环,换个框架你也能立刻上手。
第二,示例必须可复现。 书里出现的每一段代码,都保持为可以复制进编辑器、稍作调整就能运行的最小完整片段,且默认在假模型下运行。凡涉及真实 API 的地方,都会明确标注「可选」,并说明它需要什么前提。
第三,不回避难点,但也不炫技。 可靠性、可观测、成本、安全这四个难点都会认真讲,但反复提醒「能简单就别复杂」:能用一个循环解决的,就不要上多 Agent。能把复杂的东西讲得浅显,比能写出别人看不懂的架构更值得尊敬。
这本书不适合谁
一份诚实的取舍,也应该说清它不服务谁。如果你属于下面几类,这本书可能不是最合适的选择:
- 想找一本某框架的速查手册:本书从零手写,不教任何框架的 API。你需要的是官方文档,不是这本书。
- 想直接上生产、跳过原理:卷一刻意把生产化加固留给了卷二。想一步到位的人,会觉得它「进度太慢」。
- 只想读、不想写:全书默认你动手敲代码。只读不写,Agent 的知识很难真正落进手里。
- 期待确定性答案:Agent 是概率系统的外延,本书教的是「怎么把不确定性关进可控的盒子里」,而不是「怎么消除它」。
如果你读完上面几条反而更想继续,那说明这本书正是为你准备的。
一份最小的心智模型
如果要在开始前,用几句话概括 Agent 的世界观,可以是这样:
- Agent = 循环 + 模型 + 工具:循环负责推进,模型负责决策,工具负责做事,三者缺一不可。
- 一切不确定性都来自模型:把模型抽象成可替换的接口,把假模型当作默认后端,你就能把不确定性关进一个可控的盒子里。
- 上下文就是预算:喂给模型的每一个 token 都要花成本,学会裁剪与摘要,比学会写更长的提示更重要。
- 动作要能被撤销或重试:有副作用的工具必须显式对待,否则重试会制造灾难。
- 能被断言的行为才是工程:写不出确定性测试的 Agent,只能靠感觉判断好坏。
这五条会在全书反复出现。你不需要现在就完全理解它们,但记住这几句话,读后面的章节时会更有方向感。
给不同起点的读者
不同背景的人读这本书,路径应该是不一样的。
如果你有 Python 基础但没写过 Agent,这本书就是为你写的。请按顺序读,不要跳章。第 1 章先让你理解消息协议与假模型,第 2、3 章把模型接口与循环立稳,第 4 章之后才进入工具、推理与记忆。每一节的示例都请亲手敲一遍——对第一次写 Agent 的人来说,「跑通」比「读懂」重要得多。
如果你已经用过某个 Agent 框架,你可以读得很快,但要特别留意三处框架替你隐藏了的地方:循环的停止条件(第 3 章)、工具结果的合并方式(第 4 章)、上下文是怎么被裁剪的(第 6 章)。这三处想通了,你就能反过来理解框架的行为;想不通,则会一直觉得 Agent「有点玄学」。
如果你关注的是生产化,第 14–16 章(错误、可观测、评测)与第 17 章(服务化)信息密度最高。但请先读第 1–3 章把契约立稳——后面所有的工程化都建立在那套核心类型之上。
一个反复出现的提醒:能跑不等于可靠
在正式进入正题之前,有一个观念必须提前建立:Agent 能跑出结果,不等于结果可靠。
看一个具体现象:同一段代码,同一个输入,今天它顺利收尾,明天它可能在同一个工具上反复调用直到撞上步数上限。区别可能只在于模型这一轮「心情」不同。这类问题不会在启动时报错,它只是安静地在某些运行里给出错误的结果,直到某次上线才暴露。
正确的定位应该是:「能跑通」只是最低门槛,可靠性需要靠确定性测试(第 16 章)、停止条件(第 3 章)与错误处理(第 14 章)共同保证。 带着这个定位去读后面的章节,你会更容易理解为什么本书既要讲怎么把循环写出来,也要讲怎么把它测出来、看住它、算清它的成本。
读完之后,你应当具备什么能力
读完这 18 章,我希望你收获的不是「记住了多少 API」,而是几项可以迁移到任何 Agent 项目里的能力:
- 面对一个需求,能先想清楚需要哪些工具、上下文里该放什么,再动手写,而不是先堆一个循环再看;
- 看到一个 Agent 行为异常,能读懂它哪一步想错了,并知道该去查哪一节;
- 能写出一台有抽象、有测试、能被服务化的 Agent 引擎,而不只是「在我机器上能跑」;
- 能解释「为什么这个循环停不下来」「为什么重试会下两次单」这类问题;
- 需要时,能读懂一个 Agent 框架的源码,并保持自己跟进新范式的能力。
这几项能力有一个共同点:它们都不依赖某个具体的模型或框架,而是关于「Agent 引擎怎么转」的通用理解。模型会换代,框架会重写,但这套理解会让你在下一个范式到来时,依然能快速上手。
Agent 终究是工具,不是魔法。它服务于「让想法变成可以运行、可以验证的软件」这个朴素目标。如果这本书能让你在写每一行循环时,心里都清楚它在做什么,那它的任务就完成了。
那么,我们开始吧。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。