Agent Project Deep Dive

🛒 电商问数 · 项目完整拆解

NL2SQL 智能体:系统架构 · 智能体九步工作流 · LangGraph 设计 · 逐章学习笔记。归纳自 17 章实战教程(源码 didilili/shopkeeper-agent)。

← 返回 Agent 项目列表

一、系统架构:五层分工

🖥️ 服务层FastAPI 接口 + SSE 流式推送 · 前端实时展示每步执行进度 · 日志全链路追踪
🤖 智能体层LangGraph 编排九步问数工作流:Graph(可执行图)· State(共享状态)· Node(单职责节点)· Edge / 条件边(分支)
🔍 检索层Qdrant 向量库:字段与指标的语义检索 · Elasticsearch:字段真实取值的全文检索 · 双路混合召回
📚 知识层元数据知识库:统一管理有哪些表、字段什么含义、指标怎么算、字段有哪些值 · 同步脚本维护入库
🗄️ 数据层MySQL 模拟教学数仓:维度建模(事实表 + 维度表)· 承接分析查询 · 同时保存元数据

💡 一句话:数据层保事实、知识层保口径、检索层保准确、智能体层保推理、服务层保交付。

二、智能体九步工作流(完整流程图)

💬 用户提问
「华北地区各品牌的销售总额是多少?」
↓
① 关键词抽取
jieba 分词 + LLM 提炼检索关键词
↓
三路并行召回(LangGraph 并行边)
② 字段召回
Qdrant 语义检索
解决「查哪一列」
③ 指标召回
Qdrant 语义检索
解决「指标怎么算」
④ 字段取值召回
ES 全文检索
解决「条件值怎么写」
↓
⑤ 合并召回信息
三路结果去重整合
↓
⑥ 过滤指标信息 · 过滤表格信息
条件分支:与问题无关的召回内容在此剔除
↓
⑦ 补充额外上下文
时间口径、默认维度等隐含信息补全
↓
⑧ 生成 SQL
LLM 基于过滤后的上下文生成(LCEL 链)
↓
⑨ 校验 SQL
列名、表名、语法是否合法(DWMySQLRepository.validate)
✅ 校验通过
❌ 校验失败 → ⑩ 校正 SQL(把报错回喂给 LLM 修正)→ 回到校验
↓
⑪ 执行 SQL
在数仓执行查询
↓
📊 结果 + 执行过程流式返回
SSE 推送:前端逐步显示 抽取 → 召回 → 生成 → 校验 → 执行 → 结果

💡 设计要点:校验-校正是带条件边的闭环(生成 ≠ 正确);三路召回并行执行降低延迟;每个节点只做一件事并返回局部状态更新(LangGraph 的 Node 契约)。

三、LangGraph 核心设计

🧩 四个核心概念在本项目的落地

  • Graph不是画图,而是可执行的工作流图:graph.py 中注册节点、添加普通边与条件边,START 到 END 即一次完整问数。
  • StateDataAgentState 保存业务中间结果(关键词、三路召回结果、过滤后上下文、SQL、执行结果),节点间共享而非传参。
  • Node每个节点只负责一件事(抽取、召回、合并……),返回局部状态更新——单职责让节点可独立测试。
  • Edge / 条件边普通边表示固定顺序(抽取 → 三路召回);条件边表示运行时分支(校验通过执行、失败进校正)。

🛠️ 工程配套

  • Runtime ContextDataAgentContext 保存运行时工具(LLM 实例、数据库连接),与业务状态分离,依赖注入更干净。
  • 模型调用三件套统一封装 LLM:模型、temperature、token 上限从配置集中读取(支持硅基流动等 OpenAI 兼容 API),节点只复用不重复初始化。
  • 提示词集中管理所有 Prompt 集中一处维护,配合 LCEL(LangChain 表达式语言)组装最小链路。
  • Streaming节点内写出进度、astream 接收流式输出——每一步执行都能被前端实时看到,也是排查问题的第一现场。

四、逐章学习笔记(17 章)

1项目概述与数仓基础

NL2SQL 是什么;业务库 vs 数仓的区别;事实表、维度表与维度建模入门。

2整体架构与智能体流程

五层架构总览;元数据知识库 / 向量索引 / 全文索引的职责划分;九步工作流首次完整亮相。

3开发环境与基础服务

环境准备,Docker 拉起 MySQL / Qdrant / ES 等基础服务。

4项目结构与配置管理

目录分层设计;模型、数据库等配置集中管理。

5Qdrant 与 ES 接入

两个检索引擎的快速入门:向量库管语义、全文引擎管取值。

6MySQL、Embedding 与日志

数仓与元数据库落地;文本向量化;统一日志为全链路排查打底。

7元数据知识库总览

知识库的设计思路:为什么表、字段、指标、取值要分门别类管理。

8表与字段同步入库

元数据同步脚本:从数仓读取表结构,写入元数据库。

9字段与指标检索能力

构建向量索引与全文索引,让「语义找字段、全文找取值」成为可能。

10问数智能体工作流骨架

LangGraph 概念落地:定义 State / Context,占位节点,组装图,流式观察执行。

11关键词抽取与多路召回

jieba + LLM 抽取关键词;字段 / 指标 / 取值三路召回的分工与并行实现。

12召回信息合并与上下文构建

三路召回结果的去重、整合,组装成模型友好的上下文。

13信息过滤与补全

过滤与问题无关的指标和表格;补全时间口径等隐含信息——上下文贵在精不在多。

14SQL 生成与执行闭环

生成 → 校验 → 条件分支校正 → 执行;常见坑:Markdown 代码块混入、Unknown column、结果为空。

15API 接口与 FastAPI 入门

用 FastAPI 把智能体能力包装成 HTTP 服务。

16查询接口实现与依赖组装

问数接口实现,依赖注入把配置、LLM、仓储串起来。

17前后端联调与日志追踪

SSE 流式对接前端;用日志回放一次完整请求链路的排查过程。

五、高频问题排查清单

  • SQL 输出里带了 Markdown 代码块LLM 习惯性输出 ```sql 包裹——提示词里明确「只输出裸 SQL」,解析时再做剥离兜底。
  • 校验时报 Unknown column模型编造了不存在的列名——回到召回环节,说明字段上下文没给够或没过滤干净。
  • 校验通过但结果为空字段取值映射错了(如「华北」没对上真实枚举值)——检查 ES 取值召回与过滤逻辑。
  • 校正后仍然失败把报错信息回喂给 LLM 再修一轮,多次失败说明上下文有根本性缺失,别硬循环。

📌 内容归纳自实战教程学习笔记,持续更新复现进度。想交流?欢迎联系我。