从零开始:前端转型AI agent直到就业第十四天-第十七天
- 人工智能
- 3天前
- 8热度
- 0评论
前言
随着AI技术的飞速发展,前端开发领域受到了前所未有的冲击。许多传统的前端工作已经被AI自动化工具所取代,特别是在常规的页面布局和交互设计方面。对于拥有多年前端经验的开发者来说,如何在新的技术浪潮中找到自己的位置,成为了一个亟待解决的问题。本文将分享一位资深前端开发者在失业期间,通过自学AI技术,成功转型为AI Agent开发者的经历和心得。
心路历程
最近,这位开发者完成了对LangChain和LangGraph相关知识点的学习,并准备进入实战阶段。虽然这段时间减少了锻炼,但他意识到身体健康的重要性,计划在接下来的日子里恢复锻炼。他希望通过自己的努力,能够产出一个有价值的智能体项目,并与大家分享项目回顾和总结。
此外,他在学习过程中遇到了一些挑战,特别是如何提高专注力。有时候,学习概念知识时容易分心,尤其是在没有实际编程操作的情况下。为了克服这一问题,他尝试了多种方法,包括定期休息、整理知识文档和阅读伟人的名言,以激励自己继续前进。
时间分配
最近的学习时间安排并不十分规律。早晨有时会晚起,花时间查看股票市场,休息时间也有所增加。尽管如此,他依然坚持每天投入一定的时间进行技术学习。为了更好地管理时间,他建议制定详细的学习计划,并严格执行,以确保学习效果。
知识总结
LangGraph 基础概念
一句话理解 LangGraph
> LangGraph = LangChain 的“图级编排器”
> 把线性流水线变成地铁网,支持分支、循环、回退和模块化。
生活比喻:
- LangChain 像流水线:A→B→C,顺序固定
- LangGraph 像地铁图:可分支、循环、折返、换乘
核心四要素
| 概念 | 作用 | 代码对应 |
|---|---|---|
| State(状态) | 节点间传递的数据 | class StateObj(TypedDict) |
| Nodes(节点) | 执行具体任务 | graph.add_node("model", modelCb) |
| Edges(边) | 定义执行顺序 | graph.add_edge(START, "model") |
| Graph(图) | 整体结构容器 | StateGraph(StateObj) |
基本连接LLM代码
from typing import TypedDict, Annotated, List
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os
load_dotenv(encoding='utf-8')
# 关键:Annotated + add_messages 实现消息追加而非覆盖
class StateObj(TypedDict):
messages: Annotated[List, add_messages]
llm = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 关键:每个节点接收当前状态,返回部分更新
def modelCb(state: StateObj) -> StateObj:
reply = llm.invoke(state["messages"])
state["messages"].append({"role": "assistant", "content": reply})
return state代码解释
定义状态(State):
- 使用 TypedDict 和 Annotated 来定义状态对象 StateObj,其中 messages 是一个列表,用于存储对话消息。
- add_messages 函数确保消息列表在传递过程中不会被覆盖,而是追加新消息。
初始化大模型:
- 使用 init_chat_model 函数初始化一个大模型实例 llm,指定模型名称、提供商、API密钥和基础URL。
- 通过 os.getenv 从环境变量中读取API密钥,确保安全性。
定义节点函数:
- modelCb 函数接收当前状态 state,调用大模型的 invoke 方法生成回复。
- 将生成的回复添加到 messages 列表中,并返回更新后的状态对象。
总结
通过本文的分享,希望读者能够对从零开始构建AI Agent的过程有一个清晰的认识。无论是前端开发者还是其他领域的技术人员,都可以借鉴这位开发者的经验和方法,逐步掌握AI技术,实现职业转型。建议在学习过程中注重理论与实践相结合,合理安排时间,保持良好的生活习惯,不断提升自己的技术水平和竞争力。
4. 构建图
graph = StateGraph(StateObj) # 创建图,绑定状态类型
graph.add_node("model", modelCb) # 添加节点
graph.add_edge(START, "model") # 起点 → 模型节点
graph.add_edge("model", END) # 模型节点 → 终点在这段代码中,我们首先创建了一个 StateGraph 实例,并绑定了状态类型 StateObj。然后,我们添加了一个名为 "model" 的节点,并定义了从起点 START 到该节点以及从该节点到终点 END 的边。这一步骤构建了图的基本结构,为后续的编译和运行奠定了基础。
5. 编译运行
app = graph.compile()
result = app.invoke({"messages": "请简单说明一下LangGraph的运作流程"})
print(result["messages"][-1].content)通过调用 graph.compile() 方法,我们将图编译成一个可执行的 Runnable 对象 app。接着,我们使用 app.invoke() 方法传递初始状态,并获取最终结果。这里,我们传递了一个包含消息的字典,并打印出最后一条消息的内容。这一步骤展示了如何实际运行图结构并获取结果。
6. 可视化图结构
1. 打印图的ASCII可视化结构
print(app.get_graph().print_ascii())
print("="*50)通过 app.get_graph().print_ascii() 方法,我们可以以 ASCII 形式打印图的结构。这对于调试和理解图的拓扑结构非常有帮助。打印结果将以文本形式展示节点和边的关系,便于快速查看。
2. 打印图的Mermaid代码可视化结构
print(app.get_graph().draw_mermaid())app.get_graph().draw_mermaid() 方法生成图的 Mermaid 代码,可以通过在线工具如 ProcessOn 的 Mermaid 编辑器进行可视化。这种方法提供了更直观的图形展示,有助于更好地理解和分享图结构。
代码中的三个关键机制
1. Annotated[List, add_messages]
- 作用: 告诉 LangGraph 新消息追加到列表末尾,而不是覆盖。
- 不加的话: 每次返回 {"messages": [reply]} 会丢掉之前的对话历史。
通过使用 Annotated[List, add_messages],我们可以确保每次返回的消息都会被追加到现有列表中,而不是覆盖原有的对话历史。这对于维护连续的对话上下文非常重要。
2. 节点函数只返回部分状态
- 作用: LangGraph 自动将返回值合并到当前状态。
- 好处: 不需要返回整个 StateObj,极大简化代码。
节点函数只需返回需要更新的部分状态,LangGraph 会自动将其合并到当前状态对象中。这种方式不仅简化了代码,还提高了代码的可读性和维护性。
3. graph.compile() 的作用
- 作用: 验证图结构(无孤立节点、无不可达节点、无非法循环)。
- 生成: 可执行的 Runnable 对象。
- 准备: 为后续扩展(如检查点、中断等)做准备。
graph.compile() 方法不仅验证图的结构是否正确,还生成一个可执行的 Runnable 对象。此外,它还为后续的功能扩展(如检查点、中断等)做好了准备,确保图在复杂场景下的稳定性和可靠性。
LangGraph 的重要特性
1. 条件分支(Conditional Edges)
- 作用: 根据当前状态选择不同路径。
- 代码示例:
def route(state):
if state["need_human"]:
return "human_node"
return "model_node"
graph.add_conditional_edges("model", route, {"human_node": "human", "model_node": "model"})- 生活比喻: 地铁到站后,根据乘客目的地决定换乘哪条线。
条件分支允许我们在图中根据当前状态动态选择不同的路径,增加了图的灵活性和适应性。
2. 循环(Cycles)
- 作用: 边可以指回之前的节点,形成循环。
- 典型场景: 信息不足时重复搜索,直到条件满足。
- 生活比喻: 坐错站了,坐回头车回到上一站。
循环结构使得图可以在某些条件下反复执行特定的节点,直到满足预定的条件,适用于需要多次迭代的场景。
3. 持久化与断点续跑(Persistence & Interrupt)
- 作用: 使用 checkpointer 保存状态,程序重启后可恢复。
- 代码示例:
from langgraph.checkpoint import MemorySaver
app = graph.compile(checkpointer=MemorySaver())- 生活比喻: 游戏存档,退出后能接着玩。
持久化功能允许我们在程序中断后恢复到之前的状态,确保长时间运行的任务不会因意外中断而丢失进度。
4. 人机协作(Human-in-the-Loop)
- 作用: 图中插入人工节点,interrupt 暂停等待人工输入。
- 典型场景: AI 生成内容后人工审核、敏感操作前人工确认。
- 生活比喻: 自动驾驶遇到复杂路口,让司机接管一下。
人机协作功能使得图可以在需要人工干预的节点暂停执行,等待人工输入后再继续,适用于需要人工审核或确认的场景。
5. 子图(Subgraphs)
- 作用: 一个节点可以是另一个完整的 StateGraph。
- 好处: 模块化、可复用、独立测试。
- 生活比喻: 地铁环线本身是一个完整的图,可以被嵌入全市地铁网。
子图功能允许我们将复杂的图结构分解为多个独立的子图,提高代码的模块化和可复用性,同时也方便独立测试和维护。
6. 时间旅行(Time Travel)
- 作用: 回退到历史某个状态重新执行。
- 生活比喻: 游戏中的“读档”功能。
时间旅行功能使得我们可以在图的执行过程中回退到历史状态,重新执行某些步骤,适用于需要调试或纠正错误的场景。
7. 多智能体协作(Multi-Agent)
- 作用: 多个 Agent 节点在同一图中分工、协调、竞争。
- 架构模式: 网络式、层级式、监督式等。
多智能体协作功能支持多个 Agent 节点在同一图中协同工作,适用于需要多个智能体共同完成任务的复杂场景。
8. 可观测性(Observability)
- 作用: get_graph().print_ascii() 直接打印执行路径。
- 好处: 清晰看到 Agent 的决策路径,快速定位问题。
- 生活比喻: 地铁线路图贴在墙上,永远不会迷路。
可观测性功能使得我们能够清晰地看到图的执行路径和决策过程,有助于快速定位和解决问题,提高系统的透明度和可维护性。
适用场景速查
| ✅ 适合 | ❌ 不适合 |
|---|---|
| 多步复杂推理 | 简单一次性问答 |
| 需要循环/分支的逻辑 | 线性链就够用的场景 |
| 长时间运行任务(需持久化) | 快速原型验证 |
| 需要人工介入 | - |
| 多智能体协作 | - |
| 追求生产级可观测性 | - |
总结
State 是灵魂,Node 是手脚,Edge 是路线,Graph 是地图。
LangGraph 的核心价值在于:把 AI 工作流从线性锁链变成可控的网络,让你能自由实现分支、循环、持久化、人机协作、模块化复用等复杂逻辑。
目标
成为 AI Agent 工程师并且就业。
帮助
感谢大家的关注和支持,你们的鼓励是我前进的动力。希望未来有机会能与各位技术大牛合作,共同成长。