Agent 开发·从心智模型到造出 Claude Code
墨叔开场:老哥,先别急着问”怎么用 LangChain""怎么接个 SDK”。咱们先把一件事说清楚——你不是不会做 agent,你是被一个错误的画面困住了。
你脑子里大概是这样的:大模型那么聪明,我把它塞进程序里,调个接口,它就能自己干活了吧?然后你一试,发现它胡说、它乱调工具、它干到一半忘了要干嘛。你于是得出结论:这东西”没法逻辑”。
今天墨叔要把这盆冷水泼准地方。LLM(大语言模型)从来就不负责”逻辑”——逻辑是你写的那个循环(loop)的责任。模型本身只负责一件事:在给定一段文字时,预测”接下来最合理的那段文字”是什么。把这两件事搞混,是一切 agent 焦虑的根源。
这本教程要干的事,就是帮你把”循环”这层补全,再把 Claude Code、Codex 这些你已经用得挺爽的工具,拆开看看里面到底转着几个齿轮。等你看懂了齿轮,自己造一个就不是”能不能”的问题,而是”想造多大”的问题。
你不是不会,是缺了”循环”这层心智模型
老哥,我问你一个有点刁钻的问题:你觉得一段 Go 代码”有逻辑”,逻辑到底藏在哪?
你说:藏在 if、for、func 里啊,藏在我把输入变成输出的那条控制流里。好,那我再问:如果我把这段逻辑里的所有”判断”都删掉,只留一个黑盒函数 f(input) -> output,而且这个黑盒每次返回的结果不完全一样,但大体上都”说得通”——你还会说它有逻辑吗?
你大概会说:那不就是个没谱的预言机吗?逻辑早没了。
没错。而这就是很多人第一次接触大模型写程序时的错觉来源。他们以为自己拿到了一个”聪明的函数”,塞进去需求,吐出来答案。可这个函数有两个让他们崩溃的特性:它没有内部状态(每次调用都是一张白纸),它的输出是概率性的(同样的问题问两遍,答案可能不一样)。
那为什么 Claude Code 这种东西看起来”很有逻辑”?因为它外面套了一个循环。这个循环干的事,本质上和你写的 for 循环一模一样:观察现状 → 决定下一步 → 执行 → 再看现状 → 再决定……只不过”决定下一步”这一步,不是你写死的 if err != nil,而是交给模型去”猜”一个最可能对的动作。
我给你一个能立刻记住的比喻。
想象一个从没去过厨房的顶级大厨,被蒙着眼睛绑在椅子上,只能通过纸条和外界交流。你(循环)每次递给他一张纸条,写上”现在锅里的状态是 XXX,你上次做了 YYY,下一步你建议做什么?“他回你一张纸条:“建议把火关小,并且把盐递过来。“你(循环)照做,然后更新状态,再递下一张纸条。
这个大厨本人不进厨房、不摸锅、不记事儿——他每次都从零读你给他的纸条。但他之所以能”做菜”,全靠你这个递纸条的人把上下文喂全、把他的建议落到实处、再把结果读回来。
Agent = 大厨(模型)+ 递纸条的人(你的代码循环)。
所以,老哥,你之前觉得”LLM 没法逻辑”,其实你只看到了大厨,没看到那个递纸条的循环——而逻辑,恰恰在那个循环里。这不是你能力的问题,是没人把这张图给你画全。
【思考题】
- 你过去写过的程序里,有哪些”逻辑”其实也依赖于一个看不见的循环?举一个你最熟悉的例子(比如一个 HTTP 服务是怎么一圈圈转起来的)。
- 如果模型每次输出都不确定,那”agent 的确定性”到底从哪来?是模型给的,还是循环给的?
- 蒙眼大厨的比喻里,哪一部分最脆弱?如果递纸条的人偷懒、少写了”锅里的状态”,会发生什么?
【参考答案】
- 最典型的就是你的 HTTP 服务本身:它跑在一个
for { conn := listener.Accept(); go handle(conn) }的接受循环里,每一个请求都是”观察连接 → 解析 → 路由 → 执行 handler → 写回响应”的小循环。你早就懂”逻辑在循环里”——只是没意识到 agent 只是把”下一步做什么”从写死的路由表,换成了一个会”读上下文猜动作”的模型。你不是新手,你是换了个循环体。 - 确定性主要来自循环的结构,而不是模型。循环决定了:何时调用模型、把什么上下文喂给它、拿到输出后如何校验和落地、出错如何兜底。模型只提供”建议”,而”是否采纳、如何执行、失败怎么办”全是循环硬编码的纪律。换句话说,agent 的可靠性上限由循环设计决定,模型的随机性被循环的约束(重试、校验、回滚)给”框”住了。
- 最脆弱的是”上下文的准确性与完整性”。递纸条的人如果少写了关键状态(比如没告诉大厨”刚才盐已经加过了”),大厨就会基于错误的前提给建议,导致重复加盐或漏步骤。这对应 agent 里最常见的 bug:上下文窗口里丢了关键信息,或者工具返回的结果没被正确读回循环。这也预告了后面”记忆”和”上下文工程”两章——它们解决的就是”纸条怎么写才不出错”。
小结:agent 不是更聪明的函数,而是”模型 + 循环”的组合。你焦虑的”逻辑缺失”,其实只看到了模型那一半;补全循环这层心智模型,后面所有机制才有落脚点。
LLM 是函数还是人?把概率模型想清楚
老哥,这一节我们要把”模型到底是什么”这层底裤扒下来看清楚。因为只要你对模型的本质有一丝模糊,写 agent 时就会反复踩同一个坑:你以为它在”思考”,其实它只在”续写”。
先给一个冷冰冰的定义:大语言模型是一个参数为千亿量级的、做”下一个 token 预测”的神经网络。你输入一串 token(文字被切成的小块),它输出下一个 token 的概率分布,采样出一个,拼回去,再预测下一个,如此往复,直到它觉得该停了。
注意这三个字:预测下一个。它不”理解”你的问题,不”记得”上一轮对话(除非你把上一轮塞回输入),更不”规划”——它只是在每一个时刻,根据当前这整段文字,算出”接下来最可能接着写什么”。
这就是为什么你问它”1+1 等于几”,它答得飞快且正确——因为”1+1=2”在训练语料里出现的频率高到离谱,续写出来就是 2。但你让它算”7391 乘以 8824”,它常常算错——因为精确的多位数乘法在语料里不够多,它凭”数字长什么样”的模糊模式去续写,而不是真的在算。
你现在应该品出味儿来了:模型擅长的是”像”,不是”对”。它给出的是”人类在类似语境下最可能说出的话”,而不是”经过逻辑推导的必然结论”。
这和”人”差在哪?人做算术是执行算法;模型做算术是回忆/模仿一个像算术的过程。这俩在简单题上重合,在复杂题上分家。一个 Go 后端最容易栽的地方就在这:你本能地以为”它聪明 = 它靠谱 = 它能算对”,于是把本该由代码保证正确性的事,轻率地交给了模型。
那”它像人”的部分又该怎么用?关键在于:把模型当成一个”语言能力极强的、但会一本正经胡说八道的实习生”。实习生好处是,你给他一段背景、一个任务、几个例子,他能写得很像样;坏处是,他不知道公司数据库不能乱删,也不知道自己其实算不对乘法,你得在流程里给他加护栏。
我再用一个比喻收一下。模型像个口才极好的即兴演讲者,你递给他一张写满上下文的提词卡,他能用流畅的话接下去。但他不会因为你希望他”算对”就真的去算——他只会把”算对时人们会怎么说”演出来。所以凡是需要”必然正确”的,请放代码里;凡是需要”语言流畅、能凑出方案、能读得懂人话”的,交给模型。
【思考题】
- 既然模型只是”续写”,那为什么它能写出看起来很有逻辑的长篇论证?是它真的在推理,还是别的原因?
- 你作为一个后端,日常有哪些任务其实属于”需要必然正确”(必须放代码),有哪些属于”语言流畅即可”(可以交给模型)?各举两个。
- “像”和”对”的分家,对你设计 agent 的工具边界有什么启示?
【参考答案】
- 长篇论证”看起来有逻辑”,主要来自两方面:一是训练语料里大量逻辑性文本让它学会了”逻辑话语的表面结构”(先立论、再分点、再总结);二是你给它的上下文里往往已经隐含了推理链(比如你贴了一段代码,它顺着代码结构续写分析)。但它并没有在内部跑一个逻辑引擎去”验证”每一步——你把它中间任意一步改错,它大概率会顺着错往下圆,而不是指出矛盾。所以”看起来有逻辑”≠“经得起验证”。这也是为什么 agent 里要有”反思/校验”环节,而不是只靠一次生成。
- “必然正确”类:算账、判断权限、解析协议字段、事务性数据库写入、签名校验——这些错一点就出事故,必须代码硬编码。“语言流畅”类:把需求翻译成自然语言计划、给代码写注释和文档、把报错信息用人话解释给用户、生成多种方案供人挑选——这些”像”就够了,人来做最终判断。设计 agent 时,凡是落在第一类的动作,都要做成确定性工具由代码执行,模型只负责”决定调用哪个工具、传什么参数”。
- 核心启示:工具的边界要划在”必然正确”和”语言流畅”的交界处。让模型做”决定”和”表达”,让代码做”执行”和”保证”。比如”删除文件”这种需要必然正确的危险动作,绝不让模型直接
os.remove,而是封装成一个带确认、带白名单、带日志的工具,模型只能”请求删除”,循环来执行并兜底。模型负责说”我想删这个”,代码负责”在规则内安全地删”。
小结:模型是”下一个 token 预测器”,擅长”像”而非”对”。把它当成一个口才好但会胡说、算不对的实习生——你写循环和工具来补足它的”必然正确”,它负责语言和方案的流畅度。
这本教程怎么读:一张地图与一种学习方法
老哥,前面两节把最底层的那张图给你画了:agent = 模型(大厨)+ 循环(递纸条的人)。接下来这本教程,我会一层层把”递纸条的人”到底该怎么设计,以及 Claude Code 们为什么丝滑,全拆给你看。
我先给你一张地图,你心里有数,读的时候才不会迷路。
整本分九条线(Part),大致是从”内”到”外”、从”理论”到”真实工具”:
- Part 1 心智模型:把 ReAct、Agent Loop、上下文窗口、概率程序的可信度讲透——这是地基。
- Part 2 工具机制:怎么给模型一只”手”(Function Calling),schema 怎么设计,失败怎么兜,副作用怎么管。
- Part 3 规划与分解:模型”想一步走一步”的缺陷,Plan-and-Execute,反思自修正。
- Part 4 记忆:短期(上下文)和长期(外部存储),RAG 什么时候该用、什么时候是毒药。
- Part 5 工程化:状态可恢复、流式输出为什么丝滑、成本延迟限流、可观测性、安全护栏。
- Part 6 架构剖析:直接拆 Claude Code / Codex 真实长什么样,它们的系统提示词藏了什么。
- Part 7 多智能体:什么时候需要一个以上的 agent,Orchestrator-Worker,主流框架取舍。
- Part 8 迷你 Claude Code 蓝图:如果你要自己造一个,该怎么分层设计(蓝图,不写可运行代码)。
- Part 9 进阶与避坑:怎么评测 agent、常见反模式、未来图景。
我建议你别跳着读。前面心智模型和工具机制是后面所有章节的词汇表,跳了就会处处卡。
再说一种学习方法,这是我带新人最管用的一招:每读完一个机制,先逼自己回答章末的思考练习,再去看对应的参考答案。参考答案是当学习材料看的,不是测验——但你必须先自己想,答案才有意义。一个机制你”看懂了”和”能反过来讲给另一个人听”,中间差着十万八千里,而思考题就是逼你跨那道沟。
还有一条:这本教程里所有 Python 片段都是示意,不是让你抄去跑的。它们的唯一作用是把”这个机制在代码里长什么样”钉死,免得你停留在比喻层面。真要动手,等你读完 Part 8 的蓝图,你自然知道该补哪些工程细节。
最后,老哥,我得跟你交个底:agent 这个领域变化极快,今天最丝滑的工具,半年后可能被新的范式取代。所以这本教程不教你某个 SDK 的写法(那会过期),而是教你那套十年不过时的心智模型和系统设计取舍。SDK 会变,但”循环为什么这么转""工具边界划在哪""上下文怎么管理”这些,是底层逻辑。抓住这些,你换任何框架都只是换个螺丝刀。
【思考题】
- 用你自己的话,画一张”agent = 模型 + 循环”的图(不用画图软件,用文字描述也行),并标出哪部分最容易出 bug。
- 你打算先拿 agent 解决自己工作里的哪个具体问题?这个问题属于”必然正确”还是”语言流畅”为主?
- 既然教程不教具体 SDK,你担心”学完还是不会写”吗?墨叔的这个取舍,你怎么看?
【参考答案】
- 一张极简文字图:
[用户目标] →(写进纸条)→ [循环: 拼上下文] → [模型: 预测下一步动作] → [循环: 校验动作] → [工具: 代码执行] → [结果读回纸条] → 回到循环,直到目标达成。最容易出 bug 的是两个接口处:一是”拼上下文”——漏写关键状态,模型就瞎指挥;二是”校验动作”——没拦住危险或非法调用,工具就真把事搞砸了。这俩对应后面的”上下文工程”和”安全护栏”,是工程里最该下功夫的地方。 - 这个问题只有你知道答案,但墨叔给你个判断尺:如果你脑子里第一个冒出来的问题是”帮我把这段代码写个单元测试”或”帮我把这段报错解释一下”,那属于”语言流畅为主”,最适合拿 agent 试水,风险低、收益直观。如果是”帮我把生产库里的脏数据修掉”,那属于”必然正确为主”,初期别让 agent 直接动,先做只读分析。
- 你的担心很正常,但墨叔坚持这个取舍是有原因的:SDK 层面的”会写”保质期太短,而心智模型是”会造”的前提。等你理解了循环、工具、记忆、上下文这些齿轮,任何一个框架(LangGraph、自研、甚至未来的新东西)你都能在一周内上手,因为你读得懂它的设计意图,而不是只会调它的 API。学”怎么造轮子”的人,永远比学”怎么用别人轮子”的人值钱——这和你当年从”会用 Go 标准库”走到”能写自己的中间件”是同一回事。
小结:地图给了你,方法也给了你——按顺序读、先想再看答案、把代码当锚点不当圣经。接下来从 Part 1 的心智模型开始,咱们一层层把”递纸条的人”拆明白。