如果你刚学 LangGraph,大概率会跟我一样有个错觉:
“AgentExecutor 用得好好的,为什么要换?”
然后真进了生产环境,立马被打脸。
想加个人工确认?加不了。想看中间调了几次工具?看不到。想改个重试逻辑?得重写整个黑盒。
我折腾完 LangGraph 全链路后,最大的体会就一条:AgentExecutor 是玩具,LangGraph 才是生产工具。
一、AgentExecutor 这个黑盒,我忍了很久
最开始我用LangChain里的 AgentExecutor 构建了能调工具、查知识、记历史的 Agent。看起来挺全能,但有个致命问题:
你看不到中间发生了什么。
有次用户说”删除项目数据”,Agent 直接调了 delete 工具。我想加个”删除前确认”,查了半天文档,发现 AgentExecutor 不支持。
LangGraph 怎么解决的?
一行interrupt_before=["tools"]搞定。在进入 tools 节点前暂停,等人工确认后再继续。
app=workflow.compile(checkpointer=MemorySaver(),interrupt_before=["tools"]# 就这行)这事的教训:黑盒用起来爽,出事了你连怎么死的都不知道。
二、State、Node、Edge,三要素我一开始也懵
教程说 LangGraph 就三个核心元素:
但我一开始理解错了。
我以为 State 就是个普通字典,随便定义。结果有次我定义了个messages字段,节点返回时直接覆盖了之前的消息,记忆全丢了。
后来才知道:
from langgraph.graph import MessagesStateclass State(MessagesState): # 继承这个 user_id: str session_data: dictMessagesState里的messages字段有特殊处理,节点返回新消息时会自动追加而不是覆盖。我自己定义的字段没这个待遇。
踩坑两小时,就为搞懂这个。
三、LangSmith 这个调试工具,不用真的瞎
LangGraph 提供内置的流程图生成功能:
with open('workflow.png', 'wb') as f: f.write(app.get_graph().draw_mermaid_png())但这只是静态架构图,看不到运行时状态。
真正有用的是 LangSmith。
注册个账号,配三个环境变量:
os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_PROJECT"] = "my_demo" os.environ["LANGCHAIN_API_KEY"] = langchain_api_key运行后,每次app.invoke()都会生成一条 Trace 记录。点进去能看到:
- 每一步的输入/输出
- LLM 的 prompt 和 token 消耗
- 工具调用的参数和返回
- 错误堆栈直接标红
有次我的 Agent 陷入无限循环,本地调试半天没头绪。打开 LangSmith 一看,should_continue函数永远返回”tools”,因为 tool_calls 判断逻辑写反了。
这工具省了我至少一半调试时间。建议从第一个 LangGraph 项目就启用,别等出问题了再补。
四、thread_id 和 session_id,这俩名字把我坑惨了
LangChain 里用session_id标识会话,LangGraph 里用thread_id。
我一开始没注意,代码里全写的session_id:
config = { "configurable": {"session_id": "user123"} # 错了!}跑起来记忆功能完全失效。查了半天文档才发现,LangGraph 必须用thread_id。
config = { "configurable": {"thread_id": "user123"} # 对了}这俩名字太像了,真的容易混。我的建议:LangGraph 代码里看到 session_id 就改成 thread_id,别犹豫。
五、系统提示词这么写,不然会污染历史
多轮对话里加系统提示词,我一开始是这么写的:
inputs = { "messages": [ SystemMessage(content=sys_prompt), HumanMessage(content=user_input) ]}结果每轮对话都重复插入 SystemMessage,历史记录越来越长,token 疯涨。
正确做法:
def call_model(state: MessagesState): # 仅在 LLM 调用时临时拼接,不写入状态 message_for_llm = [SystemMessage(content=sys_prompt)] + state["messages"] response = llm_with_tools.invoke(message_for_llm) return {"messages": [response]} # 只返回 AI 回复,不包含 prompt**系统提示词只影响当前推理,不保存到历史记录。**这才能确保历史记录流转合理。
六、人工干预这个功能,生产环境必开
刚看到 Human-in-the-Loop时,还觉得“自动化这么方便,干嘛还得一个个对命令手工确认,费事儿”。
后来用agent帮我编程,而且给了他删改权限。等他执行完我傻眼了:我的代码被他改的乱七八糟,找不出一点我之前代码的影子。吓得我赶紧回滚,幸好commit记录还在。从这之后我只给它只读权限,如果涉及真正的代码处理,必须、一定要人工确认!
现在我的做法:
app = workflow.compile( checkpointer=MemorySaver(), interrupt_before=["tools"] ) # 运行时判断哪些工具需要审批 if tool_name == "analyze_server_logs": # 查询类工具,自动放行 inputs = None elif tool_name == "restart_service": # 高危操作,人工确认 approval = input("是否批准?(yes/no): ") if approval == "yes": inputs = None else: break查询类工具自动过,写操作人工批。这样既安全又不影响效率。
七、Graph-as-a-Tool,这个设计我真服
有次我要做个”带重试的 API 调用”工具。一开始直接写函数:
@tooldef call_api(query): try: return api_call(query) except: return api_call(query) # 重试一次后来需求变了,要支持”最多重试 3 次”“指数退避”“失败后通知”……函数越写越长,最后 200 行,根本没法维护。
LangGraph 的解法:把子流程也做成图。
# 子图:带重试的 API 调用 retry_workflow = StateGraph(RetryState) retry_workflow.add_node("call_api", call_unstable_api) retry_workflow.add_conditional_edges("call_api", should_retry, {...}) retry_app = retry_workflow.compile() # 封装为 tool @tool def create_order(query: str) -> str: result = retry_app.invoke({"query": query, "attempt": 1}) return result["result"]主图看不到子图内部逻辑,只知道调用个工具。子图里爱怎么重试、怎么退避都行,主流程不受影响。
这个设计有点像微服务。大系统拆小模块,每个模块自己管好自己,对外只暴露接口。
八、Multi-Agent 编排,单 Agent 真的会崩
我之前习惯让一个 Agent 干所有活:查文档、搜网页、写代码、回邮件……
后来项目大了,问题全来了:
- Prompt 太长,LLM 经常忽略指令
- 记忆爆炸,上下文飞速扩张
- 工具混杂,模型容易误调用
LangGraph 的解法:多专家 + 总控。
# 专家节点 def rag_expert(state): # 只查私有知识 def web_research(state): # 只搜公开信息 def code_writer(state): # 只写代码 # 总控节点 def supervisor(state): # 只负责调度 # 根据任务类型指派专家 return {"next_speaker": "rag_expert"}测试过,同样任务,单 Agent 要 1500 token,多 Agent 只要 800。因为每个专家只关注自己那摊事,不用背全局上下文。不仅总token少了,每个Agent只需负责自己的上下文,总上下文开销与注意力保持也能更好。
九、条件边的两种写法,我一开始也分不清
LangGraph 的条件边有两种写法:
动态路由(函数直接返回节点名):
def route_supervisor(state): return state["next_speaker"] # 可能返回任何专家名字 workflow.add_conditional_edges("supervisor", route_supervisor)静态映射(字典指定分支):
def should_continue(state): if has_tool_calls: return "tools" return "supervisor" workflow.add_conditional_edges( "member", should_continue, {"tools": "tools", "supervisor": "supervisor"} # 显式映射 )区别在哪?
动态路由适合目标不确定的情况(Supervisor 可能指派任何专家);静态映射适合结构固定的场景(二选一或三选一)。
我一开始全用的动态路由,结果有次拼错节点名,报错信息又看不懂,查了两小时。后来固定结构的地方全改静态映射,至少能提前发现拼写错误。
十、一条我走过来的学习路径
我会建议按这个顺序走:
- 先跑通最小 LangGraph(State + Node + Edge)
- 接入 LangSmith,学会看 Trace
- 用 LangGraph 复现 ReAct 循环(替代 AgentExecutor)
- 加持久化记忆(checkpointer=MemorySaver())
- 加人工干预(interrupt_before)
- 学 Graph-as-a-Tool(子图封装)
- 搞 Multi-Agent 编排(总控 + 专家)
你会发现,LangGraph 学习的本质不是”背 API”,而是:
- 状态驱动意识(State 是核心,节点只是状态转换器)
- 流程可视化意识(能用 LangSmith 就别盲猜)
- 分层抽象意识(主图管决策,子图管执行)
最后说一句
LangGraph 最难的从来不是”画流程图”,而是”理解状态怎么流转”。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~