Notes · 2025.12.20
LangGraph 第一次跑通
智能体链路。
技能栏写了 LangGraph、LangChain、AgentKit、RAG、Tool Calling。第一次把图跑通,高兴了半天。图在笔记本上转完,终端里打出一条路线,我以为产品成了。高兴完要看产物:哪个文件、什么 schema、哪一步写出来。命令能启动不等于链路通。我高兴的那半天,终端里只有打印。打印在滚动历史里,两天后自己也不认。认的是文件:路线写到哪、字段是什么、失败有没有位置。文件没有,图跑通只是表演。
跑通和图还在,不是一回事
跑通的意思经常只是:入口脚本没报错,模型回了一段字。图还在的意思是:节点之间的边在下一次输入时仍按我理解的那样走。第一次成功很容易是碰巧。碰巧的路径里,某个节点被跳过,某个工具没调用,输出却看起来完整。看起来完整最危险。
我把天气、住宿、景点、预算拆开,是智在旅途那套。拆开之后,每个节点都可以单独演示。单独演示都漂亮。收成一条路线时,字段对不上:预算节点要的是数,景点节点给的是一段话。图「跑通了」,产品没有。
LangChain 的链、LangGraph 的图、AgentKit 的装配,我会用。用的时候容易把教程里的例子留在项目里。例子的产物是打印。产品的产物是文件。打印在滚动的终端里,两天后自己也不认。
先定产物契约
我后来写智能体,先问三个问题。哪个文件是产物。里面什么字段。哪一步写出来。三个问题没有答案,就不让图变复杂。复杂图会制造过程感。过程感很像工作量。工作量没有产物,评委一问就空。
schema 不必大。有路线、有预算上限、有失败原因,就够演示。失败原因要占一个字段。模型失败时如果只抛异常,界面只能转圈。转圈在评委眼里是挂了。挂了和「这个节点今天不工作,走降级」是两件事。后者需要契约里先有位置。
RAG 和 Tool Calling 也一样。检索到了什么,工具到底有没有调用,要落盘或至少写进 trace。我口头说「它调用了天气工具」,不如给一条记录。记录可以很土,json 一行。没有这一行,调试只能靠再跑一遍碰运气。
拆开之后要收
智在旅途把天气、住宿、景点、预算拆开。拆开是为了各司其职,也是为了评委能看懂。拆开之后要收。收才是产品。收的时候断过。断过之后我才知道,编排节点比生成节点难写。生成节点有模型帮忙。编排节点要我对字段。
收的规则写在代码里,不要只写在提示词里。提示词会漂。字段名一漂,下游就静默空。静默空比报错坏,因为图还是绿的。绿的图我会以为第一次跑通可以复制到答辩。答辩复制的是绿,不是路线。
AgentKit 一类装配工具,适合把能跑的骨架接进来,再换我们的语义。从零发明一套平行抽象,我会写得很爽,接工具时全裂。第一次跑通如果建立在自己发明的抽象上,第二次接真实 API 往往要推翻。推翻的成本高于当时的爽。
命令能启动的假象
--help 能打印、uvicorn 起来了、图编译成功,都是入口活着。入口活着可以庆祝十秒。第十秒之后看一次真实输入走到产物文件。没有文件,就还没做完。做完的定义是链路:触发、工具、产物、失败路径。缺失败路径,也是没做完。
本机出网走 7890。智能体调外部工具时,新终端没代理,会表现为工具「不聪明」。不聪明的原因是网。网的问题和提示词的问题要分开。我分错过,改了一晚上提示词。
高兴可以,停在产物上
第一次跑通值得高兴。高兴写在这篇标题里。限制写在正文里:不编没出现的库名,不把教程仓库的数字当成我的结果,不把一次终端打印写成系统已上线。图还会挂。挂了怎么办,是下一篇。
第一次跑通之后,我最想加节点。节点一加,演示更好看,契约更容易丢。丢了的字段会在收路线时再断一次。断一次可以改。断在评委眼前,就是智在旅途已经崩过的那种湿手心。所以跑通的庆祝只停在产物文件出现的那一刻。文件没有,图再顺也只是终端表演。表演可以留给自己。答辩要文件。