本文深入解析LangGraph上Plan-and-Execute Agent的实现,从ReAct模式的缺陷切入,详细阐述状态设计、Schema定义、三大节点逻辑及图编排。通过实例展示如何构建一个高效可控的AI Agent,并探讨实际应用中的关键设计取舍,适合对大模型开发感兴趣的小白和程序员学习参考。
本篇约 1.2 万字,阅读时长约 30 分钟。
从 ReAct 的固有缺陷切入,拆解 LangGraph 上 Plan-and-Execute Agent 的完整实现,涵盖状态设计、Schema 定义、三大节点深度剖析、Provider 路由与 REPL 流式输出。
在 AI Agent 落地的过程中,ReAct(推理-行动)模式是大家最熟悉的套路:模型先想一想,再调个工具,拿到结果再想,循环往复。但问题来了——当任务复杂、链路变长时,ReAct的 LLM 每一步都要重新审视全局上下文再做决策,token 消耗大,中间步骤容易跑偏。
举个例子:你让 Agent 去查"2024年澳网男单冠军的家乡在哪"。ReAct的做法是先搜索冠军是谁,再搜索这个人的家乡。听起来没毛病,但每一步推理都带着完整历史消息,模型在第二步可能因为上下文太长而忘了第一步搜到的名字,或者干脆自作主张用参数知识直接回答。
那么有没有一种更靠谱的思路?有,就是 Plan-and-Execute(先规划再执行)。本篇就基于LangGraph从零拆解一套完整的 Plan-and-Execute Agent 源码,涵盖状态设计、Schema 定义、节点逻辑、图编排以及实际运行中的踩坑经验。
一、ReAct 的瓶颈与 Plan-and-Execute 的破局
要理解 Plan-and-Execute,先得搞清楚它在解决ReAct的什么毛病。
1、ReAct 模式的固有缺陷
ReAct的核心循环是 Think -> Act -> Observe,模型每走一步都要把完整的历史消息重新过一遍。这带来三个问题:
- token 爆炸:每一步都把之前的对话历史塞进 prompt,步数越多上下文越长,成本线性增长
- 决策漂移:模型在长链路中容易丢失初始目标,越走越偏
- 无法并行:因为是边想边做,前一步的结果决定了下一步的方向,串行依赖无法打破
用一句定性结论来说:ReAct是个优秀的执行者,但不是个好规划者。
2、Plan-and-Execute 的核心思路
Plan-and-Execute 的设计哲学很朴素:先想清楚再动手。
它把 Agent 的职责拆成三个角色:
- Planner(军师):拿到用户目标,一次性生成完整的步骤列表,运筹帷幄
- Executor(先锋):严格按步骤执行,每做完一步汇报结果,冲锋陷阵
- Replanner(裁判):审视执行结果,决定是继续执行剩余步骤还是直接给出最终答案,决定继续还是收兵
三位角色各司其职,形成闭环。
3、两种模式对比
| 对比维度 | ReAct | Plan-and-Execute |
|---|---|---|
| 决策方式 | 边想边做,逐步推理 | 先规划全局,再逐步执行 |
| token 消耗 | 高(每步重载全量上下文) | 低(执行时只看当前步骤) |
| 错误纠正 | 只能通过观察被动纠正 | Replanner 可主动调整计划 |
| 并行能力 | 差(串行依赖强) | 好(步骤间可并行设计) |
| 适用场景 | 简单任务、短链路 | 复杂任务、多步骤组合 |
鱼和熊掌不可兼得,ReAct胜在灵活,Plan-and-Execute 胜在可控。
二、整体架构与流程图
那么,这套 Plan-and-Execute 的图结构长什么样?
先用 mermaid 看一下节点连线关系的骨架:
核心链路就一条线:START -> planner -> agent -> replan,然后replan通过should_end条件边决定是回到agent还是走向END。
但光看连线骨架还不够。三个角色各自读写 State 的哪些字段?should_end怎么路由?用一张全景图把全貌画出来:
这张图把三件事讲清楚了:节点的执行顺序、should_end的路由分支、以及PlanExecuteState 在各节点间的读写关系。
这里有一个关键设计:每次只执行plan[0],而不是一次性跑完所有步骤。为什么?因为replan节点需要在每一步执行后审视全局,可能调整后续计划。这种"执行一步 -> 回顾一次"的节奏,保证了灵活性。
个人认为,这种设计在工程上是很务实的——既不像ReAct那样每步都要从头推理,也不像批处理那样无法动态调整。
三、状态设计与 Schema 定义
图有了,节点之间的数据怎么流转?靠的是State。
1、PlanExecute 状态结构
LangGraph的核心概念之一就是State(状态),它是图中所有节点共享的数据容器。来看PlanExecute的定义:
class PlanExecute(TypedDict): """The plan-and-execute agent's state.""" input: str plan: list[str] past_steps: Annotated[list[tuple[str, str]], operator.add] response: str四个字段,职责分明:
input:用户的原始输入plan:当前待执行的步骤列表past_steps:已完成的步骤及结果,用operator.add做 reducerresponse:最终答案
这里最值得关注的是past_steps的注解:
past_steps: Annotated[list[tuple[str, str]], operator.add]Annotated+operator.add是LangGraph的 reducer 机制。普通字段在节点更新时会被直接覆盖,而加了operator.add的字段会做 累加追加,永远不会被覆盖。
用 ASCII 图来对比一下两种更新方式的区别:
普通字段(覆盖模式) ┌─────────────────────────────────────────┐ │ 节点A: past = [step1] │ │ 节点B: past = [step2] ← 直接覆盖 │ │ 最终: past = [step2] │ └─────────────────────────────────────────┘ reducer = operator.add(追加模式) ┌─────────────────────────────────────────┐ │ 节点A: past = [step1] │ │ 节点B: past = [step2] ← operator.add │ │ 最终: past = [step1, step2] │ └─────────────────────────────────────────┘这意味着每次agent节点执行完一步,结果会 append 到past_steps里,而不会把之前的记录冲掉。这是有必要的——replanner需要看到所有已完成的步骤才能做出判断。
2、Plan Schema
class Plan(BaseModel): """Plan to follow in future.""" steps: list[str] = Field( description="different steps to follow, should be in sorted order" )Plan很简单,就是一个字符串列表。planner节点的输出会被结构化为这个 Schema,确保每一步都是一个清晰的任务描述。
3、Act Schema——一个踩坑点
Act是replanner的输出 Schema,它需要表达两种可能:要么返回最终答案,要么返回更新后的计划。
先看 notebook 原版的设计:
# notebook 原版:用 Union action: Union[Response, Plan]看起来很优雅,但实际跑起来会出问题。当对接 GLM/MiniMax 等 OpenAI 兼容的 Provider 时,langchain的解析器会把 Union 字段展平,和模型返回的嵌套结构{"action": {...}}对不上,导致解析失败。
这算是踩了个大坑。所以本项目把它展平成了Literal判别符 + 两个可选字段:
class Act(BaseModel): """Action to perform (replanner output).""" action_type: Literal["response", "plan"] = Field( description="Use 'response' to answer the user, 'plan' to keep working." ) response: str | None = Field( default=None, description="Final answer to the user; set when action_type='response'.", ) steps: list[str] | None = Field( default=None, description="Remaining steps to do; set when action_type='plan'.", )用action_type做判别符,response和steps根据类型填充。没有嵌套结构,兼容性直接拉满。
这是一个务实的选择——牺牲了一点类型层面的优雅,换来了跨 Provider 的稳定性。
四、三大节点深度剖析
有了 State 和 Schema,接下来看图中的三个核心节点。每个节点都是一个工厂函数,返回一个接收PlanExecute状态、返回状态更新的闭包。
1、planner 节点:军师出招
def make_plan_step(planner) -> Callable[[PlanExecute], dict]: def plan_step(state: PlanExecute) -> dict: plan = planner.invoke({"messages": [("user", state["input"])]}) steps = plan.steps if (plan and plan.steps) else [state["input"]] return {"plan": steps} return plan_step逻辑很直白:把用户输入丢给planner,拿到Plan结构,提取steps返回。
但有一行防御代码值得注意:
steps = plan.steps if (plan and plan.steps) else [state["input"]]如果模型没有返回有效的steps(比如直接用自然语言回答了),就把整个输入当作一个步骤。这样即使 planner 罢工了,executor 也还能跑起来,不至于直接崩。
这是工程上的兜底策略——别让一个节点的异常拖垮整条链路。
2、execute_step 节点:先锋冲锋——本篇最核心的设计取舍
这个节点是整个项目最有深度的部分,也是踩坑最多的地方。
当局者迷,旁观者清——每一步都看不全大局的 executor先看完整代码:
def make_execute_step(agent_executor) -> Callable[[PlanExecute], dict]: def execute_step(state: PlanExecute) -> dict: plan = state["plan"] plan_str = "/n".join(f"{i + 1}. {step}" for i, step in enumerate(plan)) task = plan[0] past = state.get("past_steps") or [] past_str = ( "/n".join(f"- {step}: {result}" for step, result in past) or "(none yet)" ) task_formatted = ( f"For the following plan:/n{plan_str}/n/n" f"You are tasked with executing step 1, {task}." ) agent_response = agent_executor.invoke({"messages": [("user", task_formatted)]}) return {"past_steps": [(task, agent_response["messages"][-1].content)]} return execute_step先说正常流程:取plan[0],格式化成任务描述,丢给agent_executor(一个预构建的ReActAgent)执行,把结果 append 到past_steps。
但注意看task_formatted的构造——它只带了plan_str和当前task,没有带past_str。
代码里其实算出了past_str,但最终没用上。为什么?
execute_step 的上下文传递设计——全文最关键的取舍这要分两种场景来分析。
简单任务场景:
比如查询"2024年澳网男单冠军的家乡"。planner生成的计划是:
查 2024 年澳网男单冠军是谁
查这个人的家乡
第一步执行后,replanner拿到结果(Jannik Sinner),可以直接用 LLM 自身知识回答他的家乡,不需要执行第二步。这种情况下,不带历史上下文反而更省 token。
复杂任务场景:
如果任务是多步骤深度关联的,比如:
查某公司最近的财报数据
根据财报数据计算关键指标
根据指标生成投资建议
第二步依赖第一步的数值结果,第三步依赖第二步的计算结果。
如果execute_step不带历史上下文,第二步就不知道第一步算出了什么。
那么会怎样?下一步的执行就永远得不到正确答案。
整个流程会陷入 step-replan 的死循环,对系统稳定性是毁灭性打击。
解决方案在代码注释里写得很清楚——把past_str加进task_formatted:
# 携带历史 step 上下文的版本 task_formatted = ( f"For the following plan:/n{plan_str}/n/n" f"Steps already completed and their results:/n{past_str}/n/n" f"You are tasked with executing step 1, {task}./n" f"Reuse the results above when they are relevant — do not redo " f"work that is already done." )但本项目最终选择不带上下文,注释说明了原因:
# task_formatted 不携带历史 step 上下文,并不是省 token 的好办法, # 而是对简单任务的取舍,实际复杂任务每一个 step 是需要更多历史 step 的上下文的个人认为,这个取舍的核心在于:简单任务的演示价值在于展示 Plan-and-Execute 的完整闭环流程,而不是追求复杂场景的生产级可用。
复杂任务需要的不仅仅是past_str,而是更完善的上下文共享机制(比如把中间结构化结果存入 State,而不只是文本摘要)。
用 ASCII 图把 execute_step 的上下文流转画出来,两种模式的对比更直观:
┌──────────── 不带 past_str(默认)────────────┐ │ │ │ execute_step 调用 agent_executor 时: │ │ │ │ task_formatted = plan_str + task │ │ ┌──────┐ │ │ │ agent│ ← 看不到 step1 结果 │ │ └──────┘ │ │ 结果:step2 不知道 step1 产出了什么 │ │ → 简单任务 OK,复杂任务死循环 │ │ │ ├──────────── 带 past_str(改进版)─────────────┤ │ │ │ execute_step 调用 agent_executor 时: │ │ │ │ task_formatted = plan_str + past_str + task │ │ ┌──────┐ │ │ │ agent│ ← step1 结果在手 │ │ └──────┘ │ │ 结果:step2 能复用 step1 的输出 │ │ → 复杂任务也能跑通 │ │ │ └────────────────────────────────────────────────┘3、replan 节点:裁判定夺
def make_replan_step(replanner) -> Callable[[PlanExecute], dict]: def replan_step(state: PlanExecute) -> dict: output: Act = replanner.invoke(state) if output.action_type == "response": return {"response": output.response} return {"plan": output.steps or []} return replan_stepreplanner拿到当前完整 State(包含input、plan、past_steps),输出Act结构。
- 如果
action_type == "response",把最终答案写入response字段 - 否则,用
output.steps更新plan(剩余步骤)
注意output.steps or []这个写法——如果模型返回了plan类型但steps为空,就用空列表兜底,避免plan[0]越界。
4、should_end:路由条件
def should_end(state: PlanExecute) -> str: """Route: stop when a response exists, otherwise keep executing.""" if state.get("response"): return END return "agent"一句话:有response就结束,没有就回agent继续干。简单粗暴但有效。
五、图编排与编译——build_app 的依赖注入设计
三个节点都有了,接下来就是把它们组装成图。核心是build_app函数:
def build_app( *, model: BaseChatModel | None = None, tools: list | None = None, planner: Runnable | None = None, replanner: Runnable | None = None, agent_executor: Any | None = None, checkpointer: Any | None = None, ) -> CompiledStateGraph:每一个参数都是可选注入的。留None的角色会从model和tools自动推导。
为什么这么设计?因为 测试需要。测试时可以注入 fake 的planner、replanner、agent_executor,完全不需要真实的 LLM Provider,就能跑通整个图的逻辑。这个依赖注入整得挺靠谱。
来看核心装配逻辑:
# 只有角色还没构建时才需要 model,所以注入了全部角色的测试不需要 Provider Key if planner is None or replanner is None or agent_executor is None: if model is None: model = make_default_model() if planner is None: planner = planner_prompt | model.with_structured_output( Plan, method="function_calling" ) if replanner is None: replanner = replanner_prompt | model.with_structured_output( Act, method="function_calling" ) if agent_executor is None: agent_executor = create_react_agent( model, tools, prompt="You are a helpful assistant." )这里有一个关键细节:method="function_calling"。
为什么不用json_schema?因为 GLM 和 MiniMax 的json_schemaresponse_format 不靠谱(返回的是纯文本而非 JSON)。而function_calling方式通过工具调用的结构化返回,兼容性更好。
接下来是图的组装:
workflow = StateGraph(PlanExecute) workflow.add_node("planner", make_plan_step(planner)) workflow.add_node("agent", make_execute_step(agent_executor)) workflow.add_node("replan", make_replan_step(replanner)) workflow.add_edge(START, "planner") workflow.add_edge("planner", "agent") workflow.add_edge("agent", "replan") workflow.add_conditional_edges("replan", should_end, ["agent", END]) return workflow.compile(checkpointer=checkpointer)四行add_edge就把整张图画完了:
START -> planner -> agent -> replanreplan通过条件边should_end路由到agent或END
checkpointer默认用InMemorySaver(),支持LangGraph的断点续传和状态回溯。
六、Provider 配置与工具体系
1、Provider 路由:一个字典搞定多模型切换
本项目支持 GLM 和 MiniMax 两种 Provider,切换方式是通过环境变量LLM_PROVIDER控制。核心设计如下:
@dataclass(frozen=True) class Provider: key_env: str # API Key 的环境变量名 model_env: str # 模型名覆盖的环境变量名 model_default: str # 默认模型名 base_url_env: str # Base URL 覆盖的环境变量名 base_url_default: str # 默认 Base URL两个 Provider 的配置对照:
| Provider | key_env | model_default | base_url_default |
|---|---|---|---|
glm | ZHIPUAI_API_KEY | GLM-5.1 | https://open.bigmodel.cn/api/coding/paas/v4 |
minimax | MINIMAX_API_KEY | MinMax-M3 | https://api.minimaxi.com/v1 |
这个设计的精妙之处在于 开闭原则:要加一个新 Provider,只需要在PROVIDERS字典里加一条记录,路由逻辑一行都不用改。
实际使用时,.env配置示例如下:
# .env 文件 LLM_PROVIDER=glm ZHIPUAI_API_KEY=your_api_key_here # 可选:覆盖默认模型 # GLM_MODEL=GLM-5.1 # 可选:覆盖默认 Base URL # GLM_BASE_URL=https://open.bigmodel.cn/api/coding/paas/v4 # 如果想切到 MiniMax # LLM_PROVIDER=minimax # MINIMAX_API_KEY=your_minimax_keymake_default_model的路由逻辑也很干脆:
def make_default_model() -> ChatOpenAI: provider = os.getenv("LLM_PROVIDER", DEFAULT_PROVIDER).lower() if provider not in PROVIDERS: sys.stderr.write( f"error: unknown LLM_PROVIDER='{provider}'. " f"Choose one of: {', '.join(sorted(PROVIDERS))}./n" ) sys.exit(2) cfg = PROVIDERS[provider] api_key = require_env(cfg.key_env) model = os.getenv(cfg.model_env, cfg.model_default) base_url = os.getenv(cfg.base_url_env, cfg.base_url_default) return ChatOpenAI(model=model, api_key=api_key, base_url=base_url)找不到 Provider 或者 Key 没配?直接sys.exit(2)退出,绝不静默降级。这是必须的——配置错误就要第一时间暴露,别等到运行到一半才报错。
2、工具体系:离线模式与在线模式
tools.py提供了一个内置的离线搜索引擎,内置了一组关键词-答案映射:
_KB: list[tuple[tuple[str, ...], str]] = [ (("australian open", "2024", "men", "winner"), "Jannik Sinner won the 2024 Australian Open men's singles title."), (("sinner", "hometown"), "Jannik Sinner is from Sexten (Sesto), in South Tyrol, Italy."), # ... ]这个离线知识库的目的是让多步规划端到端跑通,不需要任何外部 API Key。
如果配置了TAVILY_API_KEY,会自动切换到真实的Tavily搜索:
def get_tools() -> list: if os.getenv("TAVILY_API_KEY"): from langchain_community.tools.tavily_search import TavilySearchResults return [TavilySearchResults(max_results=3)] return [search]两种模式无缝切换,对上层图结构完全透明。
七、REPL 运行与流式输出
最后来看入口文件__main__.py,它提供了一个交互式 REPL,用stream_mode="updates"实时打印每一步的执行过程。
1、流式追踪设计
def _print_trace(node: str, update: dict) -> None: if node == "planner": plan = update.get("plan") or [] print("/n--- plan ---") for i, step in enumerate(plan, 1): print(f"{i}. {step}") elif node == "agent": for task, result in update.get("past_steps") or []: print(f"/n▶ executing: {task}") print(f" -> {result}") elif node == "replan": if update.get("response") is not None: print("/n--- replan: done (final answer) ---") print(update["response"]) else: remaining = update.get("plan") or [] print("/n--- replan: continue, remaining plan ---") for i, step in enumerate(remaining, 1): print(f"{i}. {step}")stream_mode="updates"的机制是:每跑完一个节点,立刻推送该节点的状态更新。这样计划、执行步骤、重规划决策都是实时打印的,而不是等全部跑完一次性 dump。
2、REPL 主循环
def repl() -> None: load_env() app = build_app() while True: try: user_input = input("/n> ").strip() except (EOFError, KeyboardInterrupt): print("/nbye") return if user_input == ":quit": return thread_id = str(uuid.uuid4()) config = {"configurable": {"thread_id": thread_id}, "recursion_limit": 50} for chunk in app.stream({"input": user_input}, config, stream_mode="updates"): for node, update in chunk.items(): _print_trace(node, update)每次查询都是独立的thread_id,保证 plan、past_steps、response 不会跨查询泄漏。
recursion_limit设为 50,因为 plan->execute->replan 的循环可能跑好几轮,默认的 25 可能不够用。
REPL 还支持Ctrl-D(EOF)和Ctrl-C(键盘中断)优雅退出,输入:quit也能直接退出。代码里用try/except (EOFError, KeyboardInterrupt)捕获这两种中断信号,保证不会因为用户的误操作而抛出一堆 traceback。
3、实际运行效果
以查询"who won the 2024 Australian Open men’s title and where is that person from"为例,运行时输出大致如下:
--- plan --- 1. **Identify the winner of the 2024 Australian Open men's singles title.** 2. **Research the hometown/birthplace of that winner.** ▶ executing: Identify the winner of the 2024 Australian Open men's singles title. -> Jannik Sinner won the 2024 Australian Open men's singles title. --- replan: continue, remaining plan --- 1. **Research the hometown/birthplace of that winner.** ▶ executing: Research the hometown/birthplace of that winner. -> Jannik Sinner is from Sexten (Sesto), in South Tyrol, Italy. --- replan: done (final answer) --- The winner is Jannik Sinner, from Sexten (Sesto), South Tyrol, Italy.计划 -> 执行 -> 重规划 -> 执行 -> 最终答案,完整闭环,这流程 yyds。
八、Prompt 模板:planner 与 replanner 的提示词设计
1、planner_prompt
planner_prompt = ChatPromptTemplate.from_messages([ ("system", "For the given objective, come up with a simple step by step plan. " "This plan should involve individual tasks, that if executed correctly will yield the correct answer. " "Do not add any superfluous steps. " "The result of the final step should be the final answer. " "Make sure that each step has all the information needed - do not skip steps."), ("placeholder", "{messages}"), ])核心要求四点:
生成逐步计划
每步是独立可执行的任务
不要多余步骤
每步要包含足够信息
2、replanner_prompt:宽松版 vs 严格版
两个版本共享相同的模板变量槽位:
{input}:用户的原始目标{plan}:当前计划{past_steps}:已完成的步骤及结果
区别在于关键约束段不同。先看当前生效的宽松版完整模板:
replanner_prompt = ChatPromptTemplate.from_template( "For the given objective, come up with a simple step by step plan. " # ...(前段与 planner_prompt 一致) "Your objective was this:/n{input}/n/n" "Your original plan was this:/n{plan}/n/n" "You have currently done the follow steps:/n{past_steps}/n/n" "Update your plan accordingly. If no more steps are needed and you can return to the user, then respond with that. " "Otherwise, fill out the plan. Only add steps to the plan that still NEED to be done. " "Do not return previously done steps as part of the plan./n/n" "Return action_type='response' (with the final answer in `response`) when you can answer the user, " "otherwise action_type='plan' (with the remaining steps in `steps`)." )再看注释掉的严格版,关键差异段如下:
# 严格版(注释中)的差异段 "Prefer executing the remaining steps over answering early: return a final response only when the " "objective is fully covered by tool results already in `past_steps`. " "Do NOT short-circuit an unexecuted step by answering from your own knowledge..." "the `steps` field must contain ONLY the original-plan steps that have not yet been executed, kept " "VERBATIM and in their original order — do not rephrase, merge, split, or add new steps."两个版本的核心差异一目了然:
| 策略维度 | 宽松版(默认) | 严格版 |
|---|---|---|
| 提前回答 | 允许,如果认为可以回答就直接出最终结果 | 禁止,除非目标已被工具结果完全覆盖 |
| 步骤改写 | 允许调整剩余步骤的措辞 | 禁止,只允许删除已完成步骤,剩余步骤必须原样保留 |
| 代词消解 | replanner 可改写步骤让代词指向明确 | 步骤原样保留,代词无法被消解 |
| 适用场景 | 简单任务、演示闭环 | 模拟复杂任务的上下文缺失问题 |
为什么默认不用严格版?因为严格版禁止改写步骤措辞,这意味着如果 step2 依赖 step1 的结果(比如"查那个人的家乡"),step2 中的代词"那个人"就永远无法被解析。
所以两种版本的选择本质上是:宽松版适合简单任务的全流程演示,严格版适合验证复杂任务在缺少上下文共享时的问题。这是一个典型的工程权衡——没有银弹。
九、要点总结
Plan-and-Execute 的核心拓扑是
START -> planner -> agent -> replan -> (agent | END),每次只执行plan[0],由replanner决定继续还是收兵past_steps使用operator.addreducer 做累加追加,保证已完成的步骤记录不会被覆盖ActSchema 从Union[Response, Plan]展平为Literal判别符 + 可选字段,解决 OpenAI 兼容 Provider 的结构化输出解析问题execute_step是否携带历史上下文是核心设计取舍:简单任务不带可省 token,复杂任务不带会陷入死循环build_app的全参数依赖注入设计,让测试可以完全脱离真实 LLM Provider 离线运行method="function_calling"比json_schema更适合对接 GLM/MiniMax 等国产模型Provider 路由用字典注册实现开闭原则,加模型只需加一条配置
stream_mode="updates"实现节点级实时追踪,计划和执行过程逐行打印
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套AI 大模型突围资料包:
- ✅ 从零到一的 AI 学习路径图
- ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
- ✅ 百度/阿里专家闭门录播课
- ✅ 大模型当下最新行业报告
- ✅ 真实大厂面试真题
- ✅ 2026 最新岗位需求图谱
所有资料 ⚡️ ,朋友们如果有需要《AI大模型入门+进阶学习资源包》,下方扫码获取~
① 全套AI大模型应用开发视频教程
(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
② 大模型系统化学习路线
作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
③ 大模型学习书籍&文档
学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
④ AI大模型最新行业报告
2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
⑤ 大模型项目实战&配套源码
学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
⑥ 大模型大厂面试真题
面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。
以上资料如何领取?
为什么大家都在学大模型?
最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!
不出1年,“有AI项目经验”将成为投递简历的门槛。
风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!
这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。