最近好几个准备投CV+AI Agent工程师岗位的朋友,都来问我同一个问题:LangGraph自学应该按什么节奏走。这个问题确实问到点子上了,因为现在视觉方向的Agent岗位招聘里,几乎必然要涉及模型编排、工具调用、多轮状态管理这些能力,而LangGraph正是目前处理这些事最主流的工程框架之一。这篇自学计划不劝你硬背文档,而是把从零开始到能独立交付一个视觉理解Agent的完整路径、核心重点和踩过的坑一次性梳理清楚。
先交代一下适用人群。如果你做过传统CV项目,比如图像分类、目标检测、OCR等等,但还没系统写过Agent编排逻辑,那这份计划非常适合你;如果你之前用过LangChain的链式调用,想往图编排、有状态Agent的方向深入,也可以直接参考。如果你既不清楚视觉模型能做什么,也没碰过LLM,建议先补一周相关基础再开始,否则直接上LangGraph容易一头雾水。
1. CV+AI Agent 工程师岗位能力拆解:LangGraph 为什么是核心
很多人在自学LangGraph之前,没有先想清楚一个问题:岗位JD里写着CV+AI Agent工程师,到底是要你解决什么?如果只是会跑几个框架Demo,面试大概率撑不过二十分钟。要理解这件事,得先看这个岗位演进背后的逻辑。
1.1 岗位能力模型:CV 技能与 Agent 编排技能怎么配比
传统CV工程师的核心能力大家都熟悉:数据处理、模型训练、效果调优、部署上线。但CV+AI Agent工程师的交付物已经不是"一个模型文件"或"一个后处理接口",而是一个能够自主决策的完整流程。
举一个很常见的例子,智能巡检场景。传统做法是训练一个缺陷分类模型,输入图片,输出缺陷标签。Agent化之后业务流程会变成:Agent先理解用户传上来的图是什么任务,决定调用哪个视觉模型,比如缺陷检测、OCR识别还是图像分类;拿到检测结果后,如果置信度不够高,还需要触发二次检测;确定出现缺陷时,不是简单输出一个标签,而是结合历史工单和上下文生成维修建议;最后还要以自然语言的形式输出一份报告。
所以你会发现,这个岗位的能力要求大致分成三层:
- 视觉模型功底,占比大概四成,需要知道分类、检测、分割、OCR这类任务能做到什么程度,以及模型的输入输出边界。
- 语言模型与提示词功底,占比约三成,需要懂得怎么给LLM下指令、做结构化输出、用好工具调用。
- Agent编排功底,占比约三成,这是新增的部分,也是LangGraph这类框架真正解决的部分。
不同团队的配比会有差异,但Agent编排能力一定是共同增量。简历上写了LangGraph,面试官默认的就是你理解Agent的核心是"有状态、可控制的流程编排",而不只是调一次LLM凑个回答。
1.2 LangGraph 为什么被单独拎出来讲
你可能会问,Agent流程用普通Python函数直接写不就行了,为什么非要引入LangGraph这种图框架?这是个好问题,也是面试大概率会问的问题。
真实世界的Agent流程长什么样?它不是一个从A到B的固定线性流程,而是包含循环、条件分支、并行处理、中途恢复的复杂流程。举个例子,Agent需要不断判断"我该调用工具了,还是可以给出最终答案",这个判断每轮对话都会发生,本质上是个循环。如果用普通代码表达这个循环,你会发现状态管理非常麻烦,每轮工具的返回结果存哪里、上一轮对话历史怎么传、怎么判断是否终止,最后全都得自己造轮子。
LangGraph的核心抽象就四个概念:
- 状态State:一个贯穿整个流程的对象,保存所有需要流转的数据。
- 节点Node:一个节点做一件事,本质就是普通的Python函数。
- 边Edge:定义节点之间的流转方向。
- 条件边Conditional Edge:根据当前状态的内容决定下一步去哪。
我用一个粗略的类比帮助理解:普通流程代码像一份写死的操作手册,每个步骤都提前定好;而图结构像一张带决策点的路线图,走到某个路口时,由当前手里的数据决定往哪拐。这就是Agent编排和传统脚本最本质的差别。
1.3 你与能胜任之间的差距在哪:自测清单
在开始学之前,我建议你先用几个问题自测一下,哪道题卡住了,后面就重点关注哪一块:
- 工具调用也就是function calling的原理是什么?模型是真正执行了函数,还是只输出一个调用意图?
- 如果模型连续三次返回同一个工具调用,说明什么问题?你怎么设计终止条件?
- 多模态图片数据应该放进LangGraph的State里,还是放在外部存储、节点之间只传引用?
- Agent需要记住之前几轮对话说了什么,LangGraph里面怎么办?
- 工具调用失败时,你怎么设计恢复策略,是直接结束还是换一条路径重试?
这些问题如果现在答不上来,非常正常,这份计划的每一章就是在帮你逐个补齐。千万别小看它们,这些内容经常会直接出现在一面和二面的技术问题里。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. LangGraph 自学路线整体设计:四阶段打怪升级
我见过不少自学LangGraph的人走入一个共同误区:拿到资料先抄一遍官方Demo,跑通了就觉得自己会了,结果面试一深挖就露馅。这里我把路线拆成四个阶段,每个阶段都有明确的目标和验证标准,跟着走完基本能够覆盖岗位的硬性要求。
2.1 阶段一:先摸清你手上的模型能力边界(约1周)
这个阶段完全不碰LangGraph,但恰恰最容易被忽略。如果你不清楚模型在什么情况下会胡说八道、什么输入会拒绝回答、输出结构有多不稳定,后面Agent出了任何问题,你都没办法判断是哪个环节出的错。
一周以内完成三件事:
- 选一个你手上可用的主流大模型API,写一个简单的function calling程序。用户说"帮我查一下这个订单的物流状态",模型输出一个结构化调用参数,然后由你自己写代码执行查询并返回结果。这个流程能帮你建立最关键的认知:模型不负责执行工具,它只负责表达意图,真正干活的是代码。
- 准备一张有明显主体的测试图片,把它交给一个多模态视觉模型,观察它返回的字段。这里重点不是看它识别得准不准,而是看输出形态。是自然语言描述,还是结构化标签?图片里多个物体时,它输出的内容是"我看到了什么"还是"图里有什么可以操作的对象"?
- 把你未来要接的外部能力都列出来,比如检索接口、检测模型、OCR服务,命名成一个个普通函数,先用纯Python调用一遍,确保输入输出参数你都清楚。
我强烈建议不要跳过这个阶段。之前带过几个转岗的同学,上来直接写LangGraph,遇到问题后连是不是模型幻觉都判断不了,又绕回来补LLM基础,反而更慢。
2.2 阶段二:LangGraph 核心基础(约1~2周)
第二阶段的目标是亲手跑通三个最基本的图模式,不用追求复杂,关键在于把状态流转的感觉建立起来。
第一是线性链。一个节点接收图片路径,第二个节点调用视觉描述模型生成图片描述,最后输出。重点观察State如何从一个节点传递到下一个节点。
第二是条件分支。根据视觉描述的结果,决定下一步走"继续检索"节点还是"直接返回"节点。这里你会接触到条件边的写法,感受到图结构的不同。
第三是循环。模型先输出一个工具调用的意图,框架帮你执行工具,把结果写回状态,再传回给模型判断是继续还是结束。这个循环是所有Agent工作的基础,也是后面第三周重点攻克的东西。
我的实操建议是:先看官方文档的基础概念部分,然后不要复制粘贴示例代码,每天手写一遍"状态定义加两个节点函数加一条条件边"。连续写三天,肌肉记忆自然就有了。很多人在这个阶段急着去看多智能体、并行流、高级记忆机制,我建议先按住,三条基础边的代码模式没有形成直觉之前,学高级功能很容易变成只会抄API。
2.3 阶段三:Agent 核心机制专项(约2周)
第三阶段开始系统攻克工具型Agent的五大核心机制:
- 工具注册。把一个普通函数变成能被模型感知的tool,核心是写好函数描述和参数schema,因为模型是靠读描述来理解工具的。
- ToolNode。使用框架内置的工具执行节点,减少手写工具调用逻辑的工作量。
- 循环终止。通过条件边判断模型返回里是否还有tool_calls,没有就走向结束。
- 检查点与记忆。让Agent可以被暂停、恢复,让多轮对话拥有记忆。
- 人工介入。在敏感操作执行之前卡住流程,等人类确认后再继续。
这五个机制每项都可以配一个mini项目练手。比如:
- 做一个图像信息判断Agent,让模型自己决定调用哪个工具来检查图片的分辨率、格式、文件大小。
- 做一个带记忆的连续问答Agent。第一次问"这张图的整体色调是什么",第二次问"这个色调适合什么风格的场景",第二个问题模型必须能引用第一次回答里得到的色调信息。
这两个mini项目都不复杂,但能覆盖绝大多数面试考点,性价比很高。
2.4 阶段四:CV 场景融合项目(约2~3周)
最后这个阶段是真正拉开差距的地方。我建议只选一个完整项目做透,做到可以自信地跟别人讲清楚每一步设计取舍。
推荐三个方向供参考:
- 拍照识物咨询Agent。用户上传一张商品图片,Agent提取图中的商品信息,检索库存和价格,生成推荐理由,并支持连续追问。
- 产线质检报告Agent。用户传一张可能有缺陷的产线图片,Agent调用缺陷检测模型,对照历史维修工单,输出一份维修建议报告。
- 文档图像抽取Agent。从包含表格的长文档图片中抽取结构化数据,Agent自己决定先用OCR还是先做版面分析。
项目必须覆盖四种能力:多模态输入怎么接入、工具循环怎么设计、跨轮记忆怎么做、失败重试怎么兜底。做完之后逼自己写一篇复盘文章,核心回答一个问题:"为什么这个场景需要Agent,而不是写死一段if-else?" 这个问题回答不好,项目水平会直接被面试官看穿;回答好了,就是全场最有说服力的谈资。
3. LangGraph 核心概念逐个拆解:状态、节点、工具循环与记忆
前面讲的是路线规划,这一章进入硬核拆解。LangGraph真正难理解的其实是四个概念如何配合,我按实战顺序逐个说清楚。
3.1 状态(State):一切流转的数据载体
State在LangGraph里就是一个贯穿整个流程的TypedDict字典,所有节点需要的数据、产生的中间结果,都在这个字典里传递。
以CV场景为例,一个典型的状态定义长这样:
python复制from typing import TypedDict, Annotated
import operator
class VisionAgentState(TypedDict):
image_path: str # 输入图片路径
user_query: str # 用户原始问题
vision_result: str # 视觉模型提取结果
retrieval_result: list # 检索返回的候选条目
messages: Annotated[list, operator.add] # 历史消息,按追加方式合并
这里值得重点理解的是字段更新规则。默认情况下,节点返回的字段值会覆盖State里的旧值,这在大多数时候没问题。但messages这种需要不断追加内容的字段,就必须用Annotated[list, operator.add]告诉框架:新消息不要覆盖旧消息,而是拼在列表后面。
我踩过的一个比较深的坑:一开始为了图省事,把所有数据全塞进messages字段,让模型可以"看到一切"。结果节点逻辑变得极其难调试,打印出来的状态混着一堆历史消息,很难定位当前中间结果。后面学乖了,核心中间结果一定要独立成字段,比如vision_result、retrieval_result,这样每个节点处理什么数据一目了然,加缓存、加日志、条件判断都方便得多。
3.2 节点与边:四种图形态与 CV 场景一一对应
节点就是一个普通Python函数,接收当前的State作为参数,返回一个字典,字典里的字段会被更新到State上。边定义节点之间的连接关系,而条件边会根据当前State决定下一步去哪个节点。
实际项目里会遇到四种图形态:
- 线性图:图片路径到OCR节点,OCR结果到翻译节点,一条道走到黑。
- 条件分支图:视觉描述结果里包含目标对象就走检索节点,不包含就直接结束。
- 循环图:检测结果置信度低于阈值,重新回到检测节点再跑一次。
- 子图:把"图像预处理加检测加后处理"封装成一个子图节点,对外层表现为一个简单的节点,方便上层流程复用。
这里给一个最小可运行的条件分支示例:
python复制from langgraph.graph import StateGraph, END
def ocr_node(state):
text = run_ocr(state["image_path"])
return {"vision_result": text}
def translate_node(state):
translated = translate_text(state["vision_result"])
return {"final_result": translated}
def decide_after_ocr(state):
if state["vision_result"]:
return "translate"
return END
graph = StateGraph(VisionAgentState)
graph.add_node("ocr", ocr_node)
graph.add_node("translate", translate_node)
graph.set_entry_point("ocr")
graph.add_conditional_edges("ocr", decide_after_ocr, {"translate": "translate", END: END})
graph.add_edge("translate", END)
app = graph.compile()
这段代码里,set_entry_point声明入口节点,add_node注册节点函数,add_conditional_edges声明从OCR节点出来后根据decide_after_ocr的返回值决定去向,END是框架内置的终止节点。注意第一参数是当前节点名,第二个参数是路由函数,第三个参数是路由结果和目标节点的映射。
这一章不需要死记API,核心理解是:图决定流程流向,State决定图中的数据内存。你在面试时把这个关系讲清楚,就能跟只会背API的人拉开距离。
3.3 工具调用循环:Agent 的心脏
Agent和普通问答最本质的区别就是可以反复调用工具。原理层面必须清楚:模型本身不执行工具,它只是根据用户的请求,输出一个"我要调用某个工具,参数是什么"的结构化意图。真正的函数执行是框架或你自己的代码来做的。
LangGraph里实现工具调用循环,最标准的方式是这样:
python复制from langgraph.graph import StateGraph, END
from langchain_core.tools import tool
@tool
def query_product(keyword: str) -> str:
"""根据商品关键词返回库存和价格信息"""
# 实际项目里这里会请求商品服务
return f"商品: {keyword}, 库存: 有货, 参考价: 99元"
def assistant_node(state):
# 调用带工具能力的模型,由模型决定是调用工具还是直接回答
response = model_with_tools.invoke(state["messages"])
return {"messages": [response]}
def route_after_assistant(state):
last_message = state["messages"][-1]
if hasattr(last_message, "tool_calls") and last_message.tool_calls:
return "tools"
return END
graph = StateGraph(VisionAgentState)
graph.add_node("assistant", assistant_node)
graph.add_node("tools", ToolNode([query_product]))
graph.set_entry_point("assistant")
graph.add_conditional_edges("assistant", route_after_assistant, {"tools": "tools", END: END})
graph.add_edge("tools", "assistant")
app = graph.compile()
这段代码的循环逻辑非常清晰:assistant节点调用模型,模型如果决定调用工具,就把带tool_calls的消息追加到messages里;路由函数检测到最后一条消息有tool_calls,就走tools节点;ToolNode执行工具之后,把工具结果也追加到messages;然后边又把流程带回assistant节点,让模型再次判断。只有当模型认为不需要调用任何工具时,路由才走向END,循环结束。
在CV场景里,工具是什么?就是一个接收图片路径或文本特征、返回结构化结果的函数。比如detect_defect(image_path)返回一个字典,search_product(keyword)返回JSON字符串。这里有个关键体会:工具返回的文本,就是Agent"眼中"的图像结果,工具描述写得不清楚,模型很容易理解错。实际使用中,工具函数名、参数名、函数描述要像写文档一样严谨。
3.4 记忆与会话保持:让 Agent 像个助手而不是接口
Agent和普通接口最大的区别在于它记得之前的对话。LangGraph里记忆分两个层次。
短期记忆就是上面代码里的messages字段。模型每次调用时,都能看到这个列表里包含的所有历史消息,所以它自然能理解"你上一轮问过色调,这一轮问适合什么场景"这种上下文关联。
长期记忆则需要使用checkpointer,也就是检查点机制。它会在每个节点运行后保存当前状态的快照,通过thread_id区分不同会话。这样即便Agent运行到一半被中断,比如网络失败、人工暂停,也可以从最近一次快照恢复,而不是从头重跑。
配置一个基础的检查点只需要几行:
python复制from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
app = graph.compile(checkpointer=memory)
# 调用时传入会话标识
config = {"configurable": {"thread_id": "session-001"}}
result = app.invoke({"image_path": "./img_001.jpg", "user_query": "这是什么商品"}, config=config)
人工介入的应用价值在CV场景中也很明显。比如某个工具调用会触发一个高成本的第三方服务,或者检测结果即将用于生产决策,你会希望Agent先停下,把中间结果展示给用户确认,再继续执行。这可以通过设置一个"等待用户确认"的节点实现,本质上就是Agent流程的可控性。
面试里经常被追问:记忆应该放在State里还是外部数据库?我的回答思路是:State负责"本次流程内部"的数据传递和短期记忆;而跨会话、海量的长期记忆,要放到外部数据库,比如向量库或者关系型库,在每次流程启动时再把需要的历史信息加载进State。这样既保证了流程内的高效流转,又避免了State无限膨胀。
4. CV 场景融合实操:从零搭建一个拍照识物分析 Agent 完整项目
理论讲再多,都不如动手做个完整项目。这一章带着你完整过一遍我前面反复提到的"拍照识物分析Agent",从需求到代码到调优,每一步都有具体的可落地细节。
4.1 项目需求与整体设计
先明确场景:用户上传一张商品图片,Agent需要识别图中的商品,去商品库里检索匹配项,给出价格、库存、推荐理由,还支持追问,比如"还有其他颜色吗""这材质好打理吗"。
为什么这个场景一定要用Agent而不是写死逻辑?因为用户的问题存在大量分支。图片模糊时,需要引导用户重新上传;画面里有多个商品时,Agent要判断用户最关心哪一个;商品库没有匹配结果时,需要降级成开放式的知识问答;用户连续追问时,Agent要始终记得上一轮识别出来的是哪款商品。这种多分支、动态决策的流程,用图编排实现远比堆if-else清晰。
整体流程设计:
- 入口节点:接收图片路径和用户问题,启动流程。
- 视觉理解节点:调用多模态视觉模型,提取商品类别、品牌线索、颜色、形态描述。
- 检索节点:把视觉结果作为关键词,调用商品搜索服务。
- 决策路由:如果检索结果为空或置信度太低,回到视觉理解节点换一组关键词;如果结果可用,进入回答节点。
- 回答节点:综合图片信息、检索结果、用户问题,生成自然语言回复。
4.2 关键代码实现:状态、工具、节点与图
第一步定义状态。项目需要的字段在前面已经出现过,但这里增加一个retry_count,用来记录重试次数,防止在"视觉理解到检索"之间死循环。
python复制class ShoppingAgentState(TypedDict):
image_path: str
user_query: str
vision_result: str
retrieval_result: str
retry_count: int
messages: Annotated[list, operator.add]
第二步定义工具。工具是Agent调用外部能力的接口,search_product接收视觉模型提取出来的特征描述,返回匹配商品的信息。
python复制from langchain_core.tools import tool
@tool
def search_product(features: str) -> str:
"""根据商品特征描述查询匹配商品,返回JSON格式的商品信息"""
# 这里在实际项目中会请求商品搜索服务
return '{"name": "某品牌保温杯", "price": 129, "stock": "有货"}'
第三步实现节点函数。视觉理解节点负责把图片"翻译"成模型能理解的文字特征;检索节点负责调用工具;回答节点负责整理信息生成最终答复;路由函数负责决定下一步走向。
python复制def vision_understand_node(state):
prompt = (
f"请描述这张图片中的主要商品,包括类别、品牌线索、颜色、外观特征。"
f"只描述你确定看到的内容,不确定就写不确定。用户的问题是:{state['user_query']}"
)
desc = vision_model.summarize(image_path=state["image_path"], prompt=prompt)
return {"vision_result": desc}
def search_node(state):
result = search_product.invoke({"features": state["vision_result"]})
return {"retrieval_result": result}
def answer_node(state):
content = (
f"图片识别结果:{state['vision_result']}\n"
f"检索到的商品信息:{state['retrieval_result']}\n"
f"用户的原始问题:{state['user_query']}"
)
answer = chat_model.invoke(content)
return {"messages": [answer]}
def decide_after_search(state):
# 检索结果为空且还没有重试过两次,就回到视觉理解节点重新提取
if "暂无匹配" in state["retrieval_result"] and state["retry_count"] < 2:
return "retry"
return "answer"
第四步就是构建图并编译。这里把条件边和retry_count的逻辑接起来。
python复制from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver
graph = StateGraph(ShoppingAgentState)
graph.add_node("vision", vision_understand_node)
graph.add_node("search", search_node)
graph.add_node("answer", answer_node)
graph.set_entry_point("vision")
graph.add_edge("vision", "search")
graph.add_conditional_edges(
"search",
decide_after_search,
{"retry": "vision", "answer": "answer"}
)
graph.add_edge("answer", END)
memory = MemorySaver()
app = graph.compile(checkpointer=memory)
# 运行示例
config = {"configurable": {"thread_id": "session-001"}}
result = app.invoke(
{"image_path": "./product.jpg", "user_query": "这个杯子适合送人吗"},
config=config
)
多轮追问的实现也很直接。直接用同一个thread_id调用第二次,因为启动时通过checkpointer会恢复上一次的状态快照,所以messages里带着上一轮的识别结果和回答。用户第二次问"有没有其他颜色",模型就能自然地结合上一轮识别出的信息回答,而不用重新走一遍视觉理解节点。
4.3 调参与优化经验
项目跑通只是第一步,真正花时间的是调参和优化。这里分享几条实际测试中非常有效的经验。
工具返回格式一定要精简且结构化。我给search_product写过非常口语化的返回,比如"我们有一款很不错的保温杯",结果模型回答时无法准确引用价格字段。改成JSON格式之后,模型的引用准确率明显提升。工具是给模型用的,不是给人看的,格式明确比内容花哨重要。
视觉提取阶段的模型温度要低。我在视觉理解节点里把温度调到接近0,保证提取的特征每次都比较稳定;回答节点的温度可以放到0.3左右,保留一点回答的多样性。这个分配方式在多个场景里都实测有效。
工具内部必须做异常捕获和重试。有一次我在项目里没做任何异常处理,商品服务刚好临时不可用,整个Agent流程直接报错,没有兜底,体验非常差。之后我在工具内部加了重试和统一异常返回,确保工具永远会返回一个模型可以消费的结果,哪怕是一个"查询失败"的提示,也比直接中断强。
最后是评估。我建议准备5张测试图片,每张图准备3个不同类型的追问,把Agent的完整对话保存下来,人工检查三类失败点:视觉提取错误、检索结果未命中、回答内容跑偏。统计每一类的比例,针对性地修改prompt和工具描述。这个评估习惯可能有些耗时,但这是区分"能跑Demo"和"能交付"的一个重要标志。
5. 常见问题排查与面试避坑经验
最后一个部分,我把自学Agent的过程中经常遇到的问题整理出来,同时聊聊面试里真正能拉开差距的表达方式。
5.1 自学阶段最容易踩的五个坑
第一个坑,也是最经典的:模型在工具还没执行时就开始编造结果。常见原因是没有真正接入ToolNode,只是用提示词假装"模型会调用工具",或者是循环中没有检查模型返回的tool_calls字段。排查方式很简单:打印模型原始返回,看看里面是否存在结构化的工具调用字段,如果没有,说明模型压根没走工具循环。
第二个坑,死循环。我见过一个案例,Agent反复调用"获取图片尺寸"工具,因为它的系统提示词要求"必须先确认图片存在",而工具返回值里没有它想要的"图片格式"字段,于是模型不断重试。解决思路有两个:一是修正工具返回值,让返回内容完整覆盖模型关心的字段;二是在路由函数里加最大重试次数,超过次数强制结束,类似我们前面项目里的retry_count。
第三个坑,上下文爆炸。很多人习惯把整张图片的base64编码塞进messages字段,每次循环都传一遍,很快就把模型的上下文窗口撑爆了。正确的做法是,图片数据只在视觉节点内部做一次推理,节点往State里写入的是"图片被翻译出来的文字描述",而不是图片本身。
第四个坑,状态字段被覆盖。多个节点都往同一个字段写数据,又没有声明合并方式,结果某些中间结果莫名其妙丢失。排查时先确认这个字段应该是覆盖还是追加,追加就使用Annotated[list, operator.add]。
第五个坑,视觉模型本身也在幻觉。视觉模型同样可能编造图片里不存在的内容。解决方式是在视觉节点的prompt里明确要求"只描述可见内容,不确定就写不确定",同时在下游节点对描述结果做合理性校验。很多人只防语言模型幻觉,忽略了视觉模型这一层,这个细节如果能在面试里主动提出来,会是明显的加分项。
5.2 面试时真正拉开差距的表达方式
能在简历上写LangGraph的人很多,但面试官真正想考察的是你有没有把框架理解成原理,而不是只会调用API。
我整理了三个最高频的考察角度:
- StateGraph和Chain的区别在哪里。比较好的回答是:Chain是编译期就确定的线性管道,流程固定;StateGraph是运行期由状态驱动的图,天然支持条件分支和循环,更适合表达Agent的决策过程。
- 工具调用出错怎么办。不要只说"加try except"。更好的答案是:节点内部捕获异常并重试,路由函数根据错误类型决定走修复节点还是降级节点,最后用最大轮次兜底,确保Agent不会无限卡住。
- 多模态信息在Agent里怎么组织。最好是能说明:图片不直接进入模型上下文,而是先由视觉工具转换成结构化文本,再参与后续的决策和对话。这是CV+Agent岗位区别于纯文本Agent最重要的设计点。
我建议你把项目复盘按照"项目背景、架构设计、遇到的坑、你的解决方案"四段式准备,控制在三分钟讲完。不要只说做了什么,要说清楚为什么这么做,以及做的时候怎么取舍。面试官对"为什么"的兴趣远远大于"What"。
最后再分享一个面试加分项:准备一个小型评估集。你可以说,我为项目准备了10个测试案例,其中5个是图片识别场景,5个是连续追问场景,用来做版本回归。这个话题一出,面试官会觉得你不仅有实现能力,还具备工程交付意识。
我个人在带人做Agent方向转型时最深的体会是:LangGraph本身的学习曲线并不陡峭,真正难的是建立"Agent运行画面"——状态在节点间流动,模型在决策,工具在执行,条件边在不断判断方向。脑子里有了这个画面,写代码只是把它落到语法上;没有这个画面,学多少API都容易散。希望这份自学计划对正在准备这个岗位方向的朋友有实际帮助,也欢迎在实践中遇到具体问题后多回来翻翻,对照自查。
