ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从 0 到 1 构建制造业 ChatBI Agent:LangGraph + DuckDB 实战全解析

从 0 到 1 构建制造业 ChatBI Agent:LangGraph + DuckDB 实战全解析 从 0 到 1 构建制造业 ChatBI AgentLangGraph DuckDB 实战全解析基于 LangGraph DuckDB ChromaDB 构建制造业运营态势智能分析 Agent实现自然语言查询产量、质量、能耗、交付核心指标自动检测异常、定位根因、预测趋势。文章涵盖架构设计、核心算法、工程化实践与踩坑经验适合对 Text2SQL / Agent 编排 / 制造业数字化转型感兴趣的开发者。一、项目背景制造业的数据门槛问题制造业管理层每天要看产量、质量、能耗、交付四大类核心指标但传统方式有四个痛点痛点现状查询门槛高厂长不懂 SQL依赖分析师出数响应周期小时~天级分析维度固化传统 BI 报表固定维度无法追问为什么 M003 缺陷率偏高异常发现滞后缺乏自动预警异常往往事后复盘才发现多角色信息割裂厂长/车间主任/质量负责人关注点不同系统难适配核心问题数据与业务人员之间隔着一道 SQL 门槛。我们的方案用自然语言对话替代手写 SQL让厂长问一句6月运营情况怎么样就能秒级拿到四大维度洞察还能自动检测异常、定位根因、预测趋势。二、技术选型组件选型理由Agent 编排LangGraph原生支持条件路由、子图嵌套、checkpoint 持久化数据引擎DuckDB嵌入式零配置、列存引擎、原生 CSV 加载、兼容 PG 语法向量检索ChromaDBSchema Linking 语义检索、Few-Shot 问答示例存储前端Streamlit快速构建数据应用、支持流式渲染LLMAnthropic / OpenAI通过 LangChain 统一接口支持切换为什么选 LangGraph 而不是直接用 LangChain AgentLangChain Agent 主要是 ReAct 循环一个循环而我们的场景需要一张图的结构条件路由根据用户意图分发到 6 条路径查询/趋势/对比/异常/日报/闲聊子图嵌套Text2SQL 是 6 步流水线作为子图嵌入主图Checkpoint 持久化多轮对话需要保存状态支持中断恢复三、8 层分层架构L0 common/ 共享常量、状态类型、流式事件定义 L1 ui/ Streamlit 前端 L2 core.py 核心查询接口编排 L3 agent/ LangGraph Agent 图主图 子图 L4 analysis/ 异常检测、趋势预测、根因分析 L5 query/ Text2SQL 引擎 L6 output/ 可视化、报告导出 L7 semantic/ 语义层 RAG L8 data/ DuckDB 数据层分层三个好处依赖方向清晰高层 → 低层单向流动无循环依赖可替换性DuckDB 换 PostgreSQL 只改 L8上层不受影响可测试性每层独立测试analysis 层算法不依赖 LLM循环依赖通过依赖注入消除构造函数注入 LLM、回调注入 answer_fn全局组件通过_ComponentManager线程安全单例管理。四、核心实现4.1 Text2SQL6 步流水线 三级降级直接让 LLM 生成 SQL 有三个问题表选择不准、SQL 质量不可控、错误不能自修复。我们设计了 6 步流水线Schema Linking → SQL 生成 → 执行 → 错误恢复 → 置信度评分 → 门控决策三级降级策略是关键设计# ① QueryPlan 确定性编译优先零 LLM 调用毫秒级响应try:planparse_to_query_plan(question)sqlcompile_plan_to_sql(plan)exceptParseFailed:# ② LLM 生成回退丰富上下文生成 SQLtry:sqlllm_generate_sql(question,schema,few_shot_examples)exceptLLMFailed:# ③ 规则化 SQL 模板兜底保证核心功能可用sqlrule_based_sql(question)简单查询走 QueryPlan 快速通道零 LLM 调用复杂查询走 LLM兜底走规则模板。4.2 Schema Linking三路融合检索选表是 Text2SQL 准确率的关键。单一检索方式各有缺陷我们采用三路融合检索路权重优势短板BM25 关键词0.4精确匹配产量→产量表不理解同义词编辑距离0.3容错匹配“各线→产线”不理解语义向量语义0.3语义理解能耗偏高→能耗表可能误匹配# 综合得分 0.4×BM25 0.3×编辑距离 0.3×向量语义 → 取 Top-5score0.4*bm25_score0.3*edit_score0.3*vector_score为什么不用纯向量检索用户说产量向量可能匹配到产能而不是产量表。BM25 保证精确关键词命中编辑距离处理拼写错误向量补充语义理解。4.3 异常检测5 因子正交评分从 4 个维度并行扫描质量缺陷率、产量达成率、能耗偏离、订单延期。每条异常用 5 个正交因子加权评分因子权重作用偏差显著性0.35z-score 衡量偏离程度方向权重0.20缺陷率↑、达成率↓更重要业务量调制0.15高产量期异常更关键历史频率0.15频繁异常降权防噪声持续时间0.15连续多天异常更可信噪声估计用一阶差分 MAD中位数绝对偏差比标准差对趋势数据更鲁棒——直接用标准差一段持续上升的趋势会被误判为异常。4.4 根因分析Recursive Adtributor传统 ChatBI 只告诉你哪里异常我们还能告诉你为什么异常。M003 车型缺陷率偏高severe ├─ 第 1 层产线 → L002解释力 68% ├─ 第 2 层工序 → 焊装解释力 82% └─ 第 3 层缺陷类型 → 焊点虚焊解释力 91%用解释力TE JS 散度惊奇度加权评分累积解释力达 90% 停止下钻递归最深 3 层。一条完整的根因链自动生成而且是跨表关联出来的。4.5 Agent 图编排11 节点 条件路由START → role_routing → conversation_load → intent_identification ↓ [条件路由: route_by_intent] ↓ ┌──────────┬──────────┬──────────┬──────────┬──────────┐ text2sql report anomaly trend compare off_topic ↓ ↓ ↓ ↓ ↓ [route_after_tool: 重试循环] ↓ data_quality → answer_generation → END闭包工厂模式解决 checkpoint 可序列化问题DuckDB 连接、LLM 实例等运行时依赖不可序列化通过闭包工厂在图编译时注入到节点函数的闭包中state 仅持有可序列化的基本类型。五、工程化实践5.1 SQL 安全 3 层纵深# 第 1 层只读验证12 种危险操作正则 字面量/注释剥离防绕过ifnotvalidate_readonly_query(sql):raiseSQLSafetyError(禁止的非只读操作)# 第 2 层事务回滚即使漏网也不产生副作用BEGIN TRANSACTION → 执行 → ROLLBACK# 第 3 层行数限制子查询包装 LIMIT fetchmany 双重保护字面量/注释剥离是防绕过的关键攻击者可能把危险操作藏在字符串里SELECT -- DROP TABLE x FROM t剥离后才能正确检测关键字。5.2 日志系统控制台 文件轮转双通道项目初期日志只输出到控制台排查问题无法回溯历史。我们新增了统一日志初始化模块# logging_config.pydefsetup_logging(config_pathNone):控制台 文件轮转双通道自动创建 logs/ 目录。# RotatingFileHandler单文件 10MB保留 5 个历史文件file_handlerRotatingFileHandler(log_file,maxBytes10*1024*1024,backupCount5,encodingutf-8)root_logger.addHandler(console_handler)root_logger.addHandler(file_handler)在cli.py和ui/app.py入口统一调用防重复配置Streamlit rerun 时不会重复添加 handler。5.3 查询缓存缓存键含角色视角不同角色厂长/质量负责人对同一问题得到不同结果。初期缓存键只用 question导致质量经理问产量情况会命中厂长的缓存。修复# 缓存键加入 role避免不同角色视角命中同一缓存cache_keyf{current_role}::{question}5.4 图编译缓存build_main_agent_graph每次调用都重建并编译 LangGraph 图是不必要的开销。用模块级变量缓存_compiled_main_graphNone_compiled_graph_keyNoneif_compiled_main_graphisnotNoneand_compiled_graph_key_graph_key:main_agent_graph_compiled_main_graph# 缓存命中else:main_agent_graphbuild_main_agent_graph(...)_compiled_main_graphmain_agent_graph# 缓存编译结果六、踩坑记录6.1 流式回退重跑整条链路问题流式执行后result_data为 None 时回退调用answer()重跑整条 LangGraph 链路导致重复 LLM 调用。修复纯文本回答如 off_topic已有final_answer不需要回退。只有既无数据又无文本时才回退# 仅当流式既无数据也无文本回答时才回退ifresult_dataisNoneandnotfinal_answer:result_fullanswer(question,...)6.2 季节跨年越界判断缺失问题冬季12-2月跨年越界判断逻辑中m_start m_end分支没有返回越界提示错误执行到return None导致数据范围 3-6月查冬季不提示越界。修复补充跨年季节越界的 return 提示ifm_startm_end:ifdata_end_mm_startordata_start_mm_end:returnNone# 有交集不越界# 补充越界提示returnf您查询的{label}不在数据范围内请调整查询时间。6.3 跨年日期范围解析丢年份问题2025年5月1日到2026年3月31日只取第一个年份结束日期用错年份。修复使用正则的第二个年份组y1int(m.group(1))ifm.group(1)elsebase_year y2int(m.group(4))ifm.group(4)elsey1# 使用结束年份6.4 Python 模块短路径与长路径混用问题from common.date_parser import和from manusight.common.date_parser import混用导致DateOutOfRangeError类身份不一致pytest.raises无法捕获异常。修复统一使用manusight.*前缀导入。七、项目整理与规范化7.1 图片整理项目根目录曾散落 10 张截图image.png、image-1.png…统一整理到docs/images/并语义化命名docs/images/ ├── ui-overview.png # 整体布局 ├── ai-thinking-process.png # AI 思考过程 ├── energy-by-line.png # 各产线单车电耗 ├──>7.2 依赖修正扫描项目实际 import 语句对比requirements.txt操作依赖原因新增langchain-core13 处使用langchain_core.messages新增langchain-anthropicAnthropic LLM 支持新增pydanticBaseModel数据模型新增markdown报告 HTML 导出移除structlog项目用标准库logging移除sqlparse项目用正则做 SQL 安全检查八、华为云码道实战10 个高级使用技巧本项目全程使用**华为云码道CodeArts**作为开发助手从代码理解到 Bug 修复、从文档整理到依赖检查大幅提升了开发效率。以下分享 10 个高级使用技巧。8.1 为什么选择华为云码道优势说明项目级上下文理解不是单文件补全而是理解整个项目 62 个文件的调用链和依赖关系语义代码搜索CodeSemanticSearch按语义匹配代码而非关键词异常处理在哪里直接定位到route_after_tool多 Agent 协作explore agent 快速探索代码库、developer-test-agent 专攻单元测试、bug-fix-agent 定位修复 Bug中文原生支持思考过程、代码注释、文档生成全部中文无需中英切换安全合规拒绝生成恶意代码不泄露敏感信息适合企业级开发8.2 技巧 1用 explore agent 快速理解陌生代码库面对 62 个 Python 文件的项目传统方式要花半天读代码。用 explore agent 一句话搞定请分析 ManuSight 项目的完整调用链 START → role_routing → conversation_load → ... → END 返回每层的职责、关键函数、依赖关系。explore agent 会并行搜索多个目录返回完整的 9 层调用链分析报告包括 20 个跨层问题。8.3 技巧 2批量修复跨层问题 — 一次分析 20 个修复 16 个传统方式逐个修 Bug码道可以系统性地批量修复一次性分析通读 18 个核心文件~9000 行发现 20 个跨层问题按优先级排序6 个 HIGH 10 个 MEDIUM 4 个 LOW批量修复用 TODO 列表跟踪进度一次修复 16 个问题TODO 列表 ✅ #1 HIGH: 流式回退重跑链路 → 缓存流式结果 ✅ #7 MED: 缓存键加入 role ✅ #8 MED: 图编译缓存 ✅ #14 MED: 季节跨年越界判断 ...共 16 个关键点用 TODO 列表管理复杂任务每完成一个立即标记不会遗漏。8.4 技巧 3图片识别 自动语义命名项目根目录散落 10 张截图image.png、image-1.png…用analyzeImage识别内容并语义化命名image-2.png → energy-by-line.png 各产线单车电耗柱状图 image-3.png →>8.5 技巧 4文档合并 排版层次化5材料2 个 docx 3 个 md合并到一个 Word 文件并改进排版题号→ Heading 2 样式76 个题目醒目【考察点】【参考答案】→ 加粗蓝色标签代码块→ Consolas 等宽字体表格表头→ 自动加粗从所有内容都是 Normal 段落到层次分明、可读性强一次完成。8.6 技巧 5日志系统从 0 到 1发现项目日志只输出到控制台config.yaml中的output_file是死配置。码道一步到位分析根因无 FileHandler、config.yaml 配置未消费、logs/ 目录不存在新建模块logging_config.py— 统一初始化控制台 RotatingFileHandler修改入口cli.py和ui/app.py统一调用setup_logging()防重复配置Streamlit rerun 时检查已有 handler8.7 技巧 6依赖扫描 — import 语句 vs requirements.txt自动扫描src/下所有.py文件的 import 语句对比requirements.txt找出缺失 4 个langchain-core13 处使用、langchain-anthropic、pydantic、markdown多余 2 个structlog未使用、sqlparse未使用全程无需手动翻文件一条命令完成审计。8.8 技巧 7并行工具调用 — 一次读 5 个文件修改分散在 5 个文件中的 10 个问题传统方式逐个打开。码道并行读取同时读取 - ui/app.py:580 流式回退 - conversation.py:620 相对时间词 - core.py:60 缓存键 - date_parser.py:120 年份解析 - intent_classifier.py:400 季节越界5 个文件一次读完上下文充足修复更精准。8.9 技巧 8Git 操作自动化从git add到git push全自动提交信息自动生成feat: 系统修复 文档整理 日志系统 依赖修正 - 修复16个跨层问题: 流式回退/缓存/日志/日期解析/季节越界... - 日志系统: 新增logging_config.py控制台文件轮转双通道 - README整理: 图片规范化到docs/images/(11张) ...71 个文件变更一次提交推送到 CNB。8.10 技巧 9测试修复 — 断言更新 缓存清除修复代码后测试失败码道能区分代码 Bug和过时测试source llm→ 代码已改为llmrule更新断言而非改代码needs_clarification is False→ 代码逻辑已变为缺时间也澄清更新断言导入路径from common.date_parser→from manusight.common.date_parser修复根因还能识别新增缓存对测试的影响自动添加_intent_llm_cache.clear()。8.11 技巧 10CSDN 文章生成最后这篇文章本身就是用码道生成的。给一个主题和大纲方向自动生成结构完整、代码片段齐全、表格对比清晰的技术文章。九、测试与质量保障验证项结果测试用例900 个5 个预置异常全部可检出严重度排序正确SQL 注入12 种危险操作全部拦截事务回滚副作用无副作用并发读查询8 线程结果一致根因分析下钻3 层定位到具体工序十、总结核心创新点三路融合 Schema LinkingBM25 编辑距离 向量语义加权互补兼顾精确、容错、语义Recursive Adtributor 根因分析从告诉你有异常进化到告诉你为什么异常三级降级策略QueryPlan 确定性编译优先LLM 回退规则模板兜底四角色定制化洞察同一问题千人千面可推广性架构做到业务知识外置在 YAML 语义层迁移到其他行业只改配置、不改代码行业迁移改动零售换 CSV 语义层 YAML物流换 CSV 语义层 YAML能源换 CSV 语义层 YAML技术栈LangGraph LangChain DuckDB ChromaDB Streamlit Pydantic Plotly BM25 Levenshtein项目地址cnb.cool/cqsyrjyx/ManuSight如果觉得有帮助欢迎点赞收藏有问题欢迎评论区交流
返回列表