网站 微站建设排名,大带宽云服务器,阳江市招聘最新招聘信息,免费的seoWorkFlow介绍
工作流是 LLM 和工具通过预定义的代码路径进行编排的系统。另一方面#xff0c;智能体是 LLM 动态指导其自身流程和工具使用的系统#xff0c;它们都是构建复杂的大模型应用系统的核心组件。
LangGraph的工作流通过有向图(Directed Graph)定义#xff0c;由节…WorkFlow介绍工作流是 LLM 和工具通过预定义的代码路径进行编排的系统。另一方面智能体是 LLM 动态指导其自身流程和工具使用的系统它们都是构建复杂的大模型应用系统的核心组件。LangGraph的工作流通过有向图(Directed Graph)定义由节点Node、边Edge、状态State构成支持条件分支、循环、并行执行。通过状态图StartGraph将多个智能体Agent和任务节点Node组织成可动态调整的流程结构实现有状态、可扩展的任务编排。LangGraph通过状态图将Agent和工作流解耦让开发者能以“搭积木”的方式构建复杂AI系统:Agent是“乐高积木”负责实现具体功能;工作流是“搭建规则”定义积木如何组合、何时执行。这种设计既保留了灵活性又能通过状态管理实现大规模系统的可靠运行。一句话总结Agent 是一种特殊的节点(Node)而工作流是整个图的运行流程(Graph)。Agent 负责思考行动”工作流负责”编排调度”。相关概念StateGraphLangGraph 的核心是将 Agent 和 WorkFlow 建模为图。可以使用三个关键组件来定义一个Graph:State表示应用程序当前快照的共享数据结构。它可以是任何 Python 类型但通常是TypedDict或Pydantic BaseModel。Nodes编码代理逻辑的 Python 函数。它们接收当前的State作为输入执行一些计算或副作用并返回更新后的State。Edges根据当前State决定接下来执行哪个Node的 Python 函数。它们可以是条件分支或固定转换。构建流程先定义状态再添加节点和边最后编译成图。关键特性节点和边可包含 LLM 或纯 Python 代码支持构建复杂、循环的工作流状态随时间演进。State状态表示应用当前快照的共享数据结构通常是TypedDict或Pydantic模型。包含 schema 和 reducer 函数决定如何应用更新。Reducer 函数指定状态更新的方式默认覆盖也可自定义合并逻辑如add_messages用于消息列表的智能更新。MessagesState预构建的常用状态包含消息列表支持子类化扩展字段。Node节点执行具体逻辑的 Python 函数接收状态和可选配置作为输入返回状态更新。特殊节点START用户输入的入口节点。END终止节点。Edge边决定节点间的路由逻辑。普通边固定从一个节点到另一个节点。条件边根据路由函数的返回值动态决定下一个节点可并行执行多个节点。路由函数接收当前状态返回节点名称或映射值。案例评估器使用LangGraphLangChain 的一个扩展库构建了一个循环式工作流workflow用于自动生成并评估笑话如果笑话不够好笑就基于反馈重新生成直到达到“有趣”的标准为止。一个典型的LLM Agent 反馈循环Feedback Loop架构。大致流程如下用户提供一个主题topic系统生成一个笑话LLM 对笑话进行评估是否有趣 改进建议如果不有趣 → 带着反馈重新生成如果有趣 → 结束流程代码实现创建项目创建项目参考第三版1、LangGraph之基本介绍项目生成定义大模型importosimportdotenvfromlangchain_openaiimportChatOpenAI dotenv.load_dotenv()llmChatOpenAI(api_keyos.getenv(OPENAI_API_KEY),base_urlos.getenv(OPENAI_BASE_URL),modelQwen/Qwen2.5-72B-Instruct,)核心代码实现graph.pyfromtypingimportTypedDict,Literalfromlangchain_core.output_parsersimportStrOutputParserfromlanggraph.constantsimportSTART,ENDfromlanggraph.graphimportStateGraphfrompydanticimportBaseModel,Fieldfromagent.ai_modelimportllmclassState(TypedDict):joke:str# 笑话内容topic:str# 笑话主题feedback:str# 评估反馈funny_or_not:str# 评定是否为笑话# 结构化输出模型用于LLM评估反馈classFeedback(BaseModel):使用此工具来结构化响应内容grade:Literal[funny,not_funny]Field(examples[funny,not_funny],description笑话是否有趣)feedback:strField(description若不幽默提供改进建议,examples[可以加入双关语或意外结局])# 节点函数defgenerator_joke(state:State):生成一个笑话prompt(f根据反馈改进笑话{state[feedback]}\n主题{state[topic]}ifstate.get(feedback,None)elsef根据主题生成笑话{state[topic]})chainllm|StrOutputParser()return{joke:chain.invoke(prompt)}defevaluate_joke(state:State):评估笑话是否 有趣# 第一种写法只适用于gpt等少量模型# chain llm.with_structured_output(Feedback)# resp: Feedback chain.invoke(# f评估此笑话的幽默程度\n{state[joke]}\n# 注意幽默应包含意外性或巧妙措辞# )# return {feedback: resp.feedback, funny_or_not: resp.grade}# 第二种写法通用chainllm.bind_tools([Feedback])evaluationchain.invoke(f评估此笑话的幽默程度\n{state[joke]}\n注意幽默应包含意外性或巧妙措辞)evaluationevaluation.tool_calls[-1][args]print(fevaluation:{evaluation})return{feedback:evaluation.get(feedback,),funny_or_not:evaluation.get(grade,not funny)}# 条件边的路由函数defroute_func(state:State):动态路由决策函数return(Acceptifstate.get(funny_or_not,None)funnyelseReject Feedback)# 构建工作流builderStateGraph(State)# 添加节点builder.add_node(joke_generator,generator_joke)builder.add_node(joke_evaluator,evaluate_joke)# 添加边builder.add_edge(START,joke_generator)builder.add_edge(joke_generator,joke_evaluator)builder.add_conditional_edges(joke_evaluator,route_func,{Accept:END,Reject Feedback:joke_generator})# 编译工作流graphbuilder.compile()核心代码解析1. 类型定义StateclassState(TypedDict):joke:str# 当前生成的笑话topic:str# 用户提供的主题feedback:str# 上一轮评估给出的改进建议funny_or_not:str# funny 或 not_funnyState是整个工作流的状态容器所有节点共享这个状态。每次节点执行后会返回一个字典如{joke: ...}更新State中的部分字段。2. 结构化输出模型FeedbackclassFeedback(BaseModel):grade:Literal[funny,not_funny]Field(...)feedback:strField(...)这是一个Pydantic 模型用于强制 LLM 输出结构化的评估结果。grade只能是funny或not_funny通过Literal限制。feedback字段用于提供改进建议如“加入双关语”。 为什么需要结构化因为 LLM 默认输出是自由文本但我们需要程序能可靠地提取“是否有趣”和“建议”所以用工具调用tool calling或结构化输出来约束格式。3. 节点函数(1)generator_joke(state: State)defgenerator_joke(state:State):prompt(f根据反馈改进笑话{state[feedback]}\n主题{state[topic]}ifstate.get(feedback,None)elsef根据主题生成笑话{state[topic]})chainllm|StrOutputParser()return{joke:chain.invoke(prompt)}返回{joke: ...}更新状态中的joke字段。(2)evaluate_joke(state: State)defevaluate_joke(state:State):chainllm.bind_tools([Feedback])evaluationchain.invoke(f评估此笑话的幽默程度\n{state[joke]}\n注意幽默应包含意外性或巧妙措辞)evaluationevaluation.tool_calls[-1][args]return{feedback:evaluation.get(feedback,),funny_or_not:evaluation.get(grade,not funny)}更新状态中的feedback和funny_or_not。✅ 为什么用bind_tools而不是with_structured_outputwith_structured_output仅支持部分模型如 GPT-4o、Claude 3.5 等原生支持 JSON schema 的。bind_tools是更通用的方式几乎所有支持 function/tool calling 的模型都能用包括开源模型如 Llama 3.1 function calling 微调版。4. 路由函数route_funcdefroute_func(state:State):returnAcceptifstate.get(funny_or_not)funnyelseReject Feedback根据评估结果决定下一步如果funny_or_not funny→ 走向END接受否则 → 回到joke_generator拒绝并反馈注意返回的字符串必须与add_conditional_edges中的 key 一致。5. 构建工作流图StateGraphbuilderStateGraph(State)# 添加节点builder.add_node(joke_generator,generator_joke)builder.add_node(joke_evaluator,evaluate_joke)# 边连接builder.add_edge(START,joke_generator)builder.add_edge(joke_generator,joke_evaluator)# 条件边核心实现循环builder.add_conditional_edges(joke_evaluator,route_func,{Accept:END,Reject Feedback:joke_generator})graphbuilder.compile()6. 图结构START ↓ joke_generator → joke_evaluator ↘ (if not funny) ↖___________ (loop back) ↘ (if funny) → ENDadd_conditional_edges是实现动态路由/循环的关键。整个工作流可以执行多次迭代直到笑话被判定为“funny”。7. 潜在改进点防止无限循环可添加最大重试次数如最多3次避免 LLM 一直生成不好笑的笑话。方法在State中加attempt_count在route_func中判断。初始状态简化调用时只需传topic其他字段可设默认值可通过__init__或预处理实现。效果演示代码仓地址langgraph-workflow-evaluator自此本文分享到此结束