LangGraph构建数据分析智能体:从工作流编排到生产级实践

news2026/5/4 6:21:04
1. 项目概述当LangGraph遇上数据分析智能体如何重塑工作流最近在开源社区里看到一个挺有意思的项目叫abh2050/langgraph_data_analytics_agents。光看名字就能嗅到一股“组合拳”的味道LangGraph、数据分析、智能体。这可不是简单的工具堆砌它瞄准的是一个非常具体的痛点——如何让数据分析这个传统上依赖专业工具和人工经验的过程变得自动化、智能化并且能够像搭积木一样灵活编排。简单来说这个项目试图用 LangGraph 这个新兴的框架来构建一个或多个专门用于数据分析的智能体Agent。LangGraph 是什么你可以把它理解为一个专门为构建复杂、有状态的智能体应用而生的“流程图”工具。它让智能体之间的协作、状态流转、条件分支变得可视化、可编程。而数据分析恰恰是一个充满了“如果…那么…”、需要多步骤协作、并且严重依赖上下文状态的典型场景。比如从“理解用户问题”到“查询数据库”再到“清洗数据”、“生成图表”、“撰写报告”每一步都环环相扣上一步的结果直接影响下一步的决策。abh2050/langgraph_data_analytics_agents这个项目就是探索用 LangGraph 来优雅地解决这个链条问题。它适合谁呢首先肯定是数据工程师、数据分析师或者任何需要频繁处理数据、生成洞察的开发者。如果你厌倦了在 Jupyter Notebook 里写一堆胶水代码或者在多个工具间来回切换这个项目提供了一个全新的思路。其次对于想要深入理解“智能体工作流”和“LangGraph 实战应用”的 AI 应用开发者来说这是一个绝佳的研究和参考案例。它不只是一个工具更是一个设计模式的展示。2. 核心架构与设计哲学为什么是LangGraph2.1 从单体Agent到协同工作流在传统的智能体开发中我们常常会陷入一个困境要么构建一个“全能”但臃肿的巨型智能体它试图用一套复杂的提示词Prompt和工具集解决所有问题要么构建多个单一功能的智能体但让它们协同工作又变得异常困难需要开发者手动处理消息传递、状态管理和错误恢复。abh2050/langgraph_data_analytics_agents项目选择了一条更清晰的道路基于工作流Workflow的智能体编排。LangGraph 的核心概念是“图”Graph。在这个图里节点Node代表一个执行单元比如一个特定的智能体或一个工具函数边Edge代表执行路径决定了在某个节点执行完毕后下一步该去哪里。更重要的是LangGraph 引入了“状态”State的概念这是一个在所有节点间共享的上下文对象。数据分析的每一步——用户查询、解析出的意图、查询到的原始数据、清洗后的数据、生成的图表路径、分析结论——都可以作为状态的一部分进行传递和更新。这种设计带来了几个显著优势模块化与可复用性每个数据分析步骤如 SQL 生成、数据可视化、报告总结都可以被封装成一个独立的节点。这些节点可以像乐高积木一样在不同的分析工作流中被重复使用。清晰的逻辑与可调试性整个数据分析流程被可视化为一张图。你可以清晰地看到数据从输入到输出的完整路径哪个环节出错、状态如何变化一目了然。这对于调试复杂流程至关重要。支持复杂控制流数据分析中经常需要条件判断。例如如果查询结果为空可能需要尝试另一种查询方式或直接返回“无数据”如果数据量过大可能需要先进行采样再分析。LangGraph 的条件边Conditional Edge和分支机制可以非常自然地表达这些逻辑。持久化与恢复LangGraph 支持将工作流的状态持久化。这意味着一个长时间运行的分析任务可以被中断之后从断点恢复而不会丢失中间结果。2.2 项目可能的核心节点设计推测基于数据分析的通用流程我们可以合理推测abh2050/langgraph_data_analytics_agents项目可能包含以下几类核心节点查询理解与规划节点接收用户的自然语言查询如“上季度各区域销售额趋势如何”。该节点可能利用一个大语言模型LLM来解析用户意图识别关键实体时间上季度维度区域指标销售额并生成一个初步的分析计划存入状态。数据查询与获取节点根据规划生成结构化的查询语句如 SQL、API 调用参数。这个节点可能需要访问数据库 schema 信息或 API 文档。执行查询并将原始结果数据存入状态。数据清洗与转换节点原始数据往往包含缺失值、异常值或格式不一致的问题。这个节点负责执行一些标准化的数据清洗操作如处理空值、统一日期格式、过滤无效记录等为后续分析做好准备。分析与计算节点执行具体的计算逻辑如聚合求和、平均、排序、同比/环比计算、统计检验等。这个节点可能调用 pandas、numpy 等库或使用 LLM 进行更复杂的推理分析。可视化生成节点根据数据特性和分析目标选择合适的图表类型折线图、柱状图、散点图等调用如 matplotlib、plotly 或 seaborn 等库生成图表图像并将文件路径或 base64 编码存入状态。洞察总结与报告生成节点这是画龙点睛的一步。该节点综合前面的所有结果数据、图表使用 LLM 生成一段简洁、准确、有业务洞察力的文字总结甚至格式化为一小段报告。注意以上节点划分是一种逻辑上的推测。在实际项目中可能会根据复杂度进行合并或进一步拆分。例如可能将“查询生成”和“查询执行”合并为一个节点或者将“多种图表生成”拆分成多个专用节点。2.3 状态State设计的关键考量状态对象是这个工作流的“中央数据总线”。它的设计至关重要。一个典型的数据分析智能体状态可能包含以下字段from typing import TypedDict, List, Any, Optional from langgraph.graph.message import add_messages import pandas as pd class AgentState(TypedDict): # 用户输入与解析结果 user_input: str parsed_intent: Optional[dict] # 例如{“metrics“: [“sales“], “dimensions“: [“region“], “time_range“: “last_quarter“} analysis_plan: Optional[str] # 数据相关 raw_query: Optional[str] # 生成的SQL或API请求 raw_data: Optional[Any] # 原始查询结果可能是字典列表或字符串 cleaned_data: Optional[pd.DataFrame] # 清洗后的Pandas DataFrame analysis_results: Optional[dict] # 计算后的关键指标如 {“total_sales“: 100000, “top_region“: “North“} # 输出相关 chart_paths: List[str] # 生成的图表文件路径列表 text_summary: Optional[str] # 文本分析摘要 final_report: Optional[str] # 最终整合报告 # 控制与错误信息 error: Optional[str] current_step: str这种强类型的状态定义使得每个节点都知道自己应该读取和修改哪些部分大大降低了模块间的耦合度也方便了类型检查和自动化测试。3. 关键技术点深度解析与实现方案3.1 LangGraph 工作流构建实战构建一个 LangGraph 工作流就像编写一个状态机。我们以创建一个简化的数据分析链为例。第一步定义状态和节点我们首先定义上面提到的AgentState。然后我们需要创建各个节点函数。每个节点函数接收一个状态字典修改它并返回更新后的状态。from langgraph.graph import StateGraph, END import pandas as pd from some_llm_service import call_llm # 假设的LLM调用函数 from database import execute_query # 假设的数据库查询函数 def query_understanding_node(state: AgentState) - AgentState: 节点1理解用户查询 user_input state[“user_input“] # 构建Prompt让LLM解析查询意图 prompt f“““ 用户查询{user_input} 请将上述自然语言查询解析为结构化的意图。请输出JSON格式包含以下字段 - metrics: 用户关心的指标列表如 [“sales“, “profit“] - dimensions: 用户希望分组的维度列表如 [“region“, “product_category“] - time_range: 时间范围如 “last_month“, “2024“, “Q1-2024“ - filters: 任何过滤条件如 [“region ‘North’“] “““ llm_response call_llm(prompt) # 假设call_llm返回了解析好的字典 parsed_intent llm_response # 这里需要做JSON解析和错误处理 state[“parsed_intent“] parsed_intent state[“analysis_plan“] f“将根据{parsed_intent}进行数据分析。“ state[“current_step“] “query_understood“ return state def data_query_node(state: AgentState) - AgentState: 节点2生成并执行数据查询 intent state[“parsed_intent“] if not intent: state[“error“] “未解析到查询意图。“ return state # 根据意图生成SQL这里简化处理实际应用可能需要更复杂的模板或few-shot sql_template “““ SELECT {dimensions_str}, {metrics_str} FROM sales_data WHERE date BETWEEN ‘{start_date}’ AND ‘{end_date}’ {filter_clause} GROUP BY {dimensions_str} “““ # ... 这里需要将intent转换为具体的SQL组成部分 ... generated_sql “SELECT region, SUM(amount) as total_sales FROM sales_data WHERE quarter‘Q1’ GROUP BY region“ state[“raw_query“] generated_sql try: query_result execute_query(generated_sql) # 返回可能是列表的字典 state[“raw_data“] query_result state[“current_step“] “data_retrieved“ except Exception as e: state[“error“] f“数据库查询失败{str(e)}“ return state第二步构建图并设置边创建节点后我们需要将它们连接起来并定义流转逻辑。# 初始化图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(“understand_query“, query_understanding_node) workflow.add_node(“query_data“, data_query_node) workflow.add_node(“clean_data“, data_cleaning_node) # 假设已定义 workflow.add_node(“analyze_data“, data_analysis_node) # 假设已定义 workflow.add_node(“generate_viz“, visualization_node) # 假设已定义 workflow.add_node(“summarize“, summary_node) # 假设已定义 # 设置边的连接定义流程 workflow.set_entry_point(“understand_query“) # 设置入口节点 workflow.add_edge(“understand_query“, “query_data“) # 理解查询后去查询数据 workflow.add_edge(“query_data“, “clean_data“) # 查询数据后去清洗数据 workflow.add_edge(“clean_data“, “analyze_data“) workflow.add_edge(“analyze_data“, “generate_viz“) workflow.add_edge(“generate_viz“, “summarize“) workflow.add_edge(“summarize“, END) # 总结完成后结束工作流 # 编译图 app workflow.compile()第三步运行工作流现在我们可以像调用一个函数一样运行整个数据分析流程。# 初始化状态 initial_state: AgentState { “user_input“: “帮我分析一下上一季度各区域的销售额情况并找出销售额最高的区域。“, “parsed_intent“: None, “raw_data“: None, “cleaned_data“: None, “chart_paths“: [], “text_summary“: None, “error“: None, “current_step“: “start“ } # 执行图 final_state app.invoke(initial_state) print(final_state[“text_summary“]) print(final_state[“chart_paths“])3.2 集成大语言模型LLM的策略与技巧在这个架构中LLM 扮演着“大脑”的角色主要可能在三个节点发挥作用查询理解与规划将模糊的用户需求转化为结构化的分析指令。查询生成根据数据表结构Schema和用户意图生成准确的数据查询语句如 SQL。报告总结将数字和图表转化为有洞察力的自然语言描述。实操要点与避坑指南提示词工程是关键每个节点的 Prompt 都需要精心设计。例如在“查询生成”节点最好采用少样本Few-shot提示提供几个“用户问题 - 正确 SQL”的例子并明确给出数据库表结构这能极大提高 SQL 生成的准确率。上下文管理LangGraph 的状态对象是管理上下文的最佳工具。确保将上游节点的关键输出如解析后的意图、清洗后的数据样本放入状态并作为下游节点 Prompt 的一部分这样 LLM 才能基于完整的上下文工作。成本与延迟优化频繁调用 LLM尤其是大型模型成本高、速度慢。可以考虑以下策略缓存对相同的用户查询和参数缓存解析后的意图或生成的 SQL。模型分级在“报告总结”这种需要创造力的环节用强模型如 GPT-4在“查询理解”这种相对标准的任务上用轻量级或专用模型。异步处理如果某个节点如图表生成耗时很长可以考虑将其设计为异步任务避免阻塞整个同步工作流。错误处理与降级LLM 输出不稳定。必须在关键节点如 SQL 生成后加入验证环节。例如可以用一个简单的 SQL 语法检查器或者尝试在测试数据库上执行生成的 SQL如果失败则触发一个“修复节点”让 LLM 根据错误信息重新生成或回退到更简单的查询方案。3.3 数据处理与可视化的无缝衔接数据处理节点清洗、分析是工作流中确定性最强的部分通常使用 pandas、numpy 等成熟库。关键点在于如何与前后节点顺畅对接。数据格式约定在状态中最好使用如 Pandas DataFrame 这样结构清晰、操作方便的数据结构作为“清洁数据”的标准格式。raw_data节点负责将数据库结果转换为 DataFrame后续所有节点都基于这个 DataFrame 操作。可视化节点的灵活性generate_viz节点不应该硬编码图表类型。它应该根据analysis_results中的数据特征比如是时间序列、类别对比还是分布情况和用户的隐含需求从parsed_intent中推断动态选择最合适的图表。可以内置一个简单的决策逻辑def decide_chart_type(data: pd.DataFrame, intent: dict) - str: if “time_range“ in intent: return “line“ # 时间趋势用折线图 elif len(intent.get(“dimensions“, [])) 1: return “bar“ # 单一维度对比用柱状图 else: return “table“ # 其他情况先用表格展示输出管理生成的图表可以保存为文件如 PNG并将文件路径存入state[“chart_paths“]也可以转换为 base64 编码的字符串直接嵌入状态方便后续节点如报告生成直接使用。考虑到工作流可能被部署为 APIbase64 编码是更通用的选择但需注意状态体积会增大。4. 高级特性与生产级考量4.1 实现条件分支与循环LangGraph 最强大的特性之一是支持复杂控制流。在数据分析中这非常有用。场景处理空结果用户查询“北京地区的销售额”但数据库中没有北京的数据。简单的线性流程会生成一个空图表和一份无意义的报告。更好的方式是检测到空结果后走另一条分支。from langgraph.graph import StateGraph, END from langgraph.graph import START def check_data_node(state: AgentState) - str: 检查数据节点决定下一步走向 if state.get(“error“): return “handle_error“ # 跳转到错误处理节点 elif state[“raw_data“] is None or len(state[“raw_data“]) 0: return “handle_empty_data“ # 跳转到空数据处理节点 else: return “proceed_to_clean“ # 继续正常清洗流程 # 在构建图时使用 add_conditional_edges workflow StateGraph(AgentState) ... workflow.add_node(“check_data“, check_data_node) workflow.add_node(“handle_empty_data“, empty_data_handler_node) # 定义处理空数据的节点 workflow.add_node(“handle_error“, error_handler_node) # 定义错误处理节点 workflow.add_edge(“query_data“, “check_data“) # 查询数据后进入检查节点 # 根据 check_data 节点的返回值决定下一步 workflow.add_conditional_edges( “check_data“, check_data_node, # 这个函数返回下一个节点的名称 { “handle_empty_data“: “handle_empty_data“, “handle_error“: “handle_error“, “proceed_to_clean“: “clean_data“ } ) workflow.add_edge(“handle_empty_data“, “summarize“) # 空数据处理后直接生成提示性总结 workflow.add_edge(“handle_error“, END) # 错误处理后直接结束场景迭代分析用户问“找出过去一年每周销售额都在增长的地区”。这可能需要一个循环先获取所有地区列表然后对每个地区循环查询其每周数据并判断增长趋势。def get_regions_node(state: AgentState) - AgentState: 获取所有地区列表 state[“regions_to_analyze“] [“North“, “South“, “East“, “West“] # 假设从数据库获取 state[“current_region_index“] 0 state[“growing_regions“] [] return state def analyze_single_region_node(state: AgentState) - AgentState: 分析单个地区的增长趋势 regions state[“regions_to_analyze“] idx state[“current_region_index“] if idx len(regions): # 所有地区分析完毕跳转到最终节点 state[“next“] “finalize“ return state region regions[idx] # ... 执行该地区的周度销售趋势分析逻辑 ... is_growing True # 假设分析结果 if is_growing: state[“growing_regions“].append(region) state[“current_region_index“] idx 1 state[“next“] “analyze_single_region“ # 指示继续分析下一个地区 return state def finalize_node(state: AgentState) - AgentState: 最终汇总 state[“text_summary“] f“持续增长的地区有{‘ ‘.join(state[‘growing_regions‘])}“ return state # 构建带循环的图 workflow StateGraph(AgentState) workflow.add_node(“get_regions“, get_regions_node) workflow.add_node(“analyze_region“, analyze_single_region_node) workflow.add_node(“finalize“, finalize_node) workflow.set_entry_point(“get_regions“) workflow.add_edge(“get_regions“, “analyze_region“) # 关键设置从 analyze_region 出发的条件边实现循环 def decide_next_after_analysis(state: AgentState) - str: return state.get(“next“, “finalize“) # 根据节点设置的‘next‘字段决定去向 workflow.add_conditional_edges( “analyze_region“, decide_next_after_analysis, { “analyze_region“: “analyze_region“, # 循环回自己分析下一个地区 “finalize“: “finalize“ } ) workflow.add_edge(“finalize“, END)4.2 状态持久化与工作流恢复对于长时间运行或重要的分析任务状态持久化是必须的。LangGraph 支持与外部存储集成。from langgraph.checkpoint import MemorySaver # 使用内存检查点生产环境应使用数据库如Redis、PostgreSQL checkpointer MemorySaver() workflow StateGraph(AgentState) # ... 添加节点和边 ... app workflow.compile(checkpointercheckpointer) # 第一次调用传入一个线程IDthread_id用于标识这次会话 config {“configurable“: {“thread_id“: “analysis_123“}} initial_state {“user_input“: “...“} result_state app.invoke(initial_state, configconfig) # 假设工作流因故中断我们可以根据 thread_id 获取最新状态并继续 last_state checkpointer.get_tuple(config) # last_state 包含了中断时的状态和下一步该执行哪个节点 # 我们可以修改一些参数后继续执行 new_state app.invoke({**last_state.values, “user_input“: “修正后的查询...“}, configconfig)在生产中你会使用一个持久化的Checkpointer将状态保存在数据库中。这样即使是服务器重启也能从上次中断的地方继续执行分析任务这对于处理大数据量或复杂分析流程至关重要。4.3 监控、日志与可观测性一个健壮的生产系统离不开监控。我们需要知道工作流每个节点的执行情况。结构化日志在每个节点的开始和结束处记录日志包含节点名、执行时间、输入/输出状态的关键摘要注意不要记录敏感数据。可以使用像structlog这样的库。链路追踪为每次工作流执行生成一个唯一的trace_id并贯穿所有节点和外部调用如 LLM API、数据库查询。这能帮助你在分布式系统中快速定位问题。性能指标收集每个节点的平均执行时间、成功率、LLM 的 Token 消耗等指标。这对于成本优化和性能瓶颈分析非常有帮助。可视化调试LangGraph 本身提供了将工作流可视化为图像的能力。对于复杂流程将其图结构导出如使用graphviz可以帮助团队成员理解和沟通业务逻辑。# 一个简单的节点装饰器用于添加日志和计时 import time import functools import logging logger logging.getLogger(__name__) def log_node_execution(node_func): functools.wraps(node_func) def wrapper(state: AgentState, configNone): node_name node_func.__name__ trace_id config.get(“configurable“, {}).get(“thread_id“, “unknown“) if config else “unknown“ logger.info(f“[{trace_id}] 开始执行节点: {node_name}“, extra{“state_snapshot“: {k: type(v).__name__ for k, v in state.items()}}) start_time time.time() try: result_state node_func(state, config) duration time.time() - start_time logger.info(f“[{trace_id}] 节点 {node_name} 执行成功耗时: {duration:.2f}s“) return result_state except Exception as e: logger.error(f“[{trace_id}] 节点 {node_name} 执行失败: {str(e)}“, exc_infoTrue) state[“error“] f“节点 {node_name} 失败: {str(e)}“ return state return wrapper # 使用装饰器 log_node_execution def query_understanding_node(state: AgentState, configNone) - AgentState: # ... 原有逻辑 ...5. 常见问题、排查技巧与优化建议在实际构建和运行此类数据智能体工作流时你会遇到一些典型问题。以下是一些实录和解决方案。5.1 问题排查速查表问题现象可能原因排查步骤与解决方案工作流在某个节点后卡住不进入下一个节点。1. 节点函数没有正确返回更新后的state。2. 条件边add_conditional_edges的判断函数返回值与预设的边名称不匹配。3. 节点函数抛出了未处理的异常导致状态流转中断。1. 检查节点函数最后是否return state。2. 在条件判断函数中打印或记录其返回值确认是否与add_conditional_edges中定义的键名一致。3. 在所有节点函数外层添加try...except捕获异常并写入state[‘error‘]并设计一个错误处理节点路由。使用log_node_execution这类装饰器进行跟踪。LLM生成的SQL语法错误导致查询失败。1. Prompt 不够清晰未提供足够的表结构信息或示例。2. LLM 的上下文理解有偏差。3. 用户查询过于复杂或模糊。1.强化Prompt采用 Few-shot 方式提供3-5个高质量、覆盖不同场景的“问题-SQL”对。明确在Prompt中给出数据库Schema。2.加入验证层在data_query_node之前增加一个validate_sql_node。这个节点可以尝试进行简单的语法解析使用sqlparse库或者在一个隔离的、只有Schema的测试数据库上执行EXPLAIN命令检查SQL是否有效。如果无效则路由到“SQL修复节点”。3.用户澄清对于模糊查询可以设计一个节点让工作流暂停通过交互如API返回问题向用户请求澄清再将澄清后的信息注入状态重新开始分析。最终生成的报告内容空洞只是罗列数据。报告总结节点LLM缺乏足够的上下文和指导。1.丰富状态输入不要只把最终数据给总结节点。将parsed_intent用户原始问题、analysis_results中的关键发现如“同比增长最高的区域是X”也作为 Prompt 的一部分输入给 LLM。2.设计报告模板在 Prompt 中明确要求报告的结构例如“首先用一句话概括核心结论然后分点阐述主要发现并引用具体数据最后指出一个值得关注的异常点或趋势。”3.迭代优化收集一些“好报告”和“差报告”的样本用于对总结节点的 Prompt 进行迭代优化和测试。工作流执行速度慢尤其是涉及多个LLM调用时。1. 节点是顺序执行的同步等待每个LLM响应。2. 使用了成本高昂的大模型处理简单任务。1.分析关键路径识别哪些节点是必须顺序执行的如B依赖A的结果哪些可以并行如生成图表和计算统计指标可能可以同时进行。LangGraph 支持并行节点但需要仔细设计状态拆分与合并。2.模型分级对于“查询理解”和“报告总结”可以使用不同的模型配置。前者可用速度快、成本低的模型如 GPT-3.5-Turbo后者再用效果更好的模型如 GPT-4。3.缓存对确定的、重复的查询如相同的user_inputparsed_intent缓存生成的 SQL 甚至分析结果。状态对象变得非常庞大如图片base64影响内存和序列化性能。将大型二进制数据如图片、文件直接存储在状态字典中。1.外部存储将生成的文件图表、文档保存到对象存储如 S3、MinIO或文件系统中在状态里只保存其访问路径或URL。2.流式处理如果后续节点不需要整个文件可以考虑流式读取和处理。3.状态压缩定期清理状态中中间过程数据只保留最终输出和必要的上下文。可以在工作流结束时或某个聚合节点后执行del state[‘large_intermediate_data‘]。5.2 性能与成本优化心得预热与连接池如果你的工作流需要频繁访问数据库或外部 API在应用启动时建立连接池而不是在每个节点中临时创建连接可以大幅减少延迟。异步非阻塞节点对于 I/O 密集型节点如下载数据、调用外部 API可以考虑将其改造为异步函数使用asyncio并在 LangGraph 中配置异步执行避免阻塞整个工作流线程。需要注意的是这需要整个调用栈都支持异步。LLM 调用批处理如果工作流中有多个独立的、可以并行执行的 LLM 调用例如为多个不同的数据片段生成解释可以考虑将它们批量发送给 LLM API如果 API 支持这通常比逐个调用更高效、更便宜。设置超时与重试对于任何外部调用LLM、数据库、API务必设置合理的超时时间并实现重试逻辑最好带有指数退避。这能提高工作流在面对临时网络波动或服务降级时的鲁棒性。5.3 安全与权限考量SQL 注入防护绝对不要让用户输入直接进入 SQLLLM 生成的 SQL 也需要经过严格的校验和参数化。可以使用 ORM 或查询构建器来生成 SQL或者至少使用白名单机制校验表名和字段名。数据访问控制工作流运行时所在的上下文数据库连接、API Token应具有最小必要权限。例如数据分析智能体可能只需要读取特定视图的权限而不是整个数据库。输入输出过滤对用户输入和 LLM 生成的最终报告内容进行必要的审查和过滤防止生成不当或有害内容。审计日志记录下谁、在什么时候、执行了什么查询、产生了什么结果。这对于满足合规性和事后追溯至关重要。可以将这些审计信息写入专门的日志系统或数据库。构建abh2050/langgraph_data_analytics_agents这样的项目远不止是代码的堆砌它更像是在设计一套精密的“数据流水线”。每一个节点都是一个质量控制点每一条边都代表着一种业务逻辑。LangGraph 提供的图抽象让这种设计变得直观和可维护。从简单的线性分析到带条件分支和循环的复杂洞察你都可以通过组合节点来实现。在实际操作中最大的挑战往往不在于 LangGraph 本身而在于如何设计稳定可靠的节点尤其是与 LLM 交互的部分以及如何管理好在整个流程中流动的“状态”。这需要你对数据分析业务、软件工程以及大语言模型的能力和局限都有深入的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2580770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…